def subdividebezier(points, n): """This function takes three fontforge points, and yields n-1 evenly spaced fontforge points along the bezier defined by those points""" if n <= 0: raise ValueError("you cannot subdivide into less than one piece") if not type(n) == int: raise ValueError("you cannot subdivide into a non-integer number of pieces") i = 0 while i <= n: result1 = ((n-i)**2)*ux(points[0]) + 2*i*(n-i)*ux(points[1]) + i*i*ux(points[2]) result2 = ((n-i)**2)*uy(points[0]) + 2*i*(n-i)*uy(points[1]) + i*i*uy(points[2]) yield fontforge.point(result1/float(n*n), result2/float(n*n), True) i += 1
def subdivideline(points, n): """This function takes a list of tuples or lists and finds n-1 evenly spaced points (tuples) along the line that connects them in between the two points""" if n <= 0: raise ValueError("you cannot subdivide into less than one piece") if not type(n) == int: raise ValueError("you cannot subdivide into a non-integer number of pieces") i = 0 while i <= n: result1 = (n-i)*ux(points[0]) + i*ux(points[1]) result2 = (n-i)*uy(points[0]) + i*uy(points[1]) yield fontforge.point(result1/float(n), result2/float(n), True) i += 1
def glyphCurve(c): """Convert a glyph contour to a list of quad bezier curves.""" points = [] control = [] P0 = c[0] points.append([P0.x,P0.y]) for i in (arange(len(c))+1) % len(c): P = c[i] if P0.on_curve and P.on_curve: # straight segment control.append([0.5*(P0.x+P.x),0.5*(P0.y+P.y)]) points.append([P.x,P.y]) P0 = P continue elif P0.on_curve and not P.on_curve: # undecided P1 = P0 P0 = P continue elif not P0.on_curve and P.on_curve: # a single quadratic segment control.append([P0.x,P0.y]) points.append([P.x,P.y]) P0 = P continue else: # not P0.on_curve and not P.on_curve: # two quadratic segments, central point to be interpolated PM = fontforge.point() PM.x = 0.5*(P0.x+P.x) PM.y = 0.5*(P0.y+P.y) PM.on_curve = True points.append([PM.x,PM.y]) control.append([P0.x,P0.y]) P1 = PM P0 = P continue return Coords(points),Coords(control)
# Point, contour, and layer fidelity tests import copy import fontforge as f # point co = f.splineCorner # Embedded tuple p = f.point((2.3, 2.4)) if p.x != 2.3 or p.y != 2.4 or not p.on_curve or p.selected: raise ValueError("Bad point values") p = f.point((2.3, 2.4, False)) if p.x != 2.3 or p.y != 2.4 or p.on_curve or p.selected: raise ValueError("Bad point values") p = f.point((2.3, 2.4), False, co, True) if p.x != 2.3 or p.y != 2.4 or p.on_curve or not p.selected: raise ValueError("Bad point values") # Embedded List p = f.point([2.3, 2.4]) if p.x != 2.3 or p.y != 2.4 or not p.on_curve or p.selected: raise ValueError("Bad point values") p = f.point([2.3, 2.4, False]) if p.x != 2.3 or p.y != 2.4 or p.on_curve or p.selected: raise ValueError("Bad point values")
# Point, contour, and layer fidelity tests import copy import fontforge as f # point co = f.splineCorner # Embedded tuple p = f.point((2.3,2.4)) if p.x != 2.3 or p.y != 2.4 or not p.on_curve or p.selected: raise ValueError("Bad point values" ) p = f.point((2.3,2.4,False)) if p.x != 2.3 or p.y != 2.4 or p.on_curve or p.selected: raise ValueError("Bad point values" ) p = f.point((2.3,2.4),False,co,True) if p.x != 2.3 or p.y != 2.4 or p.on_curve or not p.selected: raise ValueError("Bad point values" ) # Embedded List p = f.point([2.3,2.4]) if p.x != 2.3 or p.y != 2.4 or not p.on_curve or p.selected: raise ValueError("Bad point values" ) p = f.point([2.3,2.4,False]) if p.x != 2.3 or p.y != 2.4 or p.on_curve or p.selected: raise ValueError("Bad point values" )
font.italicangle = slantAngle font.macstyle = 2 font.selection.none() font.selection.select(['more', 'unicode', 'singletons'], 0x2031, 0x20DD, 0x26AC, 0x030A, 0x2300, 0x2332, 0x2218, 0x2219, 0x2316, 0x232D, 0x23E5, 0x27C2) font.selection.select(['more', 'singletons'], 'percent', 'perthousand', 'slash', 'degree', 'copyright', 'registered', 'perpendicular') font.selection.select(['more', 'unicode', 'ranges'], 0x2500, 0x25FF) for glyph in font.selection.byGlyphs: glyph.horizontalComponentItalicCorrection = 0 glyph.italicCorrection = 0 bounds = glyph.boundingBox() dx = fontforge.point(0, bounds[3] + 50).transform(transformation).x glyph.transform(psMat.translate(dx, 0), ['partialRefs', None]) font.selection.select(['more', 'singletons'], '.notdef', '.null', 'nonmarkingreturn') font.selection.select(['more', 'ranges'], 0x0, 0x1F) font.selection.invert() for glyph in font.selection.byGlyphs: glyph.correctDirection() glyph.transform(transformation, ['partialRefs', None]) glyph.round() glyph.canonicalStart() font.fullname += " Slanted" font.appendSFNTName('English (US)', 'SubFamily', 'Italic') font.appendSFNTName(0x419, 'SubFamily', 'Наклонный')
def anchor_point_transform(anchor_point, transform): x = anchor_point[2] y = anchor_point[3] p = fontforge.point(x, y) p = p.transform(transform) return (anchor_point[0], anchor_point[1], p.x, p.y)
#!/usr/bin/env python from __future__ import print_function import fontforge import psMat import pickle print(fontforge.__version__, fontforge.version()) fontforge.font() print(pickle.loads(pickle.dumps(fontforge.point())))
#!/usr/local/bin/fontforge import fontforge Font = fontforge.open("VexillaNationum.sfd") for Glyph in Font.glyphs(): print Glyph.glyphname if Glyph.isWorthOutputting(): for Contour in Glyph.foreground: if len(Contour) == 1: X = Contour[0].x; Y = Contour[0].y Radius = 12 MagnPnct = fontforge.contour() MagnPnct += fontforge.point(X+Radius,Y+Radius,False) MagnPnct += fontforge.point(X+Radius,Y,True) MagnPnct += fontforge.point(X+Radius,Y-Radius,False) MagnPnct += fontforge.point(X+Radius,Y-Radius,False) MagnPnct += fontforge.point(X,Y-Radius,True) MagnPnct += fontforge.point(X-Radius,Y-Radius,False) MagnPnct += fontforge.point(X-Radius,Y-Radius,False) MagnPnct += fontforge.point(X-Radius,Y,True) MagnPnct += fontforge.point(X-Radius,Y+Radius,False) MagnPnct += fontforge.point(X-Radius,Y+Radius,False) MagnPnct += fontforge.point(X,Y+Radius,True) MagnPnct += fontforge.point(X+Radius,Y+Radius,False) MagnPnct.closed = True Glyph.foreground += MagnPnct Glyph.stroke("circular",16,"round","miter",()) Glyph.removeOverlap() Glyph.simplify(0,("mergelines",),0,0,0) Font.strokedfont = False Font.generate("VexillaNationum.ttf")
raise ValueError("Trailing quadratic contour point should be off-curve") pl.selected = True g.layers[1] = l l = g.layers[1] lclen = len(l[0]) for (i,p) in enumerate(l[0]): if (i < (lclen-1) and p.selected) or (i == lclen-1 and not p.selected): raise ValueError("Round trip of layer changed selection status") # Point Pickling p = ff.point(4.4, 5.5) pps = pickle.dumps(p) fpp = pickle.loads(pps) if fpp.x != 4.4 or fpp.y != 5.5 or not fpp.on_curve or fpp.selected or fpp.interpolated: print(fpp, fpp.selected, fpp.interpolated) raise ValueError("Pickling lost a value") p.on_curve = False p.selected = True pps = pickle.dumps(p) fpp = pickle.loads(pps) if fpp.x != 4.4 or fpp.y != 5.5 or fpp.on_curve or not fpp.selected or fpp.interpolated: print(fpp, fpp.selected, fpp.interpolated) raise ValueError("Pickling lost a value")
slantAngle = 75-90 transformation = psMat.skew ( math.radians (-slantAngle) ) font.italicangle = slantAngle font.macstyle = 2 font.selection.none () font.selection.select (['more', 'unicode', 'singletons'], 0x2031, 0x20DD, 0x26AC, 0x030A, 0x2300, 0x2332, 0x2218, 0x2219, 0x2316, 0x232D, 0x23E5, 0x27C2) font.selection.select (['more', 'singletons'], 'percent', 'perthousand', 'slash', 'degree', 'copyright', 'registered', 'perpendicular') font.selection.select (['more', 'unicode', 'ranges'], 0x2500, 0x25FF) for glyph in font.selection.byGlyphs: glyph.horizontalComponentItalicCorrection = 0 glyph.italicCorrection = 0 bounds = glyph.boundingBox() dx = fontforge.point(0, bounds[3]+50).transform(transformation).x glyph.transform ( psMat.translate( dx, 0 ), ['partialRefs', None] ) font.selection.select (['more', 'singletons'], '.notdef', '.null', 'nonmarkingreturn') font.selection.select (['more', 'ranges'], 0x0, 0x1F) font.selection.invert () for glyph in font.selection.byGlyphs: glyph.correctDirection () glyph.transform ( transformation, ['partialRefs', None] ) glyph.round () glyph.canonicalStart() font.fullname += " Slanted" font.appendSFNTName ('English (US)', 'SubFamily', 'Italic') font.appendSFNTName (0x419, 'SubFamily', 'Наклонный')
def averagepoint_as_ffpoint(point1, point2): """This function takes two fontforge points, and finds the average of them""" avgx = (point1.x + point2.x) / 2.0 avgy = (point1.y + point2.y) / 2.0 avgpoint = fontforge.point(avgx, avgy, True) return avgpoint