fonttools 4.60.2__cp311-cp311-win32.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- fontTools/__init__.py +8 -0
- fontTools/__main__.py +35 -0
- fontTools/afmLib.py +439 -0
- fontTools/agl.py +5233 -0
- fontTools/annotations.py +30 -0
- fontTools/cffLib/CFF2ToCFF.py +258 -0
- fontTools/cffLib/CFFToCFF2.py +305 -0
- fontTools/cffLib/__init__.py +3694 -0
- fontTools/cffLib/specializer.py +927 -0
- fontTools/cffLib/transforms.py +495 -0
- fontTools/cffLib/width.py +210 -0
- fontTools/colorLib/__init__.py +0 -0
- fontTools/colorLib/builder.py +664 -0
- fontTools/colorLib/errors.py +2 -0
- fontTools/colorLib/geometry.py +143 -0
- fontTools/colorLib/table_builder.py +223 -0
- fontTools/colorLib/unbuilder.py +81 -0
- fontTools/config/__init__.py +90 -0
- fontTools/cu2qu/__init__.py +15 -0
- fontTools/cu2qu/__main__.py +6 -0
- fontTools/cu2qu/benchmark.py +54 -0
- fontTools/cu2qu/cli.py +198 -0
- fontTools/cu2qu/cu2qu.c +15817 -0
- fontTools/cu2qu/cu2qu.cp311-win32.pyd +0 -0
- fontTools/cu2qu/cu2qu.py +563 -0
- fontTools/cu2qu/errors.py +77 -0
- fontTools/cu2qu/ufo.py +363 -0
- fontTools/designspaceLib/__init__.py +3343 -0
- fontTools/designspaceLib/__main__.py +6 -0
- fontTools/designspaceLib/split.py +475 -0
- fontTools/designspaceLib/statNames.py +260 -0
- fontTools/designspaceLib/types.py +147 -0
- fontTools/encodings/MacRoman.py +258 -0
- fontTools/encodings/StandardEncoding.py +258 -0
- fontTools/encodings/__init__.py +1 -0
- fontTools/encodings/codecs.py +135 -0
- fontTools/feaLib/__init__.py +4 -0
- fontTools/feaLib/__main__.py +78 -0
- fontTools/feaLib/ast.py +2143 -0
- fontTools/feaLib/builder.py +1814 -0
- fontTools/feaLib/error.py +22 -0
- fontTools/feaLib/lexer.c +17029 -0
- fontTools/feaLib/lexer.cp311-win32.pyd +0 -0
- fontTools/feaLib/lexer.py +287 -0
- fontTools/feaLib/location.py +12 -0
- fontTools/feaLib/lookupDebugInfo.py +12 -0
- fontTools/feaLib/parser.py +2394 -0
- fontTools/feaLib/variableScalar.py +118 -0
- fontTools/fontBuilder.py +1014 -0
- fontTools/help.py +36 -0
- fontTools/merge/__init__.py +248 -0
- fontTools/merge/__main__.py +6 -0
- fontTools/merge/base.py +81 -0
- fontTools/merge/cmap.py +173 -0
- fontTools/merge/layout.py +526 -0
- fontTools/merge/options.py +85 -0
- fontTools/merge/tables.py +352 -0
- fontTools/merge/unicode.py +78 -0
- fontTools/merge/util.py +143 -0
- fontTools/misc/__init__.py +1 -0
- fontTools/misc/arrayTools.py +424 -0
- fontTools/misc/bezierTools.c +39731 -0
- fontTools/misc/bezierTools.cp311-win32.pyd +0 -0
- fontTools/misc/bezierTools.py +1500 -0
- fontTools/misc/classifyTools.py +170 -0
- fontTools/misc/cliTools.py +53 -0
- fontTools/misc/configTools.py +349 -0
- fontTools/misc/cython.py +27 -0
- fontTools/misc/dictTools.py +83 -0
- fontTools/misc/eexec.py +119 -0
- fontTools/misc/encodingTools.py +72 -0
- fontTools/misc/enumTools.py +23 -0
- fontTools/misc/etree.py +456 -0
- fontTools/misc/filenames.py +245 -0
- fontTools/misc/filesystem/__init__.py +68 -0
- fontTools/misc/filesystem/_base.py +134 -0
- fontTools/misc/filesystem/_copy.py +45 -0
- fontTools/misc/filesystem/_errors.py +54 -0
- fontTools/misc/filesystem/_info.py +75 -0
- fontTools/misc/filesystem/_osfs.py +164 -0
- fontTools/misc/filesystem/_path.py +67 -0
- fontTools/misc/filesystem/_subfs.py +92 -0
- fontTools/misc/filesystem/_tempfs.py +34 -0
- fontTools/misc/filesystem/_tools.py +34 -0
- fontTools/misc/filesystem/_walk.py +55 -0
- fontTools/misc/filesystem/_zipfs.py +204 -0
- fontTools/misc/fixedTools.py +253 -0
- fontTools/misc/intTools.py +25 -0
- fontTools/misc/iterTools.py +12 -0
- fontTools/misc/lazyTools.py +42 -0
- fontTools/misc/loggingTools.py +543 -0
- fontTools/misc/macCreatorType.py +56 -0
- fontTools/misc/macRes.py +261 -0
- fontTools/misc/plistlib/__init__.py +681 -0
- fontTools/misc/plistlib/py.typed +0 -0
- fontTools/misc/psCharStrings.py +1511 -0
- fontTools/misc/psLib.py +398 -0
- fontTools/misc/psOperators.py +572 -0
- fontTools/misc/py23.py +96 -0
- fontTools/misc/roundTools.py +110 -0
- fontTools/misc/sstruct.py +227 -0
- fontTools/misc/symfont.py +242 -0
- fontTools/misc/testTools.py +233 -0
- fontTools/misc/textTools.py +156 -0
- fontTools/misc/timeTools.py +88 -0
- fontTools/misc/transform.py +516 -0
- fontTools/misc/treeTools.py +45 -0
- fontTools/misc/vector.py +147 -0
- fontTools/misc/visitor.py +158 -0
- fontTools/misc/xmlReader.py +188 -0
- fontTools/misc/xmlWriter.py +231 -0
- fontTools/mtiLib/__init__.py +1400 -0
- fontTools/mtiLib/__main__.py +5 -0
- fontTools/otlLib/__init__.py +1 -0
- fontTools/otlLib/builder.py +3465 -0
- fontTools/otlLib/error.py +11 -0
- fontTools/otlLib/maxContextCalc.py +96 -0
- fontTools/otlLib/optimize/__init__.py +53 -0
- fontTools/otlLib/optimize/__main__.py +6 -0
- fontTools/otlLib/optimize/gpos.py +439 -0
- fontTools/pens/__init__.py +1 -0
- fontTools/pens/areaPen.py +52 -0
- fontTools/pens/basePen.py +475 -0
- fontTools/pens/boundsPen.py +98 -0
- fontTools/pens/cairoPen.py +26 -0
- fontTools/pens/cocoaPen.py +26 -0
- fontTools/pens/cu2quPen.py +325 -0
- fontTools/pens/explicitClosingLinePen.py +101 -0
- fontTools/pens/filterPen.py +433 -0
- fontTools/pens/freetypePen.py +462 -0
- fontTools/pens/hashPointPen.py +89 -0
- fontTools/pens/momentsPen.c +13378 -0
- fontTools/pens/momentsPen.cp311-win32.pyd +0 -0
- fontTools/pens/momentsPen.py +879 -0
- fontTools/pens/perimeterPen.py +69 -0
- fontTools/pens/pointInsidePen.py +192 -0
- fontTools/pens/pointPen.py +643 -0
- fontTools/pens/qtPen.py +29 -0
- fontTools/pens/qu2cuPen.py +105 -0
- fontTools/pens/quartzPen.py +43 -0
- fontTools/pens/recordingPen.py +335 -0
- fontTools/pens/reportLabPen.py +79 -0
- fontTools/pens/reverseContourPen.py +96 -0
- fontTools/pens/roundingPen.py +130 -0
- fontTools/pens/statisticsPen.py +312 -0
- fontTools/pens/svgPathPen.py +310 -0
- fontTools/pens/t2CharStringPen.py +88 -0
- fontTools/pens/teePen.py +55 -0
- fontTools/pens/transformPen.py +115 -0
- fontTools/pens/ttGlyphPen.py +335 -0
- fontTools/pens/wxPen.py +29 -0
- fontTools/qu2cu/__init__.py +15 -0
- fontTools/qu2cu/__main__.py +7 -0
- fontTools/qu2cu/benchmark.py +56 -0
- fontTools/qu2cu/cli.py +125 -0
- fontTools/qu2cu/qu2cu.c +16682 -0
- fontTools/qu2cu/qu2cu.cp311-win32.pyd +0 -0
- fontTools/qu2cu/qu2cu.py +405 -0
- fontTools/subset/__init__.py +4096 -0
- fontTools/subset/__main__.py +6 -0
- fontTools/subset/cff.py +184 -0
- fontTools/subset/svg.py +253 -0
- fontTools/subset/util.py +25 -0
- fontTools/svgLib/__init__.py +3 -0
- fontTools/svgLib/path/__init__.py +65 -0
- fontTools/svgLib/path/arc.py +154 -0
- fontTools/svgLib/path/parser.py +322 -0
- fontTools/svgLib/path/shapes.py +183 -0
- fontTools/t1Lib/__init__.py +648 -0
- fontTools/tfmLib.py +460 -0
- fontTools/ttLib/__init__.py +30 -0
- fontTools/ttLib/__main__.py +148 -0
- fontTools/ttLib/macUtils.py +54 -0
- fontTools/ttLib/removeOverlaps.py +395 -0
- fontTools/ttLib/reorderGlyphs.py +285 -0
- fontTools/ttLib/scaleUpem.py +436 -0
- fontTools/ttLib/sfnt.py +661 -0
- fontTools/ttLib/standardGlyphOrder.py +271 -0
- fontTools/ttLib/tables/B_A_S_E_.py +14 -0
- fontTools/ttLib/tables/BitmapGlyphMetrics.py +64 -0
- fontTools/ttLib/tables/C_B_D_T_.py +113 -0
- fontTools/ttLib/tables/C_B_L_C_.py +19 -0
- fontTools/ttLib/tables/C_F_F_.py +61 -0
- fontTools/ttLib/tables/C_F_F__2.py +26 -0
- fontTools/ttLib/tables/C_O_L_R_.py +165 -0
- fontTools/ttLib/tables/C_P_A_L_.py +305 -0
- fontTools/ttLib/tables/D_S_I_G_.py +158 -0
- fontTools/ttLib/tables/D__e_b_g.py +35 -0
- fontTools/ttLib/tables/DefaultTable.py +49 -0
- fontTools/ttLib/tables/E_B_D_T_.py +835 -0
- fontTools/ttLib/tables/E_B_L_C_.py +718 -0
- fontTools/ttLib/tables/F_F_T_M_.py +52 -0
- fontTools/ttLib/tables/F__e_a_t.py +149 -0
- fontTools/ttLib/tables/G_D_E_F_.py +13 -0
- fontTools/ttLib/tables/G_M_A_P_.py +148 -0
- fontTools/ttLib/tables/G_P_K_G_.py +133 -0
- fontTools/ttLib/tables/G_P_O_S_.py +14 -0
- fontTools/ttLib/tables/G_S_U_B_.py +13 -0
- fontTools/ttLib/tables/G_V_A_R_.py +5 -0
- fontTools/ttLib/tables/G__l_a_t.py +235 -0
- fontTools/ttLib/tables/G__l_o_c.py +85 -0
- fontTools/ttLib/tables/H_V_A_R_.py +13 -0
- fontTools/ttLib/tables/J_S_T_F_.py +13 -0
- fontTools/ttLib/tables/L_T_S_H_.py +58 -0
- fontTools/ttLib/tables/M_A_T_H_.py +13 -0
- fontTools/ttLib/tables/M_E_T_A_.py +352 -0
- fontTools/ttLib/tables/M_V_A_R_.py +13 -0
- fontTools/ttLib/tables/O_S_2f_2.py +752 -0
- fontTools/ttLib/tables/S_I_N_G_.py +99 -0
- fontTools/ttLib/tables/S_T_A_T_.py +15 -0
- fontTools/ttLib/tables/S_V_G_.py +223 -0
- fontTools/ttLib/tables/S__i_l_f.py +1040 -0
- fontTools/ttLib/tables/S__i_l_l.py +92 -0
- fontTools/ttLib/tables/T_S_I_B_.py +13 -0
- fontTools/ttLib/tables/T_S_I_C_.py +14 -0
- fontTools/ttLib/tables/T_S_I_D_.py +13 -0
- fontTools/ttLib/tables/T_S_I_J_.py +13 -0
- fontTools/ttLib/tables/T_S_I_P_.py +13 -0
- fontTools/ttLib/tables/T_S_I_S_.py +13 -0
- fontTools/ttLib/tables/T_S_I_V_.py +26 -0
- fontTools/ttLib/tables/T_S_I__0.py +70 -0
- fontTools/ttLib/tables/T_S_I__1.py +163 -0
- fontTools/ttLib/tables/T_S_I__2.py +17 -0
- fontTools/ttLib/tables/T_S_I__3.py +22 -0
- fontTools/ttLib/tables/T_S_I__5.py +60 -0
- fontTools/ttLib/tables/T_T_F_A_.py +14 -0
- fontTools/ttLib/tables/TupleVariation.py +884 -0
- fontTools/ttLib/tables/V_A_R_C_.py +12 -0
- fontTools/ttLib/tables/V_D_M_X_.py +249 -0
- fontTools/ttLib/tables/V_O_R_G_.py +165 -0
- fontTools/ttLib/tables/V_V_A_R_.py +13 -0
- fontTools/ttLib/tables/__init__.py +98 -0
- fontTools/ttLib/tables/_a_n_k_r.py +15 -0
- fontTools/ttLib/tables/_a_v_a_r.py +193 -0
- fontTools/ttLib/tables/_b_s_l_n.py +15 -0
- fontTools/ttLib/tables/_c_i_d_g.py +24 -0
- fontTools/ttLib/tables/_c_m_a_p.py +1591 -0
- fontTools/ttLib/tables/_c_v_a_r.py +94 -0
- fontTools/ttLib/tables/_c_v_t.py +56 -0
- fontTools/ttLib/tables/_f_e_a_t.py +15 -0
- fontTools/ttLib/tables/_f_p_g_m.py +62 -0
- fontTools/ttLib/tables/_f_v_a_r.py +261 -0
- fontTools/ttLib/tables/_g_a_s_p.py +63 -0
- fontTools/ttLib/tables/_g_c_i_d.py +13 -0
- fontTools/ttLib/tables/_g_l_y_f.py +2311 -0
- fontTools/ttLib/tables/_g_v_a_r.py +340 -0
- fontTools/ttLib/tables/_h_d_m_x.py +127 -0
- fontTools/ttLib/tables/_h_e_a_d.py +130 -0
- fontTools/ttLib/tables/_h_h_e_a.py +147 -0
- fontTools/ttLib/tables/_h_m_t_x.py +164 -0
- fontTools/ttLib/tables/_k_e_r_n.py +289 -0
- fontTools/ttLib/tables/_l_c_a_r.py +13 -0
- fontTools/ttLib/tables/_l_o_c_a.py +70 -0
- fontTools/ttLib/tables/_l_t_a_g.py +72 -0
- fontTools/ttLib/tables/_m_a_x_p.py +147 -0
- fontTools/ttLib/tables/_m_e_t_a.py +112 -0
- fontTools/ttLib/tables/_m_o_r_t.py +14 -0
- fontTools/ttLib/tables/_m_o_r_x.py +15 -0
- fontTools/ttLib/tables/_n_a_m_e.py +1242 -0
- fontTools/ttLib/tables/_o_p_b_d.py +14 -0
- fontTools/ttLib/tables/_p_o_s_t.py +319 -0
- fontTools/ttLib/tables/_p_r_e_p.py +16 -0
- fontTools/ttLib/tables/_p_r_o_p.py +12 -0
- fontTools/ttLib/tables/_s_b_i_x.py +129 -0
- fontTools/ttLib/tables/_t_r_a_k.py +332 -0
- fontTools/ttLib/tables/_v_h_e_a.py +139 -0
- fontTools/ttLib/tables/_v_m_t_x.py +19 -0
- fontTools/ttLib/tables/asciiTable.py +20 -0
- fontTools/ttLib/tables/grUtils.py +92 -0
- fontTools/ttLib/tables/otBase.py +1458 -0
- fontTools/ttLib/tables/otConverters.py +2068 -0
- fontTools/ttLib/tables/otData.py +6400 -0
- fontTools/ttLib/tables/otTables.py +2703 -0
- fontTools/ttLib/tables/otTraverse.py +163 -0
- fontTools/ttLib/tables/sbixGlyph.py +149 -0
- fontTools/ttLib/tables/sbixStrike.py +177 -0
- fontTools/ttLib/tables/table_API_readme.txt +91 -0
- fontTools/ttLib/tables/ttProgram.py +594 -0
- fontTools/ttLib/ttCollection.py +125 -0
- fontTools/ttLib/ttFont.py +1148 -0
- fontTools/ttLib/ttGlyphSet.py +490 -0
- fontTools/ttLib/ttVisitor.py +32 -0
- fontTools/ttLib/woff2.py +1680 -0
- fontTools/ttx.py +479 -0
- fontTools/ufoLib/__init__.py +2575 -0
- fontTools/ufoLib/converters.py +407 -0
- fontTools/ufoLib/errors.py +30 -0
- fontTools/ufoLib/etree.py +6 -0
- fontTools/ufoLib/filenames.py +356 -0
- fontTools/ufoLib/glifLib.py +2120 -0
- fontTools/ufoLib/kerning.py +141 -0
- fontTools/ufoLib/plistlib.py +47 -0
- fontTools/ufoLib/pointPen.py +6 -0
- fontTools/ufoLib/utils.py +107 -0
- fontTools/ufoLib/validators.py +1208 -0
- fontTools/unicode.py +50 -0
- fontTools/unicodedata/Blocks.py +817 -0
- fontTools/unicodedata/Mirrored.py +446 -0
- fontTools/unicodedata/OTTags.py +50 -0
- fontTools/unicodedata/ScriptExtensions.py +832 -0
- fontTools/unicodedata/Scripts.py +3639 -0
- fontTools/unicodedata/__init__.py +306 -0
- fontTools/varLib/__init__.py +1600 -0
- fontTools/varLib/__main__.py +6 -0
- fontTools/varLib/avar/__init__.py +0 -0
- fontTools/varLib/avar/__main__.py +72 -0
- fontTools/varLib/avar/build.py +79 -0
- fontTools/varLib/avar/map.py +108 -0
- fontTools/varLib/avar/plan.py +1004 -0
- fontTools/varLib/avar/unbuild.py +271 -0
- fontTools/varLib/avarPlanner.py +8 -0
- fontTools/varLib/builder.py +215 -0
- fontTools/varLib/cff.py +631 -0
- fontTools/varLib/errors.py +219 -0
- fontTools/varLib/featureVars.py +703 -0
- fontTools/varLib/hvar.py +113 -0
- fontTools/varLib/instancer/__init__.py +2052 -0
- fontTools/varLib/instancer/__main__.py +5 -0
- fontTools/varLib/instancer/featureVars.py +190 -0
- fontTools/varLib/instancer/names.py +388 -0
- fontTools/varLib/instancer/solver.py +309 -0
- fontTools/varLib/interpolatable.py +1209 -0
- fontTools/varLib/interpolatableHelpers.py +399 -0
- fontTools/varLib/interpolatablePlot.py +1269 -0
- fontTools/varLib/interpolatableTestContourOrder.py +82 -0
- fontTools/varLib/interpolatableTestStartingPoint.py +107 -0
- fontTools/varLib/interpolate_layout.py +124 -0
- fontTools/varLib/iup.c +19815 -0
- fontTools/varLib/iup.cp311-win32.pyd +0 -0
- fontTools/varLib/iup.py +490 -0
- fontTools/varLib/merger.py +1717 -0
- fontTools/varLib/models.py +642 -0
- fontTools/varLib/multiVarStore.py +253 -0
- fontTools/varLib/mutator.py +529 -0
- fontTools/varLib/mvar.py +40 -0
- fontTools/varLib/plot.py +238 -0
- fontTools/varLib/stat.py +149 -0
- fontTools/varLib/varStore.py +739 -0
- fontTools/voltLib/__init__.py +5 -0
- fontTools/voltLib/__main__.py +206 -0
- fontTools/voltLib/ast.py +452 -0
- fontTools/voltLib/error.py +12 -0
- fontTools/voltLib/lexer.py +99 -0
- fontTools/voltLib/parser.py +664 -0
- fontTools/voltLib/voltToFea.py +911 -0
- fonttools-4.60.2.data/data/share/man/man1/ttx.1 +225 -0
- fonttools-4.60.2.dist-info/METADATA +2250 -0
- fonttools-4.60.2.dist-info/RECORD +353 -0
- fonttools-4.60.2.dist-info/WHEEL +5 -0
- fonttools-4.60.2.dist-info/entry_points.txt +5 -0
- fonttools-4.60.2.dist-info/licenses/LICENSE +21 -0
- fonttools-4.60.2.dist-info/licenses/LICENSE.external +388 -0
- fonttools-4.60.2.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
from typing import Callable
|
|
2
|
+
from fontTools.pens.basePen import BasePen
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def pointToString(pt, ntos=str):
|
|
6
|
+
return " ".join(ntos(i) for i in pt)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class SVGPathPen(BasePen):
|
|
10
|
+
"""Pen to draw SVG path d commands.
|
|
11
|
+
|
|
12
|
+
Args:
|
|
13
|
+
glyphSet: a dictionary of drawable glyph objects keyed by name
|
|
14
|
+
used to resolve component references in composite glyphs.
|
|
15
|
+
ntos: a callable that takes a number and returns a string, to
|
|
16
|
+
customize how numbers are formatted (default: str).
|
|
17
|
+
|
|
18
|
+
:Example:
|
|
19
|
+
.. code-block::
|
|
20
|
+
|
|
21
|
+
>>> pen = SVGPathPen(None)
|
|
22
|
+
>>> pen.moveTo((0, 0))
|
|
23
|
+
>>> pen.lineTo((1, 1))
|
|
24
|
+
>>> pen.curveTo((2, 2), (3, 3), (4, 4))
|
|
25
|
+
>>> pen.closePath()
|
|
26
|
+
>>> pen.getCommands()
|
|
27
|
+
'M0 0 1 1C2 2 3 3 4 4Z'
|
|
28
|
+
|
|
29
|
+
Note:
|
|
30
|
+
Fonts have a coordinate system where Y grows up, whereas in SVG,
|
|
31
|
+
Y grows down. As such, rendering path data from this pen in
|
|
32
|
+
SVG typically results in upside-down glyphs. You can fix this
|
|
33
|
+
by wrapping the data from this pen in an SVG group element with
|
|
34
|
+
transform, or wrap this pen in a transform pen. For example:
|
|
35
|
+
.. code-block:: python
|
|
36
|
+
|
|
37
|
+
spen = svgPathPen.SVGPathPen(glyphset)
|
|
38
|
+
pen= TransformPen(spen , (1, 0, 0, -1, 0, 0))
|
|
39
|
+
glyphset[glyphname].draw(pen)
|
|
40
|
+
print(tpen.getCommands())
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
def __init__(self, glyphSet, ntos: Callable[[float], str] = str):
|
|
44
|
+
BasePen.__init__(self, glyphSet)
|
|
45
|
+
self._commands = []
|
|
46
|
+
self._lastCommand = None
|
|
47
|
+
self._lastX = None
|
|
48
|
+
self._lastY = None
|
|
49
|
+
self._ntos = ntos
|
|
50
|
+
|
|
51
|
+
def _handleAnchor(self):
|
|
52
|
+
"""
|
|
53
|
+
>>> pen = SVGPathPen(None)
|
|
54
|
+
>>> pen.moveTo((0, 0))
|
|
55
|
+
>>> pen.moveTo((10, 10))
|
|
56
|
+
>>> pen._commands
|
|
57
|
+
['M10 10']
|
|
58
|
+
"""
|
|
59
|
+
if self._lastCommand == "M":
|
|
60
|
+
self._commands.pop(-1)
|
|
61
|
+
|
|
62
|
+
def _moveTo(self, pt):
|
|
63
|
+
"""
|
|
64
|
+
>>> pen = SVGPathPen(None)
|
|
65
|
+
>>> pen.moveTo((0, 0))
|
|
66
|
+
>>> pen._commands
|
|
67
|
+
['M0 0']
|
|
68
|
+
|
|
69
|
+
>>> pen = SVGPathPen(None)
|
|
70
|
+
>>> pen.moveTo((10, 0))
|
|
71
|
+
>>> pen._commands
|
|
72
|
+
['M10 0']
|
|
73
|
+
|
|
74
|
+
>>> pen = SVGPathPen(None)
|
|
75
|
+
>>> pen.moveTo((0, 10))
|
|
76
|
+
>>> pen._commands
|
|
77
|
+
['M0 10']
|
|
78
|
+
"""
|
|
79
|
+
self._handleAnchor()
|
|
80
|
+
t = "M%s" % (pointToString(pt, self._ntos))
|
|
81
|
+
self._commands.append(t)
|
|
82
|
+
self._lastCommand = "M"
|
|
83
|
+
self._lastX, self._lastY = pt
|
|
84
|
+
|
|
85
|
+
def _lineTo(self, pt):
|
|
86
|
+
"""
|
|
87
|
+
# duplicate point
|
|
88
|
+
>>> pen = SVGPathPen(None)
|
|
89
|
+
>>> pen.moveTo((10, 10))
|
|
90
|
+
>>> pen.lineTo((10, 10))
|
|
91
|
+
>>> pen._commands
|
|
92
|
+
['M10 10']
|
|
93
|
+
|
|
94
|
+
# vertical line
|
|
95
|
+
>>> pen = SVGPathPen(None)
|
|
96
|
+
>>> pen.moveTo((10, 10))
|
|
97
|
+
>>> pen.lineTo((10, 0))
|
|
98
|
+
>>> pen._commands
|
|
99
|
+
['M10 10', 'V0']
|
|
100
|
+
|
|
101
|
+
# horizontal line
|
|
102
|
+
>>> pen = SVGPathPen(None)
|
|
103
|
+
>>> pen.moveTo((10, 10))
|
|
104
|
+
>>> pen.lineTo((0, 10))
|
|
105
|
+
>>> pen._commands
|
|
106
|
+
['M10 10', 'H0']
|
|
107
|
+
|
|
108
|
+
# basic
|
|
109
|
+
>>> pen = SVGPathPen(None)
|
|
110
|
+
>>> pen.lineTo((70, 80))
|
|
111
|
+
>>> pen._commands
|
|
112
|
+
['L70 80']
|
|
113
|
+
|
|
114
|
+
# basic following a moveto
|
|
115
|
+
>>> pen = SVGPathPen(None)
|
|
116
|
+
>>> pen.moveTo((0, 0))
|
|
117
|
+
>>> pen.lineTo((10, 10))
|
|
118
|
+
>>> pen._commands
|
|
119
|
+
['M0 0', ' 10 10']
|
|
120
|
+
"""
|
|
121
|
+
x, y = pt
|
|
122
|
+
# duplicate point
|
|
123
|
+
if x == self._lastX and y == self._lastY:
|
|
124
|
+
return
|
|
125
|
+
# vertical line
|
|
126
|
+
elif x == self._lastX:
|
|
127
|
+
cmd = "V"
|
|
128
|
+
pts = self._ntos(y)
|
|
129
|
+
# horizontal line
|
|
130
|
+
elif y == self._lastY:
|
|
131
|
+
cmd = "H"
|
|
132
|
+
pts = self._ntos(x)
|
|
133
|
+
# previous was a moveto
|
|
134
|
+
elif self._lastCommand == "M":
|
|
135
|
+
cmd = None
|
|
136
|
+
pts = " " + pointToString(pt, self._ntos)
|
|
137
|
+
# basic
|
|
138
|
+
else:
|
|
139
|
+
cmd = "L"
|
|
140
|
+
pts = pointToString(pt, self._ntos)
|
|
141
|
+
# write the string
|
|
142
|
+
t = ""
|
|
143
|
+
if cmd:
|
|
144
|
+
t += cmd
|
|
145
|
+
self._lastCommand = cmd
|
|
146
|
+
t += pts
|
|
147
|
+
self._commands.append(t)
|
|
148
|
+
# store for future reference
|
|
149
|
+
self._lastX, self._lastY = pt
|
|
150
|
+
|
|
151
|
+
def _curveToOne(self, pt1, pt2, pt3):
|
|
152
|
+
"""
|
|
153
|
+
>>> pen = SVGPathPen(None)
|
|
154
|
+
>>> pen.curveTo((10, 20), (30, 40), (50, 60))
|
|
155
|
+
>>> pen._commands
|
|
156
|
+
['C10 20 30 40 50 60']
|
|
157
|
+
"""
|
|
158
|
+
t = "C"
|
|
159
|
+
t += pointToString(pt1, self._ntos) + " "
|
|
160
|
+
t += pointToString(pt2, self._ntos) + " "
|
|
161
|
+
t += pointToString(pt3, self._ntos)
|
|
162
|
+
self._commands.append(t)
|
|
163
|
+
self._lastCommand = "C"
|
|
164
|
+
self._lastX, self._lastY = pt3
|
|
165
|
+
|
|
166
|
+
def _qCurveToOne(self, pt1, pt2):
|
|
167
|
+
"""
|
|
168
|
+
>>> pen = SVGPathPen(None)
|
|
169
|
+
>>> pen.qCurveTo((10, 20), (30, 40))
|
|
170
|
+
>>> pen._commands
|
|
171
|
+
['Q10 20 30 40']
|
|
172
|
+
>>> from fontTools.misc.roundTools import otRound
|
|
173
|
+
>>> pen = SVGPathPen(None, ntos=lambda v: str(otRound(v)))
|
|
174
|
+
>>> pen.qCurveTo((3, 3), (7, 5), (11, 4))
|
|
175
|
+
>>> pen._commands
|
|
176
|
+
['Q3 3 5 4', 'Q7 5 11 4']
|
|
177
|
+
"""
|
|
178
|
+
assert pt2 is not None
|
|
179
|
+
t = "Q"
|
|
180
|
+
t += pointToString(pt1, self._ntos) + " "
|
|
181
|
+
t += pointToString(pt2, self._ntos)
|
|
182
|
+
self._commands.append(t)
|
|
183
|
+
self._lastCommand = "Q"
|
|
184
|
+
self._lastX, self._lastY = pt2
|
|
185
|
+
|
|
186
|
+
def _closePath(self):
|
|
187
|
+
"""
|
|
188
|
+
>>> pen = SVGPathPen(None)
|
|
189
|
+
>>> pen.closePath()
|
|
190
|
+
>>> pen._commands
|
|
191
|
+
['Z']
|
|
192
|
+
"""
|
|
193
|
+
self._commands.append("Z")
|
|
194
|
+
self._lastCommand = "Z"
|
|
195
|
+
self._lastX = self._lastY = None
|
|
196
|
+
|
|
197
|
+
def _endPath(self):
|
|
198
|
+
"""
|
|
199
|
+
>>> pen = SVGPathPen(None)
|
|
200
|
+
>>> pen.endPath()
|
|
201
|
+
>>> pen._commands
|
|
202
|
+
[]
|
|
203
|
+
"""
|
|
204
|
+
self._lastCommand = None
|
|
205
|
+
self._lastX = self._lastY = None
|
|
206
|
+
|
|
207
|
+
def getCommands(self):
|
|
208
|
+
return "".join(self._commands)
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
def main(args=None):
|
|
212
|
+
"""Generate per-character SVG from font and text"""
|
|
213
|
+
|
|
214
|
+
if args is None:
|
|
215
|
+
import sys
|
|
216
|
+
|
|
217
|
+
args = sys.argv[1:]
|
|
218
|
+
|
|
219
|
+
from fontTools.ttLib import TTFont
|
|
220
|
+
import argparse
|
|
221
|
+
|
|
222
|
+
parser = argparse.ArgumentParser(
|
|
223
|
+
"fonttools pens.svgPathPen", description="Generate SVG from text"
|
|
224
|
+
)
|
|
225
|
+
parser.add_argument("font", metavar="font.ttf", help="Font file.")
|
|
226
|
+
parser.add_argument("text", metavar="text", nargs="?", help="Text string.")
|
|
227
|
+
parser.add_argument(
|
|
228
|
+
"-y",
|
|
229
|
+
metavar="<number>",
|
|
230
|
+
help="Face index into a collection to open. Zero based.",
|
|
231
|
+
)
|
|
232
|
+
parser.add_argument(
|
|
233
|
+
"--glyphs",
|
|
234
|
+
metavar="whitespace-separated list of glyph names",
|
|
235
|
+
type=str,
|
|
236
|
+
help="Glyphs to show. Exclusive with text option",
|
|
237
|
+
)
|
|
238
|
+
parser.add_argument(
|
|
239
|
+
"--variations",
|
|
240
|
+
metavar="AXIS=LOC",
|
|
241
|
+
default="",
|
|
242
|
+
help="List of space separated locations. A location consist in "
|
|
243
|
+
"the name of a variation axis, followed by '=' and a number. E.g.: "
|
|
244
|
+
"wght=700 wdth=80. The default is the location of the base master.",
|
|
245
|
+
)
|
|
246
|
+
|
|
247
|
+
options = parser.parse_args(args)
|
|
248
|
+
|
|
249
|
+
fontNumber = int(options.y) if options.y is not None else 0
|
|
250
|
+
|
|
251
|
+
font = TTFont(options.font, fontNumber=fontNumber)
|
|
252
|
+
text = options.text
|
|
253
|
+
glyphs = options.glyphs
|
|
254
|
+
|
|
255
|
+
location = {}
|
|
256
|
+
for tag_v in options.variations.split():
|
|
257
|
+
fields = tag_v.split("=")
|
|
258
|
+
tag = fields[0].strip()
|
|
259
|
+
v = float(fields[1])
|
|
260
|
+
location[tag] = v
|
|
261
|
+
|
|
262
|
+
hhea = font["hhea"]
|
|
263
|
+
ascent, descent = hhea.ascent, hhea.descent
|
|
264
|
+
|
|
265
|
+
glyphset = font.getGlyphSet(location=location)
|
|
266
|
+
cmap = font["cmap"].getBestCmap()
|
|
267
|
+
|
|
268
|
+
if glyphs is not None and text is not None:
|
|
269
|
+
raise ValueError("Options --glyphs and --text are exclusive")
|
|
270
|
+
|
|
271
|
+
if glyphs is None:
|
|
272
|
+
glyphs = " ".join(cmap[ord(u)] for u in text)
|
|
273
|
+
|
|
274
|
+
glyphs = glyphs.split()
|
|
275
|
+
|
|
276
|
+
s = ""
|
|
277
|
+
width = 0
|
|
278
|
+
for g in glyphs:
|
|
279
|
+
glyph = glyphset[g]
|
|
280
|
+
|
|
281
|
+
pen = SVGPathPen(glyphset)
|
|
282
|
+
glyph.draw(pen)
|
|
283
|
+
commands = pen.getCommands()
|
|
284
|
+
|
|
285
|
+
s += '<g transform="translate(%d %d) scale(1 -1)"><path d="%s"/></g>\n' % (
|
|
286
|
+
width,
|
|
287
|
+
ascent,
|
|
288
|
+
commands,
|
|
289
|
+
)
|
|
290
|
+
|
|
291
|
+
width += glyph.width
|
|
292
|
+
|
|
293
|
+
print('<?xml version="1.0" encoding="UTF-8"?>')
|
|
294
|
+
print(
|
|
295
|
+
'<svg width="%d" height="%d" xmlns="http://www.w3.org/2000/svg">'
|
|
296
|
+
% (width, ascent - descent)
|
|
297
|
+
)
|
|
298
|
+
print(s, end="")
|
|
299
|
+
print("</svg>")
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
if __name__ == "__main__":
|
|
303
|
+
import sys
|
|
304
|
+
|
|
305
|
+
if len(sys.argv) == 1:
|
|
306
|
+
import doctest
|
|
307
|
+
|
|
308
|
+
sys.exit(doctest.testmod().failed)
|
|
309
|
+
|
|
310
|
+
sys.exit(main())
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# Copyright (c) 2009 Type Supply LLC
|
|
2
|
+
# Author: Tal Leming
|
|
3
|
+
|
|
4
|
+
from __future__ import annotations
|
|
5
|
+
|
|
6
|
+
from typing import Any, Dict, List, Tuple
|
|
7
|
+
|
|
8
|
+
from fontTools.cffLib.specializer import commandsToProgram, specializeCommands
|
|
9
|
+
from fontTools.misc.psCharStrings import T2CharString
|
|
10
|
+
from fontTools.misc.roundTools import otRound, roundFunc
|
|
11
|
+
from fontTools.pens.basePen import BasePen
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class T2CharStringPen(BasePen):
|
|
15
|
+
"""Pen to draw Type 2 CharStrings.
|
|
16
|
+
|
|
17
|
+
The 'roundTolerance' argument controls the rounding of point coordinates.
|
|
18
|
+
It is defined as the maximum absolute difference between the original
|
|
19
|
+
float and the rounded integer value.
|
|
20
|
+
The default tolerance of 0.5 means that all floats are rounded to integer;
|
|
21
|
+
a value of 0 disables rounding; values in between will only round floats
|
|
22
|
+
which are close to their integral part within the tolerated range.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
def __init__(
|
|
26
|
+
self,
|
|
27
|
+
width: float | None,
|
|
28
|
+
glyphSet: Dict[str, Any] | None,
|
|
29
|
+
roundTolerance: float = 0.5,
|
|
30
|
+
CFF2: bool = False,
|
|
31
|
+
) -> None:
|
|
32
|
+
super(T2CharStringPen, self).__init__(glyphSet)
|
|
33
|
+
self.round = roundFunc(roundTolerance)
|
|
34
|
+
self._CFF2 = CFF2
|
|
35
|
+
self._width = width
|
|
36
|
+
self._commands: List[Tuple[str | bytes, List[float]]] = []
|
|
37
|
+
self._p0 = (0, 0)
|
|
38
|
+
|
|
39
|
+
def _p(self, pt: Tuple[float, float]) -> List[float]:
|
|
40
|
+
p0 = self._p0
|
|
41
|
+
pt = self._p0 = (self.round(pt[0]), self.round(pt[1]))
|
|
42
|
+
return [pt[0] - p0[0], pt[1] - p0[1]]
|
|
43
|
+
|
|
44
|
+
def _moveTo(self, pt: Tuple[float, float]) -> None:
|
|
45
|
+
self._commands.append(("rmoveto", self._p(pt)))
|
|
46
|
+
|
|
47
|
+
def _lineTo(self, pt: Tuple[float, float]) -> None:
|
|
48
|
+
self._commands.append(("rlineto", self._p(pt)))
|
|
49
|
+
|
|
50
|
+
def _curveToOne(
|
|
51
|
+
self,
|
|
52
|
+
pt1: Tuple[float, float],
|
|
53
|
+
pt2: Tuple[float, float],
|
|
54
|
+
pt3: Tuple[float, float],
|
|
55
|
+
) -> None:
|
|
56
|
+
_p = self._p
|
|
57
|
+
self._commands.append(("rrcurveto", _p(pt1) + _p(pt2) + _p(pt3)))
|
|
58
|
+
|
|
59
|
+
def _closePath(self) -> None:
|
|
60
|
+
pass
|
|
61
|
+
|
|
62
|
+
def _endPath(self) -> None:
|
|
63
|
+
pass
|
|
64
|
+
|
|
65
|
+
def getCharString(
|
|
66
|
+
self,
|
|
67
|
+
private: Dict | None = None,
|
|
68
|
+
globalSubrs: List | None = None,
|
|
69
|
+
optimize: bool = True,
|
|
70
|
+
) -> T2CharString:
|
|
71
|
+
commands = self._commands
|
|
72
|
+
if optimize:
|
|
73
|
+
maxstack = 48 if not self._CFF2 else 513
|
|
74
|
+
commands = specializeCommands(
|
|
75
|
+
commands, generalizeFirst=False, maxstack=maxstack
|
|
76
|
+
)
|
|
77
|
+
program = commandsToProgram(commands)
|
|
78
|
+
if self._width is not None:
|
|
79
|
+
assert (
|
|
80
|
+
not self._CFF2
|
|
81
|
+
), "CFF2 does not allow encoding glyph width in CharString."
|
|
82
|
+
program.insert(0, otRound(self._width))
|
|
83
|
+
if not self._CFF2:
|
|
84
|
+
program.append("endchar")
|
|
85
|
+
charString = T2CharString(
|
|
86
|
+
program=program, private=private, globalSubrs=globalSubrs
|
|
87
|
+
)
|
|
88
|
+
return charString
|
fontTools/pens/teePen.py
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"""Pen multiplexing drawing to one or more pens."""
|
|
2
|
+
|
|
3
|
+
from fontTools.pens.basePen import AbstractPen
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
__all__ = ["TeePen"]
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class TeePen(AbstractPen):
|
|
10
|
+
"""Pen multiplexing drawing to one or more pens.
|
|
11
|
+
|
|
12
|
+
Use either as TeePen(pen1, pen2, ...) or TeePen(iterableOfPens)."""
|
|
13
|
+
|
|
14
|
+
def __init__(self, *pens):
|
|
15
|
+
if len(pens) == 1:
|
|
16
|
+
pens = pens[0]
|
|
17
|
+
self.pens = pens
|
|
18
|
+
|
|
19
|
+
def moveTo(self, p0):
|
|
20
|
+
for pen in self.pens:
|
|
21
|
+
pen.moveTo(p0)
|
|
22
|
+
|
|
23
|
+
def lineTo(self, p1):
|
|
24
|
+
for pen in self.pens:
|
|
25
|
+
pen.lineTo(p1)
|
|
26
|
+
|
|
27
|
+
def qCurveTo(self, *points):
|
|
28
|
+
for pen in self.pens:
|
|
29
|
+
pen.qCurveTo(*points)
|
|
30
|
+
|
|
31
|
+
def curveTo(self, *points):
|
|
32
|
+
for pen in self.pens:
|
|
33
|
+
pen.curveTo(*points)
|
|
34
|
+
|
|
35
|
+
def closePath(self):
|
|
36
|
+
for pen in self.pens:
|
|
37
|
+
pen.closePath()
|
|
38
|
+
|
|
39
|
+
def endPath(self):
|
|
40
|
+
for pen in self.pens:
|
|
41
|
+
pen.endPath()
|
|
42
|
+
|
|
43
|
+
def addComponent(self, glyphName, transformation):
|
|
44
|
+
for pen in self.pens:
|
|
45
|
+
pen.addComponent(glyphName, transformation)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
if __name__ == "__main__":
|
|
49
|
+
from fontTools.pens.basePen import _TestPen
|
|
50
|
+
|
|
51
|
+
pen = TeePen(_TestPen(), _TestPen())
|
|
52
|
+
pen.moveTo((0, 0))
|
|
53
|
+
pen.lineTo((0, 100))
|
|
54
|
+
pen.curveTo((50, 75), (60, 50), (50, 25))
|
|
55
|
+
pen.closePath()
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
from fontTools.pens.filterPen import FilterPen, FilterPointPen
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
__all__ = ["TransformPen", "TransformPointPen"]
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class TransformPen(FilterPen):
|
|
8
|
+
"""Pen that transforms all coordinates using a Affine transformation,
|
|
9
|
+
and passes them to another pen.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
def __init__(self, outPen, transformation):
|
|
13
|
+
"""The 'outPen' argument is another pen object. It will receive the
|
|
14
|
+
transformed coordinates. The 'transformation' argument can either
|
|
15
|
+
be a six-tuple, or a fontTools.misc.transform.Transform object.
|
|
16
|
+
"""
|
|
17
|
+
super(TransformPen, self).__init__(outPen)
|
|
18
|
+
if not hasattr(transformation, "transformPoint"):
|
|
19
|
+
from fontTools.misc.transform import Transform
|
|
20
|
+
|
|
21
|
+
transformation = Transform(*transformation)
|
|
22
|
+
self._transformation = transformation
|
|
23
|
+
self._transformPoint = transformation.transformPoint
|
|
24
|
+
self._stack = []
|
|
25
|
+
|
|
26
|
+
def moveTo(self, pt):
|
|
27
|
+
self._outPen.moveTo(self._transformPoint(pt))
|
|
28
|
+
|
|
29
|
+
def lineTo(self, pt):
|
|
30
|
+
self._outPen.lineTo(self._transformPoint(pt))
|
|
31
|
+
|
|
32
|
+
def curveTo(self, *points):
|
|
33
|
+
self._outPen.curveTo(*self._transformPoints(points))
|
|
34
|
+
|
|
35
|
+
def qCurveTo(self, *points):
|
|
36
|
+
if points[-1] is None:
|
|
37
|
+
points = self._transformPoints(points[:-1]) + [None]
|
|
38
|
+
else:
|
|
39
|
+
points = self._transformPoints(points)
|
|
40
|
+
self._outPen.qCurveTo(*points)
|
|
41
|
+
|
|
42
|
+
def _transformPoints(self, points):
|
|
43
|
+
transformPoint = self._transformPoint
|
|
44
|
+
return [transformPoint(pt) for pt in points]
|
|
45
|
+
|
|
46
|
+
def closePath(self):
|
|
47
|
+
self._outPen.closePath()
|
|
48
|
+
|
|
49
|
+
def endPath(self):
|
|
50
|
+
self._outPen.endPath()
|
|
51
|
+
|
|
52
|
+
def addComponent(self, glyphName, transformation):
|
|
53
|
+
transformation = self._transformation.transform(transformation)
|
|
54
|
+
self._outPen.addComponent(glyphName, transformation)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class TransformPointPen(FilterPointPen):
|
|
58
|
+
"""PointPen that transforms all coordinates using a Affine transformation,
|
|
59
|
+
and passes them to another PointPen.
|
|
60
|
+
|
|
61
|
+
For example::
|
|
62
|
+
|
|
63
|
+
>>> from fontTools.pens.recordingPen import RecordingPointPen
|
|
64
|
+
>>> rec = RecordingPointPen()
|
|
65
|
+
>>> pen = TransformPointPen(rec, (2, 0, 0, 2, -10, 5))
|
|
66
|
+
>>> v = iter(rec.value)
|
|
67
|
+
>>> pen.beginPath(identifier="contour-0")
|
|
68
|
+
>>> next(v)
|
|
69
|
+
('beginPath', (), {'identifier': 'contour-0'})
|
|
70
|
+
|
|
71
|
+
>>> pen.addPoint((100, 100), "line")
|
|
72
|
+
>>> next(v)
|
|
73
|
+
('addPoint', ((190, 205), 'line', False, None), {})
|
|
74
|
+
|
|
75
|
+
>>> pen.endPath()
|
|
76
|
+
>>> next(v)
|
|
77
|
+
('endPath', (), {})
|
|
78
|
+
|
|
79
|
+
>>> pen.addComponent("a", (1, 0, 0, 1, -10, 5), identifier="component-0")
|
|
80
|
+
>>> next(v)
|
|
81
|
+
('addComponent', ('a', <Transform [2 0 0 2 -30 15]>), {'identifier': 'component-0'})
|
|
82
|
+
"""
|
|
83
|
+
|
|
84
|
+
def __init__(self, outPointPen, transformation):
|
|
85
|
+
"""The 'outPointPen' argument is another point pen object.
|
|
86
|
+
It will receive the transformed coordinates.
|
|
87
|
+
The 'transformation' argument can either be a six-tuple, or a
|
|
88
|
+
fontTools.misc.transform.Transform object.
|
|
89
|
+
"""
|
|
90
|
+
super().__init__(outPointPen)
|
|
91
|
+
if not hasattr(transformation, "transformPoint"):
|
|
92
|
+
from fontTools.misc.transform import Transform
|
|
93
|
+
|
|
94
|
+
transformation = Transform(*transformation)
|
|
95
|
+
self._transformation = transformation
|
|
96
|
+
self._transformPoint = transformation.transformPoint
|
|
97
|
+
|
|
98
|
+
def addPoint(self, pt, segmentType=None, smooth=False, name=None, **kwargs):
|
|
99
|
+
self._outPen.addPoint(
|
|
100
|
+
self._transformPoint(pt), segmentType, smooth, name, **kwargs
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
def addComponent(self, baseGlyphName, transformation, **kwargs):
|
|
104
|
+
transformation = self._transformation.transform(transformation)
|
|
105
|
+
self._outPen.addComponent(baseGlyphName, transformation, **kwargs)
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
if __name__ == "__main__":
|
|
109
|
+
from fontTools.pens.basePen import _TestPen
|
|
110
|
+
|
|
111
|
+
pen = TransformPen(_TestPen(None), (2, 0, 0.5, 2, -10, 0))
|
|
112
|
+
pen.moveTo((0, 0))
|
|
113
|
+
pen.lineTo((0, 100))
|
|
114
|
+
pen.curveTo((50, 75), (60, 50), (50, 25), (0, 0))
|
|
115
|
+
pen.closePath()
|