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