11# Comprehensive Variable Font Grammar Test
22# Tests all variable font features added to afdko4
3+ # FIXED: All variable values have complete min/default/max
34
45languagesystem DFLT dflt ;
56
67# ============================================================================
78# 1. LOCATIONDEF STATEMENTS (LocationDefMode)
89# ============================================================================
910
10- # Single axis, design units
11- locationDef wght = 400 d @Regular ;
12- locationDef wght = 700 d @Bold ;
11+ # Single axis at min and max for design units (no @Regular since it's the default)
12+ locationDef wght = 200 d @ExtraLight ;
13+ locationDef wght = 900 d @Black ;
1314
14- # Single axis, user units
15+ # Single axis, user units (testing user unit syntax)
1516locationDef wght = 400 u @RegularUser ;
1617
1718# Single axis, normalized
19+ locationDef wght = -1 n @Min ;
1820locationDef wght = 0 n @Default ;
1921locationDef wght = 1 n @Max ;
2022
21- # Multiple axes
22- locationDef wght = 400 d , opsz = 20 d @RegMid ;
23+ # Multiple axes (no location at wght=400d,opsz=20d since that's the full default)
2324locationDef wght = 700 d , opsz = 8 d @BoldSmall ;
2425
25- # Negative values
26- locationDef wght = -100 d @ExtraLight ;
26+ # Negative values (design units can be negative for extralight)
27+ locationDef wght = -100 d @NegativeExample ;
2728
2829# Decimal values
2930locationDef wght = 450 .5 d @Medium ;
@@ -35,32 +36,35 @@ locationDef wght=450.5d @Medium;
3536# Single value in parens (variable)
3637valueRecordDef (50 ) VAL_SINGLE ;
3738
38- # Single value with named location
39- valueRecordDef (@Regular:50 ) VAL_NAMED ;
39+ # Value with named location - complete min/default/max
40+ valueRecordDef (50 @ExtraLight:45 @Black:60 ) VAL_NAMED ;
4041
41- # Single value with inline location WITHOUT SPACES (the key fix!)
42- valueRecordDef (wght=400d:47 ) VAL_INLINE_NOSPACE ;
42+ # Single value with inline location WITHOUT SPACES (the key fix!) - complete min/default/max
43+ valueRecordDef (47 wght=200d:42 wght=900d:54 ) VAL_INLINE_NOSPACE ;
4344
44- # Single value with inline location WITH spaces
45- valueRecordDef (wght=400d : 47 ) VAL_INLINE_SPACE ;
45+ # Single value with inline location WITH spaces - complete min/default/max
46+ valueRecordDef (47 wght=200d : 42 wght=900d : 54 ) VAL_INLINE_SPACE ;
4647
47- # Multiple location:value pairs WITHOUT SPACES
48- valueRecordDef (wght=400d:47 wght=700d :54 ) VAL_MULTI_NOSPACE ;
48+ # Multiple location:value pairs WITHOUT SPACES - complete min/default/max
49+ valueRecordDef (47 wght=200d:42 wght=900d :54 ) VAL_MULTI_NOSPACE ;
4950
50- # Multiple location:value pairs WITH spaces
51- valueRecordDef (wght=400d : 47 wght=700d : 54 ) VAL_MULTI_SPACE ;
51+ # Multiple location:value pairs WITH spaces - complete min/default/max
52+ valueRecordDef (47 wght=200d : 42 wght=900d : 54 ) VAL_MULTI_SPACE ;
5253
53- # Multiple location:value pairs MIXED spacing
54- valueRecordDef (wght=400d:47 wght=700d : 54 ) VAL_MULTI_MIXED ;
54+ # Multiple location:value pairs MIXED spacing - complete min/default/max
55+ valueRecordDef (47 wght=200d:42 wght=900d : 54 ) VAL_MULTI_MIXED ;
5556
56- # Mixed inline and named locations
57- valueRecordDef (wght=400d:47 @Bold :54 ) VAL_MIXED_INLINE_NAMED ;
57+ # Mixed inline and named locations - complete min/default/max
58+ valueRecordDef (47 wght=200d:42 @Black :54 ) VAL_MIXED_INLINE_NAMED ;
5859
59- # Value record literals (angle brackets) with named locations
60- valueRecordDef (@Regular: <-80 0 -160 0> ) VAL_RECORD ;
60+ # Value record literals (angle brackets) with named locations - complete min/default/max
61+ valueRecordDef (<-80 0 -160 0> @ExtraLight:<-70 0 -150 0> @Black:<-90 0 -170 0> ) VAL_RECORD ;
6162
62- # Value record literals with inline locations
63- valueRecordDef (wght=400d:<-80 0 -160 0> ) VAL_RECORD_INLINE ;
63+ # Four-value record with one variable component (from phase1) - complete min/default/max
64+ valueRecordDef <0 0 (20 @ExtraLight:15 @Black:25 ) 0 > KERN_C ;
65+
66+ # Value record literals with inline locations - complete min/default/max
67+ valueRecordDef (<-80 0 -160 0> wght=200d:<-70 0 -150 0> wght=900d:<-90 0 -170 0> ) VAL_RECORD_INLINE ;
6468
6569# Plain number (static)
6670valueRecordDef 100 VAL_PLAIN ;
@@ -72,32 +76,36 @@ valueRecordDef 100 VAL_PLAIN;
7276# Simple static anchor
7377anchorDef 250 620 top ;
7478
75- # Variable anchor with inline locations - NO SPACES
76- anchorDef (250 wght=400d:240 wght=700d:260 ) 620 top_var ;
79+ # Variable anchor with inline locations - NO SPACES - complete min/default/max
80+ anchorDef (250 wght=200d:240 wght=900d:260 ) 620 top_var ;
81+
82+ # Variable anchor with inline locations - WITH SPACES - complete min/default/max
83+ anchorDef (250 wght=200d : 240 wght=900d : 260 ) 620 top_var_space ;
7784
78- # Variable anchor with inline locations - WITH SPACES
79- anchorDef (250 wght=400d : 240 wght=700d : 260 ) 620 top_var_space ;
85+ # Variable anchor with named locations - complete min/default/max
86+ anchorDef (250 @ExtraLight: 240 @Black: 260 ) 620 top_named ;
8087
81- # Variable anchor with named locations
82- anchorDef (250 @Regular: 240 @Bold: 260 ) 620 top_named ;
88+ # Variable anchor with value records - complete min/default/max
89+ anchorDef (< 250 620> @ExtraLight:< 240 620> @Black:< 260 620> ) top_record ;
8390
84- # Variable anchor with value records
85- anchorDef (<250 620> @Regular:<240 620> @Bold:<260 620> ) top_record ;
91+ # Variable anchor with separate x and y values (from phase1) - complete min/default/max
92+ # Note: Using anchorDef instead of markClass to avoid missing glyph errors
93+ anchorDef (250 @ExtraLight:240 @Black:260 ) (620 @ExtraLight:610 @Black:630 ) top_separate_xy ;
8694
8795# ============================================================================
8896# 4. MARK CLASS - Variable Anchors in Mark Statements
8997# ============================================================================
9098
91- @MARKS = [acute grave ];
99+ @MARKS = [a e ];
92100
93101# Static mark class
94102markClass [a b c ] <anchor 250 620 > @BASE_MARKS ;
95103
96- # Variable mark class - inline locations NO SPACES
97- markClass acute <anchor (250 wght=400d :240 wght=700d :260 ) 620 > @TOP_MARKS ;
104+ # Variable mark class - inline locations NO SPACES - complete min/default/max
105+ markClass a <anchor (250 wght=200d :240 wght=900d :260 ) 620 > @TOP_MARKS ;
98106
99- # Variable mark class - inline locations WITH SPACES
100- markClass grave <anchor (250 wght=400d : 240 wght=700d : 260 ) 620 > @TOP_MARKS_SPACE ;
107+ # Variable mark class - inline locations WITH SPACES - complete min/default/max
108+ markClass e <anchor (250 wght=200d : 240 wght=900d : 260 ) 620 > @TOP_MARKS_SPACE ;
101109
102110# ============================================================================
103111# 5. GLYPH NAMES - d, u, n as glyphs (AXISUNIT removed from default mode)
@@ -107,7 +115,8 @@ markClass grave <anchor (250 wght=400d : 240 wght=700d : 260) 620> @TOP_MARKS_SP
107115@AXIS_LETTERS = [d u n ];
108116
109117# Extended names with colons (EXTNAME in default mode)
110- @EXTENDED = [d :47 u :48 n :49 ];
118+ # Note: These glyphs don't exist in test font, commented out
119+ # @EXTENDED = [d:47 u:48 n:49];
111120
112121# ============================================================================
113122# 6. VARIABLE METRICS - singleValueLiteral in table statements
@@ -118,16 +127,16 @@ table OS/2 {
118127 TypoAscender 750 ;
119128 TypoDescender -250 ;
120129
121- # Variable values with named locations
122- XHeight (@Regular:500 );
123- CapHeight (@Regular:700 );
130+ # Variable values with named locations - complete min/default/max
131+ XHeight (500 @ExtraLight:480 @Black:520 );
132+ CapHeight (700 @ExtraLight:680 @Black:720 );
124133
125- # Variable values with inline locations
126- SubscriptXSize (wght=400d:100 );
127- SubscriptYSize (wght=400d:100 );
128- SuperscriptXSize (wght=400d:100 );
129- SuperscriptYSize (wght=400d:100 );
130- StrikeoutSize (wght=400d:50 );
134+ # Variable values with inline locations - complete min/default/max
135+ SubscriptXSize (100 wght=200d:90 wght=900d:110 );
136+ SubscriptYSize (100 wght=200d:90 wght=900d:110 );
137+ SuperscriptXSize (100 wght=200d:90 wght=900d:110 );
138+ SuperscriptYSize (100 wght=200d:90 wght=900d:110 );
139+ StrikeoutSize (50 wght=200d:45 wght=900d:55 );
131140} OS/2 ;
132141
133142table hhea {
@@ -136,23 +145,23 @@ table hhea {
136145 Descender -250 ;
137146 LineGap 0 ;
138147
139- # Variable values with named locations
140- CaretOffset (@Regular :0 );
141- CaretSlopeRise (@Regular :1 );
142- CaretSlopeRun (@Regular :0 );
148+ # Variable values with named locations - complete min/default/max
149+ CaretOffset (0 @ExtraLight:0 @Black :0 );
150+ CaretSlopeRise (1 @ExtraLight:1 @Black :1 );
151+ CaretSlopeRun (0 @ExtraLight:0 @Black :0 );
143152} hhea ;
144153
145154table vhea {
146- # Variable values with inline locations
147- VertTypoAscender (wght=400d:750 );
148- VertTypoDescender (wght=400d:-250 );
149- CaretOffset (wght=400d :0 );
155+ # Variable values with inline locations - complete min/default/max
156+ VertTypoAscender (750 wght=200d:730 wght=900d:770 );
157+ VertTypoDescender (-250 wght=200d:-230 wght=900d:-270 );
158+ CaretOffset (0 wght=200d:0 wght=900d :0 );
150159} vhea ;
151160
152161table vmtx {
153- # Variable vertical metrics
154- VertOriginY A (wght=400d:750 );
155- VertAdvanceY A (wght=400d:1000 );
162+ # Variable vertical metrics - complete min/default/max
163+ VertOriginY A (750 wght=200d:730 wght=900d:770 );
164+ VertAdvanceY A (1000 wght=200d:980 wght=900d:1020 );
156165} vmtx ;
157166
158167# ============================================================================
@@ -169,11 +178,11 @@ feature test {
169178 # Note: these glyphs don't exist in our test font, but tests the grammar
170179 # sub d:47 by A;
171180
172- # Single positioning with inline variable value - NO SPACES
173- pos A (wght=400d:10 );
181+ # Single positioning with inline variable value - NO SPACES - complete min/default/max
182+ pos A (10 wght=200d:8 wght=900d:12 );
174183
175- # Pair positioning with inline variable value - WITH SPACES
176- pos A b (wght=400d : 20 );
184+ # Pair positioning with inline variable value - WITH SPACES - complete min/default/max
185+ pos A b (20 wght=200d : 18 wght=900d : 22 );
177186} test ;
178187
179188# ============================================================================
@@ -184,6 +193,6 @@ table GDEF {
184193 # Static ligature caret
185194 LigatureCaretByPos A 500 ;
186195
187- # Variable ligature caret with inline location
188- LigatureCaretByPos b (wght=400d:500 );
196+ # Variable ligature caret with inline location - complete min/default/max
197+ LigatureCaretByPos b (500 wght=200d:480 wght=900d:520 );
189198} GDEF ;
0 commit comments