예제 #1
0
def makeCircularString(x, y, radius, angle, text, fontName, fontSize, inside=0, G=None,textAnchor='start'):
    '''make a group with circular text in it'''
    if not G: G = Group()

    angle %= 360
    pi180 = pi/180
    phi = angle*pi180
    width = stringWidth(text, fontName, fontSize)
    sig = inside and -1 or 1
    hsig = sig*0.5
    sig90 = sig*90

    if textAnchor!='start':
        if textAnchor=='middle':
            phi += sig*(0.5*width)/radius
        elif textAnchor=='end':
            phi += sig*float(width)/radius
        elif textAnchor=='numeric':
            phi += sig*float(numericXShift(textAnchor,text,width,fontName,fontSize,None))/radius

    for letter in text:
        width = stringWidth(letter, fontName, fontSize)
        beta = float(width)/radius
        h = Group()
        h.add(String(0, 0, letter, fontName=fontName,fontSize=fontSize,textAnchor="start"))
        h.translate(x+cos(phi)*radius,y+sin(phi)*radius)    #translate to radius and angle
        h.rotate((phi-hsig*beta)/pi180-sig90)               # rotate as needed
        G.add(h)                                            #add to main group
        phi -= sig*beta                                     #increment

    return G
예제 #2
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)