• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2016  Igalia S.L.
3  *
4  *  This is part of HarfBuzz, a text shaping library.
5  *
6  * Permission is hereby granted, without written agreement and without
7  * license or royalty fees, to use, copy, modify, and distribute this
8  * software and its documentation for any purpose, provided that the
9  * above copyright notice and the following two paragraphs appear in
10  * all copies of this software.
11  *
12  * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
13  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
14  * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
15  * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
16  * DAMAGE.
17  *
18  * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
19  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20  * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
21  * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
22  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
23  *
24  * Igalia Author(s): Frédéric Wang
25  */
26 
27 
28 #include "hb-test.h"
29 
30 #include "hb-ft.h"
31 #include "hb-ot.h"
32 
33 /* Unit tests for hb-ot-math.h - OpenType MATH table  */
34 
35 static FT_Library ft_library;
36 static FT_Face ft_face;
37 static hb_font_t *hb_font;
38 static hb_face_t *hb_face;
39 
40 static inline void
initFreeType(void)41 initFreeType (void)
42 {
43   FT_Error ft_error;
44   if ((ft_error = FT_Init_FreeType (&ft_library)))
45     abort();
46 }
47 
48 static inline void
cleanupFreeType(void)49 cleanupFreeType (void)
50 {
51   FT_Done_FreeType (ft_library);
52 }
53 
54 static void
openFont(const char * fontFile)55 openFont(const char* fontFile)
56 {
57 #if GLIB_CHECK_VERSION(2,37,2)
58   gchar* path = g_test_build_filename(G_TEST_DIST, fontFile, NULL);
59 #else
60   gchar* path = g_strdup(fontFile);
61 #endif
62 
63   FT_Error ft_error;
64   if ((ft_error = FT_New_Face (ft_library, path, 0, &ft_face))) {
65     g_free(path);
66     abort();
67   }
68   g_free(path);
69 
70   if ((ft_error = FT_Set_Char_Size (ft_face, 2000, 1000, 0, 0)))
71     abort();
72   hb_font = hb_ft_font_create (ft_face, NULL);
73   hb_face = hb_face_reference (hb_font_get_face (hb_font));
74 }
75 
76 static inline void
closeFont(void)77 closeFont (void)
78 {
79   hb_face_destroy (hb_face);
80   hb_font_destroy (hb_font);
81   FT_Done_Face (ft_face);
82   hb_face = NULL;
83   hb_font = NULL;
84   ft_face = NULL;
85 }
86 
87 static void
test_has_data(void)88 test_has_data (void)
89 {
90   initFreeType();
91 
92   openFont("fonts/MathTestFontNone.otf");
93   g_assert(!hb_ot_math_has_data (hb_face)); // MATH table not available
94   closeFont();
95 
96   openFont("fonts/MathTestFontEmpty.otf");
97   g_assert(hb_ot_math_has_data (hb_face)); // MATH table available
98   closeFont();
99 
100   hb_face = hb_face_get_empty ();
101   hb_font = hb_font_create (hb_face);
102   g_assert(!hb_ot_math_has_data (hb_face)); // MATH table not available
103   hb_font_destroy (hb_font);
104   hb_face_destroy (hb_face);
105 
106   hb_font = hb_font_get_empty ();
107   hb_face = hb_font_get_face (hb_font);
108   g_assert(!hb_ot_math_has_data (hb_face)); // MATH table not available
109   hb_font_destroy (hb_font);
110   hb_face_destroy (hb_face);
111 
112   cleanupFreeType();
113 }
114 
115 static void
test_get_constant(void)116 test_get_constant (void)
117 {
118   initFreeType();
119 
120   openFont("fonts/MathTestFontEmpty.otf");
121   g_assert_cmpint(hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_DELIMITED_SUB_FORMULA_MIN_HEIGHT), ==, 0); // MathConstants not available
122   closeFont();
123 
124   openFont("fonts/MathTestFontFull.otf");
125   g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_DELIMITED_SUB_FORMULA_MIN_HEIGHT)), ==, 100);
126   g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_DISPLAY_OPERATOR_MIN_HEIGHT)), ==, 200);
127   g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_MATH_LEADING)), ==, 300);
128   g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_AXIS_HEIGHT)), ==, 400);
129   g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_ACCENT_BASE_HEIGHT)), ==, 500);
130   g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_FLATTENED_ACCENT_BASE_HEIGHT)), ==, 600);
131   g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_SUBSCRIPT_SHIFT_DOWN)), ==, 700);
132   g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_SUBSCRIPT_TOP_MAX)), ==, 800);
133   g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_SUBSCRIPT_BASELINE_DROP_MIN)), ==, 900);
134   g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_SUPERSCRIPT_SHIFT_UP)), ==, 1100);
135   g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_SUPERSCRIPT_SHIFT_UP_CRAMPED)), ==, 1200);
136   g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_SUPERSCRIPT_BOTTOM_MIN)), ==, 1300);
137   g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_SUPERSCRIPT_BASELINE_DROP_MAX)), ==, 1400);
138   g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_SUB_SUPERSCRIPT_GAP_MIN)), ==, 1500);
139   g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_SUPERSCRIPT_BOTTOM_MAX_WITH_SUBSCRIPT)), ==, 1600);
140   g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_SPACE_AFTER_SCRIPT)), ==, 3400);
141   g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_UPPER_LIMIT_GAP_MIN)), ==, 1800);
142   g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_UPPER_LIMIT_BASELINE_RISE_MIN)), ==, 1900);
143   g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_LOWER_LIMIT_GAP_MIN)), ==, 2200);
144   g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_LOWER_LIMIT_BASELINE_DROP_MIN)), ==, 2300);
145   g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_STACK_TOP_SHIFT_UP)), ==, 2400);
146   g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_STACK_TOP_DISPLAY_STYLE_SHIFT_UP)), ==, 2500);
147   g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_STACK_BOTTOM_SHIFT_DOWN)), ==, 2600);
148   g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_STACK_BOTTOM_DISPLAY_STYLE_SHIFT_DOWN)), ==, 2700);
149   g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_STACK_GAP_MIN)), ==, 2800);
150   g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_STACK_DISPLAY_STYLE_GAP_MIN)), ==, 2900);
151   g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_STRETCH_STACK_TOP_SHIFT_UP)), ==, 3000);
152   g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_STRETCH_STACK_BOTTOM_SHIFT_DOWN)), ==, 3100);
153   g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_STRETCH_STACK_GAP_ABOVE_MIN)), ==, 3200);
154   g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_STRETCH_STACK_GAP_BELOW_MIN)), ==, 3300);
155   g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_FRACTION_NUMERATOR_SHIFT_UP)), ==, 3400);
156   g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_FRACTION_NUMERATOR_DISPLAY_STYLE_SHIFT_UP)), ==, 3500);
157   g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_FRACTION_DENOMINATOR_SHIFT_DOWN)), ==, 3600);
158   g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_FRACTION_DENOMINATOR_DISPLAY_STYLE_SHIFT_DOWN)), ==, 3700);
159   g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_FRACTION_NUMERATOR_GAP_MIN)), ==, 3800);
160   g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_FRACTION_NUM_DISPLAY_STYLE_GAP_MIN)), ==, 3900);
161   g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_FRACTION_RULE_THICKNESS)), ==, 4000);
162   g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_FRACTION_DENOMINATOR_GAP_MIN)), ==, 4100);
163   g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_FRACTION_DENOM_DISPLAY_STYLE_GAP_MIN)), ==, 4200);
164   g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_SKEWED_FRACTION_HORIZONTAL_GAP)), ==, 8600);
165   g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_SKEWED_FRACTION_VERTICAL_GAP)), ==, 4400);
166   g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_OVERBAR_VERTICAL_GAP)), ==, 4500);
167   g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_OVERBAR_RULE_THICKNESS)), ==, 4600);
168   g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_OVERBAR_EXTRA_ASCENDER)), ==, 4700);
169   g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_UNDERBAR_VERTICAL_GAP)), ==, 4800);
170   g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_UNDERBAR_RULE_THICKNESS)), ==, 4900);
171   g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_UNDERBAR_EXTRA_DESCENDER)), ==, 5000);
172   g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_RADICAL_VERTICAL_GAP)), ==, 5100);
173   g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_RADICAL_DISPLAY_STYLE_VERTICAL_GAP)), ==, 5200);
174   g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_RADICAL_RULE_THICKNESS)), ==, 5300);
175   g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_RADICAL_EXTRA_ASCENDER)), ==, 5400);
176   g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_RADICAL_KERN_BEFORE_DEGREE)), ==, 11000);
177   g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_RADICAL_KERN_AFTER_DEGREE)), ==, 11200);
178   g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_SCRIPT_PERCENT_SCALE_DOWN)), ==, 87);
179   g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_SCRIPT_SCRIPT_PERCENT_SCALE_DOWN)), ==, 76);
180   g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_RADICAL_DEGREE_BOTTOM_RAISE_PERCENT)), ==, 65);
181   closeFont();
182 
183   cleanupFreeType();
184 }
185 
186 static void
test_get_glyph_italics_correction(void)187 test_get_glyph_italics_correction (void)
188 {
189   hb_codepoint_t glyph;
190   initFreeType();
191 
192   openFont("fonts/MathTestFontEmpty.otf");
193   g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph));
194   g_assert_cmpint(hb_ot_math_get_glyph_italics_correction (hb_font, glyph), ==, 0); // MathGlyphInfo not available
195   closeFont();
196 
197   openFont("fonts/MathTestFontPartial1.otf");
198   g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph));
199   g_assert_cmpint(hb_ot_math_get_glyph_italics_correction (hb_font, glyph), ==, 0); // MathGlyphInfo empty
200   closeFont();
201 
202   openFont("fonts/MathTestFontPartial2.otf");
203   g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph));
204   g_assert_cmpint(hb_ot_math_get_glyph_italics_correction (hb_font, glyph), ==, 0); // MathItalicsCorrectionInfo empty
205   closeFont();
206 
207   openFont("fonts/MathTestFontFull.otf");
208   g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph));
209   g_assert_cmpint(hb_ot_math_get_glyph_italics_correction (hb_font, glyph), ==, 0); // Glyph without italic correction.
210   g_assert(hb_font_get_glyph_from_name (hb_font, "A", -1, &glyph));
211   g_assert_cmpint(hb_ot_math_get_glyph_italics_correction (hb_font, glyph), ==, 394);
212   g_assert(hb_font_get_glyph_from_name (hb_font, "B", -1, &glyph));
213   g_assert_cmpint(hb_ot_math_get_glyph_italics_correction (hb_font, glyph), ==, 300);
214   g_assert(hb_font_get_glyph_from_name (hb_font, "C", -1, &glyph));
215   g_assert_cmpint(hb_ot_math_get_glyph_italics_correction (hb_font, glyph), ==, 904);
216   closeFont();
217 
218   cleanupFreeType();
219 }
220 
221 static void
test_get_glyph_top_accent_attachment(void)222 test_get_glyph_top_accent_attachment (void)
223 {
224   hb_codepoint_t glyph;
225   initFreeType();
226 
227   openFont("fonts/MathTestFontEmpty.otf");
228   g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph));
229   g_assert_cmpint(hb_ot_math_get_glyph_top_accent_attachment (hb_font, glyph), ==, 1000); // MathGlyphInfo not available
230   closeFont();
231 
232   openFont("fonts/MathTestFontPartial1.otf");
233   g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph));
234   g_assert_cmpint(hb_ot_math_get_glyph_top_accent_attachment (hb_font, glyph), ==, 1000); // MathGlyphInfo empty
235   closeFont();
236 
237   openFont("fonts/MathTestFontPartial2.otf");
238   g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph));
239   g_assert_cmpint(hb_ot_math_get_glyph_top_accent_attachment (hb_font, glyph), ==, 1000); // MathTopAccentAttachment empty
240   closeFont();
241 
242   openFont("fonts/MathTestFontFull.otf");
243   g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph));
244   g_assert_cmpint(hb_ot_math_get_glyph_top_accent_attachment (hb_font, glyph), ==, 1000); // Glyph without top accent attachment.
245   g_assert(hb_font_get_glyph_from_name (hb_font, "D", -1, &glyph));
246   g_assert_cmpint(hb_ot_math_get_glyph_top_accent_attachment (hb_font, glyph), ==, 748);
247   g_assert(hb_font_get_glyph_from_name (hb_font, "E", -1, &glyph));
248   g_assert_cmpint(hb_ot_math_get_glyph_top_accent_attachment (hb_font, glyph), ==, 692);
249   g_assert(hb_font_get_glyph_from_name (hb_font, "F", -1, &glyph));
250   g_assert_cmpint(hb_ot_math_get_glyph_top_accent_attachment (hb_font, glyph), ==, 636);
251   closeFont();
252 
253   cleanupFreeType();
254 }
255 
256 static void
test_is_glyph_extended_shape(void)257 test_is_glyph_extended_shape (void)
258 {
259   hb_codepoint_t glyph;
260   initFreeType();
261 
262   openFont("fonts/MathTestFontEmpty.otf");
263   g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph));
264   g_assert(!hb_ot_math_is_glyph_extended_shape (hb_face, glyph)); // MathGlyphInfo not available
265   closeFont();
266 
267   openFont("fonts/MathTestFontPartial1.otf");
268   g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph));
269   g_assert(!hb_ot_math_is_glyph_extended_shape (hb_face, glyph)); // MathGlyphInfo empty
270   closeFont();
271 
272   openFont("fonts/MathTestFontFull.otf");
273   g_assert(hb_font_get_glyph_from_name (hb_font, "G", -1, &glyph));
274   g_assert(!hb_ot_math_is_glyph_extended_shape (hb_face, glyph));
275   g_assert(hb_font_get_glyph_from_name (hb_font, "H", -1, &glyph));
276   g_assert(hb_ot_math_is_glyph_extended_shape (hb_face, glyph));
277   closeFont();
278 
279   cleanupFreeType();
280 }
281 
282 static void
test_get_glyph_kerning(void)283 test_get_glyph_kerning (void)
284 {
285   hb_codepoint_t glyph;
286   initFreeType();
287 
288   openFont("fonts/MathTestFontEmpty.otf");
289   g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph));
290   g_assert_cmpint(hb_ot_math_get_glyph_kerning (hb_font, glyph, HB_OT_MATH_KERN_TOP_RIGHT, 0), ==, 0); // MathGlyphInfo not available
291   g_assert_cmpint(hb_ot_math_get_glyph_kerning (hb_font, glyph, HB_OT_MATH_KERN_TOP_LEFT, 0), ==, 0); // MathGlyphInfo not available
292   g_assert_cmpint(hb_ot_math_get_glyph_kerning (hb_font, glyph, HB_OT_MATH_KERN_BOTTOM_RIGHT, 0), ==, 0); // MathGlyphInfo not available
293   g_assert_cmpint(hb_ot_math_get_glyph_kerning (hb_font, glyph, HB_OT_MATH_KERN_BOTTOM_LEFT, 0), ==, 0); // MathGlyphInfo not available
294   closeFont();
295 
296   openFont("fonts/MathTestFontPartial2.otf");
297   g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph));
298   g_assert_cmpint(hb_ot_math_get_glyph_kerning (hb_font, glyph, HB_OT_MATH_KERN_TOP_RIGHT, 0), ==, 0); // MathKernInfo empty
299   g_assert_cmpint(hb_ot_math_get_glyph_kerning (hb_font, glyph, HB_OT_MATH_KERN_TOP_LEFT, 0), ==, 0); // MathKernInfo empty
300   g_assert_cmpint(hb_ot_math_get_glyph_kerning (hb_font, glyph, HB_OT_MATH_KERN_BOTTOM_RIGHT, 0), ==, 0); // MathKernInfo empty
301   g_assert_cmpint(hb_ot_math_get_glyph_kerning (hb_font, glyph, HB_OT_MATH_KERN_BOTTOM_LEFT, 0), ==, 0); // MathKernInfo empty
302   closeFont();
303 
304   openFont("fonts/MathTestFontPartial3.otf");
305   g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph));
306   g_assert_cmpint(hb_ot_math_get_glyph_kerning (hb_font, glyph, HB_OT_MATH_KERN_TOP_RIGHT, 0), ==, 0); // MathKernInfoRecords empty
307   g_assert_cmpint(hb_ot_math_get_glyph_kerning (hb_font, glyph, HB_OT_MATH_KERN_TOP_LEFT, 0), ==, 0); // MathKernInfoRecords empty
308   g_assert_cmpint(hb_ot_math_get_glyph_kerning (hb_font, glyph, HB_OT_MATH_KERN_BOTTOM_RIGHT, 0), ==, 0); // MathKernInfoRecords empty
309   g_assert_cmpint(hb_ot_math_get_glyph_kerning (hb_font, glyph, HB_OT_MATH_KERN_BOTTOM_LEFT, 0), ==, 0); // MathKernInfoRecords empty
310   closeFont();
311 
312   openFont("fonts/MathTestFontFull.otf");
313   g_assert(hb_font_get_glyph_from_name (hb_font, "I", -1, &glyph));
314 
315   g_assert_cmpint(hb_ot_math_get_glyph_kerning (hb_font, glyph, HB_OT_MATH_KERN_TOP_RIGHT, 7), ==, 62); // lower than min height
316   g_assert_cmpint(hb_ot_math_get_glyph_kerning (hb_font, glyph, HB_OT_MATH_KERN_TOP_RIGHT, 14), ==, 62); // equal to min height
317   g_assert_cmpint(hb_ot_math_get_glyph_kerning (hb_font, glyph, HB_OT_MATH_KERN_TOP_RIGHT, 20), ==, 104);
318   g_assert_cmpint(hb_ot_math_get_glyph_kerning (hb_font, glyph, HB_OT_MATH_KERN_TOP_RIGHT, 23), ==, 104);
319   g_assert_cmpint(hb_ot_math_get_glyph_kerning (hb_font, glyph, HB_OT_MATH_KERN_TOP_RIGHT, 31), ==, 146);
320   g_assert_cmpint(hb_ot_math_get_glyph_kerning (hb_font, glyph, HB_OT_MATH_KERN_TOP_RIGHT, 32), ==, 146);
321   g_assert_cmpint(hb_ot_math_get_glyph_kerning (hb_font, glyph, HB_OT_MATH_KERN_TOP_RIGHT, 86), ==, 398); // equal to max height
322   g_assert_cmpint(hb_ot_math_get_glyph_kerning (hb_font, glyph, HB_OT_MATH_KERN_TOP_RIGHT, 91), ==, 440); // larger than max height
323   g_assert_cmpint(hb_ot_math_get_glyph_kerning (hb_font, glyph, HB_OT_MATH_KERN_TOP_RIGHT, 96), ==, 440); // larger than max height
324 
325   g_assert_cmpint(hb_ot_math_get_glyph_kerning (hb_font, glyph, HB_OT_MATH_KERN_TOP_RIGHT, 39), ==, 188); // top right
326   g_assert_cmpint(hb_ot_math_get_glyph_kerning (hb_font, glyph, HB_OT_MATH_KERN_TOP_LEFT, 39), ==, 110); // top left
327   g_assert_cmpint(hb_ot_math_get_glyph_kerning (hb_font, glyph, HB_OT_MATH_KERN_BOTTOM_RIGHT, 39), ==, 44); // bottom right
328   g_assert_cmpint(hb_ot_math_get_glyph_kerning (hb_font, glyph, HB_OT_MATH_KERN_BOTTOM_LEFT, 39), ==, 100); // bottom left
329 
330   closeFont();
331 
332   cleanupFreeType();
333 }
334 
335 static void
test_get_glyph_kernings(void)336 test_get_glyph_kernings (void)
337 {
338   hb_codepoint_t glyph;
339   hb_ot_math_kern_entry_t entries[20];
340   const unsigned entries_size = sizeof (entries) / sizeof (entries[0]);
341   unsigned int count;
342 
343   initFreeType();
344 
345   openFont("fonts/MathTestFontEmpty.otf");
346   g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph));
347   g_assert_cmpint(hb_ot_math_get_glyph_kernings (hb_font, glyph, HB_OT_MATH_KERN_TOP_RIGHT, 0, NULL, NULL), ==, 0); // MathGlyphInfo not available
348   g_assert_cmpint(hb_ot_math_get_glyph_kernings (hb_font, glyph, HB_OT_MATH_KERN_TOP_LEFT, 0, NULL, NULL), ==, 0); // MathGlyphInfo not available
349   g_assert_cmpint(hb_ot_math_get_glyph_kernings (hb_font, glyph, HB_OT_MATH_KERN_BOTTOM_RIGHT, 0, NULL, NULL), ==, 0); // MathGlyphInfo not available
350   g_assert_cmpint(hb_ot_math_get_glyph_kernings (hb_font, glyph, HB_OT_MATH_KERN_BOTTOM_LEFT, 0, NULL, NULL), ==, 0); // MathGlyphInfo not available
351   closeFont();
352 
353   openFont("fonts/MathTestFontPartial2.otf");
354   g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph));
355   g_assert_cmpint(hb_ot_math_get_glyph_kernings (hb_font, glyph, HB_OT_MATH_KERN_TOP_RIGHT, 0, NULL, NULL), ==, 0); // MathKernInfo empty
356   g_assert_cmpint(hb_ot_math_get_glyph_kernings (hb_font, glyph, HB_OT_MATH_KERN_TOP_LEFT, 0, NULL, NULL), ==, 0); // MathKernInfo empty
357   g_assert_cmpint(hb_ot_math_get_glyph_kernings (hb_font, glyph, HB_OT_MATH_KERN_BOTTOM_RIGHT, 0, NULL, NULL), ==, 0); // MathKernInfo empty
358   g_assert_cmpint(hb_ot_math_get_glyph_kernings (hb_font, glyph, HB_OT_MATH_KERN_BOTTOM_LEFT, 0, NULL, NULL), ==, 0); // MathKernInfo empty
359   closeFont();
360 
361   openFont("fonts/MathTestFontPartial3.otf");
362   g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph));
363   g_assert_cmpint(hb_ot_math_get_glyph_kernings (hb_font, glyph, HB_OT_MATH_KERN_TOP_RIGHT, 0, NULL, NULL), ==, 0); // MathKernInfoRecords empty
364   g_assert_cmpint(hb_ot_math_get_glyph_kernings (hb_font, glyph, HB_OT_MATH_KERN_TOP_LEFT, 0, NULL, NULL), ==, 0); // MathKernInfoRecords empty
365   g_assert_cmpint(hb_ot_math_get_glyph_kernings (hb_font, glyph, HB_OT_MATH_KERN_BOTTOM_RIGHT, 0, NULL, NULL), ==, 0); // MathKernInfoRecords empty
366   g_assert_cmpint(hb_ot_math_get_glyph_kernings (hb_font, glyph, HB_OT_MATH_KERN_BOTTOM_LEFT, 0, NULL, NULL), ==, 0); // MathKernInfoRecords empty
367   closeFont();
368 
369   openFont("fonts/MathTestFontFull.otf");
370   g_assert(hb_font_get_glyph_from_name (hb_font, "I", -1, &glyph));
371 
372   g_assert_cmpint(hb_ot_math_get_glyph_kernings (hb_font, glyph, HB_OT_MATH_KERN_TOP_RIGHT, 0, NULL, NULL), ==, 10);
373   g_assert_cmpint(hb_ot_math_get_glyph_kernings (hb_font, glyph, HB_OT_MATH_KERN_TOP_LEFT, 0, NULL, NULL), ==, 3);
374   g_assert_cmpint(hb_ot_math_get_glyph_kernings (hb_font, glyph, HB_OT_MATH_KERN_BOTTOM_RIGHT, 0, NULL, NULL), ==, 9);
375   g_assert_cmpint(hb_ot_math_get_glyph_kernings (hb_font, glyph, HB_OT_MATH_KERN_BOTTOM_LEFT, 0, NULL, NULL), ==, 7);
376 
377   count = entries_size;
378   g_assert_cmpint(hb_ot_math_get_glyph_kernings (hb_font, glyph, HB_OT_MATH_KERN_TOP_RIGHT, 0, &count, entries), ==, 10);
379   g_assert_cmpint(count, ==, 10);
380   g_assert_cmpint(entries[0].max_correction_height, ==, 14);
381   g_assert_cmpint(entries[0].kern_value, ==, 62);
382   g_assert_cmpint(entries[1].max_correction_height, ==, 23);
383   g_assert_cmpint(entries[1].kern_value, ==, 104);
384   g_assert_cmpint(entries[2].max_correction_height, ==, 32);
385   g_assert_cmpint(entries[2].kern_value, ==, 146);
386   g_assert_cmpint(entries[3].max_correction_height, ==, 41);
387   g_assert_cmpint(entries[3].kern_value, ==, 188);
388   g_assert_cmpint(entries[4].max_correction_height, ==, 50);
389   g_assert_cmpint(entries[4].kern_value, ==, 230);
390   g_assert_cmpint(entries[5].max_correction_height, ==, 59);
391   g_assert_cmpint(entries[5].kern_value, ==, 272);
392   g_assert_cmpint(entries[6].max_correction_height, ==, 68);
393   g_assert_cmpint(entries[6].kern_value, ==, 314);
394   g_assert_cmpint(entries[7].max_correction_height, ==, 77);
395   g_assert_cmpint(entries[7].kern_value, ==, 356);
396   g_assert_cmpint(entries[8].max_correction_height, ==, 86);
397   g_assert_cmpint(entries[8].kern_value, ==, 398);
398   g_assert_cmpint(entries[9].max_correction_height, ==, INT32_MAX);
399   g_assert_cmpint(entries[9].kern_value, ==, 440);
400 
401   count = entries_size;
402   g_assert_cmpint(hb_ot_math_get_glyph_kernings (hb_font, glyph, HB_OT_MATH_KERN_TOP_LEFT, 0, &count, entries), ==, 3);
403   g_assert_cmpint(count, ==, 3);
404   g_assert_cmpint(entries[0].max_correction_height, ==, 20);
405   g_assert_cmpint(entries[0].kern_value, ==, 50);
406   g_assert_cmpint(entries[1].max_correction_height, ==, 35);
407   g_assert_cmpint(entries[1].kern_value, ==, 80);
408   g_assert_cmpint(entries[2].max_correction_height, ==, INT32_MAX);
409   g_assert_cmpint(entries[2].kern_value, ==, 110);
410 
411   closeFont();
412 
413   cleanupFreeType();
414 }
415 
416 
417 static hb_position_t
get_glyph_assembly_italics_correction(hb_font_t * font,hb_codepoint_t glyph,hb_bool_t horizontal)418 get_glyph_assembly_italics_correction (hb_font_t *font,
419 				       hb_codepoint_t glyph,
420 				       hb_bool_t horizontal)
421 {
422   hb_position_t corr;
423   hb_ot_math_get_glyph_assembly (font, glyph,
424 				 horizontal ? HB_DIRECTION_LTR : HB_DIRECTION_TTB,
425 				 0, NULL, NULL,
426 				 &corr);
427   return corr;
428 }
429 
430 static void
test_get_glyph_assembly_italics_correction(void)431 test_get_glyph_assembly_italics_correction (void)
432 {
433   hb_codepoint_t glyph;
434   initFreeType();
435 
436   openFont("fonts/MathTestFontEmpty.otf");
437   g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph));
438   g_assert_cmpint(get_glyph_assembly_italics_correction (hb_font, glyph, TRUE), ==, 0); // MathVariants not available
439   g_assert_cmpint(get_glyph_assembly_italics_correction (hb_font, glyph, FALSE), ==, 0); // MathVariants not available
440   closeFont();
441 
442   openFont("fonts/MathTestFontPartial1.otf");
443   g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph));
444   g_assert_cmpint(get_glyph_assembly_italics_correction (hb_font, glyph, TRUE), ==, 0); // VertGlyphCoverage and HorizGlyphCoverage absent
445   g_assert_cmpint(get_glyph_assembly_italics_correction (hb_font, glyph, FALSE), ==, 0); // VertGlyphCoverage and HorizGlyphCoverage absent
446   closeFont();
447 
448   openFont("fonts/MathTestFontPartial2.otf");
449   g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph));
450   g_assert_cmpint(get_glyph_assembly_italics_correction (hb_font, glyph, TRUE), ==, 0); // VertGlyphCoverage and HorizGlyphCoverage empty
451   g_assert_cmpint(get_glyph_assembly_italics_correction (hb_font, glyph, FALSE), ==, 0); // VertGlyphCoverage and HorizGlyphCoverage empty
452   closeFont();
453 
454   openFont("fonts/MathTestFontPartial3.otf");
455   g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph));
456   g_assert_cmpint(get_glyph_assembly_italics_correction (hb_font, glyph, TRUE), ==, 0); // HorizGlyphConstruction and VertGlyphConstruction empty
457   g_assert_cmpint(get_glyph_assembly_italics_correction (hb_font, glyph, FALSE), ==, 0);  // HorizGlyphConstruction and VertGlyphConstruction empty
458   closeFont();
459 
460   openFont("fonts/MathTestFontPartial4.otf");
461   g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph));
462   g_assert_cmpint(get_glyph_assembly_italics_correction (hb_font, glyph, TRUE), ==, 0);
463   g_assert_cmpint(get_glyph_assembly_italics_correction (hb_font, glyph, FALSE), ==, 0);
464   closeFont();
465 
466   openFont("fonts/MathTestFontFull.otf");
467   g_assert(hb_font_get_glyph_from_name (hb_font, "arrowleft", -1, &glyph));
468   g_assert_cmpint(get_glyph_assembly_italics_correction (hb_font, glyph, TRUE), ==, 248);
469   g_assert_cmpint(get_glyph_assembly_italics_correction (hb_font, glyph, FALSE), ==, 0);
470   g_assert(hb_font_get_glyph_from_name (hb_font, "arrowup", -1, &glyph));
471   g_assert_cmpint(get_glyph_assembly_italics_correction (hb_font, glyph, TRUE), ==, 0);
472   g_assert_cmpint(get_glyph_assembly_italics_correction (hb_font, glyph, FALSE), ==, 662);
473   closeFont();
474 
475   cleanupFreeType();
476 }
477 
478 static void
test_get_min_connector_overlap(void)479 test_get_min_connector_overlap (void)
480 {
481   initFreeType();
482 
483   openFont("fonts/MathTestFontEmpty.otf");
484   g_assert_cmpint(hb_ot_math_get_min_connector_overlap(hb_font, HB_DIRECTION_LTR), ==, 0); // MathVariants not available
485   g_assert_cmpint(hb_ot_math_get_min_connector_overlap(hb_font, HB_DIRECTION_TTB), ==, 0); // MathVariants not available
486   closeFont();
487 
488   openFont("fonts/MathTestFontPartial1.otf");
489   g_assert_cmpint(hb_ot_math_get_min_connector_overlap(hb_font, HB_DIRECTION_LTR), ==, 108);
490   g_assert_cmpint(hb_ot_math_get_min_connector_overlap(hb_font, HB_DIRECTION_TTB), ==, 54);
491   closeFont();
492 
493   cleanupFreeType();
494 }
495 
496 static void
test_get_glyph_variants(void)497 test_get_glyph_variants (void)
498 {
499   hb_codepoint_t glyph;
500   hb_ot_math_glyph_variant_t variants[20];
501   unsigned variantsSize = sizeof (variants) / sizeof (variants[0]);
502   unsigned int count;
503   unsigned int offset = 0;
504 
505   initFreeType();
506 
507   openFont("fonts/MathTestFontEmpty.otf");
508   g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph));
509   g_assert_cmpint(hb_ot_math_get_glyph_variants (hb_font, glyph, HB_DIRECTION_RTL, 0, NULL, NULL), ==, 0);
510   g_assert_cmpint(hb_ot_math_get_glyph_variants (hb_font, glyph, HB_DIRECTION_BTT, 0, NULL, NULL), ==, 0);
511   closeFont();
512 
513   openFont("fonts/MathTestFontPartial1.otf");
514   g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph));
515   g_assert_cmpint(hb_ot_math_get_glyph_variants (hb_font, glyph, HB_DIRECTION_RTL, 0, NULL, NULL), ==, 0);
516   g_assert_cmpint(hb_ot_math_get_glyph_variants (hb_font, glyph, HB_DIRECTION_BTT, 0, NULL, NULL), ==, 0);
517   closeFont();
518 
519   openFont("fonts/MathTestFontPartial2.otf");
520   g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph));
521   g_assert_cmpint(hb_ot_math_get_glyph_variants (hb_font, glyph, HB_DIRECTION_RTL, 0, NULL, NULL), ==, 0);
522   g_assert_cmpint(hb_ot_math_get_glyph_variants (hb_font, glyph, HB_DIRECTION_BTT, 0, NULL, NULL), ==, 0);
523   closeFont();
524 
525   openFont("fonts/MathTestFontPartial3.otf");
526   g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph));
527   g_assert_cmpint(hb_ot_math_get_glyph_variants (hb_font, glyph, HB_DIRECTION_RTL, 0, NULL, NULL), ==, 0);
528   g_assert_cmpint(hb_ot_math_get_glyph_variants (hb_font, glyph, HB_DIRECTION_BTT, 0, NULL, NULL), ==, 0);
529   closeFont();
530 
531   openFont("fonts/MathTestFontPartial4.otf");
532   g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph));
533   g_assert_cmpint(hb_ot_math_get_glyph_variants (hb_font, glyph, HB_DIRECTION_RTL, 0, NULL, NULL), ==, 0);
534   g_assert_cmpint(hb_ot_math_get_glyph_variants (hb_font, glyph, HB_DIRECTION_BTT, 0, NULL, NULL), ==, 0);
535   closeFont();
536 
537   openFont("fonts/MathTestFontFull.otf");
538 
539   g_assert(hb_font_get_glyph_from_name (hb_font, "arrowleft", -1, &glyph));
540   g_assert_cmpint(hb_ot_math_get_glyph_variants (hb_font,
541 						 glyph,
542 						 HB_DIRECTION_BTT,
543 						 0,
544 						 NULL,
545 						 NULL), ==, 0);
546   g_assert_cmpint(hb_ot_math_get_glyph_variants (hb_font,
547 						 glyph,
548 						 HB_DIRECTION_RTL,
549 						 0,
550 						 NULL,
551 						 NULL), ==, 3);
552 
553   g_assert(hb_font_get_glyph_from_name (hb_font, "arrowup", -1, &glyph));
554   g_assert_cmpint(hb_ot_math_get_glyph_variants (hb_font,
555 						 glyph,
556 						 HB_DIRECTION_BTT,
557 						 0,
558 						 NULL,
559 						 NULL), ==, 4);
560   g_assert_cmpint(hb_ot_math_get_glyph_variants (hb_font,
561 						 glyph,
562 						 HB_DIRECTION_RTL,
563 						 0,
564 						 NULL,
565 						 NULL), ==, 0);
566 
567   g_assert(hb_font_get_glyph_from_name (hb_font, "arrowleft", -1, &glyph));
568   do {
569     count = variantsSize;
570     hb_ot_math_get_glyph_variants (hb_font,
571 				   glyph,
572 				   HB_DIRECTION_RTL,
573 				   offset,
574 				   &count,
575 				   variants);
576     offset += count;
577   } while (count == variantsSize);
578   g_assert_cmpint(offset, ==, 3);
579   g_assert(hb_font_get_glyph_from_name (hb_font, "uni2190_size2", -1, &glyph));
580   g_assert_cmpint(variants[0].glyph, ==, glyph);
581   g_assert_cmpint(variants[0].advance, ==, 4302);
582   g_assert(hb_font_get_glyph_from_name (hb_font, "uni2190_size3", -1, &glyph));
583   g_assert_cmpint(variants[1].glyph, ==, glyph);
584   g_assert_cmpint(variants[1].advance, ==, 4802);
585   g_assert(hb_font_get_glyph_from_name (hb_font, "uni2190_size4", -1, &glyph));
586   g_assert_cmpint(variants[2].glyph, ==, glyph);
587   g_assert_cmpint(variants[2].advance, ==, 5802);
588 
589   g_assert(hb_font_get_glyph_from_name (hb_font, "arrowup", -1, &glyph));
590   offset = 0;
591   do {
592     count = variantsSize;
593     hb_ot_math_get_glyph_variants (hb_font,
594 				   glyph,
595 				   HB_DIRECTION_BTT,
596 				   offset,
597 				   &count,
598 				   variants);
599     offset += count;
600   } while (count == variantsSize);
601   g_assert_cmpint(offset, ==, 4);
602   g_assert(hb_font_get_glyph_from_name (hb_font, "uni2191_size2", -1, &glyph));
603   g_assert_cmpint(variants[0].glyph, ==, glyph);
604   g_assert_cmpint(variants[0].advance, ==, 2251);
605   g_assert(hb_font_get_glyph_from_name (hb_font, "uni2191_size3", -1, &glyph));
606   g_assert_cmpint(variants[1].glyph, ==, glyph);
607   g_assert_cmpint(variants[1].advance, ==, 2501);
608   g_assert(hb_font_get_glyph_from_name (hb_font, "uni2191_size4", -1, &glyph));
609   g_assert_cmpint(variants[2].glyph, ==, glyph);
610   g_assert_cmpint(variants[2].advance, ==, 3001);
611   g_assert(hb_font_get_glyph_from_name (hb_font, "uni2191_size5", -1, &glyph));
612   g_assert_cmpint(variants[3].glyph, ==, glyph);
613   g_assert_cmpint(variants[3].advance, ==, 3751);
614 
615   closeFont();
616 
617   cleanupFreeType();
618 }
619 
620 static void
test_get_glyph_assembly(void)621 test_get_glyph_assembly (void)
622 {
623   hb_codepoint_t glyph;
624   hb_ot_math_glyph_part_t parts[20];
625   unsigned partsSize = sizeof (parts) / sizeof (parts[0]);
626   unsigned int count;
627   unsigned int offset = 0;
628 
629   initFreeType();
630 
631   openFont("fonts/MathTestFontEmpty.otf");
632   g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph));
633   g_assert_cmpint(hb_ot_math_get_glyph_assembly (hb_font, glyph, HB_DIRECTION_RTL, 0, NULL, NULL, NULL), ==, 0);
634   g_assert_cmpint(hb_ot_math_get_glyph_assembly (hb_font, glyph, HB_DIRECTION_BTT, 0, NULL, NULL, NULL), ==, 0);
635   closeFont();
636 
637   openFont("fonts/MathTestFontPartial1.otf");
638   g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph));
639   g_assert_cmpint(hb_ot_math_get_glyph_assembly (hb_font, glyph, HB_DIRECTION_RTL, 0, NULL, NULL, NULL), ==, 0);
640   g_assert_cmpint(hb_ot_math_get_glyph_assembly (hb_font, glyph, HB_DIRECTION_BTT, 0, NULL, NULL, NULL), ==, 0);
641   closeFont();
642 
643   openFont("fonts/MathTestFontPartial2.otf");
644   g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph));
645   g_assert_cmpint(hb_ot_math_get_glyph_assembly (hb_font, glyph, HB_DIRECTION_RTL, 0, NULL, NULL, NULL), ==, 0);
646   g_assert_cmpint(hb_ot_math_get_glyph_assembly (hb_font, glyph, HB_DIRECTION_BTT, 0, NULL, NULL, NULL), ==, 0);
647   closeFont();
648 
649   openFont("fonts/MathTestFontPartial3.otf");
650   g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph));
651   g_assert_cmpint(hb_ot_math_get_glyph_assembly (hb_font, glyph, HB_DIRECTION_RTL, 0, NULL, NULL, NULL), ==, 0);
652   g_assert_cmpint(hb_ot_math_get_glyph_assembly (hb_font, glyph, HB_DIRECTION_BTT, 0, NULL, NULL, NULL), ==, 0);
653   closeFont();
654 
655   openFont("fonts/MathTestFontPartial4.otf");
656   g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph));
657   g_assert_cmpint(hb_ot_math_get_glyph_assembly (hb_font, glyph, HB_DIRECTION_RTL, 0, NULL, NULL, NULL), ==, 0);
658   g_assert_cmpint(hb_ot_math_get_glyph_assembly (hb_font, glyph, HB_DIRECTION_BTT, 0, NULL, NULL, NULL), ==, 0);
659   closeFont();
660 
661   openFont("fonts/MathTestFontFull.otf");
662 
663   g_assert(hb_font_get_glyph_from_name (hb_font, "arrowright", -1, &glyph));
664   g_assert_cmpint(hb_ot_math_get_glyph_assembly (hb_font,
665 						 glyph,
666 						 HB_DIRECTION_BTT,
667 						 0,
668 						 NULL,
669 						 NULL,
670 						 NULL), ==, 0);
671   g_assert_cmpint(hb_ot_math_get_glyph_assembly (hb_font,
672 						 glyph,
673 						 HB_DIRECTION_RTL,
674 						 0,
675 						 NULL,
676 						 NULL,
677 						 NULL), ==, 3);
678 
679   g_assert(hb_font_get_glyph_from_name (hb_font, "arrowdown", -1, &glyph));
680   g_assert_cmpint(hb_ot_math_get_glyph_assembly (hb_font,
681 						 glyph,
682 						 HB_DIRECTION_BTT,
683 						 0,
684 						 NULL,
685 						 NULL,
686 						 NULL), ==, 5);
687   g_assert_cmpint(hb_ot_math_get_glyph_assembly (hb_font,
688 						 glyph,
689 						 HB_DIRECTION_RTL,
690 						 0,
691 						 NULL,
692 						 NULL,
693 						 NULL), ==, 0);
694 
695   g_assert(hb_font_get_glyph_from_name (hb_font, "arrowright", -1, &glyph));
696   do {
697     count = partsSize;
698     hb_ot_math_get_glyph_assembly (hb_font,
699 				   glyph,
700 				   HB_DIRECTION_RTL,
701 				   offset,
702 				   &count,
703 				   parts,
704 				   NULL);
705     offset += count;
706   } while (count == partsSize);
707   g_assert_cmpint(offset, ==, 3);
708   g_assert(hb_font_get_glyph_from_name (hb_font, "left", -1, &glyph));
709   g_assert_cmpint(parts[0].glyph, ==, glyph);
710   g_assert_cmpint(parts[0].start_connector_length, ==, 800);
711   g_assert_cmpint(parts[0].end_connector_length, ==, 384);
712   g_assert_cmpint(parts[0].full_advance, ==, 2000);
713   g_assert(!(parts[0].flags & HB_OT_MATH_GLYPH_PART_FLAG_EXTENDER));
714   g_assert(hb_font_get_glyph_from_name (hb_font, "horizontal", -1, &glyph));
715   g_assert_cmpint(parts[1].glyph, ==, glyph);
716   g_assert_cmpint(parts[1].start_connector_length, ==, 524);
717   g_assert_cmpint(parts[1].end_connector_length, ==, 800);
718   g_assert_cmpint(parts[1].full_advance, ==, 2000);
719   g_assert(parts[1].flags & HB_OT_MATH_GLYPH_PART_FLAG_EXTENDER);
720   g_assert(hb_font_get_glyph_from_name (hb_font, "right", -1, &glyph));
721   g_assert_cmpint(parts[2].glyph, ==, glyph);
722   g_assert_cmpint(parts[2].start_connector_length, ==, 316);
723   g_assert_cmpint(parts[2].end_connector_length, ==, 454);
724   g_assert_cmpint(parts[2].full_advance, ==, 2000);
725   g_assert(!(parts[2].flags & HB_OT_MATH_GLYPH_PART_FLAG_EXTENDER));
726 
727   g_assert(hb_font_get_glyph_from_name (hb_font, "arrowdown", -1, &glyph));
728   offset = 0;
729   do {
730     count = partsSize;
731     hb_ot_math_get_glyph_assembly (hb_font,
732 				   glyph,
733 				   HB_DIRECTION_BTT,
734 				   offset,
735 				   &count,
736 				   parts,
737 				   NULL);
738     offset += count;
739   } while (count == partsSize);
740   g_assert_cmpint(offset, ==, 5);
741   g_assert(hb_font_get_glyph_from_name (hb_font, "bottom", -1, &glyph));
742   g_assert_cmpint(parts[0].glyph, ==, glyph);
743   g_assert_cmpint(parts[0].start_connector_length, ==, 365);
744   g_assert_cmpint(parts[0].end_connector_length, ==, 158);
745   g_assert_cmpint(parts[0].full_advance, ==, 1000);
746   g_assert(!(parts[0].flags & HB_OT_MATH_GLYPH_PART_FLAG_EXTENDER));
747   g_assert(hb_font_get_glyph_from_name (hb_font, "vertical", -1, &glyph));
748   g_assert_cmpint(parts[1].glyph, ==, glyph);
749   g_assert_cmpint(parts[1].glyph, ==, glyph);
750   g_assert_cmpint(parts[1].start_connector_length, ==, 227);
751   g_assert_cmpint(parts[1].end_connector_length, ==, 365);
752   g_assert_cmpint(parts[1].full_advance, ==, 1000);
753   g_assert(parts[1].flags & HB_OT_MATH_GLYPH_PART_FLAG_EXTENDER);
754   g_assert(hb_font_get_glyph_from_name (hb_font, "center", -1, &glyph));
755   g_assert_cmpint(parts[2].glyph, ==, glyph);
756   g_assert_cmpint(parts[2].start_connector_length, ==, 54);
757   g_assert_cmpint(parts[2].end_connector_length, ==, 158);
758   g_assert_cmpint(parts[2].full_advance, ==, 1000);
759   g_assert(!(parts[2].flags & HB_OT_MATH_GLYPH_PART_FLAG_EXTENDER));
760   g_assert(hb_font_get_glyph_from_name (hb_font, "vertical", -1, &glyph));
761   g_assert_cmpint(parts[3].glyph, ==, glyph);
762   g_assert_cmpint(parts[3].glyph, ==, glyph);
763   g_assert_cmpint(parts[3].glyph, ==, glyph);
764   g_assert_cmpint(parts[3].start_connector_length, ==, 400);
765   g_assert_cmpint(parts[3].end_connector_length, ==, 296);
766   g_assert_cmpint(parts[3].full_advance, ==, 1000);
767   g_assert(parts[1].flags & HB_OT_MATH_GLYPH_PART_FLAG_EXTENDER);
768   g_assert(hb_font_get_glyph_from_name (hb_font, "top", -1, &glyph));
769   g_assert_cmpint(parts[4].glyph, ==, glyph);
770   g_assert_cmpint(parts[4].start_connector_length, ==, 123);
771   g_assert_cmpint(parts[4].end_connector_length, ==, 192);
772   g_assert_cmpint(parts[4].full_advance, ==, 1000);
773   g_assert(!(parts[4].flags & HB_OT_MATH_GLYPH_PART_FLAG_EXTENDER));
774 
775   closeFont();
776 
777   cleanupFreeType();
778 }
779 
780 int
main(int argc,char ** argv)781 main (int argc, char **argv)
782 {
783   hb_test_init (&argc, &argv);
784 
785   hb_test_add (test_has_data);
786   hb_test_add (test_get_constant);
787   hb_test_add (test_get_glyph_italics_correction);
788   hb_test_add (test_get_glyph_top_accent_attachment);
789   hb_test_add (test_is_glyph_extended_shape);
790   hb_test_add (test_get_glyph_kerning);
791   hb_test_add (test_get_glyph_kernings);
792   hb_test_add (test_get_glyph_assembly_italics_correction);
793   hb_test_add (test_get_min_connector_overlap);
794   hb_test_add (test_get_glyph_variants);
795   hb_test_add (test_get_glyph_assembly);
796 
797   return hb_test_run();
798 }
799