Esempio n. 1
0
def getFont(charater, size, x_offset, y_offset):
    font_file = "open-sans/OpenSans-Light.ttf"
    font = ttx.TTFont(font_file)
    g = glyph.Glyph(glyphquery.glyphName(font, charater))
    contours = g.calculateContours(font)
    points = []
    for letter in contours:
        xy = (glyph.decomposeOutline(letter))
        for p in xy:
            points.append(
                stitchcode.Point(x_offset + (p[0] / size),
                                 y_offset + (p[1] / size), False))
    return points
Esempio n. 2
0
def get_char(character, size, x_offset, y_offset, font):
    g = glyph.Glyph(glyphquery.glyphName(font, character))
    contours = g.calculateContours(font)
    seen = set()
    coord = []
    points = []
    for parts in contours:
        xy = (glyph.decomposeOutline(parts))
        for p in xy:
            new_point = stitchcode.Point(x_offset + (p[0] / size),
                                         y_offset + (p[1] / size), False)
            if len(points) is 0 or straight_stitch.distance(
                    points[-1], new_point) > 2:
                points.append(new_point)
        if len(points) is not 0:
            points[len(points) - 1].jump = True
            coord.append(points)
            points = []
    if len(points) is not 0:
        points[len(points) - 1].jump = True
        coord.append(points)
    return coord
Esempio n. 3
0
from ttfquery import describe, glyphquery, glyph


# Set font here ----->
f = describe.openFont("/Library/Fonts/Impact.ttf")

# Set character here, in this case its C
n = glyphquery.glyphName(f, 'C')
g = glyph.Glyph(n)
c = g.calculateContours(f)
o = glyph.decomposeOutline(c[1])

