2016-12-27 13:40:27 -05:00

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()