This repository has been archived on 2025-10-02. You can view files and clone it, but you cannot make any changes to it's state, such as pushing and creating new issues, pull requests or comments.
inter-font/misc/pylib/extractor/formats/woff.py
2017-11-28 17:11:48 -08:00

222 lines
7.9 KiB
Python
Executable file

from xml.sax.saxutils import quoteattr
from fontTools.ttLib import TTFont, TTLibError
from extractor.tools import RelaxedInfo
from extractor.formats.opentype import extractOpenTypeInfo, extractOpenTypeGlyphs, extractOpenTypeKerning
try:
from xml.etree import cElementTree as ElementTree
except ImportError:
from xml.etree import ElementTree
# ----------------
# Public Functions
# ----------------
def isWOFF(pathOrFile):
flavor = None
try:
font = TTFont(pathOrFile)
flavor = font.flavor
del font
except TTLibError:
return False
return flavor in ("woff", "woff2")
def extractFontFromWOFF(pathOrFile, destination, doGlyphs=True, doInfo=True, doKerning=True, customFunctions=[]):
source = TTFont(pathOrFile)
if doInfo:
extractWOFFInfo(source, destination)
if doGlyphs:
extractWOFFGlyphs(source, destination)
if doKerning:
kerning, groups = extractWOFFKerning(source, destination)
destination.groups.update(groups)
destination.kerning.clear()
destination.kerning.update(kerning)
for function in customFunctions:
function(source, destination)
source.close()
# ----------------
# Specific Imports
# ----------------
def extractWOFFInfo(source, destination):
info = RelaxedInfo(destination.info)
info.woffMajorVersion = source.flavorData.majorVersion
info.woffMinorVersion = source.flavorData.minorVersion
_extractWOFFMetadata(source.flavorData, info)
return extractOpenTypeInfo(source, destination)
def extractWOFFGlyphs(source, destination):
return extractOpenTypeGlyphs(source, destination)
def extractWOFFKerning(source, destination):
return extractOpenTypeKerning(source, destination)
# --------
# Metadata
# --------
def _extractWOFFMetadata(source, destination):
if source.metaData is None:
return
metadata = ElementTree.fromstring(source.metaData)
for element in metadata:
if element.tag == "uniqueid":
_extractWOFFMetadataUniqueID(element, destination)
elif element.tag == "vendor":
_extractWOFFMetadataVendor(element, destination)
elif element.tag == "credits":
_extractWOFFMetadataCredits(element, destination)
elif element.tag == "description":
_extractWOFFMetadataDescription(element, destination)
elif element.tag == "license":
_extractWOFFMetadataLicense(element, destination)
elif element.tag == "copyright":
_extractWOFFMetadataCopyright(element, destination)
elif element.tag == "trademark":
_extractWOFFMetadataTrademark(element, destination)
elif element.tag == "licensee":
_extractWOFFMetadataLicensee(element, destination)
elif element.tag == "extension":
_extractWOFFMetadataExtension(element, destination)
def _extractWOFFMetadataUniqueID(element, destination):
destination.woffMetadataUniqueID = _extractWOFFMetadataDict(element, ("id",))
def _extractWOFFMetadataVendor(element, destination):
attributes = ("name", "url", "dir", "class")
record = _extractWOFFMetadataDict(element, attributes)
destination.woffMetadataVendor = record
def _extractWOFFMetadataCredits(element, destination):
attributes = ("name", "url", "role", "dir", "class")
credits = []
for subElement in element:
if subElement.tag == "credit":
record = _extractWOFFMetadataDict(subElement, attributes)
credits.append(record)
destination.woffMetadataCredits = dict(credits=credits)
def _extractWOFFMetadataDescription(element, destination):
description = _extractWOFFMetadataDict(element, ("url",))
textRecords = _extractWOFFMetadataText(element)
if textRecords:
description["text"] = textRecords
destination.woffMetadataDescription = description
def _extractWOFFMetadataLicense(element, destination):
license = _extractWOFFMetadataDict(element, ("url", "id"))
textRecords = _extractWOFFMetadataText(element)
if textRecords:
license["text"] = textRecords
destination.woffMetadataLicense = license
def _extractWOFFMetadataCopyright(element, destination):
copyright = {}
textRecords = _extractWOFFMetadataText(element)
if textRecords:
copyright["text"] = textRecords
destination.woffMetadataCopyright = copyright
def _extractWOFFMetadataTrademark(element, destination):
trademark = {}
textRecords = _extractWOFFMetadataText(element)
if textRecords:
trademark["text"] = textRecords
destination.woffMetadataTrademark = trademark
def _extractWOFFMetadataLicensee(element, destination):
destination.woffMetadataLicensee = _extractWOFFMetadataDict(element, ("name", "dir", "class"))
def _extractWOFFMetadataExtension(element, destination):
extension = _extractWOFFMetadataDict(element, ("id",))
for subElement in element:
if subElement.tag == "name":
if "names" not in extension:
extension["names"] = []
name = _extractWOFFMetadataExtensionName(subElement)
extension["names"].append(name)
elif subElement.tag == "item":
if "items" not in extension:
extension["items"] = []
item = _extractWOFFMetadataExtensionItem(subElement)
extension["items"].append(item)
extensions = []
if destination.woffMetadataExtensions:
extensions.extend(destination.woffMetadataExtensions)
destination.woffMetadataExtensions = extensions + [extension]
def _extractWOFFMetadataExtensionItem(element):
item = _extractWOFFMetadataDict(element, ("id",))
for subElement in element:
if subElement.tag == "name":
if "names" not in item:
item["names"] = []
name = _extractWOFFMetadataExtensionName(subElement)
item["names"].append(name)
elif subElement.tag == "value":
if "values" not in item:
item["values"] = []
name = _extractWOFFMetadataExtensionValue(subElement)
item["values"].append(name)
return item
def _extractWOFFMetadataExtensionName(element):
name = _extractWOFFMetadataDict(element, ("dir", "class"))
language = _extractWOFFMetadataLanguage(element)
if language is not None:
name["language"] = language
name["text"] = _flattenWOFFMetadataString(element)
return name
def _extractWOFFMetadataExtensionValue(element):
return _extractWOFFMetadataExtensionName(element)
# support
def _extractWOFFMetadataDict(element, attributes):
record = {}
for attribute in attributes:
value = element.attrib.get(attribute)
if value is not None:
record[attribute] = value
return record
def _extractWOFFMetadataText(element):
records = []
attributes = ("dir", "class")
for subElement in element:
record = _extractWOFFMetadataDict(subElement, attributes)
# text
record["text"] = _flattenWOFFMetadataString(subElement)
# language
language = _extractWOFFMetadataLanguage(subElement)
if language is not None:
record["language"] = language
records.append(record)
return records
def _extractWOFFMetadataLanguage(element):
language = element.attrib.get("{http://www.w3.org/XML/1998/namespace}lang")
if language is None:
language = element.attrib.get("lang")
return language
def _flattenWOFFMetadataString(element, sub=False):
text = element.text.strip()
for subElement in element:
text += _flattenWOFFMetadataString(subElement, sub=True)
if element.tail:
text += element.tail.strip()
if sub:
attrib = ["%s=%s" % (key, quoteattr(value)) for key, value in element.attrib.items()]
attrib = " ".join(attrib)
if attrib:
start = "<%s %s>" % (element.tag, attrib)
else:
start = "<%s>" % (element.tag)
end = "</%s>" % (element.tag)
text = start + text + end
return text