Skip to content
This repository was archived by the owner on Jan 17, 2019. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 40 additions & 19 deletions Lib/woffTools/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,30 @@
Those objects are much faster than WOFFFont, but they require much
more care.
"""
from __future__ import print_function

from future import standard_library
standard_library.install_aliases()
import six
from builtins import range
from builtins import object
import zlib
import struct
from fontTools.misc import sstruct
from cStringIO import StringIO
from io import BytesIO
from xml.etree import ElementTree
from fontTools.ttLib import TTFont, debugmsg, sortedTagList
from fontTools.ttLib.sfnt import getSearchRange, calcChecksum, SFNTDirectoryEntry, \
from fontTools.ttLib.sfnt import calcChecksum, SFNTDirectoryEntry, \
sfntDirectoryFormat, sfntDirectorySize, sfntDirectoryEntryFormat, sfntDirectoryEntrySize

try:
from fontTools.ttLib.sfnt import getSearchRange
except ImportError:
from fontTools.ttLib import getSearchRange

try:
from fontTools.misc.sstruct import sstruct
except ImportError:
from fontTools.misc import sstruct

# -----------
# Main Object
Expand Down Expand Up @@ -60,6 +74,7 @@ def __init__(self, file=None, flavor="\000\001\000\000",
self.minorVersion = 0
self._metadata = None
self._tableOrder = None
self._tableCache=None

if file is not None:
if not hasattr(file, "read"):
Expand All @@ -68,13 +83,13 @@ def __init__(self, file=None, flavor="\000\001\000\000",
self.flavor = self.reader.flavor
self.majorVersion = self.reader.majorVersion
self.minorVersion = self.reader.minorVersion
self._tableOrder = self.reader.keys()
self._tableOrder = list(self.reader.keys())
else:
self._metadata = ElementTree.Element("metadata", version="1.0")
self.privateData = None

def __getattr__(self, attr):
if attr not in ("privateData", "metadata"):
if attr not in ("privateData", "metadata", "lazy"):
raise AttributeError(attr)
# metadata
if attr == "metadata":
Expand All @@ -91,12 +106,18 @@ def __getattr__(self, attr):
return None
# private data
elif attr == "privateData":
if not hasattr(self, "privateData"):
privateData = None
if self.reader is not None:
privateData = self.reader.privateData
self.privateData = privateData
return self.privateData
# ToDo: In Python 3 hasattr makes a infinite recursion here. Skipping support for privateData in Python 3 for now
if six.PY2:
if not hasattr(self, "privateData"):
privateData = None
if self.reader is not None:
privateData = self.reader.privateData
self.privateData = privateData
return self.privateData
else:
return None
elif attr == "lazy":
return False
# fallback to None
return None

Expand Down Expand Up @@ -155,7 +176,7 @@ def save(self, file, compressionLevel=9, recompressTables=False, reorderTables=T
# if DSIG is to be written, the table order
# must be completely specified. otherwise the
# DSIG may not be valid after decoding the WOFF.
tags = self.keys()
tags = list(self.keys())
if "GlyphOrder" in tags:
tags.remove("GlyphOrder")
if "DSIG" in tags:
Expand Down Expand Up @@ -206,7 +227,7 @@ def save(self, file, compressionLevel=9, recompressTables=False, reorderTables=T
if hasattr(self, "metadata"):
declaration = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
tree = ElementTree.ElementTree(self.metadata)
f = StringIO()
f = BytesIO()
tree.write(f, encoding="utf-8")
metadata = f.getvalue()
# make sure the metadata starts with the declaration
Expand Down Expand Up @@ -294,7 +315,7 @@ def keys(self):
of each table.
"""
sorter = []
for tag, entry in self.tables.items():
for tag, entry in list(self.tables.items()):
sorter.append((entry.offset, tag))
order = [tag for offset, tag in sorted(sorter)]
return order
Expand All @@ -314,8 +335,8 @@ def __getitem__(self, tag):
if self.checkChecksums > 1:
assert checksum == entry.origChecksum, "bad checksum for '%s' table" % tag
elif checksum != entry.origChecksum:
print "bad checksum for '%s' table" % tag
print
print("bad checksum for '%s' table" % tag)
print()
return data

