aboutsummaryrefslogtreecommitdiff
path: root/Lib/fontTools/ttLib/tables/sbixStrike.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/fontTools/ttLib/tables/sbixStrike.py')
-rw-r--r--Lib/fontTools/ttLib/tables/sbixStrike.py277
1 files changed, 153 insertions, 124 deletions
diff --git a/Lib/fontTools/ttLib/tables/sbixStrike.py b/Lib/fontTools/ttLib/tables/sbixStrike.py
index b367a99f..7614af4c 100644
--- a/Lib/fontTools/ttLib/tables/sbixStrike.py
+++ b/Lib/fontTools/ttLib/tables/sbixStrike.py
@@ -22,127 +22,156 @@ sbixGlyphDataOffsetFormatSize = sstruct.calcsize(sbixGlyphDataOffsetFormat)
class Strike(object):
- def __init__(self, rawdata=None, ppem=0, resolution=72):
- self.data = rawdata
- self.ppem = ppem
- self.resolution = resolution
- self.glyphs = {}
-
- def decompile(self, ttFont):
- if self.data is None:
- from fontTools import ttLib
- raise ttLib.TTLibError
- if len(self.data) < sbixStrikeHeaderFormatSize:
- from fontTools import ttLib
- raise(ttLib.TTLibError, "Strike header too short: Expected %x, got %x.") \
- % (sbixStrikeHeaderFormatSize, len(self.data))
-
- # read Strike header from raw data
- sstruct.unpack(sbixStrikeHeaderFormat, self.data[:sbixStrikeHeaderFormatSize], self)
-
- # calculate number of glyphs
- firstGlyphDataOffset, = struct.unpack(">L", \
- self.data[sbixStrikeHeaderFormatSize:sbixStrikeHeaderFormatSize + sbixGlyphDataOffsetFormatSize])
- self.numGlyphs = (firstGlyphDataOffset - sbixStrikeHeaderFormatSize) // sbixGlyphDataOffsetFormatSize - 1
- # ^ -1 because there's one more offset than glyphs
-
- # build offset list for single glyph data offsets
- self.glyphDataOffsets = []
- for i in range(self.numGlyphs + 1): # + 1 because there's one more offset than glyphs
- start = i * sbixGlyphDataOffsetFormatSize + sbixStrikeHeaderFormatSize
- current_offset, = struct.unpack(">L", self.data[start:start + sbixGlyphDataOffsetFormatSize])
- self.glyphDataOffsets.append(current_offset)
-
- # iterate through offset list and slice raw data into glyph data records
- for i in range(self.numGlyphs):
- current_glyph = Glyph(rawdata=self.data[self.glyphDataOffsets[i]:self.glyphDataOffsets[i+1]], gid=i)
- current_glyph.decompile(ttFont)
- self.glyphs[current_glyph.glyphName] = current_glyph
- del self.glyphDataOffsets
- del self.numGlyphs
- del self.data
-
- def compile(self, ttFont):
- self.glyphDataOffsets = b""
- self.bitmapData = b""
-
- glyphOrder = ttFont.getGlyphOrder()
-
- # first glyph starts right after the header
- currentGlyphDataOffset = sbixStrikeHeaderFormatSize + sbixGlyphDataOffsetFormatSize * (len(glyphOrder) + 1)
- for glyphName in glyphOrder:
- if glyphName in self.glyphs:
- # we have glyph data for this glyph
- current_glyph = self.glyphs[glyphName]
- else:
- # must add empty glyph data record for this glyph
- current_glyph = Glyph(glyphName=glyphName)
- current_glyph.compile(ttFont)
- current_glyph.glyphDataOffset = currentGlyphDataOffset
- self.bitmapData += current_glyph.rawdata
- currentGlyphDataOffset += len(current_glyph.rawdata)
- self.glyphDataOffsets += sstruct.pack(sbixGlyphDataOffsetFormat, current_glyph)
-
- # add last "offset", really the end address of the last glyph data record
- dummy = Glyph()
- dummy.glyphDataOffset = currentGlyphDataOffset
- self.glyphDataOffsets += sstruct.pack(sbixGlyphDataOffsetFormat, dummy)
-
- # pack header
- self.data = sstruct.pack(sbixStrikeHeaderFormat, self)
- # add offsets and image data after header
- self.data += self.glyphDataOffsets + self.bitmapData
-
- def toXML(self, xmlWriter, ttFont):
- xmlWriter.begintag("strike")
- xmlWriter.newline()
- xmlWriter.simpletag("ppem", value=self.ppem)
- xmlWriter.newline()
- xmlWriter.simpletag("resolution", value=self.resolution)
- xmlWriter.newline()
- glyphOrder = ttFont.getGlyphOrder()
- for i in range(len(glyphOrder)):
- if glyphOrder[i] in self.glyphs:
- self.glyphs[glyphOrder[i]].toXML(xmlWriter, ttFont)
- # TODO: what if there are more glyph data records than (glyf table) glyphs?
- xmlWriter.endtag("strike")
- xmlWriter.newline()
-
- def fromXML(self, name, attrs, content, ttFont):
- if name in ["ppem", "resolution"]:
- setattr(self, name, safeEval(attrs["value"]))
- elif name == "glyph":
- if "graphicType" in attrs:
- myFormat = safeEval("'''" + attrs["graphicType"] + "'''")
- else:
- myFormat = None
- if "glyphname" in attrs:
- myGlyphName = safeEval("'''" + attrs["glyphname"] + "'''")
- elif "name" in attrs:
- myGlyphName = safeEval("'''" + attrs["name"] + "'''")
- else:
- from fontTools import ttLib
- raise ttLib.TTLibError("Glyph must have a glyph name.")
- if "originOffsetX" in attrs:
- myOffsetX = safeEval(attrs["originOffsetX"])
- else:
- myOffsetX = 0
- if "originOffsetY" in attrs:
- myOffsetY = safeEval(attrs["originOffsetY"])
- else:
- myOffsetY = 0
- current_glyph = Glyph(
- glyphName=myGlyphName,
- graphicType=myFormat,
- originOffsetX=myOffsetX,
- originOffsetY=myOffsetY,
- )
- for element in content:
- if isinstance(element, tuple):
- name, attrs, content = element
- current_glyph.fromXML(name, attrs, content, ttFont)
- current_glyph.compile(ttFont)
- self.glyphs[current_glyph.glyphName] = current_glyph
- else:
- from fontTools import ttLib
- raise ttLib.TTLibError("can't handle '%s' element" % name)
+ def __init__(self, rawdata=None, ppem=0, resolution=72):
+ self.data = rawdata
+ self.ppem = ppem
+ self.resolution = resolution
+ self.glyphs = {}
+
+ def decompile(self, ttFont):
+ if self.data is None:
+ from fontTools import ttLib
+
+ raise ttLib.TTLibError
+ if len(self.data) < sbixStrikeHeaderFormatSize:
+ from fontTools import ttLib
+
+ raise (
+ ttLib.TTLibError,
+ "Strike header too short: Expected %x, got %x.",
+ ) % (sbixStrikeHeaderFormatSize, len(self.data))
+
+ # read Strike header from raw data
+ sstruct.unpack(
+ sbixStrikeHeaderFormat, self.data[:sbixStrikeHeaderFormatSize], self
+ )
+
+ # calculate number of glyphs
+ (firstGlyphDataOffset,) = struct.unpack(
+ ">L",
+ self.data[
+ sbixStrikeHeaderFormatSize : sbixStrikeHeaderFormatSize
+ + sbixGlyphDataOffsetFormatSize
+ ],
+ )
+ self.numGlyphs = (
+ firstGlyphDataOffset - sbixStrikeHeaderFormatSize
+ ) // sbixGlyphDataOffsetFormatSize - 1
+ # ^ -1 because there's one more offset than glyphs
+
+ # build offset list for single glyph data offsets
+ self.glyphDataOffsets = []
+ for i in range(
+ self.numGlyphs + 1
+ ): # + 1 because there's one more offset than glyphs
+ start = i * sbixGlyphDataOffsetFormatSize + sbixStrikeHeaderFormatSize
+ (current_offset,) = struct.unpack(
+ ">L", self.data[start : start + sbixGlyphDataOffsetFormatSize]
+ )
+ self.glyphDataOffsets.append(current_offset)
+
+ # iterate through offset list and slice raw data into glyph data records
+ for i in range(self.numGlyphs):
+ current_glyph = Glyph(
+ rawdata=self.data[
+ self.glyphDataOffsets[i] : self.glyphDataOffsets[i + 1]
+ ],
+ gid=i,
+ )
+ current_glyph.decompile(ttFont)
+ self.glyphs[current_glyph.glyphName] = current_glyph
+ del self.glyphDataOffsets
+ del self.numGlyphs
+ del self.data
+
+ def compile(self, ttFont):
+ self.glyphDataOffsets = b""
+ self.bitmapData = b""
+
+ glyphOrder = ttFont.getGlyphOrder()
+
+ # first glyph starts right after the header
+ currentGlyphDataOffset = (
+ sbixStrikeHeaderFormatSize
+ + sbixGlyphDataOffsetFormatSize * (len(glyphOrder) + 1)
+ )
+ for glyphName in glyphOrder:
+ if glyphName in self.glyphs:
+ # we have glyph data for this glyph
+ current_glyph = self.glyphs[glyphName]
+ else:
+ # must add empty glyph data record for this glyph
+ current_glyph = Glyph(glyphName=glyphName)
+ current_glyph.compile(ttFont)
+ current_glyph.glyphDataOffset = currentGlyphDataOffset
+ self.bitmapData += current_glyph.rawdata
+ currentGlyphDataOffset += len(current_glyph.rawdata)
+ self.glyphDataOffsets += sstruct.pack(
+ sbixGlyphDataOffsetFormat, current_glyph
+ )
+
+ # add last "offset", really the end address of the last glyph data record
+ dummy = Glyph()
+ dummy.glyphDataOffset = currentGlyphDataOffset
+ self.glyphDataOffsets += sstruct.pack(sbixGlyphDataOffsetFormat, dummy)
+
+ # pack header
+ self.data = sstruct.pack(sbixStrikeHeaderFormat, self)
+ # add offsets and image data after header
+ self.data += self.glyphDataOffsets + self.bitmapData
+
+ def toXML(self, xmlWriter, ttFont):
+ xmlWriter.begintag("strike")
+ xmlWriter.newline()
+ xmlWriter.simpletag("ppem", value=self.ppem)
+ xmlWriter.newline()
+ xmlWriter.simpletag("resolution", value=self.resolution)
+ xmlWriter.newline()
+ glyphOrder = ttFont.getGlyphOrder()
+ for i in range(len(glyphOrder)):
+ if glyphOrder[i] in self.glyphs:
+ self.glyphs[glyphOrder[i]].toXML(xmlWriter, ttFont)
+ # TODO: what if there are more glyph data records than (glyf table) glyphs?
+ xmlWriter.endtag("strike")
+ xmlWriter.newline()
+
+ def fromXML(self, name, attrs, content, ttFont):
+ if name in ["ppem", "resolution"]:
+ setattr(self, name, safeEval(attrs["value"]))
+ elif name == "glyph":
+ if "graphicType" in attrs:
+ myFormat = safeEval("'''" + attrs["graphicType"] + "'''")
+ else:
+ myFormat = None
+ if "glyphname" in attrs:
+ myGlyphName = safeEval("'''" + attrs["glyphname"] + "'''")
+ elif "name" in attrs:
+ myGlyphName = safeEval("'''" + attrs["name"] + "'''")
+ else:
+ from fontTools import ttLib
+
+ raise ttLib.TTLibError("Glyph must have a glyph name.")
+ if "originOffsetX" in attrs:
+ myOffsetX = safeEval(attrs["originOffsetX"])
+ else:
+ myOffsetX = 0
+ if "originOffsetY" in attrs:
+ myOffsetY = safeEval(attrs["originOffsetY"])
+ else:
+ myOffsetY = 0
+ current_glyph = Glyph(
+ glyphName=myGlyphName,
+ graphicType=myFormat,
+ originOffsetX=myOffsetX,
+ originOffsetY=myOffsetY,
+ )
+ for element in content:
+ if isinstance(element, tuple):
+ name, attrs, content = element
+ current_glyph.fromXML(name, attrs, content, ttFont)
+ current_glyph.compile(ttFont)
+ self.glyphs[current_glyph.glyphName] = current_glyph
+ else:
+ from fontTools import ttLib
+
+ raise ttLib.TTLibError("can't handle '%s' element" % name)