Behdad Esfahbod de85e4599f 2to3 sbix code
This seems to work now.

At some point we should go back and clean up and merge datastructures
between the four different color font formats.
2013-12-06 19:53:28 -05:00

105 lines
3.7 KiB
Python

from __future__ import print_function, division
from fontTools.misc.py23 import *
from fontTools.misc import sstruct
from fontTools.misc.textTools import readHex
import struct
sbixBitmapHeaderFormat = """
>
usReserved1: H # 00 00
usReserved2: H # 00 00
imageFormatTag: 4s # e.g. "png "
"""
sbixBitmapHeaderFormatSize = sstruct.calcsize(sbixBitmapHeaderFormat)
class Bitmap(object):
def __init__(self, glyphName=None, referenceGlyphName=None, usReserved1=0, usReserved2=0, imageFormatTag=None, imageData=None, rawdata=None, gid=0):
self.gid = gid
self.glyphName = glyphName
self.referenceGlyphName = referenceGlyphName
self.usReserved1 = usReserved1
self.usReserved2 = usReserved2
self.rawdata = rawdata
self.imageFormatTag = imageFormatTag
self.imageData = imageData
def decompile(self, ttFont):
self.glyphName = ttFont.getGlyphName(self.gid)
if self.rawdata is None:
from fontTools import ttLib
raise ttLib.TTLibError("No table data to decompile")
if len(self.rawdata) > 0:
if len(self.rawdata) < sbixBitmapHeaderFormatSize:
from fontTools import ttLib
#print "Bitmap %i header too short: Expected %x, got %x." % (self.gid, sbixBitmapHeaderFormatSize, len(self.rawdata))
raise ttLib.TTLibError("Bitmap header too short.")
sstruct.unpack(sbixBitmapHeaderFormat, self.rawdata[:sbixBitmapHeaderFormatSize], self)
if self.imageFormatTag == "dupe":
# bitmap is a reference to another glyph's bitmap
gid, = struct.unpack(">H", self.rawdata[sbixBitmapHeaderFormatSize:])
self.referenceGlyphName = ttFont.getGlyphName(gid)
else:
self.imageData = self.rawdata[sbixBitmapHeaderFormatSize:]
self.referenceGlyphName = None
# clean up
del self.rawdata
del self.gid
def compile(self, ttFont):
if self.glyphName is None:
from fontTools import ttLib
raise ttLib.TTLibError("Can't compile bitmap without glyph name")
# TODO: if ttFont has no maxp, cmap etc., ignore glyph names and compile by index?
# (needed if you just want to compile the sbix table on its own)
self.gid = struct.pack(">H", ttFont.getGlyphID(self.glyphName))
if self.imageFormatTag is None:
self.rawdata = ""
else:
self.rawdata = sstruct.pack(sbixBitmapHeaderFormat, self) + self.imageData
def toXML(self, xmlWriter, ttFont):
if self.imageFormatTag == None:
# TODO: ignore empty bitmaps?
# a bitmap entry is required for each glyph,
# but empty ones can be calculated at compile time
xmlWriter.simpletag("bitmap", glyphname=self.glyphName)
xmlWriter.newline()
return
xmlWriter.begintag("bitmap", format=self.imageFormatTag, glyphname=self.glyphName)
xmlWriter.newline()
#xmlWriter.simpletag("usReserved1", value=self.usReserved1)
#xmlWriter.newline()
#xmlWriter.simpletag("usReserved2", value=self.usReserved2)
#xmlWriter.newline()
if self.imageFormatTag == "dupe":
# format == "dupe" is apparently a reference to another glyph id.
xmlWriter.simpletag("ref", glyphname=self.referenceGlyphName)
else:
xmlWriter.begintag("hexdata")
xmlWriter.newline()
xmlWriter.dumphex(self.imageData)
xmlWriter.endtag("hexdata")
xmlWriter.newline()
xmlWriter.endtag("bitmap")
xmlWriter.newline()
def fromXML(self, name, attrs, content, ttFont):
#if name in ["usReserved1", "usReserved2"]:
# setattr(self, name, int(attrs["value"]))
#elif
if name == "ref":
# bitmap is a "dupe", i.e. a reference to another bitmap.
# in this case imageData contains the glyph id of the reference glyph
# get glyph id from glyphname
self.imageData = struct.pack(">H", ttFont.getGlyphID(attrs["glyphname"]))
elif name == "hexdata":
self.imageData = readHex(content)
else:
from fontTools import ttLib
raise ttLib.TTLibError("can't handle '%s' element" % name)