Spaces:
Running
Running
| # Copyright (c) 2009 Type Supply LLC | |
| # Author: Tal Leming | |
| from __future__ import annotations | |
| from typing import Any, Dict, List, Tuple | |
| from fontTools.cffLib.specializer import commandsToProgram, specializeCommands | |
| from fontTools.misc.psCharStrings import T2CharString | |
| from fontTools.misc.roundTools import otRound, roundFunc | |
| from fontTools.pens.basePen import BasePen | |
| class T2CharStringPen(BasePen): | |
| """Pen to draw Type 2 CharStrings. | |
| The 'roundTolerance' argument controls the rounding of point coordinates. | |
| It is defined as the maximum absolute difference between the original | |
| float and the rounded integer value. | |
| The default tolerance of 0.5 means that all floats are rounded to integer; | |
| a value of 0 disables rounding; values in between will only round floats | |
| which are close to their integral part within the tolerated range. | |
| """ | |
| def __init__( | |
| self, | |
| width: float | None, | |
| glyphSet: Dict[str, Any] | None, | |
| roundTolerance: float = 0.5, | |
| CFF2: bool = False, | |
| ) -> None: | |
| super(T2CharStringPen, self).__init__(glyphSet) | |
| self.round = roundFunc(roundTolerance) | |
| self._CFF2 = CFF2 | |
| self._width = width | |
| self._commands: List[Tuple[str | bytes, List[float]]] = [] | |
| self._p0 = (0, 0) | |
| def _p(self, pt: Tuple[float, float]) -> List[float]: | |
| p0 = self._p0 | |
| pt = self._p0 = (self.round(pt[0]), self.round(pt[1])) | |
| return [pt[0] - p0[0], pt[1] - p0[1]] | |
| def _moveTo(self, pt: Tuple[float, float]) -> None: | |
| self._commands.append(("rmoveto", self._p(pt))) | |
| def _lineTo(self, pt: Tuple[float, float]) -> None: | |
| self._commands.append(("rlineto", self._p(pt))) | |
| def _curveToOne( | |
| self, | |
| pt1: Tuple[float, float], | |
| pt2: Tuple[float, float], | |
| pt3: Tuple[float, float], | |
| ) -> None: | |
| _p = self._p | |
| self._commands.append(("rrcurveto", _p(pt1) + _p(pt2) + _p(pt3))) | |
| def _closePath(self) -> None: | |
| pass | |
| def _endPath(self) -> None: | |
| pass | |
| def getCharString( | |
| self, | |
| private: Dict | None = None, | |
| globalSubrs: List | None = None, | |
| optimize: bool = True, | |
| ) -> T2CharString: | |
| commands = self._commands | |
| if optimize: | |
| maxstack = 48 if not self._CFF2 else 513 | |
| commands = specializeCommands( | |
| commands, generalizeFirst=False, maxstack=maxstack | |
| ) | |
| program = commandsToProgram(commands) | |
| if self._width is not None: | |
| assert ( | |
| not self._CFF2 | |
| ), "CFF2 does not allow encoding glyph width in CharString." | |
| program.insert(0, otRound(self._width)) | |
| if not self._CFF2: | |
| program.append("endchar") | |
| charString = T2CharString( | |
| program=program, private=private, globalSubrs=globalSubrs | |
| ) | |
| return charString | |