diff options
author | Maxim Yurchuk <maxim-yurchuk@ydb.tech> | 2024-10-18 20:31:38 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-10-18 20:31:38 +0300 |
commit | 2a74bac2d2d3bccb4e10120f1ead805640ec9dd0 (patch) | |
tree | 047e4818ced5aaf73f58517629e5260b5291f9f0 /contrib/python/fonttools/fontTools/pens | |
parent | 2d9656823e9521d8c29ea4c9a1d0eab78391abfc (diff) | |
parent | 3d834a1923bbf9403cd4a448e7f32b670aa4124f (diff) | |
download | ydb-2a74bac2d2d3bccb4e10120f1ead805640ec9dd0.tar.gz |
Merge pull request #10502 from ydb-platform/mergelibs-241016-1210
Library import 241016-1210
Diffstat (limited to 'contrib/python/fonttools/fontTools/pens')
5 files changed, 173 insertions, 156 deletions
diff --git a/contrib/python/fonttools/fontTools/pens/freetypePen.py b/contrib/python/fonttools/fontTools/pens/freetypePen.py index 870776bc7b..065da932a2 100644 --- a/contrib/python/fonttools/fontTools/pens/freetypePen.py +++ b/contrib/python/fonttools/fontTools/pens/freetypePen.py @@ -46,7 +46,7 @@ class FreeTypePen(BasePen): glyphSet: a dictionary of drawable glyph objects keyed by name used to resolve component references in composite glyphs. - :Examples: + Examples: If `numpy` and `matplotlib` is available, the following code will show the glyph image of `fi` in a new window:: @@ -178,7 +178,7 @@ class FreeTypePen(BasePen): object of the resulted bitmap and ``size`` is a 2-tuple of its dimension. - :Notes: + Notes: The image size should always be given explicitly if you need to get a proper glyph image. When ``width`` and ``height`` are omitted, it forcifully fits to the bounding box and the side bearings get @@ -188,15 +188,15 @@ class FreeTypePen(BasePen): maintained but RSB won’t. The difference between the two becomes more obvious when rotate or skew transformation is applied. - :Example: - .. code-block:: + Example: + .. code-block:: pycon + >>> >> pen = FreeTypePen(None) >> glyph.draw(pen) >> buf, size = pen.buffer(width=500, height=1000) >> type(buf), len(buf), size (<class 'bytes'>, 500000, (500, 1000)) - """ transform = transform or Transform() if not hasattr(transform, "transformPoint"): @@ -269,7 +269,7 @@ class FreeTypePen(BasePen): A ``numpy.ndarray`` object with a shape of ``(height, width)``. Each element takes a value in the range of ``[0.0, 1.0]``. - :Notes: + Notes: The image size should always be given explicitly if you need to get a proper glyph image. When ``width`` and ``height`` are omitted, it forcifully fits to the bounding box and the side bearings get @@ -279,15 +279,17 @@ class FreeTypePen(BasePen): maintained but RSB won’t. The difference between the two becomes more obvious when rotate or skew transformation is applied. - :Example: - .. code-block:: + Example: + .. code-block:: pycon + >>> >> pen = FreeTypePen(None) >> glyph.draw(pen) >> arr = pen.array(width=500, height=1000) >> type(a), a.shape (<class 'numpy.ndarray'>, (1000, 500)) """ + import numpy as np buf, size = self.buffer( @@ -318,7 +320,7 @@ class FreeTypePen(BasePen): rendering glyphs with negative sidebearings without clipping. evenOdd: Pass ``True`` for even-odd fill instead of non-zero. - :Notes: + Notes: The image size should always be given explicitly if you need to get a proper glyph image. When ``width`` and ``height`` are omitted, it forcifully fits to the bounding box and the side bearings get @@ -328,9 +330,10 @@ class FreeTypePen(BasePen): maintained but RSB won’t. The difference between the two becomes more obvious when rotate or skew transformation is applied. - :Example: - .. code-block:: + Example: + .. code-block:: pycon + >>> >> pen = FreeTypePen(None) >> glyph.draw(pen) >> pen.show(width=500, height=1000) @@ -370,7 +373,7 @@ class FreeTypePen(BasePen): A ``PIL.image`` object. The image is filled in black with alpha channel obtained from the rendered bitmap. - :Notes: + Notes: The image size should always be given explicitly if you need to get a proper glyph image. When ``width`` and ``height`` are omitted, it forcifully fits to the bounding box and the side bearings get @@ -380,9 +383,10 @@ class FreeTypePen(BasePen): maintained but RSB won’t. The difference between the two becomes more obvious when rotate or skew transformation is applied. - :Example: - .. code-block:: + Example: + .. code-block:: pycon + >>> >> pen = FreeTypePen(None) >> glyph.draw(pen) >> img = pen.image(width=500, height=1000) diff --git a/contrib/python/fonttools/fontTools/pens/pointInsidePen.py b/contrib/python/fonttools/fontTools/pens/pointInsidePen.py index e1fbbbcb1d..0c022d31bc 100644 --- a/contrib/python/fonttools/fontTools/pens/pointInsidePen.py +++ b/contrib/python/fonttools/fontTools/pens/pointInsidePen.py @@ -15,7 +15,8 @@ class PointInsidePen(BasePen): Instances of this class can be recycled, as long as the setTestPoint() method is used to set the new point to test. - Typical usage: + :Example: + .. code-block:: pen = PointInsidePen(glyphSet, (100, 200)) outline.draw(pen) diff --git a/contrib/python/fonttools/fontTools/pens/recordingPen.py b/contrib/python/fonttools/fontTools/pens/recordingPen.py index ba165e1951..b8a817ccf4 100644 --- a/contrib/python/fonttools/fontTools/pens/recordingPen.py +++ b/contrib/python/fonttools/fontTools/pens/recordingPen.py @@ -33,6 +33,7 @@ class RecordingPen(AbstractPen): pen.replay(otherPen). :Example: + .. code-block:: from fontTools.ttLib import TTFont from fontTools.pens.recordingPen import RecordingPen @@ -91,47 +92,48 @@ class DecomposingRecordingPen(DecomposingPen, RecordingPen): by thir name; other arguments are forwarded to the DecomposingPen's constructor:: - >>> class SimpleGlyph(object): - ... def draw(self, pen): - ... pen.moveTo((0, 0)) - ... pen.curveTo((1, 1), (2, 2), (3, 3)) - ... pen.closePath() - >>> class CompositeGlyph(object): - ... def draw(self, pen): - ... pen.addComponent('a', (1, 0, 0, 1, -1, 1)) - >>> class MissingComponent(object): - ... def draw(self, pen): - ... pen.addComponent('foobar', (1, 0, 0, 1, 0, 0)) - >>> class FlippedComponent(object): - ... def draw(self, pen): - ... pen.addComponent('a', (-1, 0, 0, 1, 0, 0)) - >>> glyphSet = { - ... 'a': SimpleGlyph(), - ... 'b': CompositeGlyph(), - ... 'c': MissingComponent(), - ... 'd': FlippedComponent(), - ... } - >>> for name, glyph in sorted(glyphSet.items()): - ... pen = DecomposingRecordingPen(glyphSet) - ... try: - ... glyph.draw(pen) - ... except pen.MissingComponentError: - ... pass - ... print("{}: {}".format(name, pen.value)) - a: [('moveTo', ((0, 0),)), ('curveTo', ((1, 1), (2, 2), (3, 3))), ('closePath', ())] - b: [('moveTo', ((-1, 1),)), ('curveTo', ((0, 2), (1, 3), (2, 4))), ('closePath', ())] - c: [] - d: [('moveTo', ((0, 0),)), ('curveTo', ((-1, 1), (-2, 2), (-3, 3))), ('closePath', ())] - >>> for name, glyph in sorted(glyphSet.items()): - ... pen = DecomposingRecordingPen( - ... glyphSet, skipMissingComponents=True, reverseFlipped=True, - ... ) - ... glyph.draw(pen) - ... print("{}: {}".format(name, pen.value)) - a: [('moveTo', ((0, 0),)), ('curveTo', ((1, 1), (2, 2), (3, 3))), ('closePath', ())] - b: [('moveTo', ((-1, 1),)), ('curveTo', ((0, 2), (1, 3), (2, 4))), ('closePath', ())] - c: [] - d: [('moveTo', ((0, 0),)), ('lineTo', ((-3, 3),)), ('curveTo', ((-2, 2), (-1, 1), (0, 0))), ('closePath', ())] + >>> class SimpleGlyph(object): + ... def draw(self, pen): + ... pen.moveTo((0, 0)) + ... pen.curveTo((1, 1), (2, 2), (3, 3)) + ... pen.closePath() + >>> class CompositeGlyph(object): + ... def draw(self, pen): + ... pen.addComponent('a', (1, 0, 0, 1, -1, 1)) + >>> class MissingComponent(object): + ... def draw(self, pen): + ... pen.addComponent('foobar', (1, 0, 0, 1, 0, 0)) + >>> class FlippedComponent(object): + ... def draw(self, pen): + ... pen.addComponent('a', (-1, 0, 0, 1, 0, 0)) + >>> glyphSet = { + ... 'a': SimpleGlyph(), + ... 'b': CompositeGlyph(), + ... 'c': MissingComponent(), + ... 'd': FlippedComponent(), + ... } + >>> for name, glyph in sorted(glyphSet.items()): + ... pen = DecomposingRecordingPen(glyphSet) + ... try: + ... glyph.draw(pen) + ... except pen.MissingComponentError: + ... pass + ... print("{}: {}".format(name, pen.value)) + a: [('moveTo', ((0, 0),)), ('curveTo', ((1, 1), (2, 2), (3, 3))), ('closePath', ())] + b: [('moveTo', ((-1, 1),)), ('curveTo', ((0, 2), (1, 3), (2, 4))), ('closePath', ())] + c: [] + d: [('moveTo', ((0, 0),)), ('curveTo', ((-1, 1), (-2, 2), (-3, 3))), ('closePath', ())] + + >>> for name, glyph in sorted(glyphSet.items()): + ... pen = DecomposingRecordingPen( + ... glyphSet, skipMissingComponents=True, reverseFlipped=True, + ... ) + ... glyph.draw(pen) + ... print("{}: {}".format(name, pen.value)) + a: [('moveTo', ((0, 0),)), ('curveTo', ((1, 1), (2, 2), (3, 3))), ('closePath', ())] + b: [('moveTo', ((-1, 1),)), ('curveTo', ((0, 2), (1, 3), (2, 4))), ('closePath', ())] + c: [] + d: [('moveTo', ((0, 0),)), ('lineTo', ((-3, 3),)), ('curveTo', ((-2, 2), (-1, 1), (0, 0))), ('closePath', ())] """ # raises MissingComponentError(KeyError) if base glyph is not found in glyphSet @@ -145,6 +147,7 @@ class RecordingPointPen(AbstractPointPen): pointPen.replay(otherPointPen). :Example: + .. code-block:: from defcon import Font from fontTools.pens.recordingPen import RecordingPointPen @@ -211,81 +214,82 @@ class DecomposingRecordingPointPen(DecomposingPointPen, RecordingPointPen): keyed by thir name; other arguments are forwarded to the DecomposingPointPen's constructor:: - >>> from pprint import pprint - >>> class SimpleGlyph(object): - ... def drawPoints(self, pen): - ... pen.beginPath() - ... pen.addPoint((0, 0), "line") - ... pen.addPoint((1, 1)) - ... pen.addPoint((2, 2)) - ... pen.addPoint((3, 3), "curve") - ... pen.endPath() - >>> class CompositeGlyph(object): - ... def drawPoints(self, pen): - ... pen.addComponent('a', (1, 0, 0, 1, -1, 1)) - >>> class MissingComponent(object): - ... def drawPoints(self, pen): - ... pen.addComponent('foobar', (1, 0, 0, 1, 0, 0)) - >>> class FlippedComponent(object): - ... def drawPoints(self, pen): - ... pen.addComponent('a', (-1, 0, 0, 1, 0, 0)) - >>> glyphSet = { - ... 'a': SimpleGlyph(), - ... 'b': CompositeGlyph(), - ... 'c': MissingComponent(), - ... 'd': FlippedComponent(), - ... } - >>> for name, glyph in sorted(glyphSet.items()): - ... pen = DecomposingRecordingPointPen(glyphSet) - ... try: - ... glyph.drawPoints(pen) - ... except pen.MissingComponentError: - ... pass - ... pprint({name: pen.value}) - {'a': [('beginPath', (), {}), - ('addPoint', ((0, 0), 'line', False, None), {}), - ('addPoint', ((1, 1), None, False, None), {}), - ('addPoint', ((2, 2), None, False, None), {}), - ('addPoint', ((3, 3), 'curve', False, None), {}), - ('endPath', (), {})]} - {'b': [('beginPath', (), {}), - ('addPoint', ((-1, 1), 'line', False, None), {}), - ('addPoint', ((0, 2), None, False, None), {}), - ('addPoint', ((1, 3), None, False, None), {}), - ('addPoint', ((2, 4), 'curve', False, None), {}), - ('endPath', (), {})]} - {'c': []} - {'d': [('beginPath', (), {}), - ('addPoint', ((0, 0), 'line', False, None), {}), - ('addPoint', ((-1, 1), None, False, None), {}), - ('addPoint', ((-2, 2), None, False, None), {}), - ('addPoint', ((-3, 3), 'curve', False, None), {}), - ('endPath', (), {})]} - >>> for name, glyph in sorted(glyphSet.items()): - ... pen = DecomposingRecordingPointPen( - ... glyphSet, skipMissingComponents=True, reverseFlipped=True, - ... ) - ... glyph.drawPoints(pen) - ... pprint({name: pen.value}) - {'a': [('beginPath', (), {}), - ('addPoint', ((0, 0), 'line', False, None), {}), - ('addPoint', ((1, 1), None, False, None), {}), - ('addPoint', ((2, 2), None, False, None), {}), - ('addPoint', ((3, 3), 'curve', False, None), {}), - ('endPath', (), {})]} - {'b': [('beginPath', (), {}), - ('addPoint', ((-1, 1), 'line', False, None), {}), - ('addPoint', ((0, 2), None, False, None), {}), - ('addPoint', ((1, 3), None, False, None), {}), - ('addPoint', ((2, 4), 'curve', False, None), {}), - ('endPath', (), {})]} - {'c': []} - {'d': [('beginPath', (), {}), - ('addPoint', ((0, 0), 'curve', False, None), {}), - ('addPoint', ((-3, 3), 'line', False, None), {}), - ('addPoint', ((-2, 2), None, False, None), {}), - ('addPoint', ((-1, 1), None, False, None), {}), - ('endPath', (), {})]} + >>> from pprint import pprint + >>> class SimpleGlyph(object): + ... def drawPoints(self, pen): + ... pen.beginPath() + ... pen.addPoint((0, 0), "line") + ... pen.addPoint((1, 1)) + ... pen.addPoint((2, 2)) + ... pen.addPoint((3, 3), "curve") + ... pen.endPath() + >>> class CompositeGlyph(object): + ... def drawPoints(self, pen): + ... pen.addComponent('a', (1, 0, 0, 1, -1, 1)) + >>> class MissingComponent(object): + ... def drawPoints(self, pen): + ... pen.addComponent('foobar', (1, 0, 0, 1, 0, 0)) + >>> class FlippedComponent(object): + ... def drawPoints(self, pen): + ... pen.addComponent('a', (-1, 0, 0, 1, 0, 0)) + >>> glyphSet = { + ... 'a': SimpleGlyph(), + ... 'b': CompositeGlyph(), + ... 'c': MissingComponent(), + ... 'd': FlippedComponent(), + ... } + >>> for name, glyph in sorted(glyphSet.items()): + ... pen = DecomposingRecordingPointPen(glyphSet) + ... try: + ... glyph.drawPoints(pen) + ... except pen.MissingComponentError: + ... pass + ... pprint({name: pen.value}) + {'a': [('beginPath', (), {}), + ('addPoint', ((0, 0), 'line', False, None), {}), + ('addPoint', ((1, 1), None, False, None), {}), + ('addPoint', ((2, 2), None, False, None), {}), + ('addPoint', ((3, 3), 'curve', False, None), {}), + ('endPath', (), {})]} + {'b': [('beginPath', (), {}), + ('addPoint', ((-1, 1), 'line', False, None), {}), + ('addPoint', ((0, 2), None, False, None), {}), + ('addPoint', ((1, 3), None, False, None), {}), + ('addPoint', ((2, 4), 'curve', False, None), {}), + ('endPath', (), {})]} + {'c': []} + {'d': [('beginPath', (), {}), + ('addPoint', ((0, 0), 'line', False, None), {}), + ('addPoint', ((-1, 1), None, False, None), {}), + ('addPoint', ((-2, 2), None, False, None), {}), + ('addPoint', ((-3, 3), 'curve', False, None), {}), + ('endPath', (), {})]} + + >>> for name, glyph in sorted(glyphSet.items()): + ... pen = DecomposingRecordingPointPen( + ... glyphSet, skipMissingComponents=True, reverseFlipped=True, + ... ) + ... glyph.drawPoints(pen) + ... pprint({name: pen.value}) + {'a': [('beginPath', (), {}), + ('addPoint', ((0, 0), 'line', False, None), {}), + ('addPoint', ((1, 1), None, False, None), {}), + ('addPoint', ((2, 2), None, False, None), {}), + ('addPoint', ((3, 3), 'curve', False, None), {}), + ('endPath', (), {})]} + {'b': [('beginPath', (), {}), + ('addPoint', ((-1, 1), 'line', False, None), {}), + ('addPoint', ((0, 2), None, False, None), {}), + ('addPoint', ((1, 3), None, False, None), {}), + ('addPoint', ((2, 4), 'curve', False, None), {}), + ('endPath', (), {})]} + {'c': []} + {'d': [('beginPath', (), {}), + ('addPoint', ((0, 0), 'curve', False, None), {}), + ('addPoint', ((-3, 3), 'line', False, None), {}), + ('addPoint', ((-2, 2), None, False, None), {}), + ('addPoint', ((-1, 1), None, False, None), {}), + ('endPath', (), {})]} """ # raises MissingComponentError(KeyError) if base glyph is not found in glyphSet diff --git a/contrib/python/fonttools/fontTools/pens/svgPathPen.py b/contrib/python/fonttools/fontTools/pens/svgPathPen.py index 29d41a8029..29d128da36 100644 --- a/contrib/python/fonttools/fontTools/pens/svgPathPen.py +++ b/contrib/python/fonttools/fontTools/pens/svgPathPen.py @@ -9,27 +9,30 @@ def pointToString(pt, ntos=str): class SVGPathPen(BasePen): """Pen to draw SVG path d commands. - Example:: - >>> pen = SVGPathPen(None) - >>> pen.moveTo((0, 0)) - >>> pen.lineTo((1, 1)) - >>> pen.curveTo((2, 2), (3, 3), (4, 4)) - >>> pen.closePath() - >>> pen.getCommands() - 'M0 0 1 1C2 2 3 3 4 4Z' - Args: glyphSet: a dictionary of drawable glyph objects keyed by name used to resolve component references in composite glyphs. ntos: a callable that takes a number and returns a string, to customize how numbers are formatted (default: str). + :Example: + .. code-block:: + + >>> pen = SVGPathPen(None) + >>> pen.moveTo((0, 0)) + >>> pen.lineTo((1, 1)) + >>> pen.curveTo((2, 2), (3, 3), (4, 4)) + >>> pen.closePath() + >>> pen.getCommands() + 'M0 0 1 1C2 2 3 3 4 4Z' + Note: Fonts have a coordinate system where Y grows up, whereas in SVG, Y grows down. As such, rendering path data from this pen in SVG typically results in upside-down glyphs. You can fix this by wrapping the data from this pen in an SVG group element with transform, or wrap this pen in a transform pen. For example: + .. code-block:: python spen = svgPathPen.SVGPathPen(glyphset) pen= TransformPen(spen , (1, 0, 0, -1, 0, 0)) diff --git a/contrib/python/fonttools/fontTools/pens/transformPen.py b/contrib/python/fonttools/fontTools/pens/transformPen.py index ff98dbddb0..3db6efdf2f 100644 --- a/contrib/python/fonttools/fontTools/pens/transformPen.py +++ b/contrib/python/fonttools/fontTools/pens/transformPen.py @@ -58,22 +58,27 @@ class TransformPointPen(FilterPointPen): """PointPen that transforms all coordinates using a Affine transformation, and passes them to another PointPen. - >>> from fontTools.pens.recordingPen import RecordingPointPen - >>> rec = RecordingPointPen() - >>> pen = TransformPointPen(rec, (2, 0, 0, 2, -10, 5)) - >>> v = iter(rec.value) - >>> pen.beginPath(identifier="contour-0") - >>> next(v) - ('beginPath', (), {'identifier': 'contour-0'}) - >>> pen.addPoint((100, 100), "line") - >>> next(v) - ('addPoint', ((190, 205), 'line', False, None), {}) - >>> pen.endPath() - >>> next(v) - ('endPath', (), {}) - >>> pen.addComponent("a", (1, 0, 0, 1, -10, 5), identifier="component-0") - >>> next(v) - ('addComponent', ('a', <Transform [2 0 0 2 -30 15]>), {'identifier': 'component-0'}) + For example:: + + >>> from fontTools.pens.recordingPen import RecordingPointPen + >>> rec = RecordingPointPen() + >>> pen = TransformPointPen(rec, (2, 0, 0, 2, -10, 5)) + >>> v = iter(rec.value) + >>> pen.beginPath(identifier="contour-0") + >>> next(v) + ('beginPath', (), {'identifier': 'contour-0'}) + + >>> pen.addPoint((100, 100), "line") + >>> next(v) + ('addPoint', ((190, 205), 'line', False, None), {}) + + >>> pen.endPath() + >>> next(v) + ('endPath', (), {}) + + >>> pen.addComponent("a", (1, 0, 0, 1, -10, 5), identifier="component-0") + >>> next(v) + ('addComponent', ('a', <Transform [2 0 0 2 -30 15]>), {'identifier': 'component-0'}) """ def __init__(self, outPointPen, transformation): |