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 35static FT_Library ft_library; 36static FT_Face ft_face; 37static hb_font_t *hb_font; 38static hb_face_t *hb_face; 39 40static inline void 41initFreeType (void) 42{ 43 FT_Error ft_error; 44 if ((ft_error = FT_Init_FreeType (&ft_library))) 45 abort(); 46} 47 48static inline void 49cleanupFreeType (void) 50{ 51 FT_Done_FreeType (ft_library); 52} 53 54static void 55openFont(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 76static inline void 77closeFont (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 87static void 88test_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 104 hb_font = hb_font_get_empty (); 105 hb_face = hb_font_get_face (hb_font); 106 g_assert(!hb_ot_math_has_data (hb_face)); // MATH table not available 107 108 cleanupFreeType(); 109} 110 111static void 112test_get_constant (void) 113{ 114 initFreeType(); 115 116 openFont("fonts/MathTestFontEmpty.otf"); 117 g_assert_cmpint(hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_DELIMITED_SUB_FORMULA_MIN_HEIGHT), ==, 0); // MathConstants not available 118 closeFont(); 119 120 openFont("fonts/MathTestFontFull.otf"); 121 g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_DELIMITED_SUB_FORMULA_MIN_HEIGHT)), ==, 100); 122 g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_DISPLAY_OPERATOR_MIN_HEIGHT)), ==, 200); 123 g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_MATH_LEADING)), ==, 300); 124 g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_AXIS_HEIGHT)), ==, 400); 125 g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_ACCENT_BASE_HEIGHT)), ==, 500); 126 g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_FLATTENED_ACCENT_BASE_HEIGHT)), ==, 600); 127 g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_SUBSCRIPT_SHIFT_DOWN)), ==, 700); 128 g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_SUBSCRIPT_TOP_MAX)), ==, 800); 129 g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_SUBSCRIPT_BASELINE_DROP_MIN)), ==, 900); 130 g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_SUPERSCRIPT_SHIFT_UP)), ==, 1100); 131 g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_SUPERSCRIPT_SHIFT_UP_CRAMPED)), ==, 1200); 132 g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_SUPERSCRIPT_BOTTOM_MIN)), ==, 1300); 133 g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_SUPERSCRIPT_BASELINE_DROP_MAX)), ==, 1400); 134 g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_SUB_SUPERSCRIPT_GAP_MIN)), ==, 1500); 135 g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_SUPERSCRIPT_BOTTOM_MAX_WITH_SUBSCRIPT)), ==, 1600); 136 g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_SPACE_AFTER_SCRIPT)), ==, 3400); 137 g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_UPPER_LIMIT_GAP_MIN)), ==, 1800); 138 g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_UPPER_LIMIT_BASELINE_RISE_MIN)), ==, 1900); 139 g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_LOWER_LIMIT_GAP_MIN)), ==, 2200); 140 g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_LOWER_LIMIT_BASELINE_DROP_MIN)), ==, 2300); 141 g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_STACK_TOP_SHIFT_UP)), ==, 2400); 142 g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_STACK_TOP_DISPLAY_STYLE_SHIFT_UP)), ==, 2500); 143 g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_STACK_BOTTOM_SHIFT_DOWN)), ==, 2600); 144 g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_STACK_BOTTOM_DISPLAY_STYLE_SHIFT_DOWN)), ==, 2700); 145 g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_STACK_GAP_MIN)), ==, 2800); 146 g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_STACK_DISPLAY_STYLE_GAP_MIN)), ==, 2900); 147 g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_STRETCH_STACK_TOP_SHIFT_UP)), ==, 3000); 148 g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_STRETCH_STACK_BOTTOM_SHIFT_DOWN)), ==, 3100); 149 g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_STRETCH_STACK_GAP_ABOVE_MIN)), ==, 3200); 150 g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_STRETCH_STACK_GAP_BELOW_MIN)), ==, 3300); 151 g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_FRACTION_NUMERATOR_SHIFT_UP)), ==, 3400); 152 g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_FRACTION_NUMERATOR_DISPLAY_STYLE_SHIFT_UP)), ==, 3500); 153 g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_FRACTION_DENOMINATOR_SHIFT_DOWN)), ==, 3600); 154 g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_FRACTION_DENOMINATOR_DISPLAY_STYLE_SHIFT_DOWN)), ==, 3700); 155 g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_FRACTION_NUMERATOR_GAP_MIN)), ==, 3800); 156 g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_FRACTION_NUM_DISPLAY_STYLE_GAP_MIN)), ==, 3900); 157 g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_FRACTION_RULE_THICKNESS)), ==, 4000); 158 g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_FRACTION_DENOMINATOR_GAP_MIN)), ==, 4100); 159 g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_FRACTION_DENOM_DISPLAY_STYLE_GAP_MIN)), ==, 4200); 160 g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_SKEWED_FRACTION_HORIZONTAL_GAP)), ==, 8600); 161 g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_SKEWED_FRACTION_VERTICAL_GAP)), ==, 4400); 162 g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_OVERBAR_VERTICAL_GAP)), ==, 4500); 163 g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_OVERBAR_RULE_THICKNESS)), ==, 4600); 164 g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_OVERBAR_EXTRA_ASCENDER)), ==, 4700); 165 g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_UNDERBAR_VERTICAL_GAP)), ==, 4800); 166 g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_UNDERBAR_RULE_THICKNESS)), ==, 4900); 167 g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_UNDERBAR_EXTRA_DESCENDER)), ==, 5000); 168 g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_RADICAL_VERTICAL_GAP)), ==, 5100); 169 g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_RADICAL_DISPLAY_STYLE_VERTICAL_GAP)), ==, 5200); 170 g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_RADICAL_RULE_THICKNESS)), ==, 5300); 171 g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_RADICAL_EXTRA_ASCENDER)), ==, 5400); 172 g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_RADICAL_KERN_BEFORE_DEGREE)), ==, 11000); 173 g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_RADICAL_KERN_AFTER_DEGREE)), ==, 11200); 174 g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_SCRIPT_PERCENT_SCALE_DOWN)), ==, 87); 175 g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_SCRIPT_SCRIPT_PERCENT_SCALE_DOWN)), ==, 76); 176 g_assert_cmpint((hb_ot_math_get_constant (hb_font, HB_OT_MATH_CONSTANT_RADICAL_DEGREE_BOTTOM_RAISE_PERCENT)), ==, 65); 177 closeFont(); 178 179 cleanupFreeType(); 180} 181 182static void 183test_get_glyph_italics_correction (void) 184{ 185 hb_codepoint_t glyph; 186 initFreeType(); 187 188 openFont("fonts/MathTestFontEmpty.otf"); 189 g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph)); 190 g_assert_cmpint(hb_ot_math_get_glyph_italics_correction (hb_font, glyph), ==, 0); // MathGlyphInfo not available 191 closeFont(); 192 193 openFont("fonts/MathTestFontPartial1.otf"); 194 g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph)); 195 g_assert_cmpint(hb_ot_math_get_glyph_italics_correction (hb_font, glyph), ==, 0); // MathGlyphInfo empty 196 closeFont(); 197 198 openFont("fonts/MathTestFontPartial2.otf"); 199 g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph)); 200 g_assert_cmpint(hb_ot_math_get_glyph_italics_correction (hb_font, glyph), ==, 0); // MathItalicsCorrectionInfo empty 201 closeFont(); 202 203 openFont("fonts/MathTestFontFull.otf"); 204 g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph)); 205 g_assert_cmpint(hb_ot_math_get_glyph_italics_correction (hb_font, glyph), ==, 0); // Glyph without italic correction. 206 g_assert(hb_font_get_glyph_from_name (hb_font, "A", -1, &glyph)); 207 g_assert_cmpint(hb_ot_math_get_glyph_italics_correction (hb_font, glyph), ==, 394); 208 g_assert(hb_font_get_glyph_from_name (hb_font, "B", -1, &glyph)); 209 g_assert_cmpint(hb_ot_math_get_glyph_italics_correction (hb_font, glyph), ==, 300); 210 g_assert(hb_font_get_glyph_from_name (hb_font, "C", -1, &glyph)); 211 g_assert_cmpint(hb_ot_math_get_glyph_italics_correction (hb_font, glyph), ==, 904); 212 closeFont(); 213 214 cleanupFreeType(); 215} 216 217static void 218test_get_glyph_top_accent_attachment (void) 219{ 220 hb_codepoint_t glyph; 221 initFreeType(); 222 223 openFont("fonts/MathTestFontEmpty.otf"); 224 g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph)); 225 g_assert_cmpint(hb_ot_math_get_glyph_top_accent_attachment (hb_font, glyph), ==, 1000); // MathGlyphInfo not available 226 closeFont(); 227 228 openFont("fonts/MathTestFontPartial1.otf"); 229 g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph)); 230 g_assert_cmpint(hb_ot_math_get_glyph_top_accent_attachment (hb_font, glyph), ==, 1000); // MathGlyphInfo empty 231 closeFont(); 232 233 openFont("fonts/MathTestFontPartial2.otf"); 234 g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph)); 235 g_assert_cmpint(hb_ot_math_get_glyph_top_accent_attachment (hb_font, glyph), ==, 1000); // MathTopAccentAttachment empty 236 closeFont(); 237 238 openFont("fonts/MathTestFontFull.otf"); 239 g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph)); 240 g_assert_cmpint(hb_ot_math_get_glyph_top_accent_attachment (hb_font, glyph), ==, 1000); // Glyph without top accent attachment. 241 g_assert(hb_font_get_glyph_from_name (hb_font, "D", -1, &glyph)); 242 g_assert_cmpint(hb_ot_math_get_glyph_top_accent_attachment (hb_font, glyph), ==, 748); 243 g_assert(hb_font_get_glyph_from_name (hb_font, "E", -1, &glyph)); 244 g_assert_cmpint(hb_ot_math_get_glyph_top_accent_attachment (hb_font, glyph), ==, 692); 245 g_assert(hb_font_get_glyph_from_name (hb_font, "F", -1, &glyph)); 246 g_assert_cmpint(hb_ot_math_get_glyph_top_accent_attachment (hb_font, glyph), ==, 636); 247 closeFont(); 248 249 cleanupFreeType(); 250} 251 252static void 253test_is_glyph_extended_shape (void) 254{ 255 hb_codepoint_t glyph; 256 initFreeType(); 257 258 openFont("fonts/MathTestFontEmpty.otf"); 259 g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph)); 260 g_assert(!hb_ot_math_is_glyph_extended_shape (hb_face, glyph)); // MathGlyphInfo not available 261 closeFont(); 262 263 openFont("fonts/MathTestFontPartial1.otf"); 264 g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph)); 265 g_assert(!hb_ot_math_is_glyph_extended_shape (hb_face, glyph)); // MathGlyphInfo empty 266 closeFont(); 267 268 openFont("fonts/MathTestFontFull.otf"); 269 g_assert(hb_font_get_glyph_from_name (hb_font, "G", -1, &glyph)); 270 g_assert(!hb_ot_math_is_glyph_extended_shape (hb_face, glyph)); 271 g_assert(hb_font_get_glyph_from_name (hb_font, "H", -1, &glyph)); 272 g_assert(hb_ot_math_is_glyph_extended_shape (hb_face, glyph)); 273 closeFont(); 274 275 cleanupFreeType(); 276} 277 278static void 279test_get_glyph_kerning (void) 280{ 281 hb_codepoint_t glyph; 282 initFreeType(); 283 284 openFont("fonts/MathTestFontEmpty.otf"); 285 g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph)); 286 g_assert_cmpint(hb_ot_math_get_glyph_kerning (hb_font, glyph, HB_OT_MATH_KERN_TOP_RIGHT, 0), ==, 0); // MathGlyphInfo not available 287 g_assert_cmpint(hb_ot_math_get_glyph_kerning (hb_font, glyph, HB_OT_MATH_KERN_TOP_LEFT, 0), ==, 0); // MathGlyphInfo not available 288 g_assert_cmpint(hb_ot_math_get_glyph_kerning (hb_font, glyph, HB_OT_MATH_KERN_BOTTOM_RIGHT, 0), ==, 0); // MathGlyphInfo not available 289 g_assert_cmpint(hb_ot_math_get_glyph_kerning (hb_font, glyph, HB_OT_MATH_KERN_BOTTOM_LEFT, 0), ==, 0); // MathGlyphInfo not available 290 closeFont(); 291 292 openFont("fonts/MathTestFontPartial2.otf"); 293 g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph)); 294 g_assert_cmpint(hb_ot_math_get_glyph_kerning (hb_font, glyph, HB_OT_MATH_KERN_TOP_RIGHT, 0), ==, 0); // MathKernInfo empty 295 g_assert_cmpint(hb_ot_math_get_glyph_kerning (hb_font, glyph, HB_OT_MATH_KERN_TOP_LEFT, 0), ==, 0); // MathKernInfo empty 296 g_assert_cmpint(hb_ot_math_get_glyph_kerning (hb_font, glyph, HB_OT_MATH_KERN_BOTTOM_RIGHT, 0), ==, 0); // MathKernInfo empty 297 g_assert_cmpint(hb_ot_math_get_glyph_kerning (hb_font, glyph, HB_OT_MATH_KERN_BOTTOM_LEFT, 0), ==, 0); // MathKernInfo empty 298 closeFont(); 299 300 openFont("fonts/MathTestFontPartial3.otf"); 301 g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph)); 302 g_assert_cmpint(hb_ot_math_get_glyph_kerning (hb_font, glyph, HB_OT_MATH_KERN_TOP_RIGHT, 0), ==, 0); // MathKernInfoRecords empty 303 g_assert_cmpint(hb_ot_math_get_glyph_kerning (hb_font, glyph, HB_OT_MATH_KERN_TOP_LEFT, 0), ==, 0); // MathKernInfoRecords empty 304 g_assert_cmpint(hb_ot_math_get_glyph_kerning (hb_font, glyph, HB_OT_MATH_KERN_BOTTOM_RIGHT, 0), ==, 0); // MathKernInfoRecords empty 305 g_assert_cmpint(hb_ot_math_get_glyph_kerning (hb_font, glyph, HB_OT_MATH_KERN_BOTTOM_LEFT, 0), ==, 0); // MathKernInfoRecords empty 306 closeFont(); 307 308 openFont("fonts/MathTestFontFull.otf"); 309 g_assert(hb_font_get_glyph_from_name (hb_font, "I", -1, &glyph)); 310 311 g_assert_cmpint(hb_ot_math_get_glyph_kerning (hb_font, glyph, HB_OT_MATH_KERN_TOP_RIGHT, 7), ==, 62); // lower than min heigth 312 g_assert_cmpint(hb_ot_math_get_glyph_kerning (hb_font, glyph, HB_OT_MATH_KERN_TOP_RIGHT, 14), ==, 62); // equal to min height 313 g_assert_cmpint(hb_ot_math_get_glyph_kerning (hb_font, glyph, HB_OT_MATH_KERN_TOP_RIGHT, 20), ==, 104); 314 g_assert_cmpint(hb_ot_math_get_glyph_kerning (hb_font, glyph, HB_OT_MATH_KERN_TOP_RIGHT, 23), ==, 104); 315 g_assert_cmpint(hb_ot_math_get_glyph_kerning (hb_font, glyph, HB_OT_MATH_KERN_TOP_RIGHT, 31), ==, 146); 316 g_assert_cmpint(hb_ot_math_get_glyph_kerning (hb_font, glyph, HB_OT_MATH_KERN_TOP_RIGHT, 32), ==, 146); 317 g_assert_cmpint(hb_ot_math_get_glyph_kerning (hb_font, glyph, HB_OT_MATH_KERN_TOP_RIGHT, 86), ==, 398); // equal to max height 318 g_assert_cmpint(hb_ot_math_get_glyph_kerning (hb_font, glyph, HB_OT_MATH_KERN_TOP_RIGHT, 91), ==, 440); // larger than max height 319 g_assert_cmpint(hb_ot_math_get_glyph_kerning (hb_font, glyph, HB_OT_MATH_KERN_TOP_RIGHT, 96), ==, 440); // larger than max height 320 321 g_assert_cmpint(hb_ot_math_get_glyph_kerning (hb_font, glyph, HB_OT_MATH_KERN_TOP_RIGHT, 39), ==, 188); // top right 322 g_assert_cmpint(hb_ot_math_get_glyph_kerning (hb_font, glyph, HB_OT_MATH_KERN_TOP_LEFT, 39), ==, 110); // top left 323 g_assert_cmpint(hb_ot_math_get_glyph_kerning (hb_font, glyph, HB_OT_MATH_KERN_BOTTOM_RIGHT, 39), ==, 44); // bottom right 324 g_assert_cmpint(hb_ot_math_get_glyph_kerning (hb_font, glyph, HB_OT_MATH_KERN_BOTTOM_LEFT, 39), ==, 100); // bottom left 325 326 closeFont(); 327 328 cleanupFreeType(); 329} 330 331 332static hb_position_t 333get_glyph_assembly_italics_correction (hb_font_t *font, 334 hb_codepoint_t glyph, 335 hb_bool_t horizontal) 336{ 337 hb_position_t corr; 338 hb_ot_math_get_glyph_assembly (font, glyph, 339 horizontal ? HB_DIRECTION_LTR : HB_DIRECTION_TTB, 340 0, NULL, NULL, 341 &corr); 342 return corr; 343} 344 345static void 346test_get_glyph_assembly_italics_correction (void) 347{ 348 hb_codepoint_t glyph; 349 initFreeType(); 350 351 openFont("fonts/MathTestFontEmpty.otf"); 352 g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph)); 353 g_assert_cmpint(get_glyph_assembly_italics_correction (hb_font, glyph, TRUE), ==, 0); // MathVariants not available 354 g_assert_cmpint(get_glyph_assembly_italics_correction (hb_font, glyph, FALSE), ==, 0); // MathVariants not available 355 closeFont(); 356 357 openFont("fonts/MathTestFontPartial1.otf"); 358 g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph)); 359 g_assert_cmpint(get_glyph_assembly_italics_correction (hb_font, glyph, TRUE), ==, 0); // VertGlyphCoverage and HorizGlyphCoverage absent 360 g_assert_cmpint(get_glyph_assembly_italics_correction (hb_font, glyph, FALSE), ==, 0); // VertGlyphCoverage and HorizGlyphCoverage absent 361 closeFont(); 362 363 openFont("fonts/MathTestFontPartial2.otf"); 364 g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph)); 365 g_assert_cmpint(get_glyph_assembly_italics_correction (hb_font, glyph, TRUE), ==, 0); // VertGlyphCoverage and HorizGlyphCoverage empty 366 g_assert_cmpint(get_glyph_assembly_italics_correction (hb_font, glyph, FALSE), ==, 0); // VertGlyphCoverage and HorizGlyphCoverage empty 367 closeFont(); 368 369 openFont("fonts/MathTestFontPartial3.otf"); 370 g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph)); 371 g_assert_cmpint(get_glyph_assembly_italics_correction (hb_font, glyph, TRUE), ==, 0); // HorizGlyphConstruction and VertGlyphConstruction empty 372 g_assert_cmpint(get_glyph_assembly_italics_correction (hb_font, glyph, FALSE), ==, 0); // HorizGlyphConstruction and VertGlyphConstruction empty 373 closeFont(); 374 375 openFont("fonts/MathTestFontPartial4.otf"); 376 g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph)); 377 g_assert_cmpint(get_glyph_assembly_italics_correction (hb_font, glyph, TRUE), ==, 0); 378 g_assert_cmpint(get_glyph_assembly_italics_correction (hb_font, glyph, FALSE), ==, 0); 379 closeFont(); 380 381 openFont("fonts/MathTestFontFull.otf"); 382 g_assert(hb_font_get_glyph_from_name (hb_font, "arrowleft", -1, &glyph)); 383 g_assert_cmpint(get_glyph_assembly_italics_correction (hb_font, glyph, TRUE), ==, 248); 384 g_assert_cmpint(get_glyph_assembly_italics_correction (hb_font, glyph, FALSE), ==, 0); 385 g_assert(hb_font_get_glyph_from_name (hb_font, "arrowup", -1, &glyph)); 386 g_assert_cmpint(get_glyph_assembly_italics_correction (hb_font, glyph, TRUE), ==, 0); 387 g_assert_cmpint(get_glyph_assembly_italics_correction (hb_font, glyph, FALSE), ==, 662); 388 closeFont(); 389 390 cleanupFreeType(); 391} 392 393static void 394test_get_min_connector_overlap (void) 395{ 396 initFreeType(); 397 398 openFont("fonts/MathTestFontEmpty.otf"); 399 g_assert_cmpint(hb_ot_math_get_min_connector_overlap(hb_font, FALSE), ==, 0); // MathVariants not available 400 g_assert_cmpint(hb_ot_math_get_min_connector_overlap(hb_font, TRUE), ==, 0); // MathVariants not available 401 closeFont(); 402 403 openFont("fonts/MathTestFontPartial1.otf"); 404 g_assert_cmpint(hb_ot_math_get_min_connector_overlap(hb_font, HB_DIRECTION_LTR), ==, 108); 405 g_assert_cmpint(hb_ot_math_get_min_connector_overlap(hb_font, HB_DIRECTION_TTB), ==, 54); 406 closeFont(); 407 408 cleanupFreeType(); 409} 410 411static void 412test_get_glyph_variants (void) 413{ 414 hb_codepoint_t glyph; 415 hb_ot_math_glyph_variant_t variants[20]; 416 unsigned variantsSize = sizeof (variants) / sizeof (variants[0]); 417 unsigned int count; 418 unsigned int offset = 0; 419 420 initFreeType(); 421 422 openFont("fonts/MathTestFontEmpty.otf"); 423 g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph)); 424 g_assert_cmpint(hb_ot_math_get_glyph_variants (hb_font, glyph, HB_DIRECTION_RTL, 0, NULL, NULL), ==, 0); 425 g_assert_cmpint(hb_ot_math_get_glyph_variants (hb_font, glyph, HB_DIRECTION_BTT, 0, NULL, NULL), ==, 0); 426 closeFont(); 427 428 openFont("fonts/MathTestFontPartial1.otf"); 429 g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph)); 430 g_assert_cmpint(hb_ot_math_get_glyph_variants (hb_font, glyph, HB_DIRECTION_RTL, 0, NULL, NULL), ==, 0); 431 g_assert_cmpint(hb_ot_math_get_glyph_variants (hb_font, glyph, HB_DIRECTION_BTT, 0, NULL, NULL), ==, 0); 432 closeFont(); 433 434 openFont("fonts/MathTestFontPartial2.otf"); 435 g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph)); 436 g_assert_cmpint(hb_ot_math_get_glyph_variants (hb_font, glyph, HB_DIRECTION_RTL, 0, NULL, NULL), ==, 0); 437 g_assert_cmpint(hb_ot_math_get_glyph_variants (hb_font, glyph, HB_DIRECTION_BTT, 0, NULL, NULL), ==, 0); 438 closeFont(); 439 440 openFont("fonts/MathTestFontPartial3.otf"); 441 g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph)); 442 g_assert_cmpint(hb_ot_math_get_glyph_variants (hb_font, glyph, HB_DIRECTION_RTL, 0, NULL, NULL), ==, 0); 443 g_assert_cmpint(hb_ot_math_get_glyph_variants (hb_font, glyph, HB_DIRECTION_BTT, 0, NULL, NULL), ==, 0); 444 closeFont(); 445 446 openFont("fonts/MathTestFontPartial4.otf"); 447 g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph)); 448 g_assert_cmpint(hb_ot_math_get_glyph_variants (hb_font, glyph, HB_DIRECTION_RTL, 0, NULL, NULL), ==, 0); 449 g_assert_cmpint(hb_ot_math_get_glyph_variants (hb_font, glyph, HB_DIRECTION_BTT, 0, NULL, NULL), ==, 0); 450 closeFont(); 451 452 openFont("fonts/MathTestFontFull.otf"); 453 454 g_assert(hb_font_get_glyph_from_name (hb_font, "arrowleft", -1, &glyph)); 455 g_assert_cmpint(hb_ot_math_get_glyph_variants (hb_font, 456 glyph, 457 HB_DIRECTION_BTT, 458 0, 459 NULL, 460 NULL), ==, 0); 461 g_assert_cmpint(hb_ot_math_get_glyph_variants (hb_font, 462 glyph, 463 HB_DIRECTION_RTL, 464 0, 465 NULL, 466 NULL), ==, 3); 467 468 g_assert(hb_font_get_glyph_from_name (hb_font, "arrowup", -1, &glyph)); 469 g_assert_cmpint(hb_ot_math_get_glyph_variants (hb_font, 470 glyph, 471 HB_DIRECTION_BTT, 472 0, 473 NULL, 474 NULL), ==, 4); 475 g_assert_cmpint(hb_ot_math_get_glyph_variants (hb_font, 476 glyph, 477 HB_DIRECTION_RTL, 478 0, 479 NULL, 480 NULL), ==, 0); 481 482 g_assert(hb_font_get_glyph_from_name (hb_font, "arrowleft", -1, &glyph)); 483 do { 484 count = variantsSize; 485 hb_ot_math_get_glyph_variants (hb_font, 486 glyph, 487 HB_DIRECTION_RTL, 488 offset, 489 &count, 490 variants); 491 offset += count; 492 } while (count == variantsSize); 493 g_assert_cmpint(offset, ==, 3); 494 g_assert(hb_font_get_glyph_from_name (hb_font, "uni2190_size2", -1, &glyph)); 495 g_assert_cmpint(variants[0].glyph, ==, glyph); 496 g_assert_cmpint(variants[0].advance, ==, 4302); 497 g_assert(hb_font_get_glyph_from_name (hb_font, "uni2190_size3", -1, &glyph)); 498 g_assert_cmpint(variants[1].glyph, ==, glyph); 499 g_assert_cmpint(variants[1].advance, ==, 4802); 500 g_assert(hb_font_get_glyph_from_name (hb_font, "uni2190_size4", -1, &glyph)); 501 g_assert_cmpint(variants[2].glyph, ==, glyph); 502 g_assert_cmpint(variants[2].advance, ==, 5802); 503 504 g_assert(hb_font_get_glyph_from_name (hb_font, "arrowup", -1, &glyph)); 505 offset = 0; 506 do { 507 count = variantsSize; 508 hb_ot_math_get_glyph_variants (hb_font, 509 glyph, 510 HB_DIRECTION_BTT, 511 offset, 512 &count, 513 variants); 514 offset += count; 515 } while (count == variantsSize); 516 g_assert_cmpint(offset, ==, 4); 517 g_assert(hb_font_get_glyph_from_name (hb_font, "uni2191_size2", -1, &glyph)); 518 g_assert_cmpint(variants[0].glyph, ==, glyph); 519 g_assert_cmpint(variants[0].advance, ==, 2251); 520 g_assert(hb_font_get_glyph_from_name (hb_font, "uni2191_size3", -1, &glyph)); 521 g_assert_cmpint(variants[1].glyph, ==, glyph); 522 g_assert_cmpint(variants[1].advance, ==, 2501); 523 g_assert(hb_font_get_glyph_from_name (hb_font, "uni2191_size4", -1, &glyph)); 524 g_assert_cmpint(variants[2].glyph, ==, glyph); 525 g_assert_cmpint(variants[2].advance, ==, 3001); 526 g_assert(hb_font_get_glyph_from_name (hb_font, "uni2191_size5", -1, &glyph)); 527 g_assert_cmpint(variants[3].glyph, ==, glyph); 528 g_assert_cmpint(variants[3].advance, ==, 3751); 529 530 closeFont(); 531 532 cleanupFreeType(); 533} 534 535static void 536test_get_glyph_assembly (void) 537{ 538 hb_codepoint_t glyph; 539 hb_ot_math_glyph_part_t parts[20]; 540 unsigned partsSize = sizeof (parts) / sizeof (parts[0]); 541 unsigned int count; 542 unsigned int offset = 0; 543 544 initFreeType(); 545 546 openFont("fonts/MathTestFontEmpty.otf"); 547 g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph)); 548 g_assert_cmpint(hb_ot_math_get_glyph_assembly (hb_font, glyph, HB_DIRECTION_RTL, 0, NULL, NULL, NULL), ==, 0); 549 g_assert_cmpint(hb_ot_math_get_glyph_assembly (hb_font, glyph, HB_DIRECTION_BTT, 0, NULL, NULL, NULL), ==, 0); 550 closeFont(); 551 552 openFont("fonts/MathTestFontPartial1.otf"); 553 g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph)); 554 g_assert_cmpint(hb_ot_math_get_glyph_assembly (hb_font, glyph, HB_DIRECTION_RTL, 0, NULL, NULL, NULL), ==, 0); 555 g_assert_cmpint(hb_ot_math_get_glyph_assembly (hb_font, glyph, HB_DIRECTION_BTT, 0, NULL, NULL, NULL), ==, 0); 556 closeFont(); 557 558 openFont("fonts/MathTestFontPartial2.otf"); 559 g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph)); 560 g_assert_cmpint(hb_ot_math_get_glyph_assembly (hb_font, glyph, HB_DIRECTION_RTL, 0, NULL, NULL, NULL), ==, 0); 561 g_assert_cmpint(hb_ot_math_get_glyph_assembly (hb_font, glyph, HB_DIRECTION_BTT, 0, NULL, NULL, NULL), ==, 0); 562 closeFont(); 563 564 openFont("fonts/MathTestFontPartial3.otf"); 565 g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph)); 566 g_assert_cmpint(hb_ot_math_get_glyph_assembly (hb_font, glyph, HB_DIRECTION_RTL, 0, NULL, NULL, NULL), ==, 0); 567 g_assert_cmpint(hb_ot_math_get_glyph_assembly (hb_font, glyph, HB_DIRECTION_BTT, 0, NULL, NULL, NULL), ==, 0); 568 closeFont(); 569 570 openFont("fonts/MathTestFontPartial4.otf"); 571 g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph)); 572 g_assert_cmpint(hb_ot_math_get_glyph_assembly (hb_font, glyph, HB_DIRECTION_RTL, 0, NULL, NULL, NULL), ==, 0); 573 g_assert_cmpint(hb_ot_math_get_glyph_assembly (hb_font, glyph, HB_DIRECTION_BTT, 0, NULL, NULL, NULL), ==, 0); 574 closeFont(); 575 576 openFont("fonts/MathTestFontFull.otf"); 577 578 g_assert(hb_font_get_glyph_from_name (hb_font, "arrowright", -1, &glyph)); 579 g_assert_cmpint(hb_ot_math_get_glyph_assembly (hb_font, 580 glyph, 581 HB_DIRECTION_BTT, 582 0, 583 NULL, 584 NULL, 585 NULL), ==, 0); 586 g_assert_cmpint(hb_ot_math_get_glyph_assembly (hb_font, 587 glyph, 588 HB_DIRECTION_RTL, 589 0, 590 NULL, 591 NULL, 592 NULL), ==, 3); 593 594 g_assert(hb_font_get_glyph_from_name (hb_font, "arrowdown", -1, &glyph)); 595 g_assert_cmpint(hb_ot_math_get_glyph_assembly (hb_font, 596 glyph, 597 HB_DIRECTION_BTT, 598 0, 599 NULL, 600 NULL, 601 NULL), ==, 5); 602 g_assert_cmpint(hb_ot_math_get_glyph_assembly (hb_font, 603 glyph, 604 HB_DIRECTION_RTL, 605 0, 606 NULL, 607 NULL, 608 NULL), ==, 0); 609 610 g_assert(hb_font_get_glyph_from_name (hb_font, "arrowright", -1, &glyph)); 611 do { 612 count = partsSize; 613 hb_ot_math_get_glyph_assembly (hb_font, 614 glyph, 615 HB_DIRECTION_RTL, 616 offset, 617 &count, 618 parts, 619 NULL); 620 offset += count; 621 } while (count == partsSize); 622 g_assert_cmpint(offset, ==, 3); 623 g_assert(hb_font_get_glyph_from_name (hb_font, "left", -1, &glyph)); 624 g_assert_cmpint(parts[0].glyph, ==, glyph); 625 g_assert_cmpint(parts[0].start_connector_length, ==, 800); 626 g_assert_cmpint(parts[0].end_connector_length, ==, 384); 627 g_assert_cmpint(parts[0].full_advance, ==, 2000); 628 g_assert(!(parts[0].flags & HB_MATH_GLYPH_PART_FLAG_EXTENDER)); 629 g_assert(hb_font_get_glyph_from_name (hb_font, "horizontal", -1, &glyph)); 630 g_assert_cmpint(parts[1].glyph, ==, glyph); 631 g_assert_cmpint(parts[1].start_connector_length, ==, 524); 632 g_assert_cmpint(parts[1].end_connector_length, ==, 800); 633 g_assert_cmpint(parts[1].full_advance, ==, 2000); 634 g_assert(parts[1].flags & HB_MATH_GLYPH_PART_FLAG_EXTENDER); 635 g_assert(hb_font_get_glyph_from_name (hb_font, "right", -1, &glyph)); 636 g_assert_cmpint(parts[2].glyph, ==, glyph); 637 g_assert_cmpint(parts[2].start_connector_length, ==, 316); 638 g_assert_cmpint(parts[2].end_connector_length, ==, 454); 639 g_assert_cmpint(parts[2].full_advance, ==, 2000); 640 g_assert(!(parts[2].flags & HB_MATH_GLYPH_PART_FLAG_EXTENDER)); 641 642 g_assert(hb_font_get_glyph_from_name (hb_font, "arrowdown", -1, &glyph)); 643 offset = 0; 644 do { 645 count = partsSize; 646 hb_ot_math_get_glyph_assembly (hb_font, 647 glyph, 648 HB_DIRECTION_BTT, 649 offset, 650 &count, 651 parts, 652 NULL); 653 offset += count; 654 } while (count == partsSize); 655 g_assert_cmpint(offset, ==, 5); 656 g_assert(hb_font_get_glyph_from_name (hb_font, "bottom", -1, &glyph)); 657 g_assert_cmpint(parts[0].glyph, ==, glyph); 658 g_assert_cmpint(parts[0].start_connector_length, ==, 365); 659 g_assert_cmpint(parts[0].end_connector_length, ==, 158); 660 g_assert_cmpint(parts[0].full_advance, ==, 1000); 661 g_assert(!(parts[0].flags & HB_MATH_GLYPH_PART_FLAG_EXTENDER)); 662 g_assert(hb_font_get_glyph_from_name (hb_font, "vertical", -1, &glyph)); 663 g_assert_cmpint(parts[1].glyph, ==, glyph); 664 g_assert_cmpint(parts[1].glyph, ==, glyph); 665 g_assert_cmpint(parts[1].start_connector_length, ==, 227); 666 g_assert_cmpint(parts[1].end_connector_length, ==, 365); 667 g_assert_cmpint(parts[1].full_advance, ==, 1000); 668 g_assert(parts[1].flags & HB_MATH_GLYPH_PART_FLAG_EXTENDER); 669 g_assert(hb_font_get_glyph_from_name (hb_font, "center", -1, &glyph)); 670 g_assert_cmpint(parts[2].glyph, ==, glyph); 671 g_assert_cmpint(parts[2].start_connector_length, ==, 54); 672 g_assert_cmpint(parts[2].end_connector_length, ==, 158); 673 g_assert_cmpint(parts[2].full_advance, ==, 1000); 674 g_assert(!(parts[2].flags & HB_MATH_GLYPH_PART_FLAG_EXTENDER)); 675 g_assert(hb_font_get_glyph_from_name (hb_font, "vertical", -1, &glyph)); 676 g_assert_cmpint(parts[3].glyph, ==, glyph); 677 g_assert_cmpint(parts[3].glyph, ==, glyph); 678 g_assert_cmpint(parts[3].glyph, ==, glyph); 679 g_assert_cmpint(parts[3].start_connector_length, ==, 400); 680 g_assert_cmpint(parts[3].end_connector_length, ==, 296); 681 g_assert_cmpint(parts[3].full_advance, ==, 1000); 682 g_assert(parts[1].flags & HB_MATH_GLYPH_PART_FLAG_EXTENDER); 683 g_assert(hb_font_get_glyph_from_name (hb_font, "top", -1, &glyph)); 684 g_assert_cmpint(parts[4].glyph, ==, glyph); 685 g_assert_cmpint(parts[4].start_connector_length, ==, 123); 686 g_assert_cmpint(parts[4].end_connector_length, ==, 192); 687 g_assert_cmpint(parts[4].full_advance, ==, 1000); 688 g_assert(!(parts[4].flags & HB_MATH_GLYPH_PART_FLAG_EXTENDER)); 689 690 closeFont(); 691 692 cleanupFreeType(); 693} 694 695int 696main (int argc, char **argv) 697{ 698 hb_test_init (&argc, &argv); 699 700 hb_test_add (test_has_data); 701 hb_test_add (test_get_constant); 702 hb_test_add (test_get_glyph_italics_correction); 703 hb_test_add (test_get_glyph_top_accent_attachment); 704 hb_test_add (test_is_glyph_extended_shape); 705 hb_test_add (test_get_glyph_kerning); 706 hb_test_add (test_get_glyph_assembly_italics_correction); 707 hb_test_add (test_get_min_connector_overlap); 708 hb_test_add (test_get_glyph_variants); 709 hb_test_add (test_get_glyph_assembly); 710 711 return hb_test_run(); 712} 713