[symfont] Move symfont to fontTools.misc.symfont

This commit is contained in:
Behdad Esfahbod 2017-02-20 18:00:23 -06:00
parent 724e6dab4e
commit 14b46cf7a6
2 changed files with 87 additions and 88 deletions

157
Snippets/symfont.py → Lib/fontTools/misc/symfont.py Executable file → Normal file
View File

@ -1,13 +1,10 @@
#! /usr/bin/env python
from __future__ import print_function, division, absolute_import from __future__ import print_function, division, absolute_import
from fontTools.misc.py23 import * from fontTools.misc.py23 import *
import sympy as sp
import sys
from fontTools.pens.basePen import BasePen from fontTools.pens.basePen import BasePen
from functools import partial from functools import partial
from itertools import count from itertools import count
import sympy as sp
import sys
n = 3 # Max Bezier degree; 3 for cubic, 2 for quadratic n = 3 # Max Bezier degree; 3 for cubic, 2 for quadratic
@ -40,86 +37,13 @@ BezierCurveC = tuple(
sum(C[i]*bernstein for i,bernstein in enumerate(bernsteins)) sum(C[i]*bernstein for i,bernstein in enumerate(bernsteins))
for n,bernsteins in enumerate(BernsteinPolynomial)) for n,bernsteins in enumerate(BernsteinPolynomial))
def green(f, curveXY): def green(f, curveXY):
f = -sp.integrate(sp.sympify(f), y) f = -sp.integrate(sp.sympify(f), y)
f = f.subs({x:curveXY[0], y:curveXY[1]}) f = f.subs({x:curveXY[0], y:curveXY[1]})
f = sp.integrate(f * sp.diff(curveXY[0], t), (t, 0, 1)) f = sp.integrate(f * sp.diff(curveXY[0], t), (t, 0, 1))
return f return f
def printPen(penName, funcs, file=sys.stdout):
print(
'''from __future__ import print_function, division, absolute_import
from fontTools.misc.py23 import *
from fontTools.pens.basePen import BasePen
class %s(BasePen):
def __init__(self, glyphset=None):
BasePen.__init__(self, glyphset)
'''%penName, file=file)
for name,f in funcs:
print(' self.%s = 0' % name, file=file)
print('''
def _moveTo(self, p0):
self.__startPoint = p0
def _closePath(self):
p0 = self._getCurrentPoint()
if p0 != self.__startPoint:
self._lineTo(self.__startPoint)
def _endPath(self):
p0 = self._getCurrentPoint()
if p0 != self.__startPoint:
# Green theorem is not defined on open contours.
raise NotImplementedError
''', end='', file=file)
for n in (1, 2, 3):
if n == 1:
print('''
def _lineTo(self, p1):
x0,y0 = self._getCurrentPoint()
x1,y1 = p1
''', file=file)
elif n == 2:
print('''
def _qCurveToOne(self, p1, p2):
x0,y0 = self._getCurrentPoint()
x1,y1 = p1
x2,y2 = p2
''', file=file)
elif n == 3:
print('''
def _curveToOne(self, p1, p2, p3):
x0,y0 = self._getCurrentPoint()
x1,y1 = p1
x2,y2 = p2
x3,y3 = p3
''', file=file)
subs = {P[i][j]: [X, Y][j][i] for i in range(n+1) for j in range(2)}
greens = [green(f, BezierCurve[n]) for name,f in funcs]
greens = [sp.gcd_terms(f.collect(sum(P,()))) for f in greens] # Optimize
greens = [f.subs(subs) for f in greens] # Convert to p to x/y
defs, exprs = sp.cse(greens,
optimizations='basic',
symbols=(sp.Symbol('r%d'%i) for i in count()))
for name,value in defs:
print(' %s = %s' % (name, value), file=file)
print(file=file)
for name,value in zip([f[0] for f in funcs], exprs):
print(' self.%s += %s' % (name, value), file=file)
print('''
if __name__ == '__main__':
from symfont import x, y, printPen
printPen('%s', ['''%penName, file=file)
for name,f in funcs:
print(" ('%s', %s)," % (name, str(f)), file=file)
print(' ])', file=file)
class BezierFuncs(dict): class BezierFuncs(dict):
def __init__(self, symfunc): def __init__(self, symfunc):
@ -185,6 +109,81 @@ MomentYYPen = partial(GreenPen, func=y*y)
MomentXYPen = partial(GreenPen, func=x*y) MomentXYPen = partial(GreenPen, func=x*y)
def printGreenPen(penName, funcs, file=sys.stdout):
print(
'''from __future__ import print_function, division, absolute_import
from fontTools.misc.py23 import *
from fontTools.pens.basePen import BasePen
class %s(BasePen):
def __init__(self, glyphset=None):
BasePen.__init__(self, glyphset)
'''%penName, file=file)
for name,f in funcs:
print(' self.%s = 0' % name, file=file)
print('''
def _moveTo(self, p0):
self.__startPoint = p0
def _closePath(self):
p0 = self._getCurrentPoint()
if p0 != self.__startPoint:
self._lineTo(self.__startPoint)
def _endPath(self):
p0 = self._getCurrentPoint()
if p0 != self.__startPoint:
# Green theorem is not defined on open contours.
raise NotImplementedError
''', end='', file=file)
for n in (1, 2, 3):
if n == 1:
print('''
def _lineTo(self, p1):
x0,y0 = self._getCurrentPoint()
x1,y1 = p1
''', file=file)
elif n == 2:
print('''
def _qCurveToOne(self, p1, p2):
x0,y0 = self._getCurrentPoint()
x1,y1 = p1
x2,y2 = p2
''', file=file)
elif n == 3:
print('''
def _curveToOne(self, p1, p2, p3):
x0,y0 = self._getCurrentPoint()
x1,y1 = p1
x2,y2 = p2
x3,y3 = p3
''', file=file)
subs = {P[i][j]: [X, Y][j][i] for i in range(n+1) for j in range(2)}
greens = [green(f, BezierCurve[n]) for name,f in funcs]
greens = [sp.gcd_terms(f.collect(sum(P,()))) for f in greens] # Optimize
greens = [f.subs(subs) for f in greens] # Convert to p to x/y
defs, exprs = sp.cse(greens,
optimizations='basic',
symbols=(sp.Symbol('r%d'%i) for i in count()))
for name,value in defs:
print(' %s = %s' % (name, value), file=file)
print(file=file)
for name,value in zip([f[0] for f in funcs], exprs):
print(' self.%s += %s' % (name, value), file=file)
print('''
if __name__ == '__main__':
from fontTools.misc.symfont import x, y, printGreenPen
printGreenPen('%s', ['''%penName, file=file)
for name,f in funcs:
print(" ('%s', %s)," % (name, str(f)), file=file)
print(' ])', file=file)
if __name__ == '__main__': if __name__ == '__main__':
pen = AreaPen() pen = AreaPen()
pen.moveTo((100,100)) pen.moveTo((100,100))

