[feaLib] Add unit test with spec section 5.f.ii, example 4

This is another test case for the `ignore sub` statement.
After the recent changes to feaLib, the output is now identical
to the output generated by makeotf.

https://github.com/behdad/fonttools/issues/503
This commit is contained in:
Sascha Brawer 2016-02-05 15:55:53 +01:00
parent ec9077a566
commit 4a23f8eb85
3 changed files with 334 additions and 22 deletions

View File

@ -15,27 +15,31 @@ import unittest
def makeTTFont():
glyphs = (
".notdef space slash fraction semicolon period comma ampersand "
"quotedblleft quotedblright quoteleft quoteright "
"zero one two three four five six seven eight nine "
"zero.oldstyle one.oldstyle two.oldstyle three.oldstyle "
"four.oldstyle five.oldstyle six.oldstyle seven.oldstyle "
"eight.oldstyle nine.oldstyle onequarter onehalf threequarters "
"onesuperior twosuperior threesuperior ordfeminine ordmasculine "
"A B C D E F G H I J K L M N O P Q R S T U V W X Y Z "
"a b c d e f g h i j k l m n o p q r s t u v w x y z "
"A.sc B.sc C.sc D.sc E.sc F.sc G.sc H.sc I.sc J.sc K.sc L.sc M.sc "
"N.sc O.sc P.sc Q.sc R.sc S.sc T.sc U.sc V.sc W.sc X.sc Y.sc Z.sc "
"A.alt1 A.alt2 A.alt3 B.alt1 B.alt2 B.alt3 C.alt1 C.alt2 C.alt3 "
"a.alt1 a.alt2 a.alt3 b.alt c.mid d.alt d.mid e.begin e.mid "
"n.end s.end Eng Eng.alt1 Eng.alt2 Eng.alt3 "
"G.swash H.swash "
"f_l c_h c_k c_s c_t f_f f_f_i f_f_l f_i o_f_f_i s_t f_i.begin "
"a_n_d ydieresis yacute breve "
"grave acute dieresis macron circumflex cedilla umlaut ogonek caron "
"damma hamza sukun kasratan lam_meem_jeem noon.final noon.initial "
).split()
glyphs = """
.notdef space slash fraction semicolon period comma ampersand
quotedblleft quotedblright quoteleft quoteright
zero one two three four five six seven eight nine
zero.oldstyle one.oldstyle two.oldstyle three.oldstyle
four.oldstyle five.oldstyle six.oldstyle seven.oldstyle
eight.oldstyle nine.oldstyle onequarter onehalf threequarters
onesuperior twosuperior threesuperior ordfeminine ordmasculine
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
a b c d e f g h i j k l m n o p q r s t u v w x y z
A.sc B.sc C.sc D.sc E.sc F.sc G.sc H.sc I.sc J.sc K.sc L.sc M.sc
N.sc O.sc P.sc Q.sc R.sc S.sc T.sc U.sc V.sc W.sc X.sc Y.sc Z.sc
A.alt1 A.alt2 A.alt3 B.alt1 B.alt2 B.alt3 C.alt1 C.alt2 C.alt3
a.alt1 a.alt2 a.alt3 a.end b.alt c.mid d.alt d.mid
e.begin e.mid e.end m.begin n.end s.end z.end
Eng Eng.alt1 Eng.alt2 Eng.alt3
A.swash B.swash C.swash D.swash E.swash F.swash G.swash H.swash
I.swash J.swash K.swash L.swash M.swash N.swash O.swash P.swash
Q.swash R.swash S.swash T.swash U.swash V.swash W.swash X.swash
Y.swash Z.swash
f_l c_h c_k c_s c_t f_f f_f_i f_f_l f_i o_f_f_i s_t f_i.begin
a_n_d T_h T_h.swash ydieresis yacute breve
grave acute dieresis macron circumflex cedilla umlaut ogonek caron
damma hamza sukun kasratan lam_meem_jeem noon.final noon.initial
""".split()
font = TTFont()
font.setGlyphOrder(glyphs)
return font
@ -50,7 +54,7 @@ class BuilderTest(unittest.TestCase):
GPOS_1 GPOS_1_zero GPOS_2 GPOS_2b GPOS_3 GPOS_4 GPOS_5 GPOS_6 GPOS_8
GSUB_2 GSUB_3 GSUB_6 GSUB_8
spec4h1 spec5d1 spec5d2 spec5fi1 spec5fi2 spec5fi3 spec5fi4
spec5f_ii_1 spec5f_ii_2 spec5f_ii_3
spec5f_ii_1 spec5f_ii_2 spec5f_ii_3 spec5f_ii_4
spec5h1 spec6b_ii spec6d2 spec6e spec6f spec6h_ii spec6h_iii_1 spec8a
spec9b spec9c1 spec9c2 spec9c3
bug463 bug501 bug502 bug505 bug506 bug509 bug512

View File

@ -0,0 +1,23 @@
# OpenType Feature File specification, section 5.f.ii, example 4
# "Specifying exceptions to the Chain Sub rule"
# http://www.adobe.com/devnet/opentype/afdko/topic_feature_file_syntax.html
@LETTER = [A-Z a-z];
feature cswh {
# --- Glyph classes used in this feature:
@BEGINNINGS = [A-N P-Z T_h m];
@BEGINNINGS_SWASH = [A.swash-N.swash P.swash-Z.swash T_h.swash m.begin];
@ENDINGS = [a e z];
@ENDINGS_SWASH = [a.end e.end z.end];
# --- Beginning-of-word swashes:
ignore substitute @LETTER @BEGINNINGS';
substitute @BEGINNINGS' by @BEGINNINGS_SWASH;
# --- End-of-word swashes:
ignore substitute @ENDINGS' @LETTER;
substitute @ENDINGS' by @ENDINGS_SWASH;
} cswh;

View File

@ -0,0 +1,285 @@
<?xml version="1.0" encoding="UTF-8"?>
<ttFont sfntVersion="true" ttLibVersion="3.0">
<GSUB>
<Version value="1.0"/>
<ScriptList>
<!-- ScriptCount=1 -->
<ScriptRecord index="0">
<ScriptTag value="DFLT"/>
<Script>
<DefaultLangSys>
<ReqFeatureIndex value="65535"/>
<!-- FeatureCount=1 -->
<FeatureIndex index="0" value="0"/>
</DefaultLangSys>
<!-- LangSysCount=0 -->
</Script>
</ScriptRecord>
</ScriptList>
<FeatureList>
<!-- FeatureCount=1 -->
<FeatureRecord index="0">
<FeatureTag value="cswh"/>
<Feature>
<!-- LookupCount=1 -->
<LookupListIndex index="0" value="0"/>
</Feature>
</FeatureRecord>
</FeatureList>
<LookupList>
<!-- LookupCount=2 -->
<Lookup index="0">
<!-- LookupType=6 -->
<LookupFlag value="0"/>
<!-- SubTableCount=4 -->
<ChainContextSubst index="0" Format="3">
<!-- BacktrackGlyphCount=1 -->
<BacktrackCoverage index="0">
<Glyph value="A"/>
<Glyph value="B"/>
<Glyph value="C"/>
<Glyph value="D"/>
<Glyph value="E"/>
<Glyph value="F"/>
<Glyph value="G"/>
<Glyph value="H"/>
<Glyph value="I"/>
<Glyph value="J"/>
<Glyph value="K"/>
<Glyph value="L"/>
<Glyph value="M"/>
<Glyph value="N"/>
<Glyph value="O"/>
<Glyph value="P"/>
<Glyph value="Q"/>
<Glyph value="R"/>
<Glyph value="S"/>
<Glyph value="T"/>
<Glyph value="U"/>
<Glyph value="V"/>
<Glyph value="W"/>
<Glyph value="X"/>
<Glyph value="Y"/>
<Glyph value="Z"/>
<Glyph value="a"/>
<Glyph value="b"/>
<Glyph value="c"/>
<Glyph value="d"/>
<Glyph value="e"/>
<Glyph value="f"/>
<Glyph value="g"/>
<Glyph value="h"/>
<Glyph value="i"/>
<Glyph value="j"/>
<Glyph value="k"/>
<Glyph value="l"/>
<Glyph value="m"/>
<Glyph value="n"/>
<Glyph value="o"/>
<Glyph value="p"/>
<Glyph value="q"/>
<Glyph value="r"/>
<Glyph value="s"/>
<Glyph value="t"/>
<Glyph value="u"/>
<Glyph value="v"/>
<Glyph value="w"/>
<Glyph value="x"/>
<Glyph value="y"/>
<Glyph value="z"/>
</BacktrackCoverage>
<!-- InputGlyphCount=1 -->
<InputCoverage index="0">
<Glyph value="A"/>
<Glyph value="B"/>
<Glyph value="C"/>
<Glyph value="D"/>
<Glyph value="E"/>
<Glyph value="F"/>
<Glyph value="G"/>
<Glyph value="H"/>
<Glyph value="I"/>
<Glyph value="J"/>
<Glyph value="K"/>
<Glyph value="L"/>
<Glyph value="M"/>
<Glyph value="N"/>
<Glyph value="P"/>
<Glyph value="Q"/>
<Glyph value="R"/>
<Glyph value="S"/>
<Glyph value="T"/>
<Glyph value="U"/>
<Glyph value="V"/>
<Glyph value="W"/>
<Glyph value="X"/>
<Glyph value="Y"/>
<Glyph value="Z"/>
<Glyph value="m"/>
<Glyph value="T_h"/>
</InputCoverage>
<!-- LookAheadGlyphCount=0 -->
<!-- SubstCount=0 -->
</ChainContextSubst>
<ChainContextSubst index="1" Format="3">
<!-- BacktrackGlyphCount=0 -->
<!-- InputGlyphCount=1 -->
<InputCoverage index="0">
<Glyph value="A"/>
<Glyph value="B"/>
<Glyph value="C"/>
<Glyph value="D"/>
<Glyph value="E"/>
<Glyph value="F"/>
<Glyph value="G"/>
<Glyph value="H"/>
<Glyph value="I"/>
<Glyph value="J"/>
<Glyph value="K"/>
<Glyph value="L"/>
<Glyph value="M"/>
<Glyph value="N"/>
<Glyph value="P"/>
<Glyph value="Q"/>
<Glyph value="R"/>
<Glyph value="S"/>
<Glyph value="T"/>
<Glyph value="U"/>
<Glyph value="V"/>
<Glyph value="W"/>
<Glyph value="X"/>
<Glyph value="Y"/>
<Glyph value="Z"/>
<Glyph value="m"/>
<Glyph value="T_h"/>
</InputCoverage>
<!-- LookAheadGlyphCount=0 -->
<!-- SubstCount=1 -->
<SubstLookupRecord index="0">
<SequenceIndex value="0"/>
<LookupListIndex value="1"/>
</SubstLookupRecord>
</ChainContextSubst>
<ChainContextSubst index="2" Format="3">
<!-- BacktrackGlyphCount=0 -->
<!-- InputGlyphCount=1 -->
<InputCoverage index="0">
<Glyph value="a"/>
<Glyph value="e"/>
<Glyph value="z"/>
</InputCoverage>
<!-- LookAheadGlyphCount=1 -->
<LookAheadCoverage index="0">
<Glyph value="A"/>
<Glyph value="B"/>
<Glyph value="C"/>
<Glyph value="D"/>
<Glyph value="E"/>
<Glyph value="F"/>
<Glyph value="G"/>
<Glyph value="H"/>
<Glyph value="I"/>
<Glyph value="J"/>
<Glyph value="K"/>
<Glyph value="L"/>
<Glyph value="M"/>
<Glyph value="N"/>
<Glyph value="O"/>
<Glyph value="P"/>
<Glyph value="Q"/>
<Glyph value="R"/>
<Glyph value="S"/>
<Glyph value="T"/>
<Glyph value="U"/>
<Glyph value="V"/>
<Glyph value="W"/>
<Glyph value="X"/>
<Glyph value="Y"/>
<Glyph value="Z"/>
<Glyph value="a"/>
<Glyph value="b"/>
<Glyph value="c"/>
<Glyph value="d"/>
<Glyph value="e"/>
<Glyph value="f"/>
<Glyph value="g"/>
<Glyph value="h"/>
<Glyph value="i"/>
<Glyph value="j"/>
<Glyph value="k"/>
<Glyph value="l"/>
<Glyph value="m"/>
<Glyph value="n"/>
<Glyph value="o"/>
<Glyph value="p"/>
<Glyph value="q"/>
<Glyph value="r"/>
<Glyph value="s"/>
<Glyph value="t"/>
<Glyph value="u"/>
<Glyph value="v"/>
<Glyph value="w"/>
<Glyph value="x"/>
<Glyph value="y"/>
<Glyph value="z"/>
</LookAheadCoverage>
<!-- SubstCount=0 -->
</ChainContextSubst>
<ChainContextSubst index="3" Format="3">
<!-- BacktrackGlyphCount=0 -->
<!-- InputGlyphCount=1 -->
<InputCoverage index="0">
<Glyph value="a"/>
<Glyph value="e"/>
<Glyph value="z"/>
</InputCoverage>
<!-- LookAheadGlyphCount=0 -->
<!-- SubstCount=1 -->
<SubstLookupRecord index="0">
<SequenceIndex value="0"/>
<LookupListIndex value="1"/>
</SubstLookupRecord>
</ChainContextSubst>
</Lookup>
<Lookup index="1">
<!-- LookupType=1 -->
<LookupFlag value="0"/>
<!-- SubTableCount=1 -->
<SingleSubst index="0">
<Substitution in="A" out="A.swash"/>
<Substitution in="B" out="B.swash"/>
<Substitution in="C" out="C.swash"/>
<Substitution in="D" out="D.swash"/>
<Substitution in="E" out="E.swash"/>
<Substitution in="F" out="F.swash"/>
<Substitution in="G" out="G.swash"/>
<Substitution in="H" out="H.swash"/>
<Substitution in="I" out="I.swash"/>
<Substitution in="J" out="J.swash"/>
<Substitution in="K" out="K.swash"/>
<Substitution in="L" out="L.swash"/>
<Substitution in="M" out="M.swash"/>
<Substitution in="N" out="N.swash"/>
<Substitution in="P" out="P.swash"/>
<Substitution in="Q" out="Q.swash"/>
<Substitution in="R" out="R.swash"/>
<Substitution in="S" out="S.swash"/>
<Substitution in="T" out="T.swash"/>
<Substitution in="T_h" out="T_h.swash"/>
<Substitution in="U" out="U.swash"/>
<Substitution in="V" out="V.swash"/>
<Substitution in="W" out="W.swash"/>
<Substitution in="X" out="X.swash"/>
<Substitution in="Y" out="Y.swash"/>
<Substitution in="Z" out="Z.swash"/>
<Substitution in="a" out="a.end"/>
<Substitution in="e" out="e.end"/>
<Substitution in="m" out="m.begin"/>
<Substitution in="z" out="z.end"/>
</SingleSubst>
</Lookup>
</LookupList>
</GSUB>
</ttFont>