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,69 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""Calculate the perimeter of a glyph."""
|
|
3
|
+
|
|
4
|
+
from fontTools.pens.basePen import BasePen
|
|
5
|
+
from fontTools.misc.bezierTools import (
|
|
6
|
+
approximateQuadraticArcLengthC,
|
|
7
|
+
calcQuadraticArcLengthC,
|
|
8
|
+
approximateCubicArcLengthC,
|
|
9
|
+
calcCubicArcLengthC,
|
|
10
|
+
)
|
|
11
|
+
import math
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
__all__ = ["PerimeterPen"]
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def _distance(p0, p1):
|
|
18
|
+
return math.hypot(p0[0] - p1[0], p0[1] - p1[1])
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class PerimeterPen(BasePen):
|
|
22
|
+
def __init__(self, glyphset=None, tolerance=0.005):
|
|
23
|
+
BasePen.__init__(self, glyphset)
|
|
24
|
+
self.value = 0
|
|
25
|
+
self.tolerance = tolerance
|
|
26
|
+
|
|
27
|
+
# Choose which algorithm to use for quadratic and for cubic.
|
|
28
|
+
# Quadrature is faster but has fixed error characteristic with no strong
|
|
29
|
+
# error bound. The cutoff points are derived empirically.
|
|
30
|
+
self._addCubic = (
|
|
31
|
+
self._addCubicQuadrature if tolerance >= 0.0015 else self._addCubicRecursive
|
|
32
|
+
)
|
|
33
|
+
self._addQuadratic = (
|
|
34
|
+
self._addQuadraticQuadrature
|
|
35
|
+
if tolerance >= 0.00075
|
|
36
|
+
else self._addQuadraticExact
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
def _moveTo(self, p0):
|
|
40
|
+
self.__startPoint = p0
|
|
41
|
+
|
|
42
|
+
def _closePath(self):
|
|
43
|
+
p0 = self._getCurrentPoint()
|
|
44
|
+
if p0 != self.__startPoint:
|
|
45
|
+
self._lineTo(self.__startPoint)
|
|
46
|
+
|
|
47
|
+
def _lineTo(self, p1):
|
|
48
|
+
p0 = self._getCurrentPoint()
|
|
49
|
+
self.value += _distance(p0, p1)
|
|
50
|
+
|
|
51
|
+
def _addQuadraticExact(self, c0, c1, c2):
|
|
52
|
+
self.value += calcQuadraticArcLengthC(c0, c1, c2)
|
|
53
|
+
|
|
54
|
+
def _addQuadraticQuadrature(self, c0, c1, c2):
|
|
55
|
+
self.value += approximateQuadraticArcLengthC(c0, c1, c2)
|
|
56
|
+
|
|
57
|
+
def _qCurveToOne(self, p1, p2):
|
|
58
|
+
p0 = self._getCurrentPoint()
|
|
59
|
+
self._addQuadratic(complex(*p0), complex(*p1), complex(*p2))
|
|
60
|
+
|
|
61
|
+
def _addCubicRecursive(self, c0, c1, c2, c3):
|
|
62
|
+
self.value += calcCubicArcLengthC(c0, c1, c2, c3, self.tolerance)
|
|
63
|
+
|
|
64
|
+
def _addCubicQuadrature(self, c0, c1, c2, c3):
|
|
65
|
+
self.value += approximateCubicArcLengthC(c0, c1, c2, c3)
|
|
66
|
+
|
|
67
|
+
def _curveToOne(self, p1, p2, p3):
|
|
68
|
+
p0 = self._getCurrentPoint()
|
|
69
|
+
self._addCubic(complex(*p0), complex(*p1), complex(*p2), complex(*p3))
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
"""fontTools.pens.pointInsidePen -- Pen implementing "point inside" testing
|
|
2
|
+
for shapes.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from fontTools.pens.basePen import BasePen
|
|
6
|
+
from fontTools.misc.bezierTools import solveQuadratic, solveCubic
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
__all__ = ["PointInsidePen"]
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class PointInsidePen(BasePen):
|
|
13
|
+
"""This pen implements "point inside" testing: to test whether
|
|
14
|
+
a given point lies inside the shape (black) or outside (white).
|
|
15
|
+
Instances of this class can be recycled, as long as the
|
|
16
|
+
setTestPoint() method is used to set the new point to test.
|
|
17
|
+
|
|
18
|
+
:Example:
|
|
19
|
+
.. code-block::
|
|
20
|
+
|
|
21
|
+
pen = PointInsidePen(glyphSet, (100, 200))
|
|
22
|
+
outline.draw(pen)
|
|
23
|
+
isInside = pen.getResult()
|
|
24
|
+
|
|
25
|
+
Both the even-odd algorithm and the non-zero-winding-rule
|
|
26
|
+
algorithm are implemented. The latter is the default, specify
|
|
27
|
+
True for the evenOdd argument of __init__ or setTestPoint
|
|
28
|
+
to use the even-odd algorithm.
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
# This class implements the classical "shoot a ray from the test point
|
|
32
|
+
# to infinity and count how many times it intersects the outline" (as well
|
|
33
|
+
# as the non-zero variant, where the counter is incremented if the outline
|
|
34
|
+
# intersects the ray in one direction and decremented if it intersects in
|
|
35
|
+
# the other direction).
|
|
36
|
+
# I found an amazingly clear explanation of the subtleties involved in
|
|
37
|
+
# implementing this correctly for polygons here:
|
|
38
|
+
# http://graphics.cs.ucdavis.edu/~okreylos/TAship/Spring2000/PointInPolygon.html
|
|
39
|
+
# I extended the principles outlined on that page to curves.
|
|
40
|
+
|
|
41
|
+
def __init__(self, glyphSet, testPoint, evenOdd=False):
|
|
42
|
+
BasePen.__init__(self, glyphSet)
|
|
43
|
+
self.setTestPoint(testPoint, evenOdd)
|
|
44
|
+
|
|
45
|
+
def setTestPoint(self, testPoint, evenOdd=False):
|
|
46
|
+
"""Set the point to test. Call this _before_ the outline gets drawn."""
|
|
47
|
+
self.testPoint = testPoint
|
|
48
|
+
self.evenOdd = evenOdd
|
|
49
|
+
self.firstPoint = None
|
|
50
|
+
self.intersectionCount = 0
|
|
51
|
+
|
|
52
|
+
def getWinding(self):
|
|
53
|
+
if self.firstPoint is not None:
|
|
54
|
+
# always make sure the sub paths are closed; the algorithm only works
|
|
55
|
+
# for closed paths.
|
|
56
|
+
self.closePath()
|
|
57
|
+
return self.intersectionCount
|
|
58
|
+
|
|
59
|
+
def getResult(self):
|
|
60
|
+
"""After the shape has been drawn, getResult() returns True if the test
|
|
61
|
+
point lies within the (black) shape, and False if it doesn't.
|
|
62
|
+
"""
|
|
63
|
+
winding = self.getWinding()
|
|
64
|
+
if self.evenOdd:
|
|
65
|
+
result = winding % 2
|
|
66
|
+
else: # non-zero
|
|
67
|
+
result = self.intersectionCount != 0
|
|
68
|
+
return not not result
|
|
69
|
+
|
|
70
|
+
def _addIntersection(self, goingUp):
|
|
71
|
+
if self.evenOdd or goingUp:
|
|
72
|
+
self.intersectionCount += 1
|
|
73
|
+
else:
|
|
74
|
+
self.intersectionCount -= 1
|
|
75
|
+
|
|
76
|
+
def _moveTo(self, point):
|
|
77
|
+
if self.firstPoint is not None:
|
|
78
|
+
# always make sure the sub paths are closed; the algorithm only works
|
|
79
|
+
# for closed paths.
|
|
80
|
+
self.closePath()
|
|
81
|
+
self.firstPoint = point
|
|
82
|
+
|
|
83
|
+
def _lineTo(self, point):
|
|
84
|
+
x, y = self.testPoint
|
|
85
|
+
x1, y1 = self._getCurrentPoint()
|
|
86
|
+
x2, y2 = point
|
|
87
|
+
|
|
88
|
+
if x1 < x and x2 < x:
|
|
89
|
+
return
|
|
90
|
+
if y1 < y and y2 < y:
|
|
91
|
+
return
|
|
92
|
+
if y1 >= y and y2 >= y:
|
|
93
|
+
return
|
|
94
|
+
|
|
95
|
+
dx = x2 - x1
|
|
96
|
+
dy = y2 - y1
|
|
97
|
+
t = (y - y1) / dy
|
|
98
|
+
ix = dx * t + x1
|
|
99
|
+
if ix < x:
|
|
100
|
+
return
|
|
101
|
+
self._addIntersection(y2 > y1)
|
|
102
|
+
|
|
103
|
+
def _curveToOne(self, bcp1, bcp2, point):
|
|
104
|
+
x, y = self.testPoint
|
|
105
|
+
x1, y1 = self._getCurrentPoint()
|
|
106
|
+
x2, y2 = bcp1
|
|
107
|
+
x3, y3 = bcp2
|
|
108
|
+
x4, y4 = point
|
|
109
|
+
|
|
110
|
+
if x1 < x and x2 < x and x3 < x and x4 < x:
|
|
111
|
+
return
|
|
112
|
+
if y1 < y and y2 < y and y3 < y and y4 < y:
|
|
113
|
+
return
|
|
114
|
+
if y1 >= y and y2 >= y and y3 >= y and y4 >= y:
|
|
115
|
+
return
|
|
116
|
+
|
|
117
|
+
dy = y1
|
|
118
|
+
cy = (y2 - dy) * 3.0
|
|
119
|
+
by = (y3 - y2) * 3.0 - cy
|
|
120
|
+
ay = y4 - dy - cy - by
|
|
121
|
+
solutions = sorted(solveCubic(ay, by, cy, dy - y))
|
|
122
|
+
solutions = [t for t in solutions if -0.0 <= t <= 1.0]
|
|
123
|
+
if not solutions:
|
|
124
|
+
return
|
|
125
|
+
|
|
126
|
+
dx = x1
|
|
127
|
+
cx = (x2 - dx) * 3.0
|
|
128
|
+
bx = (x3 - x2) * 3.0 - cx
|
|
129
|
+
ax = x4 - dx - cx - bx
|
|
130
|
+
|
|
131
|
+
above = y1 >= y
|
|
132
|
+
lastT = None
|
|
133
|
+
for t in solutions:
|
|
134
|
+
if t == lastT:
|
|
135
|
+
continue
|
|
136
|
+
lastT = t
|
|
137
|
+
t2 = t * t
|
|
138
|
+
t3 = t2 * t
|
|
139
|
+
|
|
140
|
+
direction = 3 * ay * t2 + 2 * by * t + cy
|
|
141
|
+
incomingGoingUp = outgoingGoingUp = direction > 0.0
|
|
142
|
+
if direction == 0.0:
|
|
143
|
+
direction = 6 * ay * t + 2 * by
|
|
144
|
+
outgoingGoingUp = direction > 0.0
|
|
145
|
+
incomingGoingUp = not outgoingGoingUp
|
|
146
|
+
if direction == 0.0:
|
|
147
|
+
direction = ay
|
|
148
|
+
incomingGoingUp = outgoingGoingUp = direction > 0.0
|
|
149
|
+
|
|
150
|
+
xt = ax * t3 + bx * t2 + cx * t + dx
|
|
151
|
+
if xt < x:
|
|
152
|
+
continue
|
|
153
|
+
|
|
154
|
+
if t in (0.0, -0.0):
|
|
155
|
+
if not outgoingGoingUp:
|
|
156
|
+
self._addIntersection(outgoingGoingUp)
|
|
157
|
+
elif t == 1.0:
|
|
158
|
+
if incomingGoingUp:
|
|
159
|
+
self._addIntersection(incomingGoingUp)
|
|
160
|
+
else:
|
|
161
|
+
if incomingGoingUp == outgoingGoingUp:
|
|
162
|
+
self._addIntersection(outgoingGoingUp)
|
|
163
|
+
# else:
|
|
164
|
+
# we're not really intersecting, merely touching
|
|
165
|
+
|
|
166
|
+
def _qCurveToOne_unfinished(self, bcp, point):
|
|
167
|
+
# XXX need to finish this, for now doing it through a cubic
|
|
168
|
+
# (BasePen implements _qCurveTo in terms of a cubic) will
|
|
169
|
+
# have to do.
|
|
170
|
+
x, y = self.testPoint
|
|
171
|
+
x1, y1 = self._getCurrentPoint()
|
|
172
|
+
x2, y2 = bcp
|
|
173
|
+
x3, y3 = point
|
|
174
|
+
c = y1
|
|
175
|
+
b = (y2 - c) * 2.0
|
|
176
|
+
a = y3 - c - b
|
|
177
|
+
solutions = sorted(solveQuadratic(a, b, c - y))
|
|
178
|
+
solutions = [
|
|
179
|
+
t for t in solutions if ZERO_MINUS_EPSILON <= t <= ONE_PLUS_EPSILON
|
|
180
|
+
]
|
|
181
|
+
if not solutions:
|
|
182
|
+
return
|
|
183
|
+
# XXX
|
|
184
|
+
|
|
185
|
+
def _closePath(self):
|
|
186
|
+
if self._getCurrentPoint() != self.firstPoint:
|
|
187
|
+
self.lineTo(self.firstPoint)
|
|
188
|
+
self.firstPoint = None
|
|
189
|
+
|
|
190
|
+
def _endPath(self):
|
|
191
|
+
"""Insideness is not defined for open contours."""
|
|
192
|
+
raise NotImplementedError
|