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,14 @@
|
|
|
1
|
+
from .otBase import BaseTTXConverter
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
# https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6opbd.html
|
|
5
|
+
class table__o_p_b_d(BaseTTXConverter):
|
|
6
|
+
"""Optical Bounds table
|
|
7
|
+
|
|
8
|
+
The AAT ``opbd`` table contains optical boundary points for glyphs, which
|
|
9
|
+
applications can use for the visual alignment of lines of text.
|
|
10
|
+
|
|
11
|
+
See also https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6opbd.html
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
pass
|
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
from fontTools import ttLib
|
|
2
|
+
from fontTools.ttLib.standardGlyphOrder import standardGlyphOrder
|
|
3
|
+
from fontTools.misc import sstruct
|
|
4
|
+
from fontTools.misc.textTools import bytechr, byteord, tobytes, tostr, safeEval, readHex
|
|
5
|
+
from . import DefaultTable
|
|
6
|
+
import sys
|
|
7
|
+
import struct
|
|
8
|
+
import array
|
|
9
|
+
import logging
|
|
10
|
+
|
|
11
|
+
log = logging.getLogger(__name__)
|
|
12
|
+
|
|
13
|
+
postFormat = """
|
|
14
|
+
>
|
|
15
|
+
formatType: 16.16F
|
|
16
|
+
italicAngle: 16.16F # italic angle in degrees
|
|
17
|
+
underlinePosition: h
|
|
18
|
+
underlineThickness: h
|
|
19
|
+
isFixedPitch: L
|
|
20
|
+
minMemType42: L # minimum memory if TrueType font is downloaded
|
|
21
|
+
maxMemType42: L # maximum memory if TrueType font is downloaded
|
|
22
|
+
minMemType1: L # minimum memory if Type1 font is downloaded
|
|
23
|
+
maxMemType1: L # maximum memory if Type1 font is downloaded
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
postFormatSize = sstruct.calcsize(postFormat)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class table__p_o_s_t(DefaultTable.DefaultTable):
|
|
30
|
+
"""PostScript table
|
|
31
|
+
|
|
32
|
+
The ``post`` table contains information needed to use the font on
|
|
33
|
+
PostScript printers, including the PostScript names of glyphs and
|
|
34
|
+
data that was stored in the ``FontInfo`` dictionary for Type 1 fonts.
|
|
35
|
+
|
|
36
|
+
See also https://learn.microsoft.com/en-us/typography/opentype/spec/post
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
def decompile(self, data, ttFont):
|
|
40
|
+
sstruct.unpack(postFormat, data[:postFormatSize], self)
|
|
41
|
+
data = data[postFormatSize:]
|
|
42
|
+
if self.formatType == 1.0:
|
|
43
|
+
self.decode_format_1_0(data, ttFont)
|
|
44
|
+
elif self.formatType == 2.0:
|
|
45
|
+
self.decode_format_2_0(data, ttFont)
|
|
46
|
+
elif self.formatType == 3.0:
|
|
47
|
+
self.decode_format_3_0(data, ttFont)
|
|
48
|
+
elif self.formatType == 4.0:
|
|
49
|
+
self.decode_format_4_0(data, ttFont)
|
|
50
|
+
else:
|
|
51
|
+
# supported format
|
|
52
|
+
raise ttLib.TTLibError(
|
|
53
|
+
"'post' table format %f not supported" % self.formatType
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
def compile(self, ttFont):
|
|
57
|
+
data = sstruct.pack(postFormat, self)
|
|
58
|
+
if self.formatType == 1.0:
|
|
59
|
+
pass # we're done
|
|
60
|
+
elif self.formatType == 2.0:
|
|
61
|
+
data = data + self.encode_format_2_0(ttFont)
|
|
62
|
+
elif self.formatType == 3.0:
|
|
63
|
+
pass # we're done
|
|
64
|
+
elif self.formatType == 4.0:
|
|
65
|
+
data = data + self.encode_format_4_0(ttFont)
|
|
66
|
+
else:
|
|
67
|
+
# supported format
|
|
68
|
+
raise ttLib.TTLibError(
|
|
69
|
+
"'post' table format %f not supported" % self.formatType
|
|
70
|
+
)
|
|
71
|
+
return data
|
|
72
|
+
|
|
73
|
+
def getGlyphOrder(self):
|
|
74
|
+
"""This function will get called by a ttLib.TTFont instance.
|
|
75
|
+
Do not call this function yourself, use TTFont().getGlyphOrder()
|
|
76
|
+
or its relatives instead!
|
|
77
|
+
"""
|
|
78
|
+
if not hasattr(self, "glyphOrder"):
|
|
79
|
+
raise ttLib.TTLibError("illegal use of getGlyphOrder()")
|
|
80
|
+
glyphOrder = self.glyphOrder
|
|
81
|
+
del self.glyphOrder
|
|
82
|
+
return glyphOrder
|
|
83
|
+
|
|
84
|
+
def decode_format_1_0(self, data, ttFont):
|
|
85
|
+
self.glyphOrder = standardGlyphOrder[: ttFont["maxp"].numGlyphs]
|
|
86
|
+
|
|
87
|
+
def decode_format_2_0(self, data, ttFont):
|
|
88
|
+
(numGlyphs,) = struct.unpack(">H", data[:2])
|
|
89
|
+
numGlyphs = int(numGlyphs)
|
|
90
|
+
if numGlyphs > ttFont["maxp"].numGlyphs:
|
|
91
|
+
# Assume the numGlyphs field is bogus, so sync with maxp.
|
|
92
|
+
# I've seen this in one font, and if the assumption is
|
|
93
|
+
# wrong elsewhere, well, so be it: it's hard enough to
|
|
94
|
+
# work around _one_ non-conforming post format...
|
|
95
|
+
numGlyphs = ttFont["maxp"].numGlyphs
|
|
96
|
+
data = data[2:]
|
|
97
|
+
indices = array.array("H")
|
|
98
|
+
indices.frombytes(data[: 2 * numGlyphs])
|
|
99
|
+
if sys.byteorder != "big":
|
|
100
|
+
indices.byteswap()
|
|
101
|
+
data = data[2 * numGlyphs :]
|
|
102
|
+
maxIndex = max(indices)
|
|
103
|
+
self.extraNames = extraNames = unpackPStrings(data, maxIndex - 257)
|
|
104
|
+
self.glyphOrder = glyphOrder = [""] * int(ttFont["maxp"].numGlyphs)
|
|
105
|
+
for glyphID in range(numGlyphs):
|
|
106
|
+
index = indices[glyphID]
|
|
107
|
+
if index > 257:
|
|
108
|
+
try:
|
|
109
|
+
name = extraNames[index - 258]
|
|
110
|
+
except IndexError:
|
|
111
|
+
name = ""
|
|
112
|
+
else:
|
|
113
|
+
# fetch names from standard list
|
|
114
|
+
name = standardGlyphOrder[index]
|
|
115
|
+
glyphOrder[glyphID] = name
|
|
116
|
+
self.build_psNameMapping(ttFont)
|
|
117
|
+
|
|
118
|
+
def build_psNameMapping(self, ttFont):
|
|
119
|
+
mapping = {}
|
|
120
|
+
allNames = {}
|
|
121
|
+
glyphOrderNames = set(self.glyphOrder)
|
|
122
|
+
for i in range(ttFont["maxp"].numGlyphs):
|
|
123
|
+
glyphName = psName = self.glyphOrder[i]
|
|
124
|
+
if glyphName == "":
|
|
125
|
+
glyphName = "glyph%.5d" % i
|
|
126
|
+
|
|
127
|
+
if glyphName in allNames:
|
|
128
|
+
# make up a new glyphName that's unique
|
|
129
|
+
n = allNames[glyphName]
|
|
130
|
+
# check if the glyph name exists in the glyph order
|
|
131
|
+
while f"{glyphName}.{n}" in glyphOrderNames:
|
|
132
|
+
n += 1
|
|
133
|
+
allNames[glyphName] = n + 1
|
|
134
|
+
glyphName = f"{glyphName}.{n}"
|
|
135
|
+
|
|
136
|
+
allNames[glyphName] = 1
|
|
137
|
+
if glyphName != psName:
|
|
138
|
+
self.glyphOrder[i] = glyphName
|
|
139
|
+
mapping[glyphName] = psName
|
|
140
|
+
|
|
141
|
+
self.mapping = mapping
|
|
142
|
+
|
|
143
|
+
def decode_format_3_0(self, data, ttFont):
|
|
144
|
+
# Setting self.glyphOrder to None will cause the TTFont object
|
|
145
|
+
# try and construct glyph names from a Unicode cmap table.
|
|
146
|
+
self.glyphOrder = None
|
|
147
|
+
|
|
148
|
+
def decode_format_4_0(self, data, ttFont):
|
|
149
|
+
from fontTools import agl
|
|
150
|
+
|
|
151
|
+
numGlyphs = ttFont["maxp"].numGlyphs
|
|
152
|
+
indices = array.array("H")
|
|
153
|
+
indices.frombytes(data)
|
|
154
|
+
if sys.byteorder != "big":
|
|
155
|
+
indices.byteswap()
|
|
156
|
+
# In some older fonts, the size of the post table doesn't match
|
|
157
|
+
# the number of glyphs. Sometimes it's bigger, sometimes smaller.
|
|
158
|
+
self.glyphOrder = glyphOrder = [""] * int(numGlyphs)
|
|
159
|
+
for i in range(min(len(indices), numGlyphs)):
|
|
160
|
+
if indices[i] == 0xFFFF:
|
|
161
|
+
self.glyphOrder[i] = ""
|
|
162
|
+
elif indices[i] in agl.UV2AGL:
|
|
163
|
+
self.glyphOrder[i] = agl.UV2AGL[indices[i]]
|
|
164
|
+
else:
|
|
165
|
+
self.glyphOrder[i] = "uni%04X" % indices[i]
|
|
166
|
+
self.build_psNameMapping(ttFont)
|
|
167
|
+
|
|
168
|
+
def encode_format_2_0(self, ttFont):
|
|
169
|
+
numGlyphs = ttFont["maxp"].numGlyphs
|
|
170
|
+
glyphOrder = ttFont.getGlyphOrder()
|
|
171
|
+
assert len(glyphOrder) == numGlyphs
|
|
172
|
+
indices = array.array("H")
|
|
173
|
+
extraDict = {}
|
|
174
|
+
extraNames = self.extraNames = [
|
|
175
|
+
n for n in self.extraNames if n not in standardGlyphOrder
|
|
176
|
+
]
|
|
177
|
+
for i, name in enumerate(extraNames):
|
|
178
|
+
extraDict[name] = i
|
|
179
|
+
for glyphName in glyphOrder:
|
|
180
|
+
if glyphName in self.mapping:
|
|
181
|
+
psName = self.mapping[glyphName]
|
|
182
|
+
else:
|
|
183
|
+
psName = glyphName
|
|
184
|
+
if psName in extraDict:
|
|
185
|
+
index = 258 + extraDict[psName]
|
|
186
|
+
elif psName in standardGlyphOrder:
|
|
187
|
+
index = standardGlyphOrder.index(psName)
|
|
188
|
+
else:
|
|
189
|
+
index = 258 + len(extraNames)
|
|
190
|
+
extraDict[psName] = len(extraNames)
|
|
191
|
+
extraNames.append(psName)
|
|
192
|
+
indices.append(index)
|
|
193
|
+
if sys.byteorder != "big":
|
|
194
|
+
indices.byteswap()
|
|
195
|
+
return (
|
|
196
|
+
struct.pack(">H", numGlyphs) + indices.tobytes() + packPStrings(extraNames)
|
|
197
|
+
)
|
|
198
|
+
|
|
199
|
+
def encode_format_4_0(self, ttFont):
|
|
200
|
+
from fontTools import agl
|
|
201
|
+
|
|
202
|
+
numGlyphs = ttFont["maxp"].numGlyphs
|
|
203
|
+
glyphOrder = ttFont.getGlyphOrder()
|
|
204
|
+
assert len(glyphOrder) == numGlyphs
|
|
205
|
+
indices = array.array("H")
|
|
206
|
+
for glyphID in glyphOrder:
|
|
207
|
+
glyphID = glyphID.split("#")[0]
|
|
208
|
+
if glyphID in agl.AGL2UV:
|
|
209
|
+
indices.append(agl.AGL2UV[glyphID])
|
|
210
|
+
elif len(glyphID) == 7 and glyphID[:3] == "uni":
|
|
211
|
+
indices.append(int(glyphID[3:], 16))
|
|
212
|
+
else:
|
|
213
|
+
indices.append(0xFFFF)
|
|
214
|
+
if sys.byteorder != "big":
|
|
215
|
+
indices.byteswap()
|
|
216
|
+
return indices.tobytes()
|
|
217
|
+
|
|
218
|
+
def toXML(self, writer, ttFont):
|
|
219
|
+
formatstring, names, fixes = sstruct.getformat(postFormat)
|
|
220
|
+
for name in names:
|
|
221
|
+
value = getattr(self, name)
|
|
222
|
+
writer.simpletag(name, value=value)
|
|
223
|
+
writer.newline()
|
|
224
|
+
if hasattr(self, "mapping"):
|
|
225
|
+
writer.begintag("psNames")
|
|
226
|
+
writer.newline()
|
|
227
|
+
writer.comment(
|
|
228
|
+
"This file uses unique glyph names based on the information\n"
|
|
229
|
+
"found in the 'post' table. Since these names might not be unique,\n"
|
|
230
|
+
"we have to invent artificial names in case of clashes. In order to\n"
|
|
231
|
+
"be able to retain the original information, we need a name to\n"
|
|
232
|
+
"ps name mapping for those cases where they differ. That's what\n"
|
|
233
|
+
"you see below.\n"
|
|
234
|
+
)
|
|
235
|
+
writer.newline()
|
|
236
|
+
items = sorted(self.mapping.items())
|
|
237
|
+
for name, psName in items:
|
|
238
|
+
writer.simpletag("psName", name=name, psName=psName)
|
|
239
|
+
writer.newline()
|
|
240
|
+
writer.endtag("psNames")
|
|
241
|
+
writer.newline()
|
|
242
|
+
if hasattr(self, "extraNames"):
|
|
243
|
+
writer.begintag("extraNames")
|
|
244
|
+
writer.newline()
|
|
245
|
+
writer.comment(
|
|
246
|
+
"following are the name that are not taken from the standard Mac glyph order"
|
|
247
|
+
)
|
|
248
|
+
writer.newline()
|
|
249
|
+
for name in self.extraNames:
|
|
250
|
+
writer.simpletag("psName", name=name)
|
|
251
|
+
writer.newline()
|
|
252
|
+
writer.endtag("extraNames")
|
|
253
|
+
writer.newline()
|
|
254
|
+
if hasattr(self, "data"):
|
|
255
|
+
writer.begintag("hexdata")
|
|
256
|
+
writer.newline()
|
|
257
|
+
writer.dumphex(self.data)
|
|
258
|
+
writer.endtag("hexdata")
|
|
259
|
+
writer.newline()
|
|
260
|
+
|
|
261
|
+
def fromXML(self, name, attrs, content, ttFont):
|
|
262
|
+
if name not in ("psNames", "extraNames", "hexdata"):
|
|
263
|
+
setattr(self, name, safeEval(attrs["value"]))
|
|
264
|
+
elif name == "psNames":
|
|
265
|
+
self.mapping = {}
|
|
266
|
+
for element in content:
|
|
267
|
+
if not isinstance(element, tuple):
|
|
268
|
+
continue
|
|
269
|
+
name, attrs, content = element
|
|
270
|
+
if name == "psName":
|
|
271
|
+
self.mapping[attrs["name"]] = attrs["psName"]
|
|
272
|
+
elif name == "extraNames":
|
|
273
|
+
self.extraNames = []
|
|
274
|
+
for element in content:
|
|
275
|
+
if not isinstance(element, tuple):
|
|
276
|
+
continue
|
|
277
|
+
name, attrs, content = element
|
|
278
|
+
if name == "psName":
|
|
279
|
+
self.extraNames.append(attrs["name"])
|
|
280
|
+
else:
|
|
281
|
+
self.data = readHex(content)
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
def unpackPStrings(data, n):
|
|
285
|
+
# extract n Pascal strings from data.
|
|
286
|
+
# if there is not enough data, use ""
|
|
287
|
+
|
|
288
|
+
strings = []
|
|
289
|
+
index = 0
|
|
290
|
+
dataLen = len(data)
|
|
291
|
+
|
|
292
|
+
for _ in range(n):
|
|
293
|
+
if dataLen <= index:
|
|
294
|
+
length = 0
|
|
295
|
+
else:
|
|
296
|
+
length = byteord(data[index])
|
|
297
|
+
index += 1
|
|
298
|
+
|
|
299
|
+
if dataLen <= index + length - 1:
|
|
300
|
+
name = ""
|
|
301
|
+
else:
|
|
302
|
+
name = tostr(data[index : index + length], encoding="latin1")
|
|
303
|
+
strings.append(name)
|
|
304
|
+
index += length
|
|
305
|
+
|
|
306
|
+
if index < dataLen:
|
|
307
|
+
log.warning("%d extra bytes in post.stringData array", dataLen - index)
|
|
308
|
+
|
|
309
|
+
elif dataLen < index:
|
|
310
|
+
log.warning("not enough data in post.stringData array")
|
|
311
|
+
|
|
312
|
+
return strings
|
|
313
|
+
|
|
314
|
+
|
|
315
|
+
def packPStrings(strings):
|
|
316
|
+
data = b""
|
|
317
|
+
for s in strings:
|
|
318
|
+
data = data + bytechr(len(s)) + tobytes(s, encoding="latin1")
|
|
319
|
+
return data
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from fontTools import ttLib
|
|
2
|
+
|
|
3
|
+
superclass = ttLib.getTableClass("fpgm")
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class table__p_r_e_p(superclass):
|
|
7
|
+
"""Control Value Program table
|
|
8
|
+
|
|
9
|
+
The ``prep`` table contains TrueType instructions that can makee font-wide
|
|
10
|
+
alterations to the Control Value Table. It may potentially be executed
|
|
11
|
+
before any glyph is processed.
|
|
12
|
+
|
|
13
|
+
See also https://learn.microsoft.com/en-us/typography/opentype/spec/prep
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
pass
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from .otBase import BaseTTXConverter
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
# https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6prop.html
|
|
5
|
+
class table__p_r_o_p(BaseTTXConverter):
|
|
6
|
+
"""The AAT ``prop`` table can store a variety of per-glyph properties, such as
|
|
7
|
+
Unicode directionality or whether glyphs are non-spacing marks.
|
|
8
|
+
|
|
9
|
+
See also https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6prop.html
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
pass
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
from fontTools.misc import sstruct
|
|
2
|
+
from fontTools.misc.textTools import safeEval, num2binary, binary2num
|
|
3
|
+
from . import DefaultTable
|
|
4
|
+
from .sbixStrike import Strike
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
sbixHeaderFormat = """
|
|
8
|
+
>
|
|
9
|
+
version: H # Version number (set to 1)
|
|
10
|
+
flags: H # The only two bits used in the flags field are bits 0
|
|
11
|
+
# and 1. For historical reasons, bit 0 must always be 1.
|
|
12
|
+
# Bit 1 is a sbixDrawOutlines flag and is interpreted as
|
|
13
|
+
# follows:
|
|
14
|
+
# 0: Draw only 'sbix' bitmaps
|
|
15
|
+
# 1: Draw both 'sbix' bitmaps and outlines, in that
|
|
16
|
+
# order
|
|
17
|
+
numStrikes: L # Number of bitmap strikes to follow
|
|
18
|
+
"""
|
|
19
|
+
sbixHeaderFormatSize = sstruct.calcsize(sbixHeaderFormat)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
sbixStrikeOffsetFormat = """
|
|
23
|
+
>
|
|
24
|
+
strikeOffset: L # Offset from begining of table to data for the
|
|
25
|
+
# individual strike
|
|
26
|
+
"""
|
|
27
|
+
sbixStrikeOffsetFormatSize = sstruct.calcsize(sbixStrikeOffsetFormat)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class table__s_b_i_x(DefaultTable.DefaultTable):
|
|
31
|
+
"""Standard Bitmap Graphics table
|
|
32
|
+
|
|
33
|
+
The ``sbix`` table stores bitmap image data in standard graphics formats
|
|
34
|
+
like JPEG, PNG, or TIFF. The glyphs for which the ``sbix`` table provides
|
|
35
|
+
data are indexed by Glyph ID. For each such glyph, the ``sbix`` table can
|
|
36
|
+
hold different data for different sizes, called "strikes."
|
|
37
|
+
|
|
38
|
+
See also https://learn.microsoft.com/en-us/typography/opentype/spec/sbix
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
def __init__(self, tag=None):
|
|
42
|
+
DefaultTable.DefaultTable.__init__(self, tag)
|
|
43
|
+
self.version = 1
|
|
44
|
+
self.flags = 1
|
|
45
|
+
self.numStrikes = 0
|
|
46
|
+
self.strikes = {}
|
|
47
|
+
self.strikeOffsets = []
|
|
48
|
+
|
|
49
|
+
def decompile(self, data, ttFont):
|
|
50
|
+
# read table header
|
|
51
|
+
sstruct.unpack(sbixHeaderFormat, data[:sbixHeaderFormatSize], self)
|
|
52
|
+
# collect offsets to individual strikes in self.strikeOffsets
|
|
53
|
+
for i in range(self.numStrikes):
|
|
54
|
+
current_offset = sbixHeaderFormatSize + i * sbixStrikeOffsetFormatSize
|
|
55
|
+
offset_entry = sbixStrikeOffset()
|
|
56
|
+
sstruct.unpack(
|
|
57
|
+
sbixStrikeOffsetFormat,
|
|
58
|
+
data[current_offset : current_offset + sbixStrikeOffsetFormatSize],
|
|
59
|
+
offset_entry,
|
|
60
|
+
)
|
|
61
|
+
self.strikeOffsets.append(offset_entry.strikeOffset)
|
|
62
|
+
|
|
63
|
+
# decompile Strikes
|
|
64
|
+
for i in range(self.numStrikes - 1, -1, -1):
|
|
65
|
+
current_strike = Strike(rawdata=data[self.strikeOffsets[i] :])
|
|
66
|
+
data = data[: self.strikeOffsets[i]]
|
|
67
|
+
current_strike.decompile(ttFont)
|
|
68
|
+
# print " Strike length: %xh" % len(bitmapSetData)
|
|
69
|
+
# print "Number of Glyph entries:", len(current_strike.glyphs)
|
|
70
|
+
if current_strike.ppem in self.strikes:
|
|
71
|
+
from fontTools import ttLib
|
|
72
|
+
|
|
73
|
+
raise ttLib.TTLibError("Pixel 'ppem' must be unique for each Strike")
|
|
74
|
+
self.strikes[current_strike.ppem] = current_strike
|
|
75
|
+
|
|
76
|
+
# after the glyph data records have been extracted, we don't need the offsets anymore
|
|
77
|
+
del self.strikeOffsets
|
|
78
|
+
del self.numStrikes
|
|
79
|
+
|
|
80
|
+
def compile(self, ttFont):
|
|
81
|
+
sbixData = b""
|
|
82
|
+
self.numStrikes = len(self.strikes)
|
|
83
|
+
sbixHeader = sstruct.pack(sbixHeaderFormat, self)
|
|
84
|
+
|
|
85
|
+
# calculate offset to start of first strike
|
|
86
|
+
setOffset = sbixHeaderFormatSize + sbixStrikeOffsetFormatSize * self.numStrikes
|
|
87
|
+
|
|
88
|
+
for si in sorted(self.strikes.keys()):
|
|
89
|
+
current_strike = self.strikes[si]
|
|
90
|
+
current_strike.compile(ttFont)
|
|
91
|
+
# append offset to this strike to table header
|
|
92
|
+
current_strike.strikeOffset = setOffset
|
|
93
|
+
sbixHeader += sstruct.pack(sbixStrikeOffsetFormat, current_strike)
|
|
94
|
+
setOffset += len(current_strike.data)
|
|
95
|
+
sbixData += current_strike.data
|
|
96
|
+
|
|
97
|
+
return sbixHeader + sbixData
|
|
98
|
+
|
|
99
|
+
def toXML(self, xmlWriter, ttFont):
|
|
100
|
+
xmlWriter.simpletag("version", value=self.version)
|
|
101
|
+
xmlWriter.newline()
|
|
102
|
+
xmlWriter.simpletag("flags", value=num2binary(self.flags, 16))
|
|
103
|
+
xmlWriter.newline()
|
|
104
|
+
for i in sorted(self.strikes.keys()):
|
|
105
|
+
self.strikes[i].toXML(xmlWriter, ttFont)
|
|
106
|
+
|
|
107
|
+
def fromXML(self, name, attrs, content, ttFont):
|
|
108
|
+
if name == "version":
|
|
109
|
+
setattr(self, name, safeEval(attrs["value"]))
|
|
110
|
+
elif name == "flags":
|
|
111
|
+
setattr(self, name, binary2num(attrs["value"]))
|
|
112
|
+
elif name == "strike":
|
|
113
|
+
current_strike = Strike()
|
|
114
|
+
for element in content:
|
|
115
|
+
if isinstance(element, tuple):
|
|
116
|
+
name, attrs, content = element
|
|
117
|
+
current_strike.fromXML(name, attrs, content, ttFont)
|
|
118
|
+
self.strikes[current_strike.ppem] = current_strike
|
|
119
|
+
else:
|
|
120
|
+
from fontTools import ttLib
|
|
121
|
+
|
|
122
|
+
raise ttLib.TTLibError("can't handle '%s' element" % name)
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
# Helper classes
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
class sbixStrikeOffset(object):
|
|
129
|
+
pass
|