git-svn-id: http://svn.robofab.com/branches/ufo3k@525 b5fa9d6c-a76f-4ffd-b3cb-f825fc41095c
133 lines
3.9 KiB
Python
133 lines
3.9 KiB
Python
from robofab.world import RFont
|
|
from fontTools.pens.basePen import BasePen
|
|
from robofab.misc.arrayTools import updateBounds, pointInRect, unionRect
|
|
from robofab.misc.bezierTools import calcCubicBounds, calcQuadraticBounds
|
|
from robofab.pens.filterPen import _estimateCubicCurveLength, _getCubicPoint
|
|
import math
|
|
|
|
|
|
|
|
__all__ = ["AngledMarginPen", "getAngledMargins",
|
|
"setAngledLeftMargin", "setAngledRightMargin",
|
|
"centerAngledMargins"]
|
|
|
|
|
|
|
|
class AngledMarginPen(BasePen):
|
|
"""
|
|
Angled Margin Pen
|
|
|
|
Pen to calculate the margins as if the margin lines were slanted
|
|
according to the font.info.italicAngle.
|
|
|
|
Notes:
|
|
- this pen works on the on-curve points, and approximates the distance to curves.
|
|
- results will be float.
|
|
- when used in FontLab, the resulting margins may be slightly
|
|
different from the values originally set, due to rounding errors.
|
|
- similar to what RoboFog used to do.
|
|
- RoboFog had a special attribute for "italicoffset", horizontal
|
|
shift of all glyphs. This is missing in Robofab.
|
|
"""
|
|
def __init__(self, glyphSet, width, italicAngle):
|
|
BasePen.__init__(self, glyphSet)
|
|
self.width = width
|
|
self._angle = math.radians(90+italicAngle)
|
|
self.maxSteps = 100
|
|
self.margin = None
|
|
self._left = None
|
|
self._right = None
|
|
self._start = None
|
|
self.currentPt = None
|
|
|
|
def _getAngled(self, pt):
|
|
r = (g.width + (pt[1] / math.tan(self._angle)))-pt[0]
|
|
l = pt[0]-((pt[1] / math.tan(self._angle)))
|
|
if self._right is None:
|
|
self._right = r
|
|
else:
|
|
self._right = min(self._right, r)
|
|
if self._left is None:
|
|
self._left = l
|
|
else:
|
|
self._left = min(self._left, l)
|
|
#print pt, l, r
|
|
self.margin = self._left, self._right
|
|
|
|
def _moveTo(self, pt):
|
|
self._start = self.currentPt = pt
|
|
|
|
def _addMoveTo(self):
|
|
if self._start is None:
|
|
return
|
|
self._start = self.currentPt = None
|
|
|
|
def _lineTo(self, pt):
|
|
self._addMoveTo()
|
|
self._getAngled(pt)
|
|
|
|
def _curveToOne(self, pt1, pt2, pt3):
|
|
step = 1.0/self.maxSteps
|
|
factors = range(0, self.maxSteps+1)
|
|
for i in factors:
|
|
pt = _getCubicPoint(i*step, self.currentPt, pt1, pt2, pt3)
|
|
self._getAngled(pt)
|
|
self.currentPt = pt3
|
|
|
|
def _qCurveToOne(self, bcp, pt):
|
|
self._addMoveTo()
|
|
# add curve tracing magic here.
|
|
self._getAngled(pt)
|
|
self.currentPt = pt3
|
|
|
|
def getAngledMargins(glyph, font):
|
|
"""Get the angled margins for this glyph."""
|
|
pen = AngledMarginPen(font, glyph.width, font.info.italicAngle)
|
|
glyph.draw(pen)
|
|
return pen.margin
|
|
|
|
def setAngledLeftMargin(glyph, font, value):
|
|
"""Set the left angled margin to value, adjusted for font.info.italicAngle."""
|
|
pen = AngledMarginPen(font, glyph.width, font.info.italicAngle)
|
|
g.draw(pen)
|
|
isLeft, isRight = pen.margin
|
|
glyph.leftMargin += value-isLeft
|
|
|
|
def setAngledRightMargin(glyph, font, value):
|
|
"""Set the right angled margin to value, adjusted for font.info.italicAngle."""
|
|
pen = AngledMarginPen(font, glyph.width, font.info.italicAngle)
|
|
g.draw(pen)
|
|
isLeft, isRight = pen.margin
|
|
glyph.rightMargin += value-isRight
|
|
|
|
def centerAngledMargins(glyph, font):
|
|
"""Center the glyph on angled margins."""
|
|
pen = AngledMarginPen(font, glyph.width, font.info.italicAngle)
|
|
g.draw(pen)
|
|
isLeft, isRight = pen.margin
|
|
setAngledLeftMargin(glyph, font, (isLeft+isRight)*.5)
|
|
setAngledRightMargin(glyph, font, (isLeft+isRight)*.5)
|
|
|
|
def guessItalicOffset(glyph, font):
|
|
"""Guess the italic offset based on the margins of a symetric glyph.
|
|
For instance H or I.
|
|
"""
|
|
l, r = getAngledMargins(glyph, font)
|
|
return l - (l+r)*.5
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
# example for FontLab, with a glyph open.
|
|
from robofab.world import CurrentFont, CurrentGlyph
|
|
g = CurrentGlyph()
|
|
f = CurrentFont()
|
|
|
|
print "margins!", getAngledMargins(g, f)
|
|
# set the angled margin to a value
|
|
m = 50
|
|
setAngledLeftMargin(g, f, m)
|
|
setAngledRightMargin(g, f, m)
|
|
g.update()
|
|
|