# Print out the Polyline
print o
Esempio n. 4
0
def text(pos=(0,0), text="", font=None, height=1.0, align='left', spacing=0.03, rotate=0.0,
         scale=1.0, xscale=1.0, yscale=1.0, thickness=None, vertical_spacing=None,
         info=False):
    # If info == True, the caller wants the additional info such as upper-left, etc.
    # In this case we return an instance of the class text_info, with the Polygon as
    # an attribute, text_info.Polygon. The main client of this extra info is the text object.
    if thickness is not None:
        raise AttributeError("Thickness is not allowed in a text shape.")
    if scale != 1.0: xscale = yscale = scale
    lines = text.split('\n')
    while lines[-1] == '\n': # strip off trailing newlines
        lines = lines[:-1]
    if font is None:
        font = "serif"
    font = describe.openFont(findFont(font))
    
    try:
        fonth = glyphquery.charHeight(font)
    except:
        fonth = 1000
    if fonth == 0: fonth = 1000
    
    try:
        desc = glyphquery.charDescent(font) # charDescent may not be present
        fontheight = fonth+desc
        fontscale = 1./fontheight
        descent = fontscale*desc
    except:
        descent = -0.3*height # approximate value
        fontheight = 0.7*fonth
        fontscale = 1.3/fontheight
        
    if vertical_spacing is None:
        vertical_spacing = height*fontscale*glyphquery.lineHeight(font)

    excludef_list = [("ITCEdscr")]
    excludec_list = [("FRSCRIPT", "A"), ("jokerman", "O"),
                    ("vivaldii", "O"), ("vivaldii", "Q"),
                    ("vivaldii", "R")]
    
    ptext = [] 
    widths = []
    width = 0.0
    starts = []
    start = 0.0

    for line in range(len(lines)):
        ptext.append(Polygon())
        bb = 0
        
        for newchar in lines[line]:
            if newchar == " ":
                try:
                    if a:
                        bx = a.boundingBox()
                        bba = bx[1]-bx[0]
                        bba = min(bba, 700)
                        bb += bba
                except:
                    pass
                continue
            n = glyphquery.glyphName(font, newchar)

            if n == ".notdef":
                print("The character '"+newchar+"' is not supported in the font "+font)
                continue
            
            g = glyph.Glyph(n)
            c = g.calculateContours(font)
            contours = []

            for contour in c:
                contours.append(glyph.decomposeOutline(contour))
                if len(contours[-1]) == 0: contours.pop()

            for contour in contours:
                pp = 0
                for i in range(len(contour)-1):
                    if (contour[i][0] == contour[i+1][0]) and (contour[i][1] == contour[i+1][1]):
                        contour.pop(i)
                        pp += 1
                        if i+pp >= len(contour)-1: break

            def lenctr(contour):
                totlen = 0
                for j in range(len(contour)-1):
                    totlen += (vis.vector(contour[j])-vis.vector(contour[j+1])).mag
                return totlen

            lc = len(contours)
            
            if lc >= 4:
                mli = 0
                maxl = 0
                lengths = []
                for i in range(len(contours)):
                    totlen = lenctr(contours[i])
                    lengths.append((totlen,i))
                    if totlen > maxl:
                        mli = i
                        maxl = totlen

                lengths.sort()
                lengths.reverse()
                ocontours = []
                for ll in lengths:
                    ocontours.append(contours[ll[1]])
                contours = ocontours

                indxf = -1
                indxc = -1
                if (mli > 0 and newchar != "%"):
                    try: indxf = excludef_list.index(self.font)
                    except: pass
                    if indxf == -1:
                        try: indxc = excludec_list.index((self.font, newchar))
                        except: pass
                    if (indxf == -1 and indxc == -1):
                        maxc = contours.pop(mli)
                        contours.insert(0, maxc)
                               
            a = Polygon(contours[0])
            for i in range(1,len(contours)):
                b = Polygon(contours[i])
                if a.covers(b): a = a - b
                elif b.covers(a): a = b - a
                else: a = a + b

            a.shift(bb - a.boundingBox()[0] ,0)
           
            ptext[line] += a
            
            bx = ptext[line].boundingBox()
            bb = bx[1] - bx[0] + spacing*fontheight

        newwidth = fontscale*height*(ptext[line].boundingBox()[1]-ptext[line].boundingBox()[0])
        widths.append(newwidth)
        if newwidth > width: width = newwidth
        
        ptext[line].scale(xscale*fontscale*height, yscale*fontscale*height, 0, 0)
        
    for line in range(len(lines)):
        if align == 'left':
            ptext[line].shift(-width/2,-line*vertical_spacing)
        elif align == 'right':
            ptext[line].shift(width/2-widths[line],-line*vertical_spacing)
        else:
            ptext[line].shift(-widths[line]/2,-line*vertical_spacing)
        ptext[line].shift(pos[0], pos[1])
        if rotate != 0.0: ptext[line].rotate(rotate)
        if line == 0:
            shape = ptext[0]
            upper_left = vis.vector(ptext[line].boundingBox()[0],ptext[line].boundingBox()[3],0)
            upper_right = vis.vector(ptext[line].boundingBox()[1],ptext[line].boundingBox()[3],0)
            lower_left = vis.vector(ptext[line].boundingBox()[0],ptext[line].boundingBox()[2],0)
            lower_right = vis.vector(ptext[line].boundingBox()[1],ptext[line].boundingBox()[2],0)
        else:
            shape += ptext[line]
            xleft = ptext[line].boundingBox()[0]
            xright = ptext[line].boundingBox()[1]
            y = ptext[line].boundingBox()[2]
            if xleft < upper_left.x:
                upper_left.x = xleft
            if xright > upper_right.x:
                upper_right.x = xright
            lower_left = vis.vector(upper_left.x,ptext[line].boundingBox()[2],0)
            lower_right = vis.vector(upper_right.x,ptext[line].boundingBox()[2],0)

    dy = vis.vector(0,(upper_left.y-lower_left.y)/2-height,0)
    shape.shift(0,dy.y)
    if not info: return shape

    info = text_info()
    info.Polygon = shape
    info.upper_left = upper_left+dy
    info.upper_right = upper_right+dy
    info.lower_left = lower_left+dy
    info.lower_right = lower_right+dy
    if align == 'left':
        x = 0
    elif align == 'right':
        x = -width
    elif align == 'center':
        x = -0.5*width
    info.start = vis.vector(x,0,0)+dy
    info.starts = []
    for line in range(len(lines)):
        if align == 'left':
            x = 0
        elif align == 'right':
            x = -widths[line]
        elif align == 'center':
            x = -0.5*widths[line]
        info.starts.append(vis.vector(x,line*vertical_spacing,0)+dy)
    
    info.width = width
    info.widths = widths
    info.descent = descent
    info.vertical_spacing = vertical_spacing
    info.align = align
    info.height = height
    
    return info
