t2CharStringPen.py 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. # Copyright (c) 2009 Type Supply LLC
  2. # Author: Tal Leming
  3. from fontTools.misc.roundTools import otRound, roundFunc
  4. from fontTools.misc.psCharStrings import T2CharString
  5. from fontTools.pens.basePen import BasePen
  6. from fontTools.cffLib.specializer import specializeCommands, commandsToProgram
  7. class T2CharStringPen(BasePen):
  8. """Pen to draw Type 2 CharStrings.
  9. The 'roundTolerance' argument controls the rounding of point coordinates.
  10. It is defined as the maximum absolute difference between the original
  11. float and the rounded integer value.
  12. The default tolerance of 0.5 means that all floats are rounded to integer;
  13. a value of 0 disables rounding; values in between will only round floats
  14. which are close to their integral part within the tolerated range.
  15. """
  16. def __init__(self, width, glyphSet, roundTolerance=0.5, CFF2=False):
  17. super(T2CharStringPen, self).__init__(glyphSet)
  18. self.round = roundFunc(roundTolerance)
  19. self._CFF2 = CFF2
  20. self._width = width
  21. self._commands = []
  22. self._p0 = (0, 0)
  23. def _p(self, pt):
  24. p0 = self._p0
  25. pt = self._p0 = (self.round(pt[0]), self.round(pt[1]))
  26. return [pt[0] - p0[0], pt[1] - p0[1]]
  27. def _moveTo(self, pt):
  28. self._commands.append(("rmoveto", self._p(pt)))
  29. def _lineTo(self, pt):
  30. self._commands.append(("rlineto", self._p(pt)))
  31. def _curveToOne(self, pt1, pt2, pt3):
  32. _p = self._p
  33. self._commands.append(("rrcurveto", _p(pt1) + _p(pt2) + _p(pt3)))
  34. def _closePath(self):
  35. pass
  36. def _endPath(self):
  37. pass
  38. def getCharString(self, private=None, globalSubrs=None, optimize=True):
  39. commands = self._commands
  40. if optimize:
  41. maxstack = 48 if not self._CFF2 else 513
  42. commands = specializeCommands(
  43. commands, generalizeFirst=False, maxstack=maxstack
  44. )
  45. program = commandsToProgram(commands)
  46. if self._width is not None:
  47. assert (
  48. not self._CFF2
  49. ), "CFF2 does not allow encoding glyph width in CharString."
  50. program.insert(0, otRound(self._width))
  51. if not self._CFF2:
  52. program.append("endchar")
  53. charString = T2CharString(
  54. program=program, private=private, globalSubrs=globalSubrs
  55. )
  56. return charString