blob: 23cb6dff7086cf092f022b3d54ff8e813e8582fd [file] [log] [blame]
from __future__ import print_function, division, absolute_import
from fontTools.misc.py23 import *
from fontTools.misc import sstruct
from fontTools.misc.textTools import readHex
from . import DefaultTable
from .sbixBitmap import *
from .sbixBitmapSet import *
import struct
"""
sbix Table organization:
USHORT version?
USHORT version?
USHORT count number of bitmap sets
offsetEntry offsetEntry[count] offsetEntries
(Variable) storage for bitmap sets
offsetEntry:
ULONG offset offset from table start to bitmap set
bitmap set:
USHORT size height and width in pixels
USHORT resolution ?
offsetRecord offsetRecord[]
(Variable) storage for bitmaps
offsetRecord:
ULONG bitmapOffset offset from start of bitmap set to individual bitmap
bitmap:
ULONG reserved 00 00 00 00
char[4] format data type, e.g. "png "
(Variable) bitmap data
"""
sbixHeaderFormat = """
>
usVal1: H # 00 01
usVal2: H # 00 01
numSets: L # 00 00 00 02 # number of bitmap sets
"""
sbixHeaderFormatSize = sstruct.calcsize(sbixHeaderFormat)
sbixBitmapSetOffsetFormat = """
>
offset: L # 00 00 00 10 # offset from table start to each bitmap set
"""
sbixBitmapSetOffsetFormatSize = sstruct.calcsize(sbixBitmapSetOffsetFormat)
class table__s_b_i_x(DefaultTable.DefaultTable):
def __init__(self, tag):
self.tableTag = tag
self.usVal1 = 1
self.usVal2 = 1
self.numSets = 0
self.bitmapSets = {}
self.bitmapSetOffsets = []
def decompile(self, data, ttFont):
# read table header
sstruct.unpack(sbixHeaderFormat, data[ : sbixHeaderFormatSize], self)
# collect offsets to individual bitmap sets in self.bitmapSetOffsets
for i in range(self.numSets):
myOffset = sbixHeaderFormatSize + i * sbixBitmapSetOffsetFormatSize
offsetEntry = sbixBitmapSetOffset()
sstruct.unpack(sbixBitmapSetOffsetFormat, \
data[myOffset : myOffset+sbixBitmapSetOffsetFormatSize], \
offsetEntry)
self.bitmapSetOffsets.append(offsetEntry.offset)
# decompile BitmapSets
for i in range(self.numSets-1, -1, -1):
myBitmapSet = BitmapSet(rawdata=data[self.bitmapSetOffsets[i]:])
data = data[:self.bitmapSetOffsets[i]]
myBitmapSet.decompile(ttFont)
#print " BitmapSet length: %xh" % len(bitmapSetData)
#print "Number of Bitmaps:", myBitmapSet.numBitmaps
if myBitmapSet.size in self.bitmapSets:
from fontTools import ttLib
raise ttLib.TTLibError("Pixel 'size' must be unique for each BitmapSet")
self.bitmapSets[myBitmapSet.size] = myBitmapSet
# after the bitmaps have been extracted, we don't need the offsets anymore
del self.bitmapSetOffsets
def compile(self, ttFont):
sbixData = ""
self.numSets = len(self.bitmapSets)
sbixHeader = sstruct.pack(sbixHeaderFormat, self)
# calculate offset to start of first bitmap set
setOffset = sbixHeaderFormatSize + sbixBitmapSetOffsetFormatSize * self.numSets
for si in sorted(self.bitmapSets.keys()):
myBitmapSet = self.bitmapSets[si]
myBitmapSet.compile(ttFont)
# append offset to this bitmap set to table header
myBitmapSet.offset = setOffset
sbixHeader += sstruct.pack(sbixBitmapSetOffsetFormat, myBitmapSet)
setOffset += sbixBitmapSetHeaderFormatSize + len(myBitmapSet.data)
sbixData += myBitmapSet.data
return sbixHeader + sbixData
def toXML(self, xmlWriter, ttFont):
xmlWriter.simpletag("usVal1", value=self.usVal1)
xmlWriter.newline()
xmlWriter.simpletag("usVal2", value=self.usVal2)
xmlWriter.newline()
for i in sorted(self.bitmapSets.keys()):
self.bitmapSets[i].toXML(xmlWriter, ttFont)
def fromXML(self, name, attrs, content, ttFont):
if name in ["usVal1", "usVal2"]:
setattr(self, name, int(attrs["value"]))
elif name == "bitmapSet":
myBitmapSet = BitmapSet()
for element in content:
if isinstance(element, tuple):
name, attrs, content = element
myBitmapSet.fromXML(name, attrs, content, ttFont)
self.bitmapSets[myBitmapSet.size] = myBitmapSet
else:
from fontTools import ttLib
raise ttLib.TTLibError("can't handle '%s' element" % name)
# Helper classes
class sbixBitmapSetOffset(object):
pass