def AddEllipticalArc(self, x, y, w, h, startAngle, endAngle, clockwise=False): """ Draws an arc of an ellipse within bounding rect (x,y,w,h) from startArc to endArc (in radians, relative to the horizontal line of the eclipse)""" if True: import warnings warnings.warn("elliptical arcs are not supported") w = w / 2.0 h = h / 2.0 self.AddArc(x + w, y + h, ((w + h) / 2), startAngle, endAngle, clockwise) return else: #implement in terms of AddArc by applying a transformation matrix #Sigh this can't work, still need to patch wx to allow #either a) AddPath that's not a closed path or #b) allow pushing and popping of states on a path, not just on a context #a) is possible in GDI+, need to investigate other renderers. #b) is possible in Quartz and Cairo, but not in GDI+. It could #possibly be simulated by combining the current transform with option a. mtx = wx.GraphicsRenderer_GetDefaultRenderer().CreateMatrix() path = wx.GraphicsRenderer_GetDefaultRenderer().CreatePath() mtx.Translate(x + (w / 2.0), y + (h / 2.0)) mtx.Scale(w / 2.0, y / 2.0) path.AddArc(0, 0, 1, startAngle, endAngle, clockwise) path.Transform(mtx) self.AddPath(path) self.MoveToPoint(path.GetCurrentPoint()) self.CloseSubpath()
def createTransformOpsFromNode(self, node): """ Returns an oplist for transformations. This applies to a node, not the current state because the transform stack is saved in the wxGraphicsContext. This oplist does *not* include the push/pop state commands """ ops = [] transform = node.get('transform') #todo: replace this with a mapping list if transform: for transform, args in css.transformList.parseString(transform): if transform == 'scale': if len(args) == 1: x = y = args[0] else: x, y = args ops.append((wx.GraphicsContext.Scale, (x, y))) if transform == 'translate': if len(args) == 1: x = args[0] y = 0 else: x, y = args ops.append((wx.GraphicsContext.Translate, (x, y))) if transform == 'rotate': if len(args) == 3: angle, cx, cy = args angle = math.radians(angle) ops.extend([ (wx.GraphicsContext.Translate, (cx, cy)), (wx.GraphicsContext.Rotate, (angle, )), (wx.GraphicsContext.Translate, (-cx, -cy)), ]) else: angle = args[0] angle = math.radians(angle) ops.append((wx.GraphicsContext.Rotate, (angle, ))) if transform == 'matrix': matrix = wx.GraphicsRenderer_GetDefaultRenderer( ).CreateMatrix(*args) ops.append( (wx.GraphicsContext.ConcatTransform, (matrix, ))) if transform == 'skewX': matrix = wx.GraphicsRenderer_GetDefaultRenderer( ).CreateMatrix(1, 0, math.tan(math.radians(args[0])), 1, 0, 0) ops.append( (wx.GraphicsContext.ConcatTransform, (matrix, ))) if transform == 'skewY': matrix = wx.GraphicsRenderer_GetDefaultRenderer( ).CreateMatrix(1, math.tan(math.radians(args[0])), 0, 1, 0, 0) ops.append( (wx.GraphicsContext.ConcatTransform, (matrix, ))) return ops
def AddEllipticalArc(self, x, y, width, height, theta, dtheta, clockwise=False): """ Draws an arc of an ellipse within bounding rect (x,y,w,h) from startArc to endArc (in degrees, relative to the horizontal line of the eclipse) """ import wx # compute the cubic bezier and add that to the path by calling # AddCurveToPoint sub_paths = svg_extras.bezier_arc(x, y, x + width, y + height, theta, dtheta) for sub_path in sub_paths: x1, y1, cx1, cy1, cx2, cy2, x2, y2 = sub_path path = wx.GraphicsRenderer_GetDefaultRenderer().CreatePath() path.MoveToPoint(x1, y1) path.AddCurveToPoint(cx1, cy1, cx2, cy2, x2, y2) self.AddPath(path) self.MoveToPoint(path.GetCurrentPoint()) self.CloseSubpath()
def getPenFromState(self): pencolour = self.state.get('stroke', 'none') if pencolour == 'currentColor': pencolour = self.state.get('color', 'none') if pencolour == 'transparent': return wx.TRANSPARENT_PEN if pencolour == 'none': return wx.NullPen type, value = colourValue.parseString(pencolour) if type == 'URL': warnings.warn("Color servers for stroking not implemented") return wx.NullPen else: if value[:3] == (-1, -1, -1): return wx.NullPen pen = wx.Pen(wx.Colour(*value)) width = self.state.get('stroke-width') if width: width, units = values.length.parseString(width) pen.SetWidth(width) capmap = { 'butt':wx.CAP_BUTT, 'round':wx.CAP_ROUND, 'square':wx.CAP_PROJECTING } joinmap = { 'miter':wx.JOIN_MITER, 'round':wx.JOIN_ROUND, 'bevel':wx.JOIN_BEVEL } pen.SetCap(capmap.get(self.state.get('stroke-linecap', None), wx.CAP_BUTT)) pen.SetJoin(joinmap.get(self.state.get('stroke-linejoin', None), wx.JOIN_MITER)) return wx.GraphicsRenderer_GetDefaultRenderer().CreatePen(pen)
def inner(self, node): #brush = self.getBrushFromState() #pen = self.getPenFromState() #if not (brush or pen): # return None, [] path = wx.GraphicsRenderer_GetDefaultRenderer().CreatePath() func(self, node, path) ops = self.generatePathOps(path) return path, ops
def elliptical_arc_to(self, rx, ry, phi, large_arc_flag, sweep_flag, x2, y2): x1, y1 = self.GetCurrentPoint() arcs = svg_extras.elliptical_arc_to(self, rx, ry, phi, large_arc_flag, sweep_flag, x1, y1, x2, y2) for arc in arcs: path = wx.GraphicsRenderer_GetDefaultRenderer().CreatePath() path.MoveToPoint(x1, y1) path.AddCurveToPoint(*arc) self.AddPath(path) x1, y1 = self.GetCurrentPoint() self.MoveToPoint(x1, y1) self.CloseSubpath()
def OnPathChange(self, evt): path = wx.GraphicsRenderer_GetDefaultRenderer().CreatePath() self.FillPath(path) self.panel.SetPath(path)
def createNativePen(pen): return wx.GraphicsRenderer_GetDefaultRenderer().CreatePen(pen)
def createAffineMatrix(a,b,c,d,x,y): return wx.GraphicsRenderer_GetDefaultRenderer().CreateMatrix(a,b,c,d,x,y)
def makePath(): path = wx.GraphicsRenderer_GetDefaultRenderer().CreatePath() _fixup_path_methods(path) return path
def makeMatrix(*args): return wx.GraphicsRenderer_GetDefaultRenderer().CreateMatrix(*args)
from attributes import paintValue document = """<?xml version = "1.0" standalone = "no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg width = "4cm" height = "4cm" viewBox = "0 0 400 400" xmlns = "http://www.w3.org/2000/svg" version = "1.1"> <title>Example triangle01- simple example of a 'path'</title> <desc>A path that draws a triangle</desc> <rect x = "1" y = "1" width = "398" height = "398" fill = "none" stroke = "blue" /> <path d = "M 100 100 L 300 100 L 200 300 z" fill = "red" stroke = "blue" stroke-width = "3" /> </svg>""" makePath = lambda: wx.GraphicsRenderer_GetDefaultRenderer().CreatePath() def attrAsFloat(node, attr, defaultValue = "0"): val = node.get(attr, defaultValue) #TODO: process stuff like "inherit" by walking back up the nodes #fast path optimization - if it's a valid float, don't #try to parse it. try: return float(val) except ValueError: return valueToPixels(val) def valueToPixels(val, defaultUnits = "px"): #TODO manage default units from pyparsing import ParseException try: