Exemple #1
0
def bezier_arc_from_end_points(x1, y1, rx, ry, phi, fA, fS, x2, y2):
    if phi:
        # Our box bezier arcs can't handle rotations directly
        # move to a well known point, eliminate phi and transform the other point
        mx = mmult(rotate(-phi), translate(-x1, -y1))
        tx2, ty2 = transformPoint(mx, (x2, y2))
        # Convert to box form in unrotated coords
        cx, cy, rx, ry, start_ang, extent = end_point_to_center_parameters(
            0, 0, tx2, ty2, fA, fS, rx, ry
        )
        bp = bezier_arc_from_centre(cx, cy, rx, ry, start_ang, extent)
        # Re-rotate by the desired angle and add back the translation
        mx = mmult(translate(x1, y1), rotate(phi))
        res = []
        for x1, y1, x2, y2, x3, y3, x4, y4 in bp:
            res.append(
                transformPoint(mx, (x1, y1)) + transformPoint(mx, (x2, y2)) +
                transformPoint(mx, (x3, y3)) + transformPoint(mx, (x4, y4))
            )
        return res
    else:
        cx, cy, rx, ry, start_ang, extent = end_point_to_center_parameters(
            x1, y1, x2, y2, fA, fS, rx, ry
        )
        return bezier_arc_from_centre(cx, cy, rx, ry, start_ang, extent)
def bezier_arc_from_end_points(x1, y1, rx, ry, phi, fA, fS, x2, y2):
    if (x1 == x2 and y1 == y2):
        # From https://www.w3.org/TR/SVG/implnote.html#ArcImplementationNotes:
        # If the endpoints (x1, y1) and (x2, y2) are identical, then this is
        # equivalent to omitting the elliptical arc segment entirely.
        return []
    if phi:
        # Our box bezier arcs can't handle rotations directly
        # move to a well known point, eliminate phi and transform the other point
        mx = mmult(rotate(-phi), translate(-x1, -y1))
        tx2, ty2 = transformPoint(mx, (x2, y2))
        # Convert to box form in unrotated coords
        cx, cy, rx, ry, start_ang, extent = end_point_to_center_parameters(
            0, 0, tx2, ty2, fA, fS, rx, ry)
        bp = bezier_arc_from_centre(cx, cy, rx, ry, start_ang, extent)
        # Re-rotate by the desired angle and add back the translation
        mx = mmult(translate(x1, y1), rotate(phi))
        res = []
        for x1, y1, x2, y2, x3, y3, x4, y4 in bp:
            res.append(
                transformPoint(mx, (x1, y1)) + transformPoint(mx, (x2, y2)) +
                transformPoint(mx, (x3, y3)) + transformPoint(mx, (x4, y4)))
        return res
    else:
        cx, cy, rx, ry, start_ang, extent = end_point_to_center_parameters(
            x1, y1, x2, y2, fA, fS, rx, ry)
        return bezier_arc_from_centre(cx, cy, rx, ry, start_ang, extent)
Exemple #3
0
def bezier_arc_from_end_points(x1, y1, rx, ry, phi, fA, fS, x2, y2):
    if phi:
        # Our box bezier arcs can't handle rotations directly
        # move to a well known point, eliminate phi and transform the other point
        mx = mmult(rotate(-phi), translate(-x1, -y1))
        tx2, ty2 = transformPoint(mx, (x2, y2))
        # Convert to box form in unrotated coords
        cx, cy, rx, ry, start_ang, extent = end_point_to_center_parameters(
            0, 0, tx2, ty2, fA, fS, rx, ry
        )
        bp = bezier_arc_from_centre(cx, cy, rx, ry, start_ang, extent)
        # Re-rotate by the desired angle and add back the translation
        mx = mmult(translate(x1, y1), rotate(phi))
        res = []
        for x1, y1, x2, y2, x3, y3, x4, y4 in bp:
            res.append(
                transformPoint(mx, (x1, y1)) + transformPoint(mx, (x2, y2)) +
                transformPoint(mx, (x3, y3)) + transformPoint(mx, (x4, y4))
            )
        return res
    else:
        cx, cy, rx, ry, start_ang, extent = end_point_to_center_parameters(
            x1, y1, x2, y2, fA, fS, rx, ry
        )
        return bezier_arc_from_centre(cx, cy, rx, ry, start_ang, extent)
Exemple #4
0
 def _render(self, name, intent, dataGetter, **kwds):
     from xml.sax.saxutils import escape
     spec = self.intentSpecs[intent]
     valueName = spec.valueName
     D = self._defaults.get(intent, {}).copy()
     escapeAction = D.get('escape')
     D.update(kwds)
     if self.uppercase and 'content' in D and isinstance(D['content'], str):
         D['content'] = self.upper(D['content'])
     if valueName not in kwds:
         data = dataGetter(name, intent)
         if self.uppercase and isinstance(data, str):
             data = self.upper(data)
         if escapeAction == 'escape':
             data = escape(data)
         D[valueName] = data
     if spec.preRenderFunc: spec.preRenderFunc(D)
     rml = []
     add = rml.append
     if 'rotation' in D:
         angle = D['rotation']
         add('<saveState/><rotate degrees="%s"/>' % angle)
         angle = float(angle)
         from reportlab.graphics.shapes import rotate, inverse, transformPoint
         D['x'], D['y'] = transformPoint(inverse(rotate(float(angle))),
                                         (float(D['x']), float(D['y'])))
     add(spec.rml(D))
     if 'rotation' in D: add('<restoreState/>')
     return ''.join(rml)  #+('<!--%s-->' % name)
Exemple #5
0
 def _render(self,name,intent,dataGetter,**kwds):
     from xml.sax.saxutils import escape
     spec = self.intentSpecs[intent]
     valueName = spec.valueName
     D=self._defaults.get(intent,{}).copy()
     escapeAction=D.get('escape')
     D.update(kwds)
     if self.uppercase and 'content' in D and isinstance(D['content'],str):
         D['content'] = self.upper(D['content'])
     if valueName not in kwds:
         data = dataGetter(name, intent)
         if self.uppercase and isinstance(data,str):
             data = self.upper(data)
         if escapeAction == 'escape':
             data = escape(data)
         D[valueName] = data
     if spec.preRenderFunc: spec.preRenderFunc(D)
     rml = []
     add = rml.append
     if 'rotation' in D:
         angle = D['rotation']
         add('<saveState/><rotate degrees="%s"/>' % angle)
         angle = float(angle)
         from reportlab.graphics.shapes import rotate, inverse, transformPoint
         D['x'],D['y'] = transformPoint(inverse(rotate(float(angle))),(float(D['x']),float(D['y'])))
     add(spec.rml(D))
     if 'rotation' in D: add('<restoreState/>')
     return ''.join(rml)#+('<!--%s-->' % name)
Exemple #6
0
def getBounds(obj):
    if hasattr(obj, 'getBounds'):
        # this is the preferred "future" solution :-)
        return obj.getBounds()
    # else try all the primitive shapes
    elif isinstance(obj, shapes.Line):
        return (obj.x1, obj.y1, obj.x2, obj.y2)
    elif isinstance(obj, shapes.Rect):
        return (obj.x, obj.y, obj.x + obj.width, obj.y + obj.height)
    elif isinstance(obj, shapes.Circle):
        return (obj.cx - obj.r, obj.cy - obj.r, obj.cx + obj.r, obj.cy + obj.r)
    elif isinstance(obj, shapes.Ellipse):
        return (obj.cx - obj.rx, obj.cy - obj.ry, obj.cx + obj.rx,
                obj.cy + obj.ry)
    elif isinstance(obj, shapes.Polygon):
        return getPointsBounds(obj.points)
    elif isinstance(obj, shapes.PolyLine):
        return getPointsBounds(obj.points)
    elif isinstance(obj, shapes.Wedge):
        return getPointsBounds(obj.asPolygon().points)
    elif isinstance(obj, shapes.String):
        w = stringWidth(obj.text, obj.fontName, obj.fontSize)
        x = obj.x
        tA = obj.textAnchor
        if tA != 'start':
            if tA == 'middle':
                x -= 0.5 * w
            elif tA == 'end':
                x -= w
            elif tA == 'numeric':
                x -= shapes.numericXShift(tA, obj.text, w, obj.fontName,
                                          obj.fontSize, obj.encoding)
        return (x, obj.y - 0.2 * obj.fontSize, x + w, obj.y + obj.fontSize)
    elif isinstance(obj, shapes.Path):
        xs = []
        ys = []
        points = obj.points[:]
        while points:
            xs.append(points[0])
            ys.append(points[1])
            points = points[2:]
        return (min(xs), min(ys), max(xs), max(ys))

    # then groups, which need transformation...
    elif isinstance(obj, shapes.Group):
        #iterate over each thing getting its rect
        if obj.contents:
            b = []
            for elem in obj.contents:
                b.append(getBounds(elem))
            (x1, y1, x2, y2) = getRectsBounds(b)
            trans = obj.transform
            corners = [[x1, y1], [x1, y2], [x2, y1], [x2, y2]]
            newCorners = []
            for corner in corners:
                newCorners.append(shapes.transformPoint(trans, corner))
            return getPointsBounds(newCorners)
        else:
            #empty group needs a sane default; this
            #will happen when interactively creating a group
            #nothing has been added to yet.  The alternative is
            #to handle None as an allowed return value everywhere.
            return (0, 0, 0, 0)

    elif isinstance(obj, shapes.UserNode):
        return getBounds(obj.provideNode())

    else:
        raise ValueError("Don't know how to get bounds of %s" % obj)