View File

@ -277,12 +277,12 @@ class MomentsPen(BasePen):
self.momentYY += -r108*r121/9240 - r133*r73/9240 - r134*x3/12 - r135*r55/9240 - 3*r136*(r25 + r37)/3080 - r137*(r25 + r31 + x3)/660 + r26*(r135 + 126*r46 + 378*y2*y3)/9240 + r5*(r110*r127 + 27*r133 + 42*r134 + r138 + 70*r139 + r46*r62 + 27*r51*y2 + 15*r51*y3)/9240 - r52*(r56 + r63 + r78 + r79)/9240 - r53*(r128 + r25*y3 + 42*r43 + r82 + 42*r83 + 210*r84)/9240 - r6*(r114*x3 + r116 - 14*r119 + 84*r45)/9240 + x0*(r104*r51 + r109*r64 + 90*r110*y3 + r113*y0 + r114*y0 + r129*y1 + r132*y2 + 45*r133 + 14*r134 + 126*r136 + 770*r137 + r138 + 42*r139 + 135*r46*y1 + 14*r53*y3 + r64*r90 + r66*y3 + r69*y3 + r70*y0)/9240 - y0*(90*r118 + 63*r120 + r123 - 18*r124 - 30*r125 + 162*r126 - 27*r130 - 9*r131 + r36*y3 + 30*r43*y3 + 42*r45 + r48 + r51*r93)/9240 self.momentYY += -r108*r121/9240 - r133*r73/9240 - r134*x3/12 - r135*r55/9240 - 3*r136*(r25 + r37)/3080 - r137*(r25 + r31 + x3)/660 + r26*(r135 + 126*r46 + 378*y2*y3)/9240 + r5*(r110*r127 + 27*r133 + 42*r134 + r138 + 70*r139 + r46*r62 + 27*r51*y2 + 15*r51*y3)/9240 - r52*(r56 + r63 + r78 + r79)/9240 - r53*(r128 + r25*y3 + 42*r43 + r82 + 42*r83 + 210*r84)/9240 - r6*(r114*x3 + r116 - 14*r119 + 84*r45)/9240 + x0*(r104*r51 + r109*r64 + 90*r110*y3 + r113*y0 + r114*y0 + r129*y1 + r132*y2 + 45*r133 + 14*r134 + 126*r136 + 770*r137 + r138 + 42*r139 + 135*r46*y1 + 14*r53*y3 + r64*r90 + r66*y3 + r69*y3 + r70*y0)/9240 - y0*(90*r118 + 63*r120 + r123 - 18*r124 - 30*r125 + 162*r126 - 27*r130 - 9*r131 + r36*y3 + 30*r43*y3 + 42*r45 + r48 + r51*r93)/9240
if __name__ == '__main__': if __name__ == '__main__':
from symfont import x, y, printPen from fontTools.misc.symfont import x, y, printGreenPen
printPen('MomentsPen', [ printGreenPen('MomentsPen', [
('area', 1), ('area', 1),
('momentX', x), ('momentX', x),
('momentY', y), ('momentY', y),
('momentXX', x**2), ('momentXX', x**2),
('momentXY', x*y), ('momentXY', x*y),
('momentYY', y**2), ('momentYY', y**2),
]) ])