Esempio n. 5
0
def convert_text(dict_values, fonts, mtext):
    layer = dict_values[8][0][0]
    text = ("".join(dict_values[3][0][0])
            if 3 in dict_values else "") + dict_values[1][0][0]
    xoffset = float(dict_values[10][0][0])
    yoffset = float(dict_values[20][0][0])
    height = float(dict_values[40][0][0])
    rotation = float(
        dict_values[50][0][0]) / 180.0 * math.pi if 50 in dict_values else 0
    font = fonts[dict_values[7][0][0].lower() if 7 in
                 dict_values else "standard"]
    print("using font", font)

    if mtext:
        boxwidth = float(dict_values[41][0][0]) if 41 in dict_values else 1
        x_scale = 1
        attachment = int(dict_values[71][0][0]) if 71 in dict_values else 1

        text = re.sub("\\\\[^;]*;", "", text)
        text = re.sub("([^\\\\])\\\\P", "\g<1>\\n", text)
        spacing_fac = float(dict_values[44][0][0]) if 44 in dict_values else 1

    else:
        boxwidth = 1  #None raised error
        x_scale = float(dict_values[41][0][0]) if 41 in dict_values else 1
        xalign = float(
            dict_values[11][0][0]
        ) if 11 in dict_values else None  #only used for Horizontal text justification typ == 3
        yalign = float(
            dict_values[21][0][0]
        ) if 11 in dict_values else None  #only used for Horizontal text justification typ == 3
        drawdir = int(
            dict_values[71][0][0]
        ) if 71 in dict_values else 0  #mirroring in X (=2) or Y (=4) direction
        h_text_just = int(
            dict_values[72][0][0]
        ) if 72 in dict_values else 0  #0=left 1=center 2=right 3=aligned
        v_text_just = int(
            dict_values[73][0][0]
        ) if 73 in dict_values else 3  #0=baseline 1=bottom 2=middle 3=top
        spacing_fac = 1

    for number, name in [(51, "'oblique angle'")]:
        if number in dict_values:
            print "INFO: sorry but option ", name, "(", number, ") is not supported yet"

    cheight = float(glyphquery.charHeight(font)) / 1.32  #magic number
    objects = []
    boxwidth /= x_scale * height / cheight
    charoff = 0
    lineno = 1
    lines = [[]]

    for n, letter in enumerate(text):
        glname = glyphquery.glyphName(font, letter)
        glwidth = glyphquery.width(font, glname)

        print(glname, glwidth, letter, charoff)

        if letter == "\n" or (boxwidth and charoff + glwidth > boxwidth):
            lines.append(list())
            #charoff         = 0 # temprarily deactivated, sets charoff always to 0 else...
            lineno += 1

        if letter != "\n":
            boundaries = [cheight * 10, cheight * 10, 0, 0]
            for c in glyph.Glyph(glname).calculateContours(font):
                outlines = glyph.decomposeOutline(c, 2)
                first = True
                lines[-1].append({"layer": layer, "command": "G36*"})
                for l in outlines:
                    org_x = (l[0] + charoff) * x_scale * height / cheight
                    org_y = l[1] * height / cheight
                    x = org_x * math.cos(rotation) - org_y * math.sin(
                        rotation) + xoffset
                    y = org_x * math.sin(rotation) + org_y * math.cos(
                        rotation) + yoffset

                    # changes polarity -> clear holes in fonts
                    if first and (boundaries[0] < l[0] and l[0] < boundaries[2]
                                  and boundaries[1] < l[1]
                                  and l[1] < boundaries[3]):
                        lines[-1].pop(
                        )  #pop the last G36; the gerber file is not read correctly if LPC comes within a G36-G37 Block
                        lines[-1].append({"layer": layer, "command": "%LPC*%"})
                        lines[-1].append({"layer": layer, "command": "G36*"})

                    boundaries[0] = min(boundaries[0], l[0])
                    boundaries[1] = min(boundaries[1], l[1])
                    boundaries[2] = max(boundaries[2], l[0])
                    boundaries[3] = max(boundaries[3], l[1])

                    #x*=scaling#
                    #y*=scaling#

                    lines[-1].append({
                        "layer": layer,
                        "device": "C,0.001*",
                        "x": x,
                        "y": y,
                        "style": "D02" if first else "D01"
                    })
                    first = False
                lines[-1].append({"layer": layer, "command": "G37*"})
            lines[-1].append({"layer": layer, "command": "%LPD*%"})
            charoff += glwidth

        #print(lines)#

    #respect the alignment (only affects MTEXT. For TEXT it is already considered
    if mtext:
        spacing = height / 3 * 5 * spacing_fac
        textwidth = charoff * x_scale * height / cheight
        vertical = int((attachment - 1) / 3)  #0=oben 1=mitte 2=unten
        horizontal = (attachment - 1) % 3  #0=links 1=mitte 2=rechts

        if horizontal == 0: shift_x = 0  #links
        elif horizontal == 1: shift_x = -textwidth / 2  #mitte
        elif horizontal == 2: shift_x = -textwidth  #rechts

        lineno = 0
        for line_objects in lines:
            if vertical == 0: shift_y = -height - (lineno - 1) * spacing  #oben
            elif vertical == 1:
                shift_y = (len(lines) - lineno) * spacing / 2  #mitte
            elif vertical == 2:
                shift_y = (len(lines) - lineno) * spacing  #unten

            lineno += 1
            for o in line_objects:
                if "x" in o: o["x"] += shift_x
                if "y" in o: o["y"] += shift_y

    for line_objects in lines:
        objects.extend(line_objects)

    return objects, True