From e2da17e0328ab13162a2dcc296e49d7977adf171 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 30 Jun 2016 16:39:20 -0700 Subject: [PATCH] [opentype-gx/varLib] More work towards VariationStore And HVAR/VVAR tables. --- Lib/fontTools/ttLib/tables/H_V_A_R_.py | 7 +++ Lib/fontTools/ttLib/tables/V_V_A_R_.py | 7 +++ Lib/fontTools/ttLib/tables/__init__.py | 2 + Lib/fontTools/ttLib/tables/otConverters.py | 7 +++ Lib/fontTools/ttLib/tables/otData.py | 41 ++++++++++++++-- Lib/fontTools/varLib/__init__.py | 1 + Lib/fontTools/varLib/builder.py | 57 ++++++++++++++++++++++ README.md | 10 ++-- 8 files changed, 122 insertions(+), 10 deletions(-) create mode 100644 Lib/fontTools/ttLib/tables/H_V_A_R_.py create mode 100644 Lib/fontTools/ttLib/tables/V_V_A_R_.py create mode 100644 Lib/fontTools/varLib/builder.py diff --git a/Lib/fontTools/ttLib/tables/H_V_A_R_.py b/Lib/fontTools/ttLib/tables/H_V_A_R_.py new file mode 100644 index 000000000..efab4e721 --- /dev/null +++ b/Lib/fontTools/ttLib/tables/H_V_A_R_.py @@ -0,0 +1,7 @@ +from __future__ import print_function, division, absolute_import +from fontTools.misc.py23 import * +from .otBase import BaseTTXConverter + + +class table_H_V_A_R_(BaseTTXConverter): + pass diff --git a/Lib/fontTools/ttLib/tables/V_V_A_R_.py b/Lib/fontTools/ttLib/tables/V_V_A_R_.py new file mode 100644 index 000000000..530f0e3af --- /dev/null +++ b/Lib/fontTools/ttLib/tables/V_V_A_R_.py @@ -0,0 +1,7 @@ +from __future__ import print_function, division, absolute_import +from fontTools.misc.py23 import * +from .otBase import BaseTTXConverter + + +class table_V_V_A_R_(BaseTTXConverter): + pass diff --git a/Lib/fontTools/ttLib/tables/__init__.py b/Lib/fontTools/ttLib/tables/__init__.py index 18b60ec15..925be38ce 100644 --- a/Lib/fontTools/ttLib/tables/__init__.py +++ b/Lib/fontTools/ttLib/tables/__init__.py @@ -24,6 +24,7 @@ def _moduleFinderHint(): from . import G_P_K_G_ from . import G_P_O_S_ from . import G_S_U_B_ + from . import H_V_A_R_ from . import J_S_T_F_ from . import L_T_S_H_ from . import M_A_T_H_ @@ -44,6 +45,7 @@ def _moduleFinderHint(): from . import T_S_I__5 from . import V_D_M_X_ from . import V_O_R_G_ + from . import V_V_A_R_ from . import _a_v_a_r from . import _c_m_a_p from . import _c_v_t diff --git a/Lib/fontTools/ttLib/tables/otConverters.py b/Lib/fontTools/ttLib/tables/otConverters.py index 91906874e..c16f9042b 100644 --- a/Lib/fontTools/ttLib/tables/otConverters.py +++ b/Lib/fontTools/ttLib/tables/otConverters.py @@ -227,6 +227,13 @@ class GlyphID(SimpleValue): def write(self, writer, font, tableDict, value, repeatIndex=None): writer.writeUShort(font.getGlyphID(value)) +class VarAxisID(SimpleValue): + staticSize = 2 + def read(self, reader, font, tableDict): + return font['fvar'].axes[reader.readUShort()] + def write(self, writer, font, tableDict, value, repeatIndex=None): + writer.writeUShort(font['fvar'].axes.index(value)) + class FloatValue(SimpleValue): def xmlRead(self, attrs, content, font): return float(attrs["value"]) diff --git a/Lib/fontTools/ttLib/tables/otData.py b/Lib/fontTools/ttLib/tables/otData.py index b84f1bd40..53d72fdd7 100644 --- a/Lib/fontTools/ttLib/tables/otData.py +++ b/Lib/fontTools/ttLib/tables/otData.py @@ -837,11 +837,15 @@ otData = [ ('Offset', 'Lookup', 'LookupCount', 0, 'Array of offsets to GPOS-type lookup tables-from beginning of JstfMax table-in design order'), ]), + # - # variations + # Variation fonts # + + # VariationStore + ('VarAxis', [ - ('uint16', 'AxisIndex', None, None, ''), + ('uint16', 'VarAxisID', None, None, ''), ('F2Dot14', 'StartCoord', None, None, ''), ('F2Dot14', 'PeakCoord', None, None, ''), ('F2Dot14', 'EndCoord', None, None, ''), @@ -869,7 +873,7 @@ otData = [ ('uint16', 'ItemCount', None, None, ''), ('uint16', 'VarTupleCount', None, None, ''), ('uint16', 'VarTupleIndex', 'VarTupleCount', 0, ''), - ('struct', 'VarItemByteRecord', 'ItemCount', 0, ''), + ('VarItemByteRecord', 'Item', 'ItemCount', 0, ''), ]), ('VarDeltasFormat2', [ @@ -877,16 +881,43 @@ otData = [ ('uint16', 'ItemCount', None, None, ''), ('uint16', 'VarTupleCount', None, None, ''), ('uint16', 'VarTupleIndex', 'VarTupleCount', 0, ''), - ('struct', 'VarItemShortRecord', 'ItemCount', 0, ''), + ('VarItemShortRecord', 'Item', 'ItemCount', 0, ''), ]), ('VarStore', [ - ('LOffset', 'VarTupleList', None, None, ''), ('uint16', 'Format', None, None, 'Set to 1.'), + ('LOffset', 'VarTupleList', None, None, ''), ('uint16', 'VarDeltasCount', None, None, ''), ('LOffset', 'VarDeltas', 'VarDeltasCount', 0, ''), ]), + # Variation helpers + + ('VarIdxMapFormat1', [ + ('uint16', 'Format', None, None, 'Set to 1.'), + ('uint16', 'VarIdxCount', None, None, ''), + ('uint16', 'VarIdx', 'VarIdxCount', 0, ''), + ]), + ('VarIdxMapFormat2', [ + ('uint16', 'Format', None, None, 'Set to 2.'), + ('uint16', 'VarIdxCount', None, None, ''), + ('uint32', 'VarIdx', 'VarIdxCount', 0, ''), + ]), + + # Glyph advance variations + + ('HVAR', [ + ('Version', 'Version', None, None, 'Version of the HVAR table-initially = 0x00010000'), + ('LOffset', 'VarIdxMap', None, None, ''), + ('LOffset', 'VarStore', None, None, ''), + ]), + ('VVAR', [ + ('Version', 'Version', None, None, 'Version of the VVAR table-initially = 0x00010000'), + ('LOffset', 'VarIdxMap', None, None, ''), + ('LOffset', 'VarStore', None, None, ''), + ]), + + # # math # diff --git a/Lib/fontTools/varLib/__init__.py b/Lib/fontTools/varLib/__init__.py index 3d787cb2e..ca6184c85 100644 --- a/Lib/fontTools/varLib/__init__.py +++ b/Lib/fontTools/varLib/__init__.py @@ -25,6 +25,7 @@ from fontTools.ttLib.tables._n_a_m_e import NameRecord from fontTools.ttLib.tables._f_v_a_r import table__f_v_a_r, Axis, NamedInstance from fontTools.ttLib.tables._g_l_y_f import GlyphCoordinates from fontTools.ttLib.tables._g_v_a_r import table__g_v_a_r, GlyphVariation +from fontTools.varLib import builder import warnings try: import xml.etree.cElementTree as ET diff --git a/Lib/fontTools/varLib/builder.py b/Lib/fontTools/varLib/builder.py new file mode 100644 index 000000000..960541fac --- /dev/null +++ b/Lib/fontTools/varLib/builder.py @@ -0,0 +1,57 @@ +from __future__ import print_function, division, absolute_import +from fontTools import ttLib +from fontTools.ttLib.tables import otTables as ot + +# VariationStore + +def buildVarAxis(axisTag, axisSupport): + self = ot.VarAxis() + self.VarAxisID = axisTag + self.StartCoord, self.PeakCoord, self.EndCoord = axisSupport + return self + +def buildVarTuple(support): + self = ot.VarTuple() + self.VarAxis = [] + for axisTag in sorted(support.keys()): # TODO order by axisIdx instead of tag?! + self.VarAxis.append(buildVarAxis(axisTag, support[axisTag])) + self.VarAxisCount = len(self.VarAxis) + return self + +def buildVarTupleList(supports): + self = ot.VarTupleList() + self.VarTuple = [] + for support in supports: + self.VarTuple.append(buildVarTuple(support)) + self.VarTupleCount = len(self.VarTuple) + return self + +def buildVarDeltas(varTupleIndexes, items): + self = ot.VarDeltas() + self.format = 1 if all(all(128 <= delta <= 127 for delta in item) for item in items) else 2 + self.VarTupleIndex = list(varTupleIndexes) + tupleCount = self.VarTupleCount = len(self.VarTupleIndex) + records = self.Item = [] + for item in items: + assert len(item) == tupleCount + record = ot.VarItemByteRecord() if self.format == 1 else ot.VarItemShortRecord() + record.deltas = list(item) + records.append(record) + self.ItemCount = len(self.Item) + return self + +def buildVarStore(varTupleList, varDeltas): + self = ot.VarStore() + self.VarTupleList = varTupleList + self.VarDeltas = varDeltas + self.VarDeltasCount = len(self.VarDeltas) + return self + +# Variation helpers + +def buildVarIdxMap(varIdxes): + self = ot.VarIdxMap() + self.VarIdx = varIdxes = list(varIdxes) + self.VarIdxCount = len(self.VarIdx) + self.Format = 1 if all(x <= 0xFFFF for x in varIdxes) else 2 + return self diff --git a/README.md b/README.md index afe6f3778..8008e56a6 100644 --- a/README.md +++ b/README.md @@ -76,11 +76,11 @@ These additional options include: The following tables are currently supported: BASE, CBDT, CBLC, CFF, COLR, CPAL, DSIG, EBDT, EBLC, FFTM, GDEF, - GMAP, GPKG, GPOS, GSUB, JSTF, LTSH, MATH, META, OS/2, SING, SVG, - TSI0, TSI1, TSI2, TSI3, TSI5, TSIB, TSID, TSIJ, TSIP, TSIS, TSIV, - VDMX, VORG, avar, cmap, cvt, feat, fpgm, fvar, gasp, glyf, gvar, - hdmx, head, hhea, hmtx, kern, loca, ltag, maxp, meta, name, post, - prep, sbix, trak, vhea and vmtx + GMAP, GPKG, GPOS, GSUB, HVAR, JSTF, LTSH, MATH, META, OS/2, SING, + SVG, TSI0, TSI1, TSI2, TSI3, TSI5, TSIB, TSID, TSIJ, TSIP, TSIS, + TSIV, VDMX, VORG, VVAR, avar, cmap, cvt, feat, fpgm, fvar, gasp, + glyf, gvar, hdmx, head, hhea, hmtx, kern, loca, ltag, maxp, meta, + name, post, prep, sbix, trak, vhea and vmtx Other tables are dumped as hexadecimal data.