def getCompressedTableData(self, tag):
Expand Down Expand Up @@ -683,7 +704,7 @@ def calcHeadCheckSumAdjustment(flavor, tables):
sfntEntry.length = entry["length"]
directory += sfntEntry.toString()
# calculate the checkSumAdjustment
checkSums = [entry["checkSum"] for entry in tables.values()]
checkSums = [entry["checkSum"] for entry in list(tables.values())]
checkSums.append(calcChecksum(directory))
checkSumAdjustment = sum(checkSums)
checkSumAdjustment = (0xB1B0AFBA - checkSumAdjustment) & 0xffffffff
Expand Down Expand Up @@ -913,8 +934,8 @@ def _testOverlaps(tableDirectory):
edges[entry["tag"]] = (start, end)
# look for overlaps
overlaps = set()
for tag, (start, end) in edges.items():
for otherTag, (otherStart, otherEnd) in edges.items():
for tag, (start, end) in list(edges.items()):
for otherTag, (otherStart, otherEnd) in list(edges.items()):
tag = tag.strip()
otherTag = otherTag.strip()
if tag == otherTag:
Expand Down
8 changes: 4 additions & 4 deletions Lib/woffTools/test/test_validate.py
Original file line number Diff line number Diff line change
Expand Up @@ -696,7 +696,7 @@ def decompressedLengthTest1():
header, directory, tableData = defaultTestData(header=True, directory=True, tableData=True)
origData = testDataTableData
compData = zlib.compress(origData)
for tag, (origData, compData) in tableData.items():
for tag, (origData, compData) in list(tableData.items()):
tableData[tag] = (origData, zlib.compress(origData))
updateDirectoryEntries(directory, tableData)
return packTestHeader(header) + packTestDirectory(directory) + packTestTableData(directory, tableData)
Expand All @@ -711,7 +711,7 @@ def decompressedLengthTest2():
header, directory, tableData = defaultTestData(header=True, directory=True, tableData=True)
origData = testDataTableData
compData = zlib.compress(origData)
for tag, (origData, compData) in tableData.items():
for tag, (origData, compData) in list(tableData.items()):
tableData[tag] = (origData, zlib.compress(origData))
updateDirectoryEntries(directory, tableData)
for entry in directory:
Expand Down Expand Up @@ -952,7 +952,7 @@ def decompressionTest1():
(False, 'PASS')
"""
header, directory, tableData = defaultTestData(header=True, directory=True, tableData=True)
for tag, (origData, compData) in tableData.items():
for tag, (origData, compData) in list(tableData.items()):
tableData[tag] = (origData, zlib.compress(compData))
updateDirectoryEntries(directory, tableData)
return packTestHeader(header) + packTestDirectory(directory) + packTestTableData(directory, tableData)
Expand All @@ -965,7 +965,7 @@ def decompressionTest2():
(True, 'ERROR')
"""
header, directory, tableData = defaultTestData(header=True, directory=True, tableData=True)
for tag, (origData, compData) in tableData.items():
for tag, (origData, compData) in list(tableData.items()):
compData = "".join(reversed(zlib.compress(compData)))
tableData[tag] = (origData, compData)
updateDirectoryEntries(directory, tableData)
Expand Down
26 changes: 16 additions & 10 deletions Lib/woffTools/tools/css.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,13 @@
This can also be used as a command line tool for generating
CSS @font-face rules from WOFF files.
"""
from __future__ import print_function

# import test

from future import standard_library
standard_library.install_aliases()
from builtins import hex
importErrors = []
try:
import numpy
Expand All @@ -24,13 +28,13 @@

if importErrors:
import sys
print "Could not import needed module(s):", ", ".join(importErrors)
print("Could not import needed module(s):", ", ".join(importErrors))
sys.exit()

# import

import os
import urllib
import urllib.request, urllib.parse, urllib.error
import optparse
from woffTools import WOFFFont
from woffTools.tools.support import findUniqueFileName
Expand Down Expand Up @@ -90,7 +94,7 @@ def makeFontFaceSrc(font, fileName, doLocalSrc=True):
s = "/* " + s + " */"
sources.append(s)
# file name
s = "url(\"%s\")" % urllib.quote(fileName) # XXX: format(\"woff\")
s = "url(\"%s\")" % urllib.parse.quote(fileName) # XXX: format(\"woff\")
sources.append(s)
# write
sources = "\n\t".join(sources)
Expand Down Expand Up @@ -194,7 +198,7 @@ def _skimNameIDs(font, priority):
text = nameRecord.string
nameIDs[nameID, platformID, platEncID, langID] = text
for (nameID, platformID, platEncID, langID) in priority:
for (nID, pID, pEID, lID), text in nameIDs.items():
for (nID, pID, pEID, lID), text in list(nameIDs.items()):
if nID != nameID:
continue
if pID != platformID and platformID is not None:
Expand All @@ -203,6 +207,7 @@ def _skimNameIDs(font, priority):
continue
if lID != langID and langID is not None:
continue
text = text.decode("utf-8")
text = "".join([i for i in text if i != "\x00"])
return text

Expand Down Expand Up @@ -252,22 +257,23 @@ def makeFontFaceRule(font, fontPath, doLocalSrc=True):
"""

def main():
parser = optparse.OptionParser(usage=usage, description=description, version="%prog 0.1beta")
parser = optparse.OptionParser(usage=usage, description=description, version="%prog 0.2")
parser.add_option("-d", dest="outputDirectory", help="Output directory. The default is to output the CSS into the same directory as the font file.")
parser.add_option("-o", dest="outputFileName", help="Output file name. The default is \"fontfilename.css\". If this file already exists a time stamp will be added to the file name.")
parser.add_option("-l", action="store_true", dest="doLocalSrc", help="Write \"local\" instructions as part of the \"src\" descriptor.")
(options, args) = parser.parse_args()
outputDirectory = options.outputDirectory
if outputDirectory is not None and not os.path.exists(outputDirectory):
print "Directory does not exist:", outputDirectory
print("Directory does not exist:", outputDirectory)
sys.exit()
for fontPath in args:
if not os.path.exists(fontPath):
print "File does not exist:", fontPath
print("File does not exist:", fontPath)
sys.exit()
else:
print "Creating CSS: %s..." % fontPath
fontPath = fontPath.decode("utf-8")
print("Creating CSS: %s..." % fontPath)
if hasattr(fontPath, "decode"):
fontPath = fontPath.decode("utf-8")
font = WOFFFont(fontPath)
css = makeFontFaceRule(font, fontPath, doLocalSrc=options.doLocalSrc)
# make the output file name
Expand All @@ -285,7 +291,7 @@ def main():
path = os.path.join(directory, fileName)
path = findUniqueFileName(path)
f = open(path, "wb")
f.write(css)
f.write(css.encode('utf-8'))
f.close()

if __name__ == "__main__":
Expand Down
22 changes: 14 additions & 8 deletions Lib/woffTools/tools/info.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,14 @@

This can also be used as a command line tool.
"""
from __future__ import print_function

# import test

from builtins import str
from builtins import hex
from builtins import chr
from builtins import range
importErrors = []
try:
import numpy
Expand All @@ -23,7 +28,7 @@

if importErrors:
import sys
print "Could not import needed module(s):", ", ".join(importErrors)
print("Could not import needed module(s):", ", ".join(importErrors))
sys.exit()

# import
Expand Down Expand Up @@ -175,7 +180,7 @@ def writePrivateData(font, writer):
src = font.privateData
length = 16
result = []
for i in xrange(0, len(src), length):
for i in range(0, len(src), length):
s = src[i:i+length]
hexa = []
c = []
Expand Down Expand Up @@ -256,22 +261,23 @@ def reportInfo(font, fontPath):
"""

def main():
parser = optparse.OptionParser(usage=usage, description=description, version="%prog 0.1beta")
parser = optparse.OptionParser(usage=usage, description=description, version="%prog 0.2")
parser.add_option("-d", dest="outputDirectory", help="Output directory. The default is to output the report into the same directory as the font file.")
parser.add_option("-o", dest="outputFileName", help="Output file name. The default is \"fontfilename_info.html\".")
parser.set_defaults(excludeTests=[])
(options, args) = parser.parse_args()
outputDirectory = options.outputDirectory
if outputDirectory is not None and not os.path.exists(outputDirectory):
print "Directory does not exist:", outputDirectory
print("Directory does not exist:", outputDirectory)
sys.exit()
for fontPath in args:
if not os.path.exists(fontPath):
print "File does not exist:", fontPath
print("File does not exist:", fontPath)
sys.exit()
else:
print "Creating Info Report: %s..." % fontPath
fontPath = fontPath.decode("utf-8")
print("Creating Info Report: %s..." % fontPath)
if hasattr(fontPath, 'decode'):
fontPath = fontPath.decode("utf-8")
font = WOFFFont(fontPath)
html = reportInfo(font, fontPath)
# make the output file name
Expand All @@ -289,7 +295,7 @@ def main():
path = os.path.join(directory, fileName)
path = findUniqueFileName(path)
f = open(path, "wb")
f.write(html)
f.write(html.encode('utf-8'))
f.close()

if __name__ == "__main__":
Expand Down
Loading