From 36d22d82aa202bb199967e9512281e9a53db42c9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 21:33:14 +0200 Subject: Adding upstream version 115.7.0esr. Signed-off-by: Daniel Baumann --- .../reftests/fonts/gsubtest/gsubtest-features.js | 105 +++++ .../reftests/fonts/gsubtest/gsubtest-features.txt | 328 +++++++++++++ .../reftests/fonts/gsubtest/gsubtest-lookup1.otf | Bin 0 -> 158316 bytes .../reftests/fonts/gsubtest/gsubtest-lookup3.otf | Bin 0 -> 383716 bytes layout/reftests/fonts/gsubtest/gsubtest-shell.ttx | 304 ++++++++++++ layout/reftests/fonts/gsubtest/makegsubfonts.py | 517 +++++++++++++++++++++ 6 files changed, 1254 insertions(+) create mode 100644 layout/reftests/fonts/gsubtest/gsubtest-features.js create mode 100644 layout/reftests/fonts/gsubtest/gsubtest-features.txt create mode 100644 layout/reftests/fonts/gsubtest/gsubtest-lookup1.otf create mode 100644 layout/reftests/fonts/gsubtest/gsubtest-lookup3.otf create mode 100644 layout/reftests/fonts/gsubtest/gsubtest-shell.ttx create mode 100644 layout/reftests/fonts/gsubtest/makegsubfonts.py (limited to 'layout/reftests/fonts/gsubtest') diff --git a/layout/reftests/fonts/gsubtest/gsubtest-features.js b/layout/reftests/fonts/gsubtest/gsubtest-features.js new file mode 100644 index 0000000000..fef981cb76 --- /dev/null +++ b/layout/reftests/fonts/gsubtest/gsubtest-features.js @@ -0,0 +1,105 @@ + +/* This file is autogenerated by makegsubfonts.py */ + +/* + Features defined in gsubtest fonts with associated base + codepoints for each feature: + + cp = codepoint for feature featX + + cp default PASS + cp featX=1 FAIL + cp featX=2 FAIL + + cp+1 default FAIL + cp+1 featX=1 PASS + cp+1 featX=2 FAIL + + cp+2 default FAIL + cp+2 featX=1 FAIL + cp+2 featX=2 PASS + +*/ + +var gFeatures = { + "MWL1": 0xe000, "NUM2": 0xe004, "PRIV": 0xe008, "T3ST": 0xe00c, + "TPSP": 0xe010, "abvf": 0xe014, "abvm": 0xe018, "abvs": 0xe01c, + "afrc": 0xe020, "akhn": 0xe024, "blwf": 0xe028, "blwm": 0xe02c, + "blws": 0xe030, "c2pc": 0xe034, "c2sc": 0xe038, "calt": 0xe03c, + "case": 0xe040, "ccmp": 0xe044, "cfar": 0xe048, "cjct": 0xe04c, + "clig": 0xe050, "cpct": 0xe054, "cpsp": 0xe058, "cswh": 0xe05c, + "curs": 0xe060, "cv00": 0xe064, "cv01": 0xe068, "cv02": 0xe06c, + "cv03": 0xe070, "cv04": 0xe074, "cv05": 0xe078, "cv06": 0xe07c, + "cv07": 0xe080, "cv08": 0xe084, "cv09": 0xe088, "cv10": 0xe08c, + "cv11": 0xe090, "cv12": 0xe094, "cv13": 0xe098, "cv14": 0xe09c, + "cv15": 0xe0a0, "cv16": 0xe0a4, "cv17": 0xe0a8, "cv18": 0xe0ac, + "cv19": 0xe0b0, "cv20": 0xe0b4, "cv21": 0xe0b8, "cv22": 0xe0bc, + "cv23": 0xe0c0, "cv24": 0xe0c4, "cv25": 0xe0c8, "cv26": 0xe0cc, + "cv27": 0xe0d0, "cv28": 0xe0d4, "cv29": 0xe0d8, "cv30": 0xe0dc, + "cv31": 0xe0e0, "cv32": 0xe0e4, "cv33": 0xe0e8, "cv34": 0xe0ec, + "cv35": 0xe0f0, "cv36": 0xe0f4, "cv37": 0xe0f8, "cv38": 0xe0fc, + "cv39": 0xe100, "cv40": 0xe104, "cv41": 0xe108, "cv42": 0xe10c, + "cv43": 0xe110, "cv44": 0xe114, "cv45": 0xe118, "cv46": 0xe11c, + "cv47": 0xe120, "cv48": 0xe124, "cv49": 0xe128, "cv50": 0xe12c, + "cv51": 0xe130, "cv52": 0xe134, "cv53": 0xe138, "cv54": 0xe13c, + "cv55": 0xe140, "cv56": 0xe144, "cv57": 0xe148, "cv58": 0xe14c, + "cv59": 0xe150, "cv60": 0xe154, "cv61": 0xe158, "cv62": 0xe15c, + "cv63": 0xe160, "cv64": 0xe164, "cv65": 0xe168, "cv66": 0xe16c, + "cv67": 0xe170, "cv68": 0xe174, "cv69": 0xe178, "cv70": 0xe17c, + "cv71": 0xe180, "cv72": 0xe184, "cv73": 0xe188, "cv74": 0xe18c, + "cv75": 0xe190, "cv76": 0xe194, "cv77": 0xe198, "cv78": 0xe19c, + "cv79": 0xe1a0, "cv80": 0xe1a4, "cv81": 0xe1a8, "cv82": 0xe1ac, + "cv83": 0xe1b0, "cv84": 0xe1b4, "cv85": 0xe1b8, "cv86": 0xe1bc, + "cv87": 0xe1c0, "cv88": 0xe1c4, "cv89": 0xe1c8, "cv90": 0xe1cc, + "cv91": 0xe1d0, "cv92": 0xe1d4, "cv93": 0xe1d8, "cv94": 0xe1dc, + "cv95": 0xe1e0, "cv96": 0xe1e4, "cv97": 0xe1e8, "cv98": 0xe1ec, + "cv99": 0xe1f0, "dist": 0xe1f4, "dlig": 0xe1f8, "dnom": 0xe1fc, + "expt": 0xe200, "falt": 0xe204, "fin2": 0xe208, "fin3": 0xe20c, + "fina": 0xe210, "frac": 0xe214, "fwid": 0xe218, "half": 0xe21c, + "haln": 0xe220, "halt": 0xe224, "hist": 0xe228, "hkna": 0xe22c, + "hlig": 0xe230, "hngl": 0xe234, "hojo": 0xe238, "hwid": 0xe23c, + "init": 0xe240, "isol": 0xe244, "ital": 0xe248, "jalt": 0xe24c, + "jp04": 0xe250, "jp78": 0xe254, "jp83": 0xe258, "jp90": 0xe25c, + "kern": 0xe260, "lfbd": 0xe264, "liga": 0xe268, "ljmo": 0xe26c, + "lnum": 0xe270, "locl": 0xe274, "ltra": 0xe278, "ltrm": 0xe27c, + "mark": 0xe280, "med2": 0xe284, "medi": 0xe288, "mgrk": 0xe28c, + "mkmk": 0xe290, "mset": 0xe294, "nalt": 0xe298, "nlck": 0xe29c, + "nukt": 0xe2a0, "numr": 0xe2a4, "onum": 0xe2a8, "opbd": 0xe2ac, + "ordn": 0xe2b0, "ornm": 0xe2b4, "palt": 0xe2b8, "pcap": 0xe2bc, + "pkna": 0xe2c0, "pnum": 0xe2c4, "pref": 0xe2c8, "pres": 0xe2cc, + "pstf": 0xe2d0, "psts": 0xe2d4, "pwid": 0xe2d8, "qwid": 0xe2dc, + "rand": 0xe2e0, "rkrf": 0xe2e4, "rlig": 0xe2e8, "rphf": 0xe2ec, + "rtbd": 0xe2f0, "rtla": 0xe2f4, "rtlm": 0xe2f8, "ruby": 0xe2fc, + "salt": 0xe300, "sinf": 0xe304, "size": 0xe308, "smcp": 0xe30c, + "smpl": 0xe310, "ss00": 0xe314, "ss01": 0xe318, "ss02": 0xe31c, + "ss03": 0xe320, "ss04": 0xe324, "ss05": 0xe328, "ss06": 0xe32c, + "ss07": 0xe330, "ss08": 0xe334, "ss09": 0xe338, "ss10": 0xe33c, + "ss11": 0xe340, "ss12": 0xe344, "ss13": 0xe348, "ss14": 0xe34c, + "ss15": 0xe350, "ss16": 0xe354, "ss17": 0xe358, "ss18": 0xe35c, + "ss19": 0xe360, "ss20": 0xe364, "ss21": 0xe368, "ss22": 0xe36c, + "ss23": 0xe370, "ss24": 0xe374, "ss25": 0xe378, "ss26": 0xe37c, + "ss27": 0xe380, "ss28": 0xe384, "ss29": 0xe388, "ss30": 0xe38c, + "ss31": 0xe390, "ss32": 0xe394, "ss33": 0xe398, "ss34": 0xe39c, + "ss35": 0xe3a0, "ss36": 0xe3a4, "ss37": 0xe3a8, "ss38": 0xe3ac, + "ss39": 0xe3b0, "ss40": 0xe3b4, "ss41": 0xe3b8, "ss42": 0xe3bc, + "ss43": 0xe3c0, "ss44": 0xe3c4, "ss45": 0xe3c8, "ss46": 0xe3cc, + "ss47": 0xe3d0, "ss48": 0xe3d4, "ss49": 0xe3d8, "ss50": 0xe3dc, + "ss51": 0xe3e0, "ss52": 0xe3e4, "ss53": 0xe3e8, "ss54": 0xe3ec, + "ss55": 0xe3f0, "ss56": 0xe3f4, "ss57": 0xe3f8, "ss58": 0xe3fc, + "ss59": 0xe400, "ss60": 0xe404, "ss61": 0xe408, "ss62": 0xe40c, + "ss63": 0xe410, "ss64": 0xe414, "ss65": 0xe418, "ss66": 0xe41c, + "ss67": 0xe420, "ss68": 0xe424, "ss69": 0xe428, "ss70": 0xe42c, + "ss71": 0xe430, "ss72": 0xe434, "ss73": 0xe438, "ss74": 0xe43c, + "ss75": 0xe440, "ss76": 0xe444, "ss77": 0xe448, "ss78": 0xe44c, + "ss79": 0xe450, "ss80": 0xe454, "ss81": 0xe458, "ss82": 0xe45c, + "ss83": 0xe460, "ss84": 0xe464, "ss85": 0xe468, "ss86": 0xe46c, + "ss87": 0xe470, "ss88": 0xe474, "ss89": 0xe478, "ss90": 0xe47c, + "ss91": 0xe480, "ss92": 0xe484, "ss93": 0xe488, "ss94": 0xe48c, + "ss95": 0xe490, "ss96": 0xe494, "ss97": 0xe498, "ss98": 0xe49c, + "ss99": 0xe4a0, "subs": 0xe4a4, "sups": 0xe4a8, "swsh": 0xe4ac, + "titl": 0xe4b0, "tjmo": 0xe4b4, "tnam": 0xe4b8, "tnum": 0xe4bc, + "trad": 0xe4c0, "twid": 0xe4c4, "unic": 0xe4c8, "valt": 0xe4cc, + "vatu": 0xe4d0, "vert": 0xe4d4, "vhal": 0xe4d8, "vjmo": 0xe4dc, + "vkna": 0xe4e0, "vkrn": 0xe4e4, "vpal": 0xe4e8, "vrt2": 0xe4ec, + "zero": 0xe4f0 +}; diff --git a/layout/reftests/fonts/gsubtest/gsubtest-features.txt b/layout/reftests/fonts/gsubtest/gsubtest-features.txt new file mode 100644 index 0000000000..eb976de2be --- /dev/null +++ b/layout/reftests/fonts/gsubtest/gsubtest-features.txt @@ -0,0 +1,328 @@ +# Feature To Unicode Mapping +# -------------------------- +# This file is structured as: +# feature tag target first alternate second alternate third alternate +# with tab being the delimiter. +# +# Lines beginning with # should be ignored. +# Empty or whitespace only lines should be ignored. + +abvf +abvm +abvs +afrc +akhn +blwf +blwm +blws +calt +case +ccmp +cfar +cjct +clig +cpct +cpsp +cswh +curs +# cv00 is a deliberately invalid feature tag +cv00 +cv01 +cv02 +cv03 +cv04 +cv05 +cv06 +cv07 +cv08 +cv09 +cv10 +cv11 +cv12 +cv13 +cv14 +cv15 +cv16 +cv17 +cv18 +cv19 +cv20 +cv21 +cv22 +cv23 +cv24 +cv25 +cv26 +cv27 +cv28 +cv29 +cv30 +cv31 +cv32 +cv33 +cv34 +cv35 +cv36 +cv37 +cv38 +cv39 +cv40 +cv41 +cv42 +cv43 +cv44 +cv45 +cv46 +cv47 +cv48 +cv49 +cv50 +cv51 +cv52 +cv53 +cv54 +cv55 +cv56 +cv57 +cv58 +cv59 +cv60 +cv61 +cv62 +cv63 +cv64 +cv65 +cv66 +cv67 +cv68 +cv69 +cv70 +cv71 +cv72 +cv73 +cv74 +cv75 +cv76 +cv77 +cv78 +cv79 +cv80 +cv81 +cv82 +cv83 +cv84 +cv85 +cv86 +cv87 +cv88 +cv89 +cv90 +cv91 +cv92 +cv93 +cv94 +cv95 +cv96 +cv97 +cv98 +cv99 +c2pc +c2sc +dist +dlig +dnom +expt +falt +fin2 +fin3 +fina +frac +fwid +half +haln +halt +hist +hkna +hlig +hngl +hojo +hwid +init +isol +ital +jalt +jp78 +jp83 +jp90 +jp04 +kern +lfbd +liga +ljmo +lnum +locl +ltra +ltrm +mark +med2 +medi +mgrk +mkmk +mset +nalt +nlck +nukt +numr +onum +opbd +ordn +ornm +palt +pcap +pkna +pnum +pref +pres +pstf +psts +pwid +qwid +rand +rkrf +rlig +rphf +rtbd +rtla +rtlm +ruby +salt +sinf +size +smcp +smpl +# ss00 is a deliberately invalid feature tag +ss00 +ss01 +ss02 +ss03 +ss04 +ss05 +ss06 +ss07 +ss08 +ss09 +ss10 +ss11 +ss12 +ss13 +ss14 +ss15 +ss16 +ss17 +ss18 +ss19 +ss20 +ss21 +ss22 +ss23 +ss24 +ss25 +ss26 +ss27 +ss28 +ss29 +ss30 +ss31 +ss32 +ss33 +ss34 +ss35 +ss36 +ss37 +ss38 +ss39 +ss40 +ss41 +ss42 +ss43 +ss44 +ss45 +ss46 +ss47 +ss48 +ss49 +ss50 +ss51 +ss52 +ss53 +ss54 +ss55 +ss56 +ss57 +ss58 +ss59 +ss60 +ss61 +ss62 +ss63 +ss64 +ss65 +ss66 +ss67 +ss68 +ss69 +ss70 +ss71 +ss72 +ss73 +ss74 +ss75 +ss76 +ss77 +ss78 +ss79 +ss80 +ss81 +ss82 +ss83 +ss84 +ss85 +ss86 +ss87 +ss88 +ss89 +ss90 +ss91 +ss92 +ss93 +ss94 +ss95 +ss96 +ss97 +ss98 +ss99 +subs +sups +swsh +titl +tjmo +tnam +tnum +trad +twid +unic +valt +vatu +vert +vhal +vjmo +vkna +vkrn +vpal +vrt2 +zero +MWL1 +NUM2 +PRIV +T3ST +TPSP diff --git a/layout/reftests/fonts/gsubtest/gsubtest-lookup1.otf b/layout/reftests/fonts/gsubtest/gsubtest-lookup1.otf new file mode 100644 index 0000000000..34ec50f9dd Binary files /dev/null and b/layout/reftests/fonts/gsubtest/gsubtest-lookup1.otf differ diff --git a/layout/reftests/fonts/gsubtest/gsubtest-lookup3.otf b/layout/reftests/fonts/gsubtest/gsubtest-lookup3.otf new file mode 100644 index 0000000000..1933648132 Binary files /dev/null and b/layout/reftests/fonts/gsubtest/gsubtest-lookup3.otf differ diff --git a/layout/reftests/fonts/gsubtest/gsubtest-shell.ttx b/layout/reftests/fonts/gsubtest/gsubtest-shell.ttx new file mode 100644 index 0000000000..541f11f004 --- /dev/null +++ b/layout/reftests/fonts/gsubtest/gsubtest-shell.ttx @@ -0,0 +1,304 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + __familyName__ + + + Regular + + + 1.000;TPSP;__familyName__-Regular + + + __familyName__ + + + Version 1.000 + + + __familyName__-Regular + + + Tal Leming with modifications by John Daggett + + + http://scripts.sil.org/OFL + + + __familyName__ + + + Regular + + + 1.000;TPSP;__familyName__-Regular + + + __familyName__ + + + Version 1.000 + + + __familyName__-Regular + + + Tal Leming with modifications by John Daggett + + + http://scripts.sil.org/OFL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + endchar + + + -102 787 hmoveto + 31 119 rlineto + 203 hlineto + 32 -119 rlineto + 246 hlineto + -213 700 rlineto + -296 hlineto + -213 -700 rlineto + -477 hmoveto + 237 244 245 162 -245 130 287 164 -524 hlineto + 1586 -700 rmoveto + 518 180 -281 520 -237 hlineto + -332 -700 rmoveto + 237 700 -237 hlineto + -434 -196 rmoveto + 60 -228 rlineto + -120 hlineto + endchar + + + -107 394 306 rmoveto + 153 86 82 115 115 -86 82 -153 hvcurveto + -294 -15 91 -670 -91 -15 297 15 -101 291 hlineto + 632 -291 rmoveto + -15 276 15 -67 vlineto + -254 690 rlineto + -12 hlineto + -219 -593 rlineto + -69 -25 -46 -28 -59 hhcurveto + -5 -15 259 15 -26 hlineto + -67 -35 34 71 26 hvcurveto + 43 116 rlineto + 232 hlineto + 78 -221 rlineto + 599 695 rmoveto + -28 -11 -5 -6 -14 -22 -44 34 -78 hhcurveto + -124 -91 -73 -106 -95 52 -64 147 -61 hvcurveto + 126 -52 30 -44 -79 vvcurveto + -81 -55 -50 -81 -103 -85 70 168 -17 vhcurveto + -15 -253 15 hlineto + 22 4 13 15 18 45 32 -37 98 hhcurveto + 130 92 82 116 83 -32 66 -173 73 hvcurveto + -120 50 -33 43 72 vvcurveto + 71 51 49 82 90 65 -92 -119 13 vhcurveto + 15 226 hlineto + -1118 -207 rmoveto + -119 -49 -63 -96 vhcurveto + -82 364 82 hlineto + 96 49 -63 -119 hvcurveto + 312 53 rmoveto + 108 -305 rlineto + -221 hlineto + 1420 459 rmoveto + -28 -11 -5 -6 -14 -22 -44 34 -78 hhcurveto + -124 -91 -73 -106 -95 52 -64 147 -61 hvcurveto + 126 -52 30 -44 -79 vvcurveto + -81 -55 -50 -81 -103 -85 70 168 -17 vhcurveto + -15 -253 15 hlineto + 22 4 13 15 18 45 32 -37 98 hhcurveto + 130 92 82 116 83 -32 66 -173 73 hvcurveto + -120 50 -33 43 72 vvcurveto + 71 51 49 82 90 65 -92 -119 13 vhcurveto + 15 226 hlineto + endchar + + + endchar + + + + + + + + + + + + + + + + + + diff --git a/layout/reftests/fonts/gsubtest/makegsubfonts.py b/layout/reftests/fonts/gsubtest/makegsubfonts.py new file mode 100644 index 0000000000..73d022e6be --- /dev/null +++ b/layout/reftests/fonts/gsubtest/makegsubfonts.py @@ -0,0 +1,517 @@ +import os +import textwrap +from xml.etree import ElementTree +from fontTools.ttLib import TTFont, newTable +from fontTools.misc.psCharStrings import T2CharString +from fontTools.ttLib.tables.otTables import ( + GSUB, + ScriptList, + ScriptRecord, + Script, + DefaultLangSys, + FeatureList, + FeatureRecord, + Feature, + LookupList, + Lookup, + AlternateSubst, + SingleSubst, +) + +# paths +directory = os.path.dirname(__file__) +shellSourcePath = os.path.join(directory, "gsubtest-shell.ttx") +shellTempPath = os.path.join(directory, "gsubtest-shell.otf") +featureList = os.path.join(directory, "gsubtest-features.txt") +javascriptData = os.path.join(directory, "gsubtest-features.js") +outputPath = os.path.join(os.path.dirname(directory), "gsubtest-lookup%d") + +baseCodepoint = 0xE000 + +# ------- +# Features +# ------- + +f = open(featureList, "rb") +text = f.read() +f.close() +mapping = [] +for line in text.splitlines(): + line = line.strip() + if not line: + continue + if line.startswith("#"): + continue + # parse + values = line.split("\t") + tag = values.pop(0) + mapping.append(tag) + +# -------- +# Outlines +# -------- + + +def addGlyphToCFF( + glyphName=None, + program=None, + private=None, + globalSubrs=None, + charStringsIndex=None, + topDict=None, + charStrings=None, +): + charString = T2CharString(program=program, private=private, globalSubrs=globalSubrs) + charStringsIndex.append(charString) + glyphID = len(topDict.charset) + charStrings.charStrings[glyphName] = glyphID + topDict.charset.append(glyphName) + + +def makeLookup1(): + # make a variation of the shell TTX data + f = open(shellSourcePath) + ttxData = f.read() + f.close() + ttxData = ttxData.replace("__familyName__", "gsubtest-lookup1") + tempShellSourcePath = shellSourcePath + ".temp" + f = open(tempShellSourcePath, "wb") + f.write(ttxData) + f.close() + + # compile the shell + shell = TTFont(sfntVersion="OTTO") + shell.importXML(tempShellSourcePath) + shell.save(shellTempPath) + os.remove(tempShellSourcePath) + + # load the shell + shell = TTFont(shellTempPath) + + # grab the PASS and FAIL data + hmtx = shell["hmtx"] + glyphSet = shell.getGlyphSet() + + failGlyph = glyphSet["F"] + failGlyph.decompile() + failGlyphProgram = list(failGlyph.program) + failGlyphMetrics = hmtx["F"] + + passGlyph = glyphSet["P"] + passGlyph.decompile() + passGlyphProgram = list(passGlyph.program) + passGlyphMetrics = hmtx["P"] + + # grab some tables + hmtx = shell["hmtx"] + cmap = shell["cmap"] + + # start the glyph order + existingGlyphs = [".notdef", "space", "F", "P"] + glyphOrder = list(existingGlyphs) + + # start the CFF + cff = shell["CFF "].cff + globalSubrs = cff.GlobalSubrs + topDict = cff.topDictIndex[0] + topDict.charset = existingGlyphs + private = topDict.Private + charStrings = topDict.CharStrings + charStringsIndex = charStrings.charStringsIndex + + features = sorted(mapping) + + # build the outline, hmtx and cmap data + cp = baseCodepoint + for index, tag in enumerate(features): + + # tag.pass + glyphName = "%s.pass" % tag + glyphOrder.append(glyphName) + addGlyphToCFF( + glyphName=glyphName, + program=passGlyphProgram, + private=private, + globalSubrs=globalSubrs, + charStringsIndex=charStringsIndex, + topDict=topDict, + charStrings=charStrings, + ) + hmtx[glyphName] = passGlyphMetrics + + for table in cmap.tables: + if table.format == 4: + table.cmap[cp] = glyphName + else: + raise NotImplementedError( + "Unsupported cmap table format: %d" % table.format + ) + cp += 1 + + # tag.fail + glyphName = "%s.fail" % tag + glyphOrder.append(glyphName) + addGlyphToCFF( + glyphName=glyphName, + program=failGlyphProgram, + private=private, + globalSubrs=globalSubrs, + charStringsIndex=charStringsIndex, + topDict=topDict, + charStrings=charStrings, + ) + hmtx[glyphName] = failGlyphMetrics + + for table in cmap.tables: + if table.format == 4: + table.cmap[cp] = glyphName + else: + raise NotImplementedError( + "Unsupported cmap table format: %d" % table.format + ) + + # bump this up so that the sequence is the same as the lookup 3 font + cp += 3 + + # set the glyph order + shell.setGlyphOrder(glyphOrder) + + # start the GSUB + shell["GSUB"] = newTable("GSUB") + gsub = shell["GSUB"].table = GSUB() + gsub.Version = 1.0 + + # make a list of all the features we will make + featureCount = len(features) + + # set up the script list + scriptList = gsub.ScriptList = ScriptList() + scriptList.ScriptCount = 1 + scriptList.ScriptRecord = [] + scriptRecord = ScriptRecord() + scriptList.ScriptRecord.append(scriptRecord) + scriptRecord.ScriptTag = "DFLT" + script = scriptRecord.Script = Script() + defaultLangSys = script.DefaultLangSys = DefaultLangSys() + defaultLangSys.FeatureCount = featureCount + defaultLangSys.FeatureIndex = range(defaultLangSys.FeatureCount) + defaultLangSys.ReqFeatureIndex = 65535 + defaultLangSys.LookupOrder = None + script.LangSysCount = 0 + script.LangSysRecord = [] + + # set up the feature list + featureList = gsub.FeatureList = FeatureList() + featureList.FeatureCount = featureCount + featureList.FeatureRecord = [] + for index, tag in enumerate(features): + # feature record + featureRecord = FeatureRecord() + featureRecord.FeatureTag = tag + feature = featureRecord.Feature = Feature() + featureList.FeatureRecord.append(featureRecord) + # feature + feature.FeatureParams = None + feature.LookupCount = 1 + feature.LookupListIndex = [index] + + # write the lookups + lookupList = gsub.LookupList = LookupList() + lookupList.LookupCount = featureCount + lookupList.Lookup = [] + for tag in features: + # lookup + lookup = Lookup() + lookup.LookupType = 1 + lookup.LookupFlag = 0 + lookup.SubTableCount = 1 + lookup.SubTable = [] + lookupList.Lookup.append(lookup) + # subtable + subtable = SingleSubst() + subtable.Format = 2 + subtable.LookupType = 1 + subtable.mapping = { + "%s.pass" % tag: "%s.fail" % tag, + "%s.fail" % tag: "%s.pass" % tag, + } + lookup.SubTable.append(subtable) + + path = outputPath % 1 + ".otf" + if os.path.exists(path): + os.remove(path) + shell.save(path) + + # get rid of the shell + if os.path.exists(shellTempPath): + os.remove(shellTempPath) + + +def makeLookup3(): + # make a variation of the shell TTX data + f = open(shellSourcePath) + ttxData = f.read() + f.close() + ttxData = ttxData.replace("__familyName__", "gsubtest-lookup3") + tempShellSourcePath = shellSourcePath + ".temp" + f = open(tempShellSourcePath, "wb") + f.write(ttxData) + f.close() + + # compile the shell + shell = TTFont(sfntVersion="OTTO") + shell.importXML(tempShellSourcePath) + shell.save(shellTempPath) + os.remove(tempShellSourcePath) + + # load the shell + shell = TTFont(shellTempPath) + + # grab the PASS and FAIL data + hmtx = shell["hmtx"] + glyphSet = shell.getGlyphSet() + + failGlyph = glyphSet["F"] + failGlyph.decompile() + failGlyphProgram = list(failGlyph.program) + failGlyphMetrics = hmtx["F"] + + passGlyph = glyphSet["P"] + passGlyph.decompile() + passGlyphProgram = list(passGlyph.program) + passGlyphMetrics = hmtx["P"] + + # grab some tables + hmtx = shell["hmtx"] + cmap = shell["cmap"] + + # start the glyph order + existingGlyphs = [".notdef", "space", "F", "P"] + glyphOrder = list(existingGlyphs) + + # start the CFF + cff = shell["CFF "].cff + globalSubrs = cff.GlobalSubrs + topDict = cff.topDictIndex[0] + topDict.charset = existingGlyphs + private = topDict.Private + charStrings = topDict.CharStrings + charStringsIndex = charStrings.charStringsIndex + + features = sorted(mapping) + + # build the outline, hmtx and cmap data + cp = baseCodepoint + for index, tag in enumerate(features): + + # tag.pass + glyphName = "%s.pass" % tag + glyphOrder.append(glyphName) + addGlyphToCFF( + glyphName=glyphName, + program=passGlyphProgram, + private=private, + globalSubrs=globalSubrs, + charStringsIndex=charStringsIndex, + topDict=topDict, + charStrings=charStrings, + ) + hmtx[glyphName] = passGlyphMetrics + + # tag.fail + glyphName = "%s.fail" % tag + glyphOrder.append(glyphName) + addGlyphToCFF( + glyphName=glyphName, + program=failGlyphProgram, + private=private, + globalSubrs=globalSubrs, + charStringsIndex=charStringsIndex, + topDict=topDict, + charStrings=charStrings, + ) + hmtx[glyphName] = failGlyphMetrics + + # tag.default + glyphName = "%s.default" % tag + glyphOrder.append(glyphName) + addGlyphToCFF( + glyphName=glyphName, + program=passGlyphProgram, + private=private, + globalSubrs=globalSubrs, + charStringsIndex=charStringsIndex, + topDict=topDict, + charStrings=charStrings, + ) + hmtx[glyphName] = passGlyphMetrics + + for table in cmap.tables: + if table.format == 4: + table.cmap[cp] = glyphName + else: + raise NotImplementedError( + "Unsupported cmap table format: %d" % table.format + ) + cp += 1 + + # tag.alt1,2,3 + for i in range(1, 4): + glyphName = "%s.alt%d" % (tag, i) + glyphOrder.append(glyphName) + addGlyphToCFF( + glyphName=glyphName, + program=failGlyphProgram, + private=private, + globalSubrs=globalSubrs, + charStringsIndex=charStringsIndex, + topDict=topDict, + charStrings=charStrings, + ) + hmtx[glyphName] = failGlyphMetrics + for table in cmap.tables: + if table.format == 4: + table.cmap[cp] = glyphName + else: + raise NotImplementedError( + "Unsupported cmap table format: %d" % table.format + ) + cp += 1 + + # set the glyph order + shell.setGlyphOrder(glyphOrder) + + # start the GSUB + shell["GSUB"] = newTable("GSUB") + gsub = shell["GSUB"].table = GSUB() + gsub.Version = 1.0 + + # make a list of all the features we will make + featureCount = len(features) + + # set up the script list + scriptList = gsub.ScriptList = ScriptList() + scriptList.ScriptCount = 1 + scriptList.ScriptRecord = [] + scriptRecord = ScriptRecord() + scriptList.ScriptRecord.append(scriptRecord) + scriptRecord.ScriptTag = "DFLT" + script = scriptRecord.Script = Script() + defaultLangSys = script.DefaultLangSys = DefaultLangSys() + defaultLangSys.FeatureCount = featureCount + defaultLangSys.FeatureIndex = range(defaultLangSys.FeatureCount) + defaultLangSys.ReqFeatureIndex = 65535 + defaultLangSys.LookupOrder = None + script.LangSysCount = 0 + script.LangSysRecord = [] + + # set up the feature list + featureList = gsub.FeatureList = FeatureList() + featureList.FeatureCount = featureCount + featureList.FeatureRecord = [] + for index, tag in enumerate(features): + # feature record + featureRecord = FeatureRecord() + featureRecord.FeatureTag = tag + feature = featureRecord.Feature = Feature() + featureList.FeatureRecord.append(featureRecord) + # feature + feature.FeatureParams = None + feature.LookupCount = 1 + feature.LookupListIndex = [index] + + # write the lookups + lookupList = gsub.LookupList = LookupList() + lookupList.LookupCount = featureCount + lookupList.Lookup = [] + for tag in features: + # lookup + lookup = Lookup() + lookup.LookupType = 3 + lookup.LookupFlag = 0 + lookup.SubTableCount = 1 + lookup.SubTable = [] + lookupList.Lookup.append(lookup) + # subtable + subtable = AlternateSubst() + subtable.Format = 1 + subtable.LookupType = 3 + subtable.alternates = { + "%s.default" % tag: ["%s.fail" % tag, "%s.fail" % tag, "%s.fail" % tag], + "%s.alt1" % tag: ["%s.pass" % tag, "%s.fail" % tag, "%s.fail" % tag], + "%s.alt2" % tag: ["%s.fail" % tag, "%s.pass" % tag, "%s.fail" % tag], + "%s.alt3" % tag: ["%s.fail" % tag, "%s.fail" % tag, "%s.pass" % tag], + } + lookup.SubTable.append(subtable) + + path = outputPath % 3 + ".otf" + if os.path.exists(path): + os.remove(path) + shell.save(path) + + # get rid of the shell + if os.path.exists(shellTempPath): + os.remove(shellTempPath) + + +def makeJavascriptData(): + features = sorted(mapping) + outStr = [] + + outStr.append("") + outStr.append("/* This file is autogenerated by makegsubfonts.py */") + outStr.append("") + outStr.append("/* ") + outStr.append(" Features defined in gsubtest fonts with associated base") + outStr.append(" codepoints for each feature:") + outStr.append("") + outStr.append(" cp = codepoint for feature featX") + outStr.append("") + outStr.append(" cp default PASS") + outStr.append(" cp featX=1 FAIL") + outStr.append(" cp featX=2 FAIL") + outStr.append("") + outStr.append(" cp+1 default FAIL") + outStr.append(" cp+1 featX=1 PASS") + outStr.append(" cp+1 featX=2 FAIL") + outStr.append("") + outStr.append(" cp+2 default FAIL") + outStr.append(" cp+2 featX=1 FAIL") + outStr.append(" cp+2 featX=2 PASS") + outStr.append("") + outStr.append("*/") + outStr.append("") + outStr.append("var gFeatures = {") + cp = baseCodepoint + + taglist = [] + for tag in features: + taglist.append('"%s": 0x%x' % (tag, cp)) + cp += 4 + + outStr.append( + textwrap.fill(", ".join(taglist), initial_indent=" ", subsequent_indent=" ") + ) + outStr.append("};") + outStr.append("") + + if os.path.exists(javascriptData): + os.remove(javascriptData) + + f = open(javascriptData, "wb") + f.write("\n".join(outStr)) + f.close() + + +# build fonts + +print("Making lookup type 1 font...") +makeLookup1() + +print("Making lookup type 3 font...") +makeLookup3() + +# output javascript data + +print("Making javascript data file...") +makeJavascriptData() -- cgit v1.2.3