summaryrefslogtreecommitdiffstats
path: root/layout/reftests/fonts/gsubtest
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--layout/reftests/fonts/gsubtest/gsubtest-features.js105
-rw-r--r--layout/reftests/fonts/gsubtest/gsubtest-features.txt328
-rw-r--r--layout/reftests/fonts/gsubtest/gsubtest-lookup1.otfbin0 -> 158316 bytes
-rw-r--r--layout/reftests/fonts/gsubtest/gsubtest-lookup3.otfbin0 -> 383716 bytes
-rw-r--r--layout/reftests/fonts/gsubtest/gsubtest-shell.ttx304
-rw-r--r--layout/reftests/fonts/gsubtest/makegsubfonts.py515
6 files changed, 1252 insertions, 0 deletions
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
--- /dev/null
+++ b/layout/reftests/fonts/gsubtest/gsubtest-lookup1.otf
Binary files 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
--- /dev/null
+++ b/layout/reftests/fonts/gsubtest/gsubtest-lookup3.otf
Binary files 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 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<ttFont sfntVersion="OTTO" ttLibVersion="2.2">
+
+ <GlyphOrder>
+ <!-- The 'id' attribute is only for humans; it is ignored when parsed. -->
+ <GlyphID id="0" name=".notdef"/>
+ <GlyphID id="1" name="space"/>
+ <GlyphID id="2" name="F"/>
+ <GlyphID id="3" name="P"/>
+ </GlyphOrder>
+
+ <head>
+ <!-- Most of this table will be recalculated by the compiler -->
+ <tableVersion value="1.0"/>
+ <fontRevision value="1.0"/>
+ <checkSumAdjustment value="0xae4c554b"/>
+ <magicNumber value="0x5f0f3cf5"/>
+ <flags value="00000000 00000011"/>
+ <unitsPerEm value="1000"/>
+ <created value="Tue Mar 22 13:46:27 2011"/>
+ <modified value="Tue Mar 22 13:46:27 2011"/>
+ <xMin value="100"/>
+ <yMin value="-10"/>
+ <xMax value="2204"/>
+ <yMax value="710"/>
+ <macStyle value="00000000 00000000"/>
+ <lowestRecPPEM value="3"/>
+ <fontDirectionHint value="2"/>
+ <indexToLocFormat value="0"/>
+ <glyphDataFormat value="0"/>
+ </head>
+
+ <hhea>
+ <tableVersion value="1.0"/>
+ <ascent value="750"/>
+ <descent value="-250"/>
+ <lineGap value="9"/>
+ <advanceWidthMax value="2304"/>
+ <minLeftSideBearing value="100"/>
+ <minRightSideBearing value="100"/>
+ <xMaxExtent value="2204"/>
+ <caretSlopeRise value="1"/>
+ <caretSlopeRun value="0"/>
+ <caretOffset value="0"/>
+ <reserved0 value="0"/>
+ <reserved1 value="0"/>
+ <reserved2 value="0"/>
+ <reserved3 value="0"/>
+ <metricDataFormat value="0"/>
+ <numberOfHMetrics value="4"/>
+ </hhea>
+
+ <maxp>
+ <tableVersion value="0x5000"/>
+ <numGlyphs value="4"/>
+ </maxp>
+
+ <OS_2>
+ <version value="4"/>
+ <xAvgCharWidth value="1525"/>
+ <usWeightClass value="400"/>
+ <usWidthClass value="5"/>
+ <fsType value="00000000 00000000"/>
+ <ySubscriptXSize value="650"/>
+ <ySubscriptYSize value="600"/>
+ <ySubscriptXOffset value="0"/>
+ <ySubscriptYOffset value="75"/>
+ <ySuperscriptXSize value="650"/>
+ <ySuperscriptYSize value="600"/>
+ <ySuperscriptXOffset value="0"/>
+ <ySuperscriptYOffset value="350"/>
+ <yStrikeoutSize value="50"/>
+ <yStrikeoutPosition value="300"/>
+ <sFamilyClass value="0"/>
+ <panose>
+ <bFamilyType value="0"/>
+ <bSerifStyle value="0"/>
+ <bWeight value="0"/>
+ <bProportion value="0"/>
+ <bContrast value="0"/>
+ <bStrokeVariation value="0"/>
+ <bArmStyle value="0"/>
+ <bLetterForm value="0"/>
+ <bMidline value="0"/>
+ <bXHeight value="0"/>
+ </panose>
+ <ulUnicodeRange1 value="00000000 00000000 00000000 00000001"/>
+ <ulUnicodeRange2 value="00000000 00000000 00000000 00000000"/>
+ <ulUnicodeRange3 value="00000000 00000000 00000000 00000000"/>
+ <ulUnicodeRange4 value="00000000 00000000 00000000 00000000"/>
+ <achVendID value="None"/>
+ <fsSelection value="00000001 11000000"/>
+ <fsFirstCharIndex value="32"/>
+ <fsLastCharIndex value="80"/>
+ <sTypoAscender value="750"/>
+ <sTypoDescender value="-250"/>
+ <sTypoLineGap value="0"/>
+ <usWinAscent value="1000"/>
+ <usWinDescent value="0"/>
+ <ulCodePageRange1 value="00100000 00000000 00000000 00000001"/>
+ <ulCodePageRange2 value="00000000 00000000 00000000 00000000"/>
+ <sxHeight value="500"/>
+ <sCapHeight value="750"/>
+ <usDefaultChar value="0"/>
+ <usBreakChar value="32"/>
+ <usMaxContex value="0"/>
+ </OS_2>
+
+ <name>
+ <namerecord nameID="1" platformID="1" platEncID="0" langID="0x0">
+ __familyName__
+ </namerecord>
+ <namerecord nameID="2" platformID="1" platEncID="0" langID="0x0">
+ Regular
+ </namerecord>
+ <namerecord nameID="3" platformID="1" platEncID="0" langID="0x0">
+ 1.000;TPSP;__familyName__-Regular
+ </namerecord>
+ <namerecord nameID="4" platformID="1" platEncID="0" langID="0x0">
+ __familyName__
+ </namerecord>
+ <namerecord nameID="5" platformID="1" platEncID="0" langID="0x0">
+ Version 1.000
+ </namerecord>
+ <namerecord nameID="6" platformID="1" platEncID="0" langID="0x0">
+ __familyName__-Regular
+ </namerecord>
+ <namerecord nameID="9" platformID="3" platEncID="0" langID="0x0">
+ Tal Leming with modifications by John Daggett
+ </namerecord>
+ <namerecord nameID="14" platformID="3" platEncID="0" langID="0x0">
+ http://scripts.sil.org/OFL
+ </namerecord>
+ <namerecord nameID="1" platformID="3" platEncID="1" langID="0x409">
+ __familyName__
+ </namerecord>
+ <namerecord nameID="2" platformID="3" platEncID="1" langID="0x409">
+ Regular
+ </namerecord>
+ <namerecord nameID="3" platformID="3" platEncID="1" langID="0x409">
+ 1.000;TPSP;__familyName__-Regular
+ </namerecord>
+ <namerecord nameID="4" platformID="3" platEncID="1" langID="0x409">
+ __familyName__
+ </namerecord>
+ <namerecord nameID="5" platformID="3" platEncID="1" langID="0x409">
+ Version 1.000
+ </namerecord>
+ <namerecord nameID="6" platformID="3" platEncID="1" langID="0x409">
+ __familyName__-Regular
+ </namerecord>
+ <namerecord nameID="9" platformID="3" platEncID="1" langID="0x409">
+ Tal Leming with modifications by John Daggett
+ </namerecord>
+ <namerecord nameID="14" platformID="3" platEncID="1" langID="0x409">
+ http://scripts.sil.org/OFL
+ </namerecord>
+ </name>
+
+ <cmap>
+ <tableVersion version="0"/>
+ <cmap_format_4 platformID="0" platEncID="3" language="0">
+ <map code="0x20" name="space"/><!-- SPACE -->
+ <map code="0x46" name="F"/><!-- LATIN CAPITAL LETTER F -->
+ <map code="0x50" name="P"/><!-- LATIN CAPITAL LETTER P -->
+ </cmap_format_4>
+ <cmap_format_4 platformID="3" platEncID="1" language="0">
+ <map code="0x20" name="space"/><!-- SPACE -->
+ <map code="0x46" name="F"/><!-- LATIN CAPITAL LETTER F -->
+ <map code="0x50" name="P"/><!-- LATIN CAPITAL LETTER P -->
+ </cmap_format_4>
+ </cmap>
+
+ <post>
+ <formatType value="3.0"/>
+ <italicAngle value="0.0"/>
+ <underlinePosition value="-75"/>
+ <underlineThickness value="50"/>
+ <isFixedPitch value="0"/>
+ <minMemType42 value="0"/>
+ <maxMemType42 value="0"/>
+ <minMemType1 value="0"/>
+ <maxMemType1 value="0"/>
+ </post>
+
+ <CFF>
+
+ <CFFFont name="__familyName__-Regular">
+ <version value="001.000"/>
+ <FullName value="__familyName__"/>
+ <FamilyName value="__familyName__"/>
+ <Weight value="Normal"/>
+ <isFixedPitch value="0"/>
+ <ItalicAngle value="0"/>
+ <UnderlineThickness value="50"/>
+ <PaintType value="0"/>
+ <CharstringType value="2"/>
+ <FontMatrix value="0.001 0 0 0.001 0 0"/>
+ <FontBBox value="100 0 2204 750"/>
+ <StrokeWidth value="0"/>
+ <!-- charset is dumped separately as the 'GlyphOrder' element -->
+ <Encoding name="StandardEncoding"/>
+ <Private>
+ <BlueValues value="0 0"/>
+ <BlueScale value="0.039625"/>
+ <BlueShift value="7"/>
+ <BlueFuzz value="1"/>
+ <ForceBold value="0"/>
+ <LanguageGroup value="0"/>
+ <ExpansionFactor value="0.06"/>
+ <initialRandomSeed value="0"/>
+ <defaultWidthX value="750"/>
+ <nominalWidthX value="2406"/>
+ </Private>
+ <CharStrings>
+ <CharString name=".notdef">
+ endchar
+ </CharString>
+ <CharString name="F">
+ -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
+ </CharString>
+ <CharString name="P">
+ -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
+ </CharString>
+ <CharString name="space">
+ endchar
+ </CharString>
+ </CharStrings>
+ </CFFFont>
+
+ <GlobalSubrs>
+ <!-- The 'index' attribute is only for humans; it is ignored when parsed. -->
+ </GlobalSubrs>
+
+ </CFF>
+
+ <hmtx>
+ <mtx name=".notdef" width="750" lsb="0"/>
+ <mtx name="F" width="2304" lsb="100"/>
+ <mtx name="P" width="2299" lsb="100"/>
+ <mtx name="space" width="750" lsb="0"/>
+ </hmtx>
+
+</ttFont>
diff --git a/layout/reftests/fonts/gsubtest/makegsubfonts.py b/layout/reftests/fonts/gsubtest/makegsubfonts.py
new file mode 100644
index 0000000000..8cd6476d97
--- /dev/null
+++ b/layout/reftests/fonts/gsubtest/makegsubfonts.py
@@ -0,0 +1,515 @@
+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()