def autoNameGlyphPoints(junk, glyph): if not has_layers(glyph.font): return begin_state = glyph.layers["Fore"] end_state = glyph.layers["End state"] hoi_paths = glyph.layers["HOI paths"] Locs = dict() acc = 0 for c in begin_state: for i, p in enumerate(c): Locs[(math.floor(p.x), math.floor(p.y))] = { "contour": c, "idx": i, "total_idx": acc, "on": p.on_curve } acc += 1 new_hoi = fontforge.layer() for i, c in enumerate(hoi_paths): for p in c: p.name = '' new_hoi += c start = c[0] l = (math.floor(start.x), math.floor(start.y)) if l in Locs: info = Locs[l] new_hoi[i][0].name = str(info["total_idx"]) glyph.layers["HOI paths"] = new_hoi
def make_master(g, d1, d2): deltas = dict() for c in g.layers["HOI paths"]: dx = c[d1].x - c[d2].x dy = c[d1].y - c[d2].y deltas[int(c[0].name)] = {"dx": dx, "dy": dy} newfore = fontforge.layer() acc = 0 for i, c in enumerate(g.foreground): for j, p in enumerate(c): if acc in deltas: p.x += deltas[acc]["dx"] p.y += deltas[acc]["dy"] acc+=1 newfore+=c pts_s = list(itertools.chain.from_iterable(g.foreground)) pts_e = list(itertools.chain.from_iterable(g.layers["End state"])) deltas2 = dict() for i, pt in enumerate(pts_s): if i in deltas: continue lpt = pts_e[i] if pt.x == lpt.x and pt.y == lpt.y: continue if i-1 in deltas and pts_s[i-1].on_curve: deltas2[i] = deltas[i-1] elif i+1 in deltas and pts_s[i+1].on_curve: deltas2[i] = deltas[i+1] elif i == len(pts_s)-1 and 0 in deltas: deltas2[i] = deltas[0] acc = 0 for i, c in enumerate(newfore): for j, p in enumerate(c): if acc in deltas2: p.x += deltas2[acc]["dx"] p.y += deltas2[acc]["dy"] newfore[i][j] = p acc+=1 g.foreground = newfore
def generateAcute(font): # we will try to generate an acute from é. # é is chosen, as it's common in French, so it's probably avialable in the font glyph = font.createChar(0x00e9); layer = fontforge.layer() contour = None maxpos = -sys.maxint - 1; # we will search for the contour which has the highest point. That's probably the accent # search in foreground char = glyph.foreground for cont in char: for point in cont: if point.y > maxpos: maxpos = point.y contour = cont # search in references for ref in glyph.references: name = ref[0] mat = ref[1] char = font.createChar(fontforge.unicodeFromName(name)).foreground; for cont in char: cont.transform(mat); for point in cont: if point.y > maxpos: maxpos = point.y contour = cont # only add this contour if not contour: print "é character is invalid, accent not generated" return layer.is_quadratic = contour.is_quadratic layer += contour # save layer glyph = font.createChar(0x02ca); glyph.foreground = layer
def make_pin(glyph): glyph.preserveLayerAsUndo() new_layer = fontforge.layer() layer = glyph.layers[glyph.activeLayer] for contour in layer: points = list(contour) for i in range(0, len(points)): if points[i].on_curve and points[i].selected: if i == 0 and contour.closed and not points[-1].on_curve: points[-1].x = points[0].x points[-1].y = points[0].y elif i == len(points) - 1 and contour.closed and not points[0].on_curve: points[0].x = points[-1].x points[0].y = points[-1].y if i != len(points) - 1 and not points[i + 1].on_curve: points[i + 1].x = points[i].x points[i + 1].y = points[i].y if i != 0 and not points[i - 1].on_curve: points[i - 1].x = points[i].x points[i - 1].y = points[i].y c = point_list_to_contour(points, contour.closed, contour.is_quadratic) new_layer += c glyph.layers[glyph.activeLayer] = new_layer
def fixContour(glyph): newLayer = fontforge.layer() for contour in glyph.foreground.__iter__(): newContour = fontforge.contour() tmpContour = fontforge.contour() lastX = None; lastY = None firstX = None; firstY = None for point in contour.__iter__(): if (lastX is None) or (lastY is None): lastX = point.x; lastY = point.y firstX = point.x; firstY = point.y newContour += point else: tmpContour += point if point.on_curve: if hypot(point.x - lastX, point.y - lastY) > 3.0: newContour += tmpContour tmpContour = fontforge.contour() lastX = point.x; lastY = point.y if hypot(firstX - lastX, firstY - lastY) > 3.0: newContour += tmpContour newContour.closed = True newLayer += newContour glyph.foreground = newLayer
co = fontforge.splineCorner cu = fontforge.splineCurve tn = fontforge.splineTangent hv = fontforge.splineHVCurve ff = fontforge.font() g = ff.createMappedChar('a') cl = [(0,0,True,hv),(0,0,False),(5,-1,False),(5,0,True,hv),(5,1,False),(5,3,False),(4,4,True,hv),(3,5,False),(0,3,False),(0,2,True,hv)] c = fontforge.contour() c[:] = cl c.closed = True l = fontforge.layer() l += c g.setLayer(l,1,('select_none','hvcurve')) cc = g.layers[1][0] for (i,t) in [(0,hv),(3,hv),(6,hv),(9,hv)]: if cc[i].type != t: raise ValueError("Type of point " + str(i) + " should be " + str(t) + " rather than " + str(cc[i].type)) g.setLayer(l,1,('select_all','hvcurve','force')) cc = g.layers[1][0] for (i,t) in [(1,False),(2,True),(4,True),(5,False),(7,False),(8,False)]: if (cc[i] == c[i]) != t: print(cc[i],c[i]) raise ValueError("Coordinates of point " + str(i) + " should have " + ("stayed the same" if t else "changed"))
nc2 = next(j) except: break k += 1 if nc != nc2: raise ValueError("Corrupted contour iterator") if k != 10: raise ValueError("Corrupted contour iterator") pn = f.point(.5, .5) if not c2[3] in c or pn in c2 or not (1, 1) in c2 or (.5, .5) in c2: raise ValueError("Bad contour contains") l = f.layer() if len(l) != 0 or l.is_quadratic: raise ValueError("Bad layer values") l2 = f.layer(True) if len(l2) != 0 or not l2.is_quadratic: raise ValueError("Bad layer values") #c[:] = ptl try: l2 += c except: pass else: raise TypeError("Layer accepted contour of wrong type")
nc2 = next(j) except: break k += 1 if nc != nc2: raise ValueError("Corrupted contour iterator") if k != 10: raise ValueError("Corrupted contour iterator") pn = f.point(.5,.5) if not c2[3] in c or pn in c2 or not (1,1) in c2 or (.5,.5) in c2: raise ValueError("Bad contour contains") l = f.layer() if len(l) != 0 or l.is_quadratic: raise ValueError("Bad layer values") l2 = f.layer(True) if len(l2) != 0 or not l2.is_quadratic: raise ValueError("Bad layer values") #c[:] = ptl try: l2 += c except: pass else: raise TypeError("Layer accepted contour of wrong type")
def dupLayer(layer): newLayer = fontforge.layer() for contour in glyph.layers[layerID]: newLayer += contour return newLayer
# <codecell> font = fontforge.open(fontFileName) # <codecell> font.familyname = font.familyname+"-Blank" font.fontname = font.fontname+"-Blank" font.fullname = font.fontname+"-Blank" # <codecell> for glyph in font.glyphs(): if glyph.unicode != -1 and glyph.unicode != 95: glyph.layers[0] = fontforge.layer() glyph.layers[1] = fontforge.layer() # <codecell> #for glyph in font.glyphs(): # if glyph.unicode != -1 and glyph.unicode != 95: # resizedContour = font[95].layers[1][0].dup() # # The -5 compensates for underscores hanging 5 pixels to the left of their box # rightEdge = glyph.width - 5 # resizedContour[0].x = rightEdge # resizedContour[3].x = rightEdge # glyph.layers[1] += resizedContour # <codecell>
"closingbar_high4_conb", "capclosingbar_low1", "capclosingbar_low2", "capclosingbar_low3", "capclosingbar_low4", "capclosingbar_high1", "capclosingbar_high2", "capclosingbar_high3", "capclosingbar_high4", "teema1luuva", "teema1luuva_conr", "teema1luuvar", "teema1luuvar_conr", "teema2luuva", "teema2luuvar", "teema3luuva", "teema3luuvar", "teema4luuva", "teema4luuvar", "capteema1luuva", "capteema1luuvar", "capteema2luuva", "capteema2luuvar", "capteema3luuva", "capteema3luuvar", "capteema4luuva", "capteema4luuvar"): font[char].unlinkThisGlyph() font[char].clear() #end for # Clear the bitmaps (native script command ClearBackground();). # This does not work at the moment. Bug? for char in font: font[char].layers[0] = fontforge.layer() font.selection.all() font.removeOverlap() font.transform(psMat.scale(1.25)) # Should match scale factor in tracing.mf font.addExtrema() font.simplify(2, ("removesingletonpoints"), 0, 0, 5000) font.round() font.simplify(2, ("ignoreextrema"), 0, 0, 5000) font.addExtrema() font.round() font.simplify(2, ("setstarttoextremum"), 0, 0, 5000) font.mergeFonts("numerals.sfd") font.encoding = "unicode" font.encoding = "compacted"
# Round-trip point selection tests. import copy import fontforge as ff import pickle c0 = [(293.0,48.0,1), (291.0,48.0,1), (271.0,32.0,1), (227.0,-2.0,0), (196.8,-10.0,0), (162.0,-10.0,1), (92.0,-10.0,0), (36.0,16.0,0), (36.0,98.0,1), (36.0,166.0,0), (105.0,219.0,0), (201.0,243.0,1), (287.0,264.0,1), (290.0,265.0,0), (293.0,269.0,0), (293.0,276.0,1), (293.0,389.0,0), (246.0,406.0,0), (212.0,406.0,1), (174.0,406.0,0), (132.0,395.0,0), (132.0,364.0,1), (132.0,353.0,0), (133.0,347.0,0), (134.0,344.0,1), (136.0,340.0,0), (137.0,333.0,0), (137.0,326.0,1), (137.0,313.0,0), (119.0,292.0,0), (90.0,292.0,1), (67.0,292.0,0), (55.0,304.0,0), (55.0,328.0,1), (55.0,385.0,0), (138.0,439.0,0), (220.0,439.0,1), (293.0,439.0,0), (371.0,412.0,0), (371.0,270.0,1), (371.0,123.0,1), (371.0,77.0,0), (372.0,38.0,0), (401.0,38.0,1), (413.7,38.0,0), (430.5,47.8,0), (438.0,54.0,1), (449.3,47.7,0), (453.3,39.3,0), (455.0,27.0,1), (434.3,7.0,0), (398.3,-10.0,0), (360.0,-10.0,1), (309.6,-10.0,0), (299.0,17.0,0)] f = ff.font() g = f.createMappedChar('a') l = ff.layer() c = ff.contour() # Cubic c[:] = c0 c.closed = True l += c for (i,p) in enumerate(l[0]): if i % 5 == 0: p.selected = True g.layers[1] = l l = g.layers[1] for (i,p) in enumerate(l[0]): if (i % 5 == 0 and not p.selected) or (i % 5 != 0 and p.selected): raise ValueError("Round trip of layer changed selection status")
]) for i, cl in enumerate(clKern[1]) ]) font.alterKerningClass( subtable, clKern[0], [cls.glyphs for cls in glyphClasses], reduce(list.__add__, [[cls.offsets[i] for cls in glyphClasses] for i in range(len(clKern[0]))])) else: for glyph in font.glyphs(): newKernPairs = () for k in glyph.getPosSub(subtable): newKern = kernOffsetPostProcessing(k[5]) if (newKern != 0): newKernPairs += ((k[2], newKern), ) glyph.removePosSub(subtable) for kernPair in newKernPairs: glyph.addPosSub(subtable, kernPair[0], kernPair[1]) tempFeatureFile = destfile.replace('.sfd', '.fea') font.generateFeatureFile(tempFeatureFile, kernLookup) font.close() font = fontforge.open(sourcefile) for glyph in font.glyphs(): # if not ( glyph.background.isEmpty() ): glyph.layers[1] += glyph.background glyph.layerrefs[1] += glyph.layerrefs[0] glyph.layers[0] = fontforge.layer() font.removeLookup(kernLookup) font.mergeFeature(tempFeatureFile) font.save(destfile)
def add_glyph(font, glyph, ext): new_glyph = font.createChar(-1, glyph[0] + "." + ext) nl = fontforge.layer() for c in glyph[1]: nl += c new_glyph.layers[1] = nl