[VARC] Towards XML

This commit is contained in:
Behdad Esfahbod 2023-12-14 20:40:37 -07:00
parent c3175b271a
commit aad01a9d85
3 changed files with 57 additions and 13 deletions

View File

@ -18,7 +18,7 @@ from .otBase import (
) )
from .otTables import ( from .otTables import (
lookupTypes, lookupTypes,
VarCompositeGlyphRecord, VarCompositeGlyph,
AATStateTable, AATStateTable,
AATState, AATState,
AATAction, AATAction,
@ -1910,6 +1910,18 @@ class CFF2Index(BaseConverter):
for item in items: for item in items:
writer.writeData(item) writer.writeData(item)
def xmlRead(self, attrs, content, font):
abort
items = []
for eName, eAttrs, _eContent in filter(istuple, content):
print(eName)
return items
def xmlWrite(self, xmlWriter, font, value, name, attrs):
for i, item in enumerate(value):
item.toXML(xmlWriter, font, [("index", i)], name)
class LookupFlag(UShort): class LookupFlag(UShort):
def xmlWrite(self, xmlWriter, font, value, name, attrs): def xmlWrite(self, xmlWriter, font, value, name, attrs):
@ -1988,7 +2000,7 @@ converterMapping = {
"ExtendMode": ExtendMode, "ExtendMode": ExtendMode,
"CompositeMode": CompositeMode, "CompositeMode": CompositeMode,
"STATFlags": STATFlags, "STATFlags": STATFlags,
"VarCompositeGlyphRecords": partial(CFF2Index, itemClass=VarCompositeGlyphRecord), "VarCompositeGlyphList": partial(CFF2Index, itemClass=VarCompositeGlyph),
# AAT # AAT
"CIDGlyphMap": CIDGlyphMap, "CIDGlyphMap": CIDGlyphMap,
"GlyphCIDMap": GlyphCIDMap, "GlyphCIDMap": GlyphCIDMap,

View File

@ -3348,7 +3348,7 @@ otData = [
( (
"VarCompositeGlyphs", "VarCompositeGlyphs",
[ [
("VarCompositeGlyphRecords", "items", None, None, ""), ("VarCompositeGlyphList", "glyphs", None, None, ""),
], ],
), ),
# Glyph advance variations # Glyph advance variations

View File

@ -100,7 +100,7 @@ VAR_COMPONENT_TRANSFORM_MAPPING = {
} }
class VarComponentRecord: class VarComponent:
def __init__(self): def __init__(self):
self.glyphName = None self.glyphName = None
self.location = {} self.location = {}
@ -159,7 +159,7 @@ class VarComponentRecord:
fi2fl( fi2fl(
struct.unpack(">h", data[i : i + 2])[0], values.fractionalBits struct.unpack(">h", data[i : i + 2])[0], values.fractionalBits
) )
* values.scale, * values.scale
) )
i += 2 i += 2
return v return v
@ -207,12 +207,16 @@ class VarComponentRecord:
flags |= VarComponentFlags.GID_IS_24BIT flags |= VarComponentFlags.GID_IS_24BIT
data.append(struct.pack(">L", glyphID)[1:]) data.append(struct.pack(">L", glyphID)[1:])
else: else:
if flags & VarComponentFlags.GID_IS_24BIT:
flags ^= VarComponentFlags.GID_IS_24BIT
data.append(struct.pack(">H", glyphID)) data.append(struct.pack(">H", glyphID))
fvarAxisIndices = {axis.axisTag: i for i, axis in enumerate(font["fvar"].axes)} fvarAxisIndices = {axis.axisTag: i for i, axis in enumerate(font["fvar"].axes)}
axisIndices = [fvarAxisIndices[tag] for tag in self.location.keys()] axisIndices = [fvarAxisIndices[tag] for tag in self.location.keys()]
if all(a <= 255 for a in axisIndices): if all(a <= 255 for a in axisIndices):
axisIndices = array.array("B", axisIndices) axisIndices = array.array("B", axisIndices)
if flags & VarComponentFlags.AXIS_INDICES_ARE_SHORT:
flags ^= VarComponentFlags.AXIS_INDICES_ARE_SHORT
else: else:
axisIndices = array.array("H", axisIndices) axisIndices = array.array("H", axisIndices)
if sys.byteorder != "big": if sys.byteorder != "big":
@ -229,6 +233,8 @@ class VarComponentRecord:
if self.locationVarIdxBase != NO_VARIATION_INDEX: if self.locationVarIdxBase != NO_VARIATION_INDEX:
flags |= VarComponentFlags.AXIS_VALUES_HAVE_VARIATION flags |= VarComponentFlags.AXIS_VALUES_HAVE_VARIATION
data.append(struct.pack(">L", self.locationVarIdxBase)) data.append(struct.pack(">L", self.locationVarIdxBase))
elif flags & VarComponentFlags.AXIS_VALUES_HAVE_VARIATION:
flags ^= VarComponentFlags.AXIS_VALUES_HAVE_VARIATION
def write_transform_component(value, values): def write_transform_component(value, values):
if flags & values.flag: if flags & values.flag:
@ -245,11 +251,13 @@ class VarComponentRecord:
if self.transformVarIdxBase != NO_VARIATION_INDEX: if self.transformVarIdxBase != NO_VARIATION_INDEX:
flags |= VarComponentFlags.TRANSFORM_HAS_VARIATION flags |= VarComponentFlags.TRANSFORM_HAS_VARIATION
data.append(struct.pack(">L", self.transformVarIdxBase)) data.append(struct.pack(">L", self.transformVarIdxBase))
elif flags & VarComponentFlags.TRANSFORM_HAS_VARIATION:
flags ^= VarComponentFlags.TRANSFORM_HAS_VARIATION
return struct.pack(">H", flags) + bytesjoin(data) return struct.pack(">H", flags) + bytesjoin(data)
def toXML(self, writer, ttFont): def toXML(self, writer, ttFont, attrs):
attrs = [("glyphName", self.glyphName)] attrs.append(("glyphName", self.glyphName))
if hasattr(self, "flags"): if hasattr(self, "flags"):
attrs = attrs + [("flags", hex(self.flags))] attrs = attrs + [("flags", hex(self.flags))]
@ -259,7 +267,7 @@ class VarComponentRecord:
if v != mapping.defaultValue: if v != mapping.defaultValue:
attrs.append((attr_name, fl2str(v, mapping.fractionalBits))) attrs.append((attr_name, fl2str(v, mapping.fractionalBits)))
writer.begintag("varComponent", attrs) writer.begintag("VarComponent", attrs)
writer.newline() writer.newline()
writer.begintag("location") writer.begintag("location")
@ -270,7 +278,7 @@ class VarComponentRecord:
writer.endtag("location") writer.endtag("location")
writer.newline() writer.newline()
writer.endtag("varComponent") writer.endtag("VarComponent")
writer.newline() writer.newline()
def fromXML(self, name, attrs, content, ttFont): def fromXML(self, name, attrs, content, ttFont):
@ -309,7 +317,8 @@ class VarComponentRecord:
return result if result is NotImplemented else not result return result if result is NotImplemented else not result
class VarCompositeGlyphRecord: class VarCompositeGlyph(BaseTable):
def populateDefaults(self, propagator=None): def populateDefaults(self, propagator=None):
if not hasattr(self, "components"): if not hasattr(self, "components"):
self.components = [] self.components = []
@ -317,7 +326,7 @@ class VarCompositeGlyphRecord:
def decompile(self, data, font): def decompile(self, data, font):
self.components = [] self.components = []
while data: while data:
component = VarComponentRecord() component = VarComponent()
data = component.decompile(data, font) data = component.decompile(data, font)
self.components.append(component) self.components.append(component)
@ -328,11 +337,34 @@ class VarCompositeGlyphRecord:
return bytesjoin(data) return bytesjoin(data)
def toXML(self, xmlWriter, font, attrs, name): def toXML(self, xmlWriter, font, attrs, name):
raise NotImplementedError xmlWriter.begintag("VarCompositeGlyph", attrs)
xmlWriter.newline()
for i, component in enumerate(self.components):
component.toXML(xmlWriter, font, [("index", i)])
xmlWriter.endtag("VarCompositeGlyph")
xmlWriter.newline()
def fromXML(self, name, attrs, content, font): def fromXML(self, name, attrs, content, font):
raise NotImplementedError self.populateDefaults()
if name == "VarComponent":
component = VarComponent()
component.fromXML(name, attrs, content, font)
self.components.append(component)
class VarCompositeGlyphs(BaseTable):
def populateDefaults(self, propagator=None):
if not hasattr(self, "glyphs"):
self.glyphs = []
def fromXML(self, name, attrs, content, font):
self.populateDefaults()
if name == "VarCompositeGlyph":
glyph = VarCompositeGlyph()
content = [t for t in content if isinstance(t, tuple)]
for eltName, eltAttrs, eltContent in content:
glyph.fromXML(eltName, eltAttrs, eltContent, font)
self.glyphs.append(glyph)
class AATStateTable(object): class AATStateTable(object):
def __init__(self): def __init__(self):