aboutsummaryrefslogtreecommitdiff
path: root/Lib/fontTools/pens/ttGlyphPen.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/fontTools/pens/ttGlyphPen.py')
-rw-r--r--Lib/fontTools/pens/ttGlyphPen.py60
1 files changed, 38 insertions, 22 deletions
diff --git a/Lib/fontTools/pens/ttGlyphPen.py b/Lib/fontTools/pens/ttGlyphPen.py
index 6e2f0d31..e7841efc 100644
--- a/Lib/fontTools/pens/ttGlyphPen.py
+++ b/Lib/fontTools/pens/ttGlyphPen.py
@@ -1,6 +1,6 @@
-from __future__ import print_function, division, absolute_import
-from fontTools.misc.py23 import *
from array import array
+from fontTools.misc.fixedTools import MAX_F2DOT14, otRound, floatToFixedToFloat
+from fontTools.misc.roundTools import otRound
from fontTools.pens.basePen import LoggingPen
from fontTools.pens.transformPen import TransformPen
from fontTools.ttLib.tables import ttProgram
@@ -12,30 +12,37 @@ from fontTools.ttLib.tables._g_l_y_f import GlyphCoordinates
__all__ = ["TTGlyphPen"]
-# the max value that can still fit in an F2Dot14:
-# 1.99993896484375
-MAX_F2DOT14 = 0x7FFF / (1 << 14)
-
-
class TTGlyphPen(LoggingPen):
"""Pen used for drawing to a TrueType glyph.
- If `handleOverflowingTransforms` is True, the components' transform values
- are checked that they don't overflow the limits of a F2Dot14 number:
- -2.0 <= v < +2.0. If any transform value exceeds these, the composite
- glyph is decomposed.
- An exception to this rule is done for values that are very close to +2.0
- (both for consistency with the -2.0 case, and for the relative frequency
- these occur in real fonts). When almost +2.0 values occur (and all other
- values are within the range -2.0 <= x <= +2.0), they are clamped to the
- maximum positive value that can still be encoded as an F2Dot14: i.e.
- 1.99993896484375.
- If False, no check is done and all components are translated unmodified
- into the glyf table, followed by an inevitable `struct.error` once an
- attempt is made to compile them.
+ This pen can be used to construct or modify glyphs in a TrueType format
+ font. After using the pen to draw, use the ``.glyph()`` method to retrieve
+ a :py:class:`~._g_l_y_f.Glyph` object representing the glyph.
"""
def __init__(self, glyphSet, handleOverflowingTransforms=True):
+ """Construct a new pen.
+
+ Args:
+ glyphSet (ttLib._TTGlyphSet): A glyphset object, used to resolve components.
+ handleOverflowingTransforms (bool): See below.
+
+ If ``handleOverflowingTransforms`` is True, the components' transform values
+ are checked that they don't overflow the limits of a F2Dot14 number:
+ -2.0 <= v < +2.0. If any transform value exceeds these, the composite
+ glyph is decomposed.
+
+ An exception to this rule is done for values that are very close to +2.0
+ (both for consistency with the -2.0 case, and for the relative frequency
+ these occur in real fonts). When almost +2.0 values occur (and all other
+ values are within the range -2.0 <= x <= +2.0), they are clamped to the
+ maximum positive value that can still be encoded as an F2Dot14: i.e.
+ 1.99993896484375.
+
+ If False, no check is done and all components are translated unmodified
+ into the glyf table, followed by an inevitable ``struct.error`` once an
+ attempt is made to compile them.
+ """
self.glyphSet = glyphSet
self.handleOverflowingTransforms = handleOverflowingTransforms
self.init()
@@ -66,6 +73,9 @@ class TTGlyphPen(LoggingPen):
assert self._isClosed(), '"move"-type point must begin a new contour.'
self._addPoint(pt, 1)
+ def curveTo(self, *points):
+ raise NotImplementedError
+
def qCurveTo(self, *points):
assert len(points) >= 1
for pt in points[:-1]:
@@ -123,8 +133,12 @@ class TTGlyphPen(LoggingPen):
component = GlyphComponent()
component.glyphName = glyphName
- component.x, component.y = transformation[4:]
- transformation = transformation[:4]
+ component.x, component.y = (otRound(v) for v in transformation[4:])
+ # quantize floats to F2Dot14 so we get same values as when decompiled
+ # from a binary glyf table
+ transformation = tuple(
+ floatToFixedToFloat(v, 14) for v in transformation[:4]
+ )
if transformation != (1, 0, 0, 1):
if (self.handleOverflowingTransforms and
any(MAX_F2DOT14 < s <= 2 for s in transformation)):
@@ -137,12 +151,14 @@ class TTGlyphPen(LoggingPen):
return components
def glyph(self, componentFlags=0x4):
+ """Returns a :py:class:`~._g_l_y_f.Glyph` object representing the glyph."""
assert self._isClosed(), "Didn't close last contour."
components = self._buildComponents(componentFlags)
glyph = Glyph()
glyph.coordinates = GlyphCoordinates(self.points)
+ glyph.coordinates.toInt()
glyph.endPtsOfContours = self.endPts
glyph.flags = array("B", self.types)
self.init()