491 lines
9.2 KiB
Python
491 lines
9.2 KiB
Python
from __future__ import print_function, division, absolute_import
|
|
from __future__ import unicode_literals
|
|
from fontTools.misc.py23 import *
|
|
from fontTools.misc.xmlWriter import XMLWriter
|
|
from fontTools.ttLib import TTFont
|
|
from fontTools import mtiLib
|
|
import difflib
|
|
import os
|
|
import sys
|
|
import unittest
|
|
|
|
|
|
class MtiTest(unittest.TestCase):
|
|
|
|
GLYPH_ORDER = [
|
|
'a',
|
|
'b',
|
|
'pakannada',
|
|
'phakannada',
|
|
'vakannada',
|
|
'pevowelkannada',
|
|
'phevowelkannada',
|
|
'vevowelkannada',
|
|
'uvowelsignkannada',
|
|
'uuvowelsignkannada',
|
|
'uvowelsignaltkannada',
|
|
'uuvowelsignaltkannada',
|
|
'uuvowelsignsinh',
|
|
'uvowelsignsinh',
|
|
'rakarsinh',
|
|
'zero',
|
|
'one',
|
|
'two',
|
|
'three',
|
|
'four',
|
|
'five',
|
|
'six',
|
|
'seven',
|
|
'eight',
|
|
'nine',
|
|
'slash',
|
|
'fraction',
|
|
'A',
|
|
'B',
|
|
'C',
|
|
'fi',
|
|
'fl',
|
|
'breve',
|
|
'acute',
|
|
'uniFB01',
|
|
'ffi',
|
|
'grave',
|
|
'commaacent',
|
|
'dotbelow',
|
|
'dotabove',
|
|
'cedilla',
|
|
'commaaccent',
|
|
'Acircumflex',
|
|
'V',
|
|
'T',
|
|
'acircumflex',
|
|
'Aacute',
|
|
'Agrave',
|
|
'O',
|
|
'Oacute',
|
|
'Ograve',
|
|
'Ocircumflex',
|
|
'aacute',
|
|
'agrave',
|
|
'aimatrabindigurmukhi',
|
|
'aimatragurmukhi',
|
|
'aimatratippigurmukhi',
|
|
'aumatrabindigurmukhi',
|
|
'aumatragurmukhi',
|
|
'bindigurmukhi',
|
|
'eematrabindigurmukhi',
|
|
'eematragurmukhi',
|
|
'eematratippigurmukhi',
|
|
'oomatrabindigurmukhi',
|
|
'oomatragurmukhi',
|
|
'oomatratippigurmukhi',
|
|
'lagurmukhi',
|
|
'lanuktagurmukhi',
|
|
'nagurmukhi',
|
|
'nanuktagurmukhi',
|
|
'ngagurmukhi',
|
|
'nganuktagurmukhi',
|
|
'nnagurmukhi',
|
|
'nnanuktagurmukhi',
|
|
'tthagurmukhi',
|
|
'tthanuktagurmukhi',
|
|
'bsuperior',
|
|
'isuperior',
|
|
'vsuperior',
|
|
'wsuperior',
|
|
'periodsuperior',
|
|
'osuperior',
|
|
'tsuperior',
|
|
'dollarsuperior',
|
|
'fsuperior',
|
|
'gsuperior',
|
|
'zsuperior',
|
|
'dsuperior',
|
|
'psuperior',
|
|
'hsuperior',
|
|
'oesuperior',
|
|
'aesuperior',
|
|
'centsuperior',
|
|
'esuperior',
|
|
'lsuperior',
|
|
'qsuperior',
|
|
'csuperior',
|
|
'asuperior',
|
|
'commasuperior',
|
|
'xsuperior',
|
|
'egravesuperior',
|
|
'usuperior',
|
|
'rsuperior',
|
|
'nsuperior',
|
|
'ssuperior',
|
|
'msuperior',
|
|
'jsuperior',
|
|
'ysuperior',
|
|
'ksuperior',
|
|
'guilsinglright',
|
|
'guilsinglleft',
|
|
'uniF737',
|
|
'uniE11C',
|
|
'uniE11D',
|
|
'uniE11A',
|
|
'uni2077',
|
|
'uni2087',
|
|
'uniE11B',
|
|
'uniE119',
|
|
'uniE0DD',
|
|
'uniE0DE',
|
|
'uniF736',
|
|
'uniE121',
|
|
'uniE122',
|
|
'uniE11F',
|
|
'uni2076',
|
|
'uni2086',
|
|
'uniE120',
|
|
'uniE11E',
|
|
'uniE0DB',
|
|
'uniE0DC',
|
|
'uniF733',
|
|
'uniE12B',
|
|
'uniE12C',
|
|
'uniE129',
|
|
'uni00B3',
|
|
'uni2083',
|
|
'uniE12A',
|
|
'uniE128',
|
|
'uniF732',
|
|
'uniE133',
|
|
'uniE134',
|
|
'uniE131',
|
|
'uni00B2',
|
|
'uni2082',
|
|
'uniE132',
|
|
'uniE130',
|
|
'uniE0F9',
|
|
'uniF734',
|
|
'uniE0D4',
|
|
'uniE0D5',
|
|
'uniE0D2',
|
|
'uni2074',
|
|
'uni2084',
|
|
'uniE0D3',
|
|
'uniE0D1',
|
|
'uniF730',
|
|
'uniE13D',
|
|
'uniE13E',
|
|
'uniE13A',
|
|
'uni2070',
|
|
'uni2080',
|
|
'uniE13B',
|
|
'uniE139',
|
|
'uniE13C',
|
|
'uniF739',
|
|
'uniE0EC',
|
|
'uniE0ED',
|
|
'uniE0EA',
|
|
'uni2079',
|
|
'uni2089',
|
|
'uniE0EB',
|
|
'uniE0E9',
|
|
'uniF735',
|
|
'uniE0CD',
|
|
'uniE0CE',
|
|
'uniE0CB',
|
|
'uni2075',
|
|
'uni2085',
|
|
'uniE0CC',
|
|
'uniE0CA',
|
|
'uniF731',
|
|
'uniE0F3',
|
|
'uniE0F4',
|
|
'uniE0F1',
|
|
'uni00B9',
|
|
'uni2081',
|
|
'uniE0F2',
|
|
'uniE0F0',
|
|
'uniE0F8',
|
|
'uniF738',
|
|
'uniE0C0',
|
|
'uniE0C1',
|
|
'uniE0BE',
|
|
'uni2078',
|
|
'uni2088',
|
|
'uniE0BF',
|
|
'uniE0BD',
|
|
'I',
|
|
'Ismall',
|
|
't',
|
|
'i',
|
|
'f',
|
|
'IJ',
|
|
'J',
|
|
'IJsmall',
|
|
'Jsmall',
|
|
'tt',
|
|
'ij',
|
|
'j',
|
|
'ffb',
|
|
'ffh',
|
|
'h',
|
|
'ffk',
|
|
'k',
|
|
'ffl',
|
|
'l',
|
|
'fft',
|
|
'fb',
|
|
'ff',
|
|
'fh',
|
|
'fj',
|
|
'fk',
|
|
'ft',
|
|
'janyevoweltelugu',
|
|
'kassevoweltelugu',
|
|
'jaivoweltelugu',
|
|
'nyasubscripttelugu',
|
|
'kaivoweltelugu',
|
|
'ssasubscripttelugu',
|
|
'bayi1',
|
|
'jeemi1',
|
|
'kafi1',
|
|
'ghafi1',
|
|
'laami1',
|
|
'kafm1',
|
|
'ghafm1',
|
|
'laamm1',
|
|
'rayf2',
|
|
'reyf2',
|
|
'yayf2',
|
|
'zayf2',
|
|
'fayi1',
|
|
'ayehf2',
|
|
'hamzayeharabf2',
|
|
'hamzayehf2',
|
|
'yehf2',
|
|
'ray',
|
|
'rey',
|
|
'zay',
|
|
'yay',
|
|
'dal',
|
|
'del',
|
|
'zal',
|
|
'rayf1',
|
|
'reyf1',
|
|
'yayf1',
|
|
'zayf1',
|
|
'ayehf1',
|
|
'hamzayeharabf1',
|
|
'hamzayehf1',
|
|
'yehf1',
|
|
'dal1',
|
|
'del1',
|
|
'zal1',
|
|
'onehalf',
|
|
'onehalf.alt',
|
|
'onequarter',
|
|
'onequarter.alt',
|
|
'threequarters',
|
|
'threequarters.alt',
|
|
'AlefSuperiorNS',
|
|
'DammaNS',
|
|
'DammaRflxNS',
|
|
'DammatanNS',
|
|
'Fatha2dotsNS',
|
|
'FathaNS',
|
|
'FathatanNS',
|
|
'FourDotsAboveNS',
|
|
'HamzaAboveNS',
|
|
'MaddaNS',
|
|
'OneDotAbove2NS',
|
|
'OneDotAboveNS',
|
|
'ShaddaAlefNS',
|
|
'ShaddaDammaNS',
|
|
'ShaddaDammatanNS',
|
|
'ShaddaFathatanNS',
|
|
'ShaddaKasraNS',
|
|
'ShaddaKasratanNS',
|
|
'ShaddaNS',
|
|
'SharetKafNS',
|
|
'SukunNS',
|
|
'ThreeDotsDownAboveNS',
|
|
'ThreeDotsUpAboveNS',
|
|
'TwoDotsAboveNS',
|
|
'TwoDotsVerticalAboveNS',
|
|
'UltapeshNS',
|
|
'WaslaNS',
|
|
'AinIni.12m_MeemFin.02',
|
|
'AinIni_YehBarreeFin',
|
|
'AinMed_YehBarreeFin',
|
|
'BehxIni_MeemFin',
|
|
'BehxIni_NoonGhunnaFin',
|
|
'BehxIni_RehFin',
|
|
'BehxIni_RehFin.b',
|
|
'BehxMed_MeemFin.py',
|
|
'BehxMed_NoonGhunnaFin',
|
|
'BehxMed_NoonGhunnaFin.cup',
|
|
'BehxMed_RehFin',
|
|
'BehxMed_RehFin.cup',
|
|
'BehxMed_YehxFin',
|
|
'FehxMed_YehBarreeFin',
|
|
'HahIni_YehBarreeFin',
|
|
'KafIni_YehBarreeFin',
|
|
'KafMed.12_YehxFin.01',
|
|
'KafMed_MeemFin',
|
|
'KafMed_YehBarreeFin',
|
|
'LamAlefFin',
|
|
'LamAlefFin.cup',
|
|
'LamAlefFin.cut',
|
|
'LamAlefFin.short',
|
|
'LamAlefSep',
|
|
'LamIni_MeemFin',
|
|
'LamIni_YehBarreeFin',
|
|
'LamMed_MeemFin',
|
|
'LamMed_MeemFin.b',
|
|
'LamMed_YehxFin',
|
|
'LamMed_YehxFin.cup',
|
|
'TahIni_YehBarreeFin',
|
|
]
|
|
|
|
|
|
# Feature files in testdata/*.txt; output gets compared to testdata/*.ttx.
|
|
TESTS = {
|
|
None: (
|
|
#'mti/cmap',
|
|
),
|
|
'cmap': (
|
|
#'mti/cmap',
|
|
),
|
|
'GSUB': (
|
|
'featurename-backward',
|
|
'featurename-forward',
|
|
'lookupnames-backward',
|
|
'lookupnames-forward',
|
|
'mixed-toplevels',
|
|
|
|
'mti/scripttable',
|
|
'mti/chainedclass',
|
|
'mti/chainedcoverage',
|
|
'mti/chained-glyph',
|
|
'mti/gsubalternate',
|
|
'mti/gsubligature',
|
|
'mti/gsubmultiple',
|
|
'mti/gsubreversechanined',
|
|
'mti/gsubsingle',
|
|
),
|
|
'GPOS': (
|
|
'mti/scripttable',
|
|
'mti/chained-glyph',
|
|
'mti/gposcursive',
|
|
'mti/gposkernset',
|
|
'mti/gposmarktobase',
|
|
'mti/gpospairclass',
|
|
'mti/gpospairglyph',
|
|
'mti/gpossingle',
|
|
'mti/mark-to-ligature',
|
|
),
|
|
'GDEF': (
|
|
'mti/gdefattach',
|
|
'mti/gdefclasses',
|
|
'mti/gdefligcaret',
|
|
'mti/gdefmarkattach',
|
|
'mti/gdefmarkfilter',
|
|
),
|
|
}
|
|
# TODO:
|
|
# https://github.com/Monotype/OpenType_Table_Source/issues/12
|
|
#
|
|
# 'mti/featuretable'
|
|
# 'mti/contextclass'
|
|
# 'mti/contextcoverage'
|
|
# 'mti/context-glyph'
|
|
|
|
def __init__(self, methodName):
|
|
unittest.TestCase.__init__(self, methodName)
|
|
# Python 3 renamed assertRaisesRegexp to assertRaisesRegex,
|
|
# and fires deprecation warnings if a program uses the old name.
|
|
if not hasattr(self, "assertRaisesRegex"):
|
|
self.assertRaisesRegex = self.assertRaisesRegexp
|
|
|
|
def setUp(self):
|
|
pass
|
|
|
|
def tearDown(self):
|
|
pass
|
|
|
|
@staticmethod
|
|
def getpath(testfile):
|
|
path, _ = os.path.split(__file__)
|
|
return os.path.join(path, "testdata", testfile)
|
|
|
|
def expect_ttx(self, expected_ttx, actual_ttx, fromfile=None, tofile=None):
|
|
expected = [l+'\n' for l in expected_ttx.split('\n')]
|
|
actual = [l+'\n' for l in actual_ttx.split('\n')]
|
|
if actual != expected:
|
|
sys.stderr.write('\n')
|
|
for line in difflib.unified_diff(
|
|
expected, actual, fromfile=fromfile, tofile=tofile):
|
|
sys.stderr.write(line)
|
|
self.fail("TTX output is different from expected")
|
|
|
|
@classmethod
|
|
def create_font(celf):
|
|
font = TTFont()
|
|
font.setGlyphOrder(celf.GLYPH_ORDER)
|
|
return font
|
|
|
|
def check_mti_file(self, name, tableTag=None):
|
|
|
|
xml_expected_path = self.getpath("%s.ttx" % name + ('.'+tableTag if tableTag is not None else ''))
|
|
with open(xml_expected_path, 'rt', encoding="utf-8") as xml_expected_file:
|
|
xml_expected = xml_expected_file.read()
|
|
|
|
font = self.create_font()
|
|
|
|
with open(self.getpath("%s.txt" % name), 'rt', encoding="utf-8") as f:
|
|
table = mtiLib.build(f, font, tableTag=tableTag)
|
|
|
|
if tableTag is not None:
|
|
self.assertEqual(tableTag, table.tableTag)
|
|
tableTag = table.tableTag
|
|
|
|
# Make sure it compiles.
|
|
blob = table.compile(font)
|
|
|
|
# Make sure it decompiles.
|
|
decompiled = table.__class__()
|
|
decompiled.decompile(blob, font)
|
|
|
|
# XML from built object.
|
|
writer = XMLWriter(StringIO(), newlinestr='\n')
|
|
writer.begintag(tableTag); writer.newline()
|
|
table.toXML(writer, font)
|
|
writer.endtag(tableTag); writer.newline()
|
|
xml_built = writer.file.getvalue()
|
|
|
|
# XML from decompiled object.
|
|
writer = XMLWriter(StringIO(), newlinestr='\n')
|
|
writer.begintag(tableTag); writer.newline()
|
|
decompiled.toXML(writer, font)
|
|
writer.endtag(tableTag); writer.newline()
|
|
xml_binary = writer.file.getvalue()
|
|
|
|
self.expect_ttx(xml_binary, xml_built, fromfile='decompiled', tofile='built')
|
|
self.expect_ttx(xml_expected, xml_built, fromfile=xml_expected_path, tofile='built')
|
|
|
|
def generate_mti_file_test(name, tableTag=None):
|
|
return lambda self: self.check_mti_file(os.path.join(*name.split('/')), tableTag=tableTag)
|
|
|
|
|
|
for tableTag,tests in MtiTest.TESTS.items():
|
|
for name in tests:
|
|
setattr(MtiTest, "test_MtiFile_%s%s" % (name, '_'+tableTag if tableTag else ''),
|
|
generate_mti_file_test(name, tableTag=tableTag))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
import sys
|
|
if len(sys.argv) > 1:
|
|
from fontTools.mtiLib import main
|
|
font = MtiTest.create_font()
|
|
main (sys.argv[1:], font)
|
|
sys.exit()
|
|
unittest.main()
|