|  |  | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | from fontTools.misc.roundTools import otRound, roundFunc | 
					
						
						|  | from fontTools.misc.psCharStrings import T2CharString | 
					
						
						|  | from fontTools.pens.basePen import BasePen | 
					
						
						|  | from fontTools.cffLib.specializer import specializeCommands, commandsToProgram | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | 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, glyphSet, roundTolerance=0.5, CFF2=False): | 
					
						
						|  | super(T2CharStringPen, self).__init__(glyphSet) | 
					
						
						|  | self.round = roundFunc(roundTolerance) | 
					
						
						|  | self._CFF2 = CFF2 | 
					
						
						|  | self._width = width | 
					
						
						|  | self._commands = [] | 
					
						
						|  | self._p0 = (0, 0) | 
					
						
						|  |  | 
					
						
						|  | def _p(self, pt): | 
					
						
						|  | 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): | 
					
						
						|  | self._commands.append(("rmoveto", self._p(pt))) | 
					
						
						|  |  | 
					
						
						|  | def _lineTo(self, pt): | 
					
						
						|  | self._commands.append(("rlineto", self._p(pt))) | 
					
						
						|  |  | 
					
						
						|  | def _curveToOne(self, pt1, pt2, pt3): | 
					
						
						|  | _p = self._p | 
					
						
						|  | self._commands.append(("rrcurveto", _p(pt1) + _p(pt2) + _p(pt3))) | 
					
						
						|  |  | 
					
						
						|  | def _closePath(self): | 
					
						
						|  | pass | 
					
						
						|  |  | 
					
						
						|  | def _endPath(self): | 
					
						
						|  | pass | 
					
						
						|  |  | 
					
						
						|  | def getCharString(self, private=None, globalSubrs=None, optimize=True): | 
					
						
						|  | 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 | 
					
						
						|  |  |