2 * Copyright © 2020 Ebrahim Byagowi
4 * This is part of HarfBuzz, a text shaping library.
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.
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
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.
33 typedef struct draw_data_t
40 /* Our modified itoa, why not using libc's? it is going to be used
41 in harfbuzzjs where libc isn't available */
42 static void _hb_reverse (char *buf, unsigned int len)
44 unsigned start = 0, end = len - 1;
48 buf[end] = buf[start];
53 static unsigned _hb_itoa (float fnum, char *buf)
55 int32_t num = (int32_t) floorf (fnum + .5f);
57 hb_bool_t is_negative = num < 0;
58 if (is_negative) num = -num;
61 buf[i++] = '0' + num % 10;
64 if (is_negative) buf[i++] = '-';
70 #define ITOA_BUF_SIZE 12 // 10 digits in int32, 1 for negative sign, 1 for \0
77 g_assert_cmpmem (s, 5, "54321", 5);
81 char buf[ITOA_BUF_SIZE];
82 unsigned len = _hb_itoa (num, buf);
83 g_assert_cmpmem (buf, len, "12345", 5);
88 char buf[ITOA_BUF_SIZE];
89 unsigned len = _hb_itoa (num, buf);
90 g_assert_cmpmem (buf, len, "3152", 4);
95 char buf[ITOA_BUF_SIZE];
96 unsigned len = _hb_itoa (num, buf);
97 g_assert_cmpmem (buf, len, "-6457", 5);
102 move_to (hb_draw_funcs_t *dfuncs, draw_data_t *draw_data,
104 float to_x, float to_y,
107 /* 4 = command character space + comma + array starts with 0 index + nul character space */
108 if (draw_data->consumed + 2 * ITOA_BUF_SIZE + 4 > draw_data->size) return;
109 draw_data->str[draw_data->consumed++] = 'M';
110 draw_data->consumed += _hb_itoa (to_x, draw_data->str + draw_data->consumed);
111 draw_data->str[draw_data->consumed++] = ',';
112 draw_data->consumed += _hb_itoa (to_y, draw_data->str + draw_data->consumed);
116 line_to (hb_draw_funcs_t *dfuncs, draw_data_t *draw_data,
118 float to_x, float to_y,
121 if (draw_data->consumed + 2 * ITOA_BUF_SIZE + 4 > draw_data->size) return;
122 draw_data->str[draw_data->consumed++] = 'L';
123 draw_data->consumed += _hb_itoa (to_x, draw_data->str + draw_data->consumed);
124 draw_data->str[draw_data->consumed++] = ',';
125 draw_data->consumed += _hb_itoa (to_y, draw_data->str + draw_data->consumed);
129 quadratic_to (hb_draw_funcs_t *dfuncs, draw_data_t *draw_data,
131 float control_x, float control_y,
132 float to_x, float to_y,
136 if (draw_data->consumed + 4 * ITOA_BUF_SIZE + 6 > draw_data->size) return;
137 draw_data->str[draw_data->consumed++] = 'Q';
138 draw_data->consumed += _hb_itoa (control_x, draw_data->str + draw_data->consumed);
139 draw_data->str[draw_data->consumed++] = ',';
140 draw_data->consumed += _hb_itoa (control_y, draw_data->str + draw_data->consumed);
141 draw_data->str[draw_data->consumed++] = ' ';
142 draw_data->consumed += _hb_itoa (to_x, draw_data->str + draw_data->consumed);
143 draw_data->str[draw_data->consumed++] = ',';
144 draw_data->consumed += _hb_itoa (to_y, draw_data->str + draw_data->consumed);
148 cubic_to (hb_draw_funcs_t *dfuncs, draw_data_t *draw_data,
150 float control1_x, float control1_y,
151 float control2_x, float control2_y,
152 float to_x, float to_y,
155 if (draw_data->consumed + 6 * ITOA_BUF_SIZE + 8 > draw_data->size) return;
156 draw_data->str[draw_data->consumed++] = 'C';
157 draw_data->consumed += _hb_itoa (control1_x, draw_data->str + draw_data->consumed);
158 draw_data->str[draw_data->consumed++] = ',';
159 draw_data->consumed += _hb_itoa (control1_y, draw_data->str + draw_data->consumed);
160 draw_data->str[draw_data->consumed++] = ' ';
161 draw_data->consumed += _hb_itoa (control2_x, draw_data->str + draw_data->consumed);
162 draw_data->str[draw_data->consumed++] = ',';
163 draw_data->consumed += _hb_itoa (control2_y, draw_data->str + draw_data->consumed);
164 draw_data->str[draw_data->consumed++] = ' ';
165 draw_data->consumed += _hb_itoa (to_x, draw_data->str + draw_data->consumed);
166 draw_data->str[draw_data->consumed++] = ',';
167 draw_data->consumed += _hb_itoa (to_y, draw_data->str + draw_data->consumed);
171 close_path (hb_draw_funcs_t *dfuncs, draw_data_t *draw_data,
175 if (draw_data->consumed + 2 > draw_data->size) return;
176 draw_data->str[draw_data->consumed++] = 'Z';
179 static hb_draw_funcs_t *funcs;
180 static hb_draw_funcs_t *funcs2; /* this one translates quadratic calls to cubic ones */
183 test_hb_draw_empty (void)
185 hb_font_draw_glyph (hb_font_get_empty (), 3, funcs, NULL);
189 test_hb_draw_glyf (void)
191 hb_face_t *face = hb_test_open_font_file ("fonts/SourceSerifVariable-Roman-VVAR.abc.ttf");
192 hb_font_t *font = hb_font_create (face);
193 hb_face_destroy (face);
196 draw_data_t draw_data = {
198 .size = sizeof (str),
202 draw_data.consumed = 0;
203 hb_font_draw_glyph (font, 4, funcs, &draw_data);
205 draw_data.consumed = 0;
206 hb_font_draw_glyph (font, 3, funcs, &draw_data);
207 char expected[] = "M275,442Q232,442 198,420Q164,397 145,353Q126,309 126,245"
208 "Q126,182 147,139Q167,95 204,73Q240,50 287,50Q330,50 367,70"
209 "Q404,90 427,128L451,116Q431,54 384,21Q336,-13 266,-13"
210 "Q198,-13 148,18Q97,48 70,104Q43,160 43,236Q43,314 76,371"
211 "Q108,427 160,457Q212,487 272,487Q316,487 354,470Q392,453 417,424"
212 "Q442,395 448,358Q441,321 403,321Q378,321 367,334"
213 "Q355,347 350,366L325,454L371,417Q346,430 321,436Q296,442 275,442Z";
214 g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1);
216 /* Test translating quadratic calls to cubic by a _draw_funcs_t that doesn't set the callback */
217 draw_data.consumed = 0;
218 hb_font_draw_glyph (font, 3, funcs2, &draw_data);
219 char expected2[] = "M275,442C246,442 221,435 198,420C175,405 158,382 145,353"
220 "C132,324 126,288 126,245C126,203 133,168 147,139C160,110 179,88 204,73"
221 "C228,58 256,50 287,50C316,50 342,57 367,70C392,83 412,103 427,128"
222 "L451,116C438,75 415,43 384,21C352,-2 313,-13 266,-13C221,-13 181,-3 148,18"
223 "C114,38 88,67 70,104C52,141 43,185 43,236C43,288 54,333 76,371"
224 "C97,408 125,437 160,457C195,477 232,487 272,487C301,487 329,481 354,470"
225 "C379,459 400,443 417,424C434,405 444,383 448,358C443,333 428,321 403,321"
226 "C386,321 374,325 367,334C359,343 353,353 350,366L325,454L371,417"
227 "C354,426 338,432 321,436C304,440 289,442 275,442Z";
228 g_assert_cmpmem (str, draw_data.consumed, expected2, sizeof (expected2) - 1);
231 var.tag = HB_TAG ('w','g','h','t');
233 hb_font_set_variations (font, &var, 1);
235 draw_data.consumed = 0;
236 hb_font_draw_glyph (font, 3, funcs, &draw_data);
237 char expected3[] = "M323,448Q297,448 271,430Q244,412 226,371Q209,330 209,261"
238 "Q209,204 225,166Q242,127 272,107Q303,86 344,86Q378,86 404,101"
239 "Q430,115 451,137L488,103Q458,42 404,13Q350,-16 279,-16"
240 "Q211,-16 153,13Q95,41 60,98Q25,156 25,241Q25,323 62,382"
241 "Q99,440 163,470Q226,501 303,501Q357,501 399,480Q440,460 464,426"
242 "Q488,392 492,352Q475,297 420,297Q390,297 366,319Q342,342 339,401"
243 "L333,469L411,427Q387,438 367,443Q348,448 323,448Z";
244 g_assert_cmpmem (str, draw_data.consumed, expected3, sizeof (expected3) - 1);
246 hb_font_destroy (font);
250 test_hb_draw_cff1 (void)
252 hb_face_t *face = hb_test_open_font_file ("fonts/cff1_seac.otf");
253 hb_font_t *font = hb_font_create (face);
254 hb_face_destroy (face);
257 draw_data_t draw_data = {
259 .size = sizeof (str),
262 hb_font_draw_glyph (font, 3, funcs, &draw_data);
263 char expected[] = "M203,367C227,440 248,512 268,588L272,588C293,512 314,440 338,367L369,267L172,267L203,367Z"
264 "M3,0L88,0L151,200L390,200L452,0L541,0L319,656L225,656L3,0Z"
265 "M300,653L342,694L201,861L143,806L300,653Z";
266 g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1);
268 hb_font_destroy (font);
272 test_hb_draw_cff1_rline (void)
274 /* https://github.com/harfbuzz/harfbuzz/pull/2053 */
275 hb_face_t *face = hb_test_open_font_file ("fonts/RanaKufi-Regular.subset.otf");
276 hb_font_t *font = hb_font_create (face);
277 hb_face_destroy (face);
280 draw_data_t draw_data = {
282 .size = sizeof (str),
285 hb_font_draw_glyph (font, 1, funcs, &draw_data);
286 char expected[] = "M775,400C705,400 650,343 650,274L650,250L391,250L713,572L392,893"
287 "L287,1000C311,942 296,869 250,823C250,823 286,858 321,823L571,572"
288 "L150,150L750,150L750,276C750,289 761,300 775,300C789,300 800,289 800,276"
289 "L800,100L150,100C100,100 100,150 100,150C100,85 58,23 0,0L900,0L900,274"
290 "C900,343 844,400 775,400Z";
291 g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1);
293 hb_font_destroy (font);
297 test_hb_draw_cff2 (void)
299 hb_face_t *face = hb_test_open_font_file ("fonts/AdobeVFPrototype.abc.otf");
300 hb_font_t *font = hb_font_create (face);
301 hb_face_destroy (face);
304 draw_data_t draw_data = {
309 draw_data.consumed = 0;
310 hb_font_draw_glyph (font, 3, funcs, &draw_data);
311 char expected[] = "M275,442C303,442 337,435 371,417L325,454L350,366"
312 "C357,341 370,321 403,321C428,321 443,333 448,358"
313 "C435,432 361,487 272,487C153,487 43,393 43,236"
314 "C43,83 129,-13 266,-13C360,-13 424,33 451,116L427,128"
315 "C396,78 345,50 287,50C193,50 126,119 126,245C126,373 188,442 275,442Z";
316 g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1);
319 var.tag = HB_TAG ('w','g','h','t');
321 hb_font_set_variations (font, &var, 1);
323 draw_data.consumed = 0;
324 hb_font_draw_glyph (font, 3, funcs, &draw_data);
325 char expected2[] = "M323,448C356,448 380,441 411,427L333,469L339,401"
326 "C343,322 379,297 420,297C458,297 480,314 492,352"
327 "C486,433 412,501 303,501C148,501 25,406 25,241"
328 "C25,70 143,-16 279,-16C374,-16 447,22 488,103L451,137"
329 "C423,107 390,86 344,86C262,86 209,148 209,261C209,398 271,448 323,448Z";
330 g_assert_cmpmem (str, draw_data.consumed, expected2, sizeof (expected2) - 1);
332 hb_font_destroy (font);
336 test_hb_draw_ttf_parser_tests (void)
338 /* https://github.com/RazrFalcon/ttf-parser/blob/337e7d1c/tests/tests.rs#L50-L133 */
340 draw_data_t draw_data = {
345 hb_face_t *face = hb_test_open_font_file ("fonts/glyphs.ttf");
346 hb_font_t *font = hb_font_create (face);
347 hb_face_destroy (face);
349 draw_data.consumed = 0;
350 hb_font_draw_glyph (font, 0, funcs, &draw_data);
351 char expected[] = "M50,0L50,750L450,750L450,0L50,0Z";
352 g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1);
355 draw_data.consumed = 0;
356 hb_font_draw_glyph (font, 1, funcs, &draw_data);
357 char expected[] = "M56,416L56,487L514,487L514,416L56,416ZM56,217L56,288L514,288L514,217L56,217Z";
358 g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1);
361 draw_data.consumed = 0;
362 hb_font_draw_glyph (font, 4, funcs, &draw_data);
363 char expected[] = "M332,468L197,468L197,0L109,0L109,468L15,468L15,509L109,539"
364 "L109,570Q109,674 155,720Q201,765 283,765Q315,765 342,760"
365 "Q368,754 387,747L364,678Q348,683 327,688Q306,693 284,693"
366 "Q240,693 219,664Q197,634 197,571L197,536L332,536L332,468Z"
367 "M474,737Q494,737 510,724Q525,710 525,681Q525,653 510,639"
368 "Q494,625 474,625Q452,625 437,639Q422,653 422,681"
369 "Q422,710 437,724Q452,737 474,737ZM517,536L517,0L429,0L429,536L517,536Z";
370 g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1);
373 draw_data.consumed = 0;
374 hb_font_draw_glyph (font, 5, funcs, &draw_data);
375 char expected[] = "M15,0Q15,0 15,0Z";
376 g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1);
379 draw_data.consumed = 0;
380 hb_font_draw_glyph (font, 6, funcs, &draw_data);
381 char expected[] = "M346,468L211,468L211,0L123,0L123,468L29,468L29,509L123,539"
382 "L123,570Q123,674 169,720Q215,765 297,765Q329,765 356,760"
383 "Q382,754 401,747L378,678Q362,683 341,688Q320,693 298,693"
384 "Q254,693 233,664Q211,634 211,571L211,536L346,536L346,468Z"
386 g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1);
389 hb_font_destroy (font);
392 hb_face_t *face = hb_test_open_font_file ("fonts/cff1_flex.otf");
393 hb_font_t *font = hb_font_create (face);
394 hb_face_destroy (face);
396 draw_data.consumed = 0;
397 hb_font_draw_glyph (font, 1, funcs, &draw_data);
398 char expected[] = "M0,0C100,0 150,-20 250,-20C350,-20 400,0 500,0C500,100 520,150 520,250"
399 "C520,350 500,400 500,500C400,500 350,520 250,520C150,520 100,500 0,500"
400 "C0,400 -20,350 -20,250C-20,150 0,100 0,0ZM50,50C50,130 34,170 34,250"
401 "C34,330 50,370 50,450C130,450 170,466 250,466C330,466 370,450 450,450"
402 "C450,370 466,330 466,250C466,170 450,130 450,50C370,50 330,34 250,34"
403 "C170,34 130,50 50,50Z";
404 g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1);
406 hb_font_destroy (font);
409 hb_face_t *face = hb_test_open_font_file ("fonts/cff1_dotsect.nohints.otf");
410 hb_font_t *font = hb_font_create (face);
411 hb_face_destroy (face);
413 draw_data.consumed = 0;
414 hb_font_draw_glyph (font, 1, funcs, &draw_data);
415 char expected[] = "M82,0L164,0L164,486L82,486L82,0Z"
416 "M124,586C156,586 181,608 181,639C181,671 156,692 124,692"
417 "C92,692 67,671 67,639C67,608 92,586 124,586Z";
418 g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1);
420 hb_font_destroy (font);
425 test_hb_draw_font_kit_glyphs_tests (void)
427 /* https://github.com/foliojs/fontkit/blob/master/test/glyphs.js */
429 draw_data_t draw_data = {
433 /* truetype glyphs */
435 hb_face_t *face = hb_test_open_font_file ("fonts/OpenSans-Regular.ttf");
436 hb_font_t *font = hb_font_create (face);
437 hb_face_destroy (face);
439 /* should get a path for the glyph */
440 draw_data.consumed = 0;
441 hb_font_draw_glyph (font, 37, funcs, &draw_data);
442 char expected[] = "M201,1462L614,1462Q905,1462 1035,1375Q1165,1288 1165,1100"
443 "Q1165,970 1093,886Q1020,801 881,776L881,766Q1214,709 1214,416"
444 "Q1214,220 1082,110Q949,0 711,0L201,0L201,1462ZM371,836L651,836"
445 "Q831,836 910,893Q989,949 989,1083Q989,1206 901,1261"
446 "Q813,1315 621,1315L371,1315L371,836ZM371,692L371,145L676,145"
447 "Q853,145 943,214Q1032,282 1032,428Q1032,564 941,628Q849,692 662,692L371,692Z";
448 g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1);
450 /* should get a path for the glyph */
451 draw_data.consumed = 0;
452 hb_font_draw_glyph (font, 171, funcs, &draw_data);
453 char expected2[] = "M639,-20Q396,-20 256,128Q115,276 115,539Q115,804 246,960Q376,1116 596,1116"
454 "Q802,1116 922,981Q1042,845 1042,623L1042,518L287,518Q292,325 385,225"
455 "Q477,125 645,125Q822,125 995,199L995,51Q907,13 829,-3Q750,-20 639,-20Z"
456 "M594,977Q462,977 384,891Q305,805 291,653L864,653Q864,810 794,894"
457 "Q724,977 594,977ZM471,1266Q519,1328 575,1416Q630,1504 662,1569"
458 "L864,1569L864,1548Q820,1483 733,1388Q646,1293 582,1241L471,1241L471,1266Z";
459 g_assert_cmpmem (str, draw_data.consumed, expected2, sizeof (expected2) - 1);
461 hb_font_destroy (font);
464 hb_face_t *face = hb_test_open_font_file ("fonts/Mada-VF.ttf");
465 hb_font_t *font = hb_font_create (face);
466 hb_face_destroy (face);
468 hb_buffer_t *buffer = hb_buffer_create ();
469 hb_codepoint_t codepoint = 1610; /* ي */
470 hb_buffer_add_codepoints (buffer, &codepoint, 1, 0, -1);
471 hb_buffer_set_direction (buffer, HB_DIRECTION_RTL);
472 hb_shape (font, buffer, NULL, 0);
473 codepoint = hb_buffer_get_glyph_infos (buffer, NULL)[0].codepoint;
474 hb_buffer_destroy (buffer);
476 /* should resolve composite glyphs recursively */
477 draw_data.consumed = 0;
478 hb_font_draw_glyph (font, codepoint, funcs, &draw_data);
479 char expected[] = "M581,274L443,274Q409,274 384,259Q359,243 348,219Q336,194 340,166"
480 "Q343,138 365,111L468,-13Q470,-10 473,-6Q475,-3 477,0L253,0Q225,0 203,8"
481 "Q180,15 168,32Q155,48 155,73L155,269L50,269L50,73Q50,24 69,-10"
482 "Q88,-44 118,-64Q147,-85 181,-94Q214,-104 243,-104L473,-104"
483 "Q501,-104 525,-91Q549,-78 564,-56Q578,-34 578,-8Q578,18 557,43"
484 "L442,182Q439,179 437,176Q435,173 432,170L581,170L581,274ZM184,-194"
485 "Q184,-216 199,-231Q214,-246 236,-246Q258,-246 273,-231Q288,-216 288,-194"
486 "Q288,-172 273,-157Q258,-142 236,-142Q214,-142 199,-157Q184,-172 184,-194Z"
487 "M360,-194Q360,-216 375,-231Q390,-246 412,-246Q434,-246 449,-231"
488 "Q464,-216 464,-194Q464,-172 449,-157Q434,-142 412,-142"
489 "Q390,-142 375,-157Q360,-172 360,-194Z";
490 g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1);
492 /* should transform points of a composite glyph */
493 draw_data.consumed = 0;
494 hb_font_draw_glyph (font, 2, funcs, &draw_data); /* 2 == arAlef.fina */
495 char expected2[] = "M155,624L155,84Q150,90 146,95Q141,99 136,105"
496 "L292,105L292,0L156,0Q128,0 104,14Q79,27 65,51"
497 "Q50,74 50,104L50,624L155,624ZM282,105L312,105"
498 "L312,0L282,0L282,105Z";
499 g_assert_cmpmem (str, draw_data.consumed, expected2, sizeof (expected2) - 1);
501 hb_font_destroy (font);
503 /* CFF glyphs, should get a path for the glyph */
505 hb_face_t *face = hb_test_open_font_file ("fonts/SourceSansPro-Regular.otf");
506 hb_font_t *font = hb_font_create (face);
507 hb_face_destroy (face);
509 draw_data.consumed = 0;
510 hb_font_draw_glyph (font, 5, funcs, &draw_data);
511 char expected[] = "M90,0L258,0C456,0 564,122 564,331C564,539 456,656 254,656L90,656L90,0Z"
512 "M173,68L173,588L248,588C401,588 478,496 478,331C478,165 401,68 248,68L173,68Z";
513 g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1);
515 hb_font_destroy (font);
517 /* CFF glyphs (CID font) */
519 /* replaced with a subset as the original one was 15MB */
520 hb_face_t *face = hb_test_open_font_file ("fonts/NotoSansCJKkr-Regular-subset-colon.ttf");
521 hb_font_t *font = hb_font_create (face);
522 hb_face_destroy (face);
524 draw_data.consumed = 0;
525 hb_font_draw_glyph (font, 1, funcs, &draw_data);
526 char expected[] = "M139,390C175,390 205,419 205,459C205,501 175,530 139,530C103,530 73,501 73,459"
527 "C73,419 103,390 139,390ZM139,-13C175,-13 205,15 205,56C205,97 175,127 139,127"
528 "C103,127 73,97 73,56C73,15 103,-13 139,-13Z";
529 g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1);
531 hb_font_destroy (font);
533 /* Skip SBIX glyphs (empty path), COLR glyphs (empty path), WOFF ttf glyphs, WOFF2 ttf glyph */
537 test_hb_draw_font_kit_variations_tests (void)
539 /* https://github.com/foliojs/fontkit/blob/b310db5/test/variations.js */
541 draw_data_t draw_data = {
547 /* Skipping Skia tests for now even the fact we can actually do platform specific tests using our CIs */
549 /* truetype variations */
550 /* should support sharing all points */
552 hb_face_t *face = hb_test_open_font_file ("fonts/TestGVAROne.ttf");
553 hb_font_t *font = hb_font_create (face);
554 hb_face_destroy (face);
557 var.tag = HB_TAG ('w','g','h','t');
559 hb_font_set_variations (font, &var, 1);
561 hb_buffer_t *buffer = hb_buffer_create ();
562 hb_codepoint_t codepoint = 24396; /* 彌 */
563 hb_buffer_add_codepoints (buffer, &codepoint, 1, 0, -1);
564 hb_buffer_set_direction (buffer, HB_DIRECTION_LTR);
565 hb_shape (font, buffer, NULL, 0);
566 codepoint = hb_buffer_get_glyph_infos (buffer, NULL)[0].codepoint;
567 hb_buffer_destroy (buffer);
569 draw_data.consumed = 0;
570 hb_font_draw_glyph (font, codepoint, funcs, &draw_data);
571 char expected[] = "M371,-102L371,539L914,539L914,-27Q914,-102 840,-102"
572 "Q796,-102 755,-98L742,-59Q790,-66 836,-66Q871,-66 871,-31L871,504"
573 "L414,504L414,-102L371,-102ZM203,-94Q138,-94 86,-90L74,-52"
574 "Q137,-59 188,-59Q211,-59 222,-46Q233,-34 236,12Q238,58 240,135"
575 "Q242,211 242,262L74,262L94,527L242,527L242,719L63,719L63,754"
576 "L285,754L285,492L133,492L117,297L285,297Q285,241 284,185"
577 "Q284,104 281,46Q278,-20 269,-49Q260,-78 242,-86Q223,-94 203,-94Z"
578 "M461,12L434,43Q473,73 503,115Q478,150 441,188L469,211Q501,179 525,147"
579 "Q538,172 559,230L594,211Q571,152 551,117Q577,84 602,43L566,20"
580 "Q544,64 528,86Q500,44 461,12ZM465,258L438,285Q474,316 501,351"
581 "Q474,388 445,418L473,441Q500,414 523,381Q546,413 563,453L598,434"
582 "Q571,382 549,352Q576,320 598,285L563,262Q546,294 525,322Q491,280 465,258Z"
583 "M707,12L680,43Q717,68 753,115Q731,147 691,188L719,211Q739,190 754,172"
584 "Q769,154 774,147Q793,185 809,230L844,211Q822,155 801,117Q828,82 852,43"
585 "L820,20Q798,58 778,87Q747,43 707,12ZM621,-94L621,730L664,730L664,-94"
586 "L621,-94ZM348,570L324,605Q425,629 527,688L555,656Q491,621 439,601"
587 "Q386,581 348,570ZM715,258L688,285Q727,318 753,351Q733,378 695,418L723,441"
588 "Q754,410 775,381Q794,407 813,453L848,434Q826,387 801,352Q823,321 848,281"
589 "L813,262Q791,301 775,323Q749,288 715,258ZM348,719L348,754L941,754L941,719"
590 "L348,719ZM936,570Q870,602 817,622Q764,641 727,652L749,688Q852,655 957,605L936,570Z";
591 g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1);
593 hb_font_destroy (font);
595 /* should support sharing enumerated points */
597 hb_face_t *face = hb_test_open_font_file ("fonts/TestGVARTwo.ttf");
598 hb_font_t *font = hb_font_create (face);
599 hb_face_destroy (face);
602 var.tag = HB_TAG ('w','g','h','t');
604 hb_font_set_variations (font, &var, 1);
606 hb_buffer_t *buffer = hb_buffer_create ();
607 hb_codepoint_t codepoint = 24396; /* 彌 */
608 hb_buffer_add_codepoints (buffer, &codepoint, 1, 0, -1);
609 hb_buffer_set_direction (buffer, HB_DIRECTION_LTR);
610 hb_shape (font, buffer, NULL, 0);
611 codepoint = hb_buffer_get_glyph_infos (buffer, NULL)[0].codepoint;
612 hb_buffer_destroy (buffer);
614 draw_data.consumed = 0;
615 hb_font_draw_glyph (font, codepoint, funcs, &draw_data);
616 char expected[] = "M371,-102L371,539L914,539L914,-27Q914,-102 840,-102Q796,-102 755,-98"
617 "L742,-59Q790,-66 836,-66Q871,-66 871,-31L871,504L414,504L414,-102"
618 "L371,-102ZM203,-94Q138,-94 86,-90L74,-52Q137,-59 188,-59Q211,-59 222,-46"
619 "Q233,-34 236,12Q238,58 240,135Q242,211 242,262L74,262L94,527L242,527"
620 "L242,719L63,719L63,754L285,754L285,492L133,492L117,297L285,297"
621 "Q285,241 284,185Q284,104 281,46Q278,-20 269,-49Q260,-78 242,-86Q223,-94 203,-94Z"
622 "M461,12L434,43Q473,73 503,115Q478,150 441,188L469,211Q501,179 525,147"
623 "Q538,172 559,230L594,211Q571,152 551,117Q577,84 602,43L566,20"
624 "Q544,64 528,86Q500,44 461,12ZM465,258L438,285Q474,316 501,351"
625 "Q474,388 445,418L473,441Q500,414 523,381Q546,413 563,453L598,434"
626 "Q571,382 549,352Q576,320 598,285L563,262Q546,294 525,322Q491,280 465,258Z"
627 "M707,12L680,43Q717,68 753,115Q731,147 691,188L719,211Q739,190 754,172"
628 "Q769,154 774,147Q793,185 809,230L844,211Q822,155 801,117Q828,82 852,43L820,20"
629 "Q798,58 778,87Q747,43 707,12ZM621,-94L621,730L664,730L664,-94L621,-94ZM348,570"
630 "L324,605Q425,629 527,688L555,656Q491,621 439,601Q386,581 348,570ZM715,258L688,285"
631 "Q727,318 753,351Q733,378 695,418L723,441Q754,410 775,381Q794,407 813,453"
632 "L848,434Q826,387 801,352Q823,321 848,281L813,262Q791,301 775,323Q749,288 715,258Z"
633 "M348,719L348,754L941,754L941,719L348,719ZM936,570Q870,602 817,622"
634 "Q764,641 727,652L749,688Q852,655 957,605L936,570Z";
635 g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1);
637 hb_font_destroy (font);
639 /* should support sharing no points */
641 hb_face_t *face = hb_test_open_font_file ("fonts/TestGVARThree.ttf");
642 hb_font_t *font = hb_font_create (face);
643 hb_face_destroy (face);
646 var.tag = HB_TAG ('w','g','h','t');
648 hb_font_set_variations (font, &var, 1);
650 hb_buffer_t *buffer = hb_buffer_create ();
651 hb_codepoint_t codepoint = 24396; /* 彌 */
652 hb_buffer_add_codepoints (buffer, &codepoint, 1, 0, -1);
653 hb_buffer_set_direction (buffer, HB_DIRECTION_LTR);
654 hb_shape (font, buffer, NULL, 0);
655 codepoint = hb_buffer_get_glyph_infos (buffer, NULL)[0].codepoint;
656 hb_buffer_destroy (buffer);
658 draw_data.consumed = 0;
659 hb_font_draw_glyph (font, codepoint, funcs, &draw_data);
660 char expected[] = "M371,-102L371,539L914,539L914,-27Q914,-102 840,-102Q796,-102 755,-98"
661 "L742,-59Q790,-66 836,-66Q871,-66 871,-31L871,504L414,504L414,-102"
662 "L371,-102ZM203,-94Q138,-94 86,-90L74,-52Q137,-59 188,-59Q211,-59 222,-46"
663 "Q233,-34 236,12Q238,58 240,135Q242,211 242,262L74,262L94,527L242,527L242,719"
664 "L63,719L63,754L285,754L285,492L133,492L117,297L285,297Q285,241 284,185"
665 "Q284,104 281,46Q278,-20 269,-49Q260,-78 242,-86Q223,-94 203,-94ZM461,12"
666 "L434,43Q473,73 503,115Q478,150 441,188L469,211Q501,179 525,147"
667 "Q538,172 559,230L594,211Q571,152 551,117Q577,84 602,43L566,20Q544,64 528,86"
668 "Q500,44 461,12ZM465,258L438,285Q474,316 501,351Q474,388 445,418L473,441"
669 "Q500,414 523,381Q546,413 563,453L598,434Q571,382 549,352Q576,320 598,285"
670 "L563,262Q546,294 525,322Q491,280 465,258ZM707,12L680,43Q717,68 753,115"
671 "Q731,147 691,188L719,211Q739,190 754,172Q769,154 774,147Q793,185 809,230"
672 "L844,211Q822,155 801,117Q828,82 852,43L820,20Q798,58 778,87Q747,43 707,12Z"
673 "M621,-94L621,730L664,730L664,-94L621,-94ZM348,570L324,605Q425,629 527,688"
674 "L555,656Q491,621 439,601Q386,581 348,570ZM715,258L688,285Q727,318 753,351"
675 "Q733,378 695,418L723,441Q754,410 775,381Q794,407 813,453L848,434Q826,387 801,352"
676 "Q823,321 848,281L813,262Q791,301 775,323Q749,288 715,258ZM348,719L348,754"
677 "L941,754L941,719L348,719ZM936,570Q870,602 817,622"
678 "Q764,641 727,652L749,688Q852,655 957,605L936,570Z";
679 g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1);
681 hb_font_destroy (font);
684 /* CFF2 variations */
686 hb_face_t *face = hb_test_open_font_file ("fonts/AdobeVFPrototype-Subset.otf");
687 hb_font_t *font = hb_font_create (face);
688 hb_face_destroy (face);
691 var.tag = HB_TAG ('w','g','h','t');
692 /* applies variations to CFF2 glyphs */
695 hb_font_set_variations (font, &var, 1);
697 hb_buffer_t *buffer = hb_buffer_create ();
698 hb_codepoint_t codepoint = '$';
699 hb_buffer_add_codepoints (buffer, &codepoint, 1, 0, -1);
700 hb_buffer_set_direction (buffer, HB_DIRECTION_LTR);
701 hb_shape (font, buffer, NULL, 0);
702 codepoint = hb_buffer_get_glyph_infos (buffer, NULL)[0].codepoint;
703 hb_buffer_destroy (buffer);
705 draw_data.consumed = 0;
706 hb_font_draw_glyph (font, codepoint, funcs, &draw_data);
707 char expected[] = "M246,15C188,15 147,27 101,68L142,23L117,117C111,143 96,149 81,149"
708 "C65,149 56,141 52,126C71,40 137,-13 244,-13C348,-13 436,46 436,156"
709 "C436,229 405,295 271,349L247,359C160,393 119,439 119,506"
710 "C119,592 178,637 262,637C311,637 346,626 390,585L348,629L373,535"
711 "C380,510 394,503 408,503C424,503 434,510 437,526C418,614 348,665 259,665"
712 "C161,665 78,606 78,500C78,414 128,361 224,321L261,305C367,259 395,217 395,152"
713 "C395,65 334,15 246,15ZM267,331L267,759L240,759L240,331L267,331ZM240,-115"
714 "L267,-115L267,331L240,331L240,-115Z";
715 g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1);
719 hb_font_set_variations (font, &var, 1);
721 hb_buffer_t *buffer = hb_buffer_create ();
722 hb_codepoint_t codepoint = '$';
723 hb_buffer_add_codepoints (buffer, &codepoint, 1, 0, -1);
724 hb_buffer_set_direction (buffer, HB_DIRECTION_LTR);
725 hb_shape (font, buffer, NULL, 0);
726 codepoint = hb_buffer_get_glyph_infos (buffer, NULL)[0].codepoint;
727 hb_buffer_destroy (buffer);
729 draw_data.consumed = 0;
730 hb_font_draw_glyph (font, codepoint, funcs, &draw_data);
731 char expected[] = "M251,36C206,36 165,42 118,61L176,21L161,99C151,152 129,167 101,167"
732 "C78,167 61,155 51,131C54,43 133,-14 247,-14C388,-14 474,64 474,171"
733 "C474,258 430,321 294,370L257,383C188,406 150,438 150,499"
734 "C150,571 204,606 276,606C308,606 342,601 386,582L327,621"
735 "L343,546C355,490 382,476 408,476C428,476 448,487 455,512"
736 "C450,597 370,656 264,656C140,656 57,576 57,474C57,373 119,318 227,279"
737 "L263,266C345,236 379,208 379,145C379,76 329,36 251,36ZM289,320"
738 "L289,746L242,746L242,320L289,320ZM240,-115L286,-115L286,320L240,320L240,-115Z";
739 g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1);
741 /* substitutes GSUB features depending on variations */
744 hb_font_set_variations (font, &var, 1);
746 hb_buffer_t *buffer = hb_buffer_create ();
747 hb_codepoint_t codepoint = '$';
748 hb_buffer_add_codepoints (buffer, &codepoint, 1, 0, -1);
749 hb_buffer_set_direction (buffer, HB_DIRECTION_LTR);
750 hb_shape (font, buffer, NULL, 0);
751 codepoint = hb_buffer_get_glyph_infos (buffer, NULL)[0].codepoint;
752 hb_buffer_destroy (buffer);
754 draw_data.consumed = 0;
755 hb_font_draw_glyph (font, codepoint, funcs, &draw_data);
756 char expected[] = "M258,38C197,38 167,48 118,71L192,19L183,103C177,155 155,174 115,174"
757 "C89,174 64,161 51,125C52,36 124,-16 258,-16C417,-16 513,67 513,175"
758 "C513,278 457,328 322,388L289,403C232,429 203,452 203,500C203,562 244,589 301,589"
759 "C342,589 370,585 420,562L341,607L352,539C363,468 398,454 434,454C459,454 486,468 492,506"
760 "C491,590 408,643 290,643C141,643 57,563 57,460C57,357 122,307 233,256L265,241"
761 "C334,209 363,186 363,130C363,77 320,38 258,38ZM318,616L318,734L252,734L252,616"
762 "L318,616ZM253,-115L319,-115L319,14L253,14L253,-115Z";
763 g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1);
766 hb_font_destroy (font);
771 test_hb_draw_estedad_vf (void)
773 /* https://github.com/harfbuzz/harfbuzz/issues/2215 */
775 draw_data_t draw_data = {
780 /* See https://github.com/google/skia/blob/d38f00a1/gm/stroketext.cpp#L115-L124 */
781 hb_face_t *face = hb_test_open_font_file ("fonts/Estedad-VF.ttf");
782 hb_font_t *font = hb_font_create (face);
783 hb_face_destroy (face);
786 hb_variation_from_string ("wght=100", -1, &var);
787 hb_font_set_variations (font, &var, 1);
789 draw_data.consumed = 0;
790 hb_font_draw_glyph (font, 156, funcs, &draw_data);
791 /* Skip empty path where all the points of a path are equal */
792 char expected[] = "M150,1158L182,1158Q256,1158 317,1170Q377,1182 421,1213L421,430L521,430"
793 "L521,1490L421,1490L421,1320Q393,1279 344,1262Q294,1244 182,1244L150,1244"
794 "L150,1158ZM1815,-122L1669,-122L1669,642L1552,642L1055,-117L1055,-206"
795 "L1569,-206L1569,-458L1669,-458L1669,-206L1815,-206L1815,-122ZM1569,-122"
796 "L1166,-122L1569,494L1569,-122ZM609,-79L1639,1288L1555,1334L525,-33L609,-79Z";
797 g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1);
799 draw_data.consumed = 0;
800 hb_font_draw_glyph (font, 180, funcs, &draw_data);
801 /* Skip empty path where all the points of a path are equal */
802 char expected2[] = "M120,693Q120,545 177,414Q233,282 333,182Q433,81 567,24"
803 "Q701,-33 856,-33Q1010,-33 1144,24Q1277,81 1377,182Q1477,282 1534,414"
804 "Q1590,545 1590,693Q1590,842 1534,973Q1477,1104 1377,1205"
805 "Q1277,1305 1144,1362Q1010,1419 856,1419Q701,1419 567,1362"
806 "Q433,1305 333,1205Q233,1104 177,973Q120,842 120,693Z"
807 "M220,693Q220,828 270,945Q320,1061 409,1148Q497,1235 612,1284"
808 "Q726,1333 855,1333Q984,1333 1099,1284Q1213,1235 1302,1148"
809 "Q1390,1061 1440,945Q1490,828 1490,693Q1490,558 1440,442"
810 "Q1390,325 1302,237Q1213,149 1099,100Q984,51 855,51"
811 "Q726,51 611,100Q497,149 408,237Q320,325 270,442"
812 "Q220,558 220,693ZM690,643L690,997L886,997Q970,997 1029,949"
813 "Q1087,901 1087,819Q1087,737 1028,690Q969,643 886,643L690,643Z"
814 "M1165,334L973,568Q1065,591 1126,658Q1187,725 1187,819"
815 "Q1187,896 1147,956Q1106,1015 1037,1049Q969,1083 886,1083"
816 "L590,1083L590,310L690,310L690,557L860,557L1083,286L1165,334Z";
817 g_assert_cmpmem (str, draw_data.consumed, expected2, sizeof (expected2) - 1);
819 draw_data.consumed = 0;
820 hb_font_draw_glyph (font, 262, funcs, &draw_data);
821 /* Skip empty path where all the points of a path are equal */
822 char expected3[] = "M422,598Q495,598 545,548Q595,498 595,426Q595,353 545,303Q494,252 422,252"
823 "Q350,252 300,303Q250,353 250,426Q250,499 300,549Q349,598 422,598ZM422,698"
824 "Q347,698 285,662Q223,625 187,564Q150,502 150,426Q150,351 187,289"
825 "Q223,226 285,189Q346,152 422,152Q498,152 560,189Q622,226 658,288"
826 "Q695,351 695,426Q695,502 658,563Q621,625 559,661Q498,698 422,698Z";
827 g_assert_cmpmem (str, draw_data.consumed, expected3, sizeof (expected3) - 1);
829 hb_font_destroy (font);
834 test_hb_draw_stroking (void)
836 /* https://skia-review.googlesource.com/c/skia/+/266945
837 https://savannah.nongnu.org/bugs/index.php?57701 */
839 draw_data_t draw_data = {
844 /* See https://github.com/google/skia/blob/d38f00a1/gm/stroketext.cpp#L115-L124 */
845 hb_face_t *face = hb_test_open_font_file ("fonts/Stroking.ttf");
846 hb_font_t *font = hb_font_create (face);
847 hb_face_destroy (face);
849 draw_data.consumed = 0;
850 hb_font_draw_glyph (font, 6, funcs, &draw_data);
851 /* Skip empty path where all the points of a path are equal */
852 char expected[] = "M436,1522Q436,1280 531,1060Q625,839 784,680Q943,521 1164,427Q1384,332 1626,332"
853 "Q1868,332 2089,427Q2309,521 2468,680Q2627,839 2722,1060Q2816,1280 2816,1522"
854 "Q2816,1764 2722,1985Q2627,2205 2468,2364Q2309,2523 2089,2618Q1868,2712 1626,2712"
855 "Q1384,2712 1164,2618Q943,2523 784,2364Q625,2205 531,1985Q436,1764 436,1522ZM256,1528"
856 "Q256,1714 306,1892Q355,2069 443,2220Q531,2370 658,2497Q784,2623 935,2711"
857 "Q1085,2799 1263,2849Q1440,2898 1626,2898Q1812,2898 1990,2849Q2167,2799 2318,2711"
858 "Q2468,2623 2595,2497Q2721,2370 2809,2220Q2897,2069 2947,1892Q2996,1714 2996,1528"
859 "Q2996,1342 2947,1165Q2897,987 2809,837Q2721,686 2595,560Q2468,433 2318,345"
860 "Q2167,257 1990,208Q1812,158 1626,158Q1440,158 1263,208Q1085,257 935,345"
861 "Q784,433 658,560Q531,686 443,837Q355,987 306,1165Q256,1342 256,1528Z";
862 g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1);
864 draw_data.consumed = 0;
865 hb_font_draw_glyph (font, 7, funcs, &draw_data);
866 char expected2[] = "M436,1522Q436,1280 531,1060Q625,839 784,680Q943,521 1164,427"
867 "Q1384,332 1626,332Q1868,332 2089,427Q2309,521 2468,680"
868 "Q2627,839 2722,1060Q2816,1280 2816,1522Q2816,1764 2722,1985"
869 "Q2627,2205 2468,2364Q2309,2523 2089,2618Q1868,2712 1626,2712"
870 "Q1384,2712 1164,2618Q943,2523 784,2364Q625,2205 531,1985"
871 "Q436,1764 436,1522ZM256,1528Q256,1714 306,1892Q355,2069 443,2220"
872 "Q531,2370 658,2497Q784,2623 935,2711Q1085,2799 1263,2849"
873 "Q1440,2898 1626,2898Q1812,2898 1990,2849Q2167,2799 2318,2711"
874 "Q2468,2623 2595,2497Q2721,2370 2809,2220Q2897,2069 2947,1892"
875 "Q2996,1714 2996,1528Q2996,1342 2947,1165Q2897,987 2809,837"
876 "Q2721,686 2595,560Q2468,433 2318,345Q2167,257 1990,208"
877 "Q1812,158 1626,158Q1440,158 1263,208Q1085,257 935,345"
878 "Q784,433 658,560Q531,686 443,837Q355,987 306,1165"
879 "Q256,1342 256,1528Z";
880 g_assert_cmpmem (str, draw_data.consumed, expected2, sizeof (expected2) - 1);
882 hb_font_destroy (font);
885 /* https://github.com/google/skia/blob/d38f00a1/gm/stroketext.cpp#L131-L138 */
886 hb_face_t *face = hb_test_open_font_file ("fonts/Stroking.otf");
887 hb_font_t *font = hb_font_create (face);
888 hb_face_destroy (face);
890 draw_data.consumed = 0;
891 hb_font_draw_glyph (font, 4, funcs, &draw_data);
892 /* Skip empty path in CFF */
893 char expected[] = "M106,372C106,532 237,662 397,662C557,662 688,532 688,372C688,212 557,81 397,81C237,81 106,212 106,372Z"
894 "M62,373C62,188 212,39 397,39C582,39 731,188 731,373C731,558 582,708 397,708C212,708 62,558 62,373Z";
895 g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1);
897 draw_data.consumed = 0;
898 hb_font_draw_glyph (font, 5, funcs, &draw_data);
899 /* Fold consequent move-to commands */
900 char expected2[] = "M106,372C106,532 237,662 397,662C557,662 688,532 688,372"
901 "C688,212 557,81 397,81C237,81 106,212 106,372ZM62,373"
902 "C62,188 212,39 397,39C582,39 731,188 731,373"
903 "C731,558 582,708 397,708C212,708 62,558 62,373Z";
904 g_assert_cmpmem (str, draw_data.consumed, expected2, sizeof (expected2) - 1);
906 hb_font_destroy (font);
911 test_hb_draw_drawing_funcs (void)
914 draw_data_t draw_data = {
920 hb_draw_state_t st = HB_DRAW_STATE_DEFAULT;
921 draw_data.consumed = 0;
922 hb_draw_move_to (funcs, &draw_data, &st, 90.f, 0.f);
923 hb_draw_line_to (funcs, &draw_data, &st, 258.f, 0.f);
924 hb_draw_cubic_to (funcs, &draw_data, &st, 456.f, 0.f, 564.f, 122.f, 564.f, 331.f);
925 hb_draw_cubic_to (funcs, &draw_data, &st, 564.f, 539.f, 456.f, 656.f, 254.f, 656.f);
926 hb_draw_line_to (funcs, &draw_data, &st, 90.f, 656.f);
927 hb_draw_line_to (funcs, &draw_data, &st, 90.f, 0.f);
928 hb_draw_close_path (funcs, &draw_data, &st);
930 char expected[] = "M90,0L258,0C456,0 564,122 564,331C564,539 456,656 254,656L90,656L90,0Z";
931 g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1);
935 hb_draw_state_t st = HB_DRAW_STATE_DEFAULT;
936 draw_data.consumed = 0;
937 hb_draw_move_to (funcs, &draw_data, &st, 155.f, 624.f);
938 hb_draw_line_to (funcs, &draw_data, &st, 155.f, 84.f);
939 hb_draw_quadratic_to (funcs, &draw_data, &st, 150.f, 90.f, 146.f, 95.f);
940 hb_draw_quadratic_to (funcs, &draw_data, &st, 141.f, 99.f, 136.f, 105.f);
941 hb_draw_line_to (funcs, &draw_data, &st, 292.f, 105.f);
942 hb_draw_line_to (funcs, &draw_data, &st, 292.f, 0.f);
943 hb_draw_line_to (funcs, &draw_data, &st, 156.f, 0.f);
944 hb_draw_quadratic_to (funcs, &draw_data, &st, 128.f, 0.f, 104.f, 14.f);
945 hb_draw_quadratic_to (funcs, &draw_data, &st, 79.f, 27.f, 65.f, 51.f);
946 hb_draw_quadratic_to (funcs, &draw_data, &st, 50.f, 74.f, 50.f, 104.f);
947 hb_draw_line_to (funcs, &draw_data, &st, 50.f, 624.f);
948 hb_draw_line_to (funcs, &draw_data, &st, 155.f, 624.f);
949 hb_draw_close_path (funcs, &draw_data, &st);
951 char expected[] = "M155,624L155,84Q150,90 146,95Q141,99 136,105"
952 "L292,105L292,0L156,0Q128,0 104,14Q79,27 65,51"
953 "Q50,74 50,104L50,624L155,624Z";
954 g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1);
959 test_hb_draw_synthetic_slant (void)
962 draw_data_t draw_data = {
967 hb_face_t *face = hb_test_open_font_file ("fonts/OpenSans-Regular.ttf");
968 hb_font_t *font = hb_font_create (face);
969 hb_face_destroy (face);
970 hb_font_set_synthetic_slant (font, 0.2f);
972 draw_data.consumed = 0;
973 hb_font_draw_glyph (font, 37, funcs, &draw_data);
974 char expected[] = "M493,1462L906,1462Q1197,1462 1310,1375Q1423,1288 1385,1100"
975 "Q1359,970 1270,886Q1180,801 1036,776L1034,766Q1356,709 1297,416"
976 "Q1258,220 1104,110Q949,0 711,0L201,0L493,1462ZM538,836L818,836"
977 "Q998,836 1089,893Q1179,949 1206,1083Q1230,1206 1153,1261"
978 "Q1076,1315 884,1315L634,1315L538,836ZM509,692L400,145L705,145"
979 "Q882,145 985,214Q1088,282 1118,428Q1145,564 1066,628Q987,692 800,692L509,692Z";
980 g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1);
982 hb_font_destroy (font);
985 hb_face_t *face = hb_test_open_font_file ("fonts/SourceSansPro-Regular.otf");
986 hb_font_t *font = hb_font_create (face);
987 hb_face_destroy (face);
988 hb_font_set_synthetic_slant (font, 0.2f);
990 draw_data.consumed = 0;
991 hb_font_draw_glyph (font, 5, funcs, &draw_data);
992 char expected[] = "M90,0L258,0C456,0 588,122 630,331C672,539 587,656 385,656L221,656L90,0Z"
993 "M187,68L291,588L366,588C519,588 577,496 544,331C511,165 415,68 262,68L187,68Z";
994 g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1);
996 hb_font_destroy (font);
1001 test_hb_draw_subfont_scale (void)
1004 draw_data_t draw_data = {
1006 .size = sizeof (str)
1010 hb_face_t *face = hb_test_open_font_file ("fonts/OpenSans-Regular.ttf");
1011 hb_font_t *font1 = hb_font_create (face);
1012 hb_font_t *font2 = hb_font_create_sub_font (font1);
1014 hb_font_get_scale (font1, &x, &y);
1015 hb_font_set_scale (font2, x*2, y*2);
1017 draw_data.consumed = 0;
1018 hb_font_draw_glyph (font1, 37, funcs, &draw_data);
1019 char expected1[] = "M201,1462L614,1462Q905,1462 1035,1375Q1165,1288 1165,1100"
1020 "Q1165,970 1093,886Q1020,801 881,776L881,766Q1214,709 1214,416"
1021 "Q1214,220 1082,110Q949,0 711,0L201,0L201,1462ZM371,836L651,836"
1022 "Q831,836 910,893Q989,949 989,1083Q989,1206 901,1261"
1023 "Q813,1315 621,1315L371,1315L371,836ZM371,692L371,145L676,145"
1024 "Q853,145 943,214Q1032,282 1032,428Q1032,564 941,628Q849,692 662,692L371,692Z";
1025 g_assert_cmpmem (str, draw_data.consumed, expected1, sizeof (expected1) - 1);
1027 draw_data.consumed = 0;
1028 hb_font_draw_glyph (font2, 37, funcs, &draw_data);
1029 char expected2[] = "M402,2924L1228,2924Q1810,2924 2070,2750Q2330,2576 2330,2200"
1030 "Q2330,1940 2185,1771Q2040,1602 1762,1552L1762,1532Q2428,1418 2428,832"
1031 "Q2428,440 2163,220Q1898,0 1422,0L402,0L402,2924ZM742,1672L1302,1672"
1032 "Q1662,1672 1820,1785Q1978,1898 1978,2166Q1978,2412 1802,2521"
1033 "Q1626,2630 1242,2630L742,2630L742,1672ZM742,1384L742,290L1352,290"
1034 "Q1706,290 1885,427Q2064,564 2064,856Q2064,1128 1881,1256Q1698,1384 1324,1384L742,1384Z";
1035 g_assert_cmpmem (str, draw_data.consumed, expected2, sizeof (expected2) - 1);
1037 hb_font_destroy (font1);
1038 hb_font_destroy (font2);
1039 hb_face_destroy (face);
1042 hb_face_t *face = hb_test_open_font_file ("fonts/SourceSansPro-Regular.otf");
1043 hb_font_t *font1 = hb_font_create (face);
1044 hb_font_t *font2 = hb_font_create_sub_font (font1);
1046 hb_font_get_scale (font1, &x, &y);
1047 hb_font_set_scale (font2, x*2, y*2);
1049 draw_data.consumed = 0;
1050 hb_font_draw_glyph (font1, 5, funcs, &draw_data);
1051 char expected1[] = "M90,0L258,0C456,0 564,122 564,331C564,539 456,656 254,656L90,656L90,0Z"
1052 "M173,68L173,588L248,588C401,588 478,496 478,331C478,165 401,68 248,68L173,68Z";
1053 g_assert_cmpmem (str, draw_data.consumed, expected1, sizeof (expected1) - 1);
1055 draw_data.consumed = 0;
1056 hb_font_draw_glyph (font2, 5, funcs, &draw_data);
1057 char expected2[] = "M180,0L516,0C912,0 1128,244 1128,662C1128,1078 912,1312 508,1312L180,1312L180,0Z"
1058 "M346,136L346,1176L496,1176C802,1176 956,992 956,662C956,330 802,136 496,136L346,136Z";
1059 g_assert_cmpmem (str, draw_data.consumed, expected2, sizeof (expected2) - 1);
1061 hb_font_destroy (font1);
1062 hb_font_destroy (font2);
1063 hb_face_destroy (face);
1068 test_hb_draw_immutable (void)
1070 hb_draw_funcs_t *draw_funcs = hb_draw_funcs_create ();
1071 g_assert (!hb_draw_funcs_is_immutable (draw_funcs));
1072 hb_draw_funcs_make_immutable (draw_funcs);
1073 g_assert (hb_draw_funcs_is_immutable (draw_funcs));
1074 hb_draw_funcs_destroy (draw_funcs);
1077 #ifdef HAVE_FREETYPE
1078 static void test_hb_draw_ft (void)
1081 draw_data_t draw_data = {
1083 .size = sizeof (str)
1086 hb_face_t *face = hb_test_open_font_file ("fonts/glyphs.ttf");
1087 hb_font_t *font = hb_font_create (face);
1088 hb_ft_font_set_funcs (font);
1089 hb_face_destroy (face);
1091 draw_data.consumed = 0;
1092 hb_font_draw_glyph (font, 0, funcs, &draw_data);
1093 char expected[] = "M50,0L50,750L450,750L450,0L50,0Z";
1094 g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1);
1097 draw_data.consumed = 0;
1098 hb_font_draw_glyph (font, 5, funcs, &draw_data);
1099 char expected[] = "M15,0Q15,0 15,0Z";
1100 g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1);
1102 hb_font_destroy (font);
1105 hb_face_t *face = hb_test_open_font_file ("fonts/cff1_flex.otf");
1106 hb_font_t *font = hb_font_create (face);
1107 hb_ft_font_set_funcs (font);
1108 hb_face_destroy (face);
1110 draw_data.consumed = 0;
1111 hb_font_draw_glyph (font, 1, funcs, &draw_data);
1112 char expected[] = "M0,0C100,0 150,-20 250,-20C350,-20 400,0 500,0C500,100 520,150 520,250"
1113 "C520,350 500,400 500,500C400,500 350,520 250,520C150,520 100,500 0,500"
1114 "C0,400 -20,350 -20,250C-20,150 0,100 0,0ZM50,50C50,130 34,170 34,250"
1115 "C34,330 50,370 50,450C130,450 170,466 250,466C330,466 370,450 450,450"
1116 "C450,370 466,330 466,250C466,170 450,130 450,50C370,50 330,34 250,34"
1117 "C170,34 130,50 50,50Z";
1118 g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1);
1120 hb_font_destroy (font);
1125 test_hb_draw_compare_ot_ft (void)
1128 draw_data_t draw_data = {
1130 .size = sizeof (str),
1134 draw_data_t draw_data2 = {
1136 .size = sizeof (str2),
1140 hb_face_t *face = hb_test_open_font_file ("fonts/cff1_flex.otf");
1141 hb_font_t *font = hb_font_create (face);
1143 hb_font_set_scale (font, 100, 100);
1145 hb_font_draw_glyph (font, 1, funcs, &draw_data);
1146 draw_data.str[draw_data.consumed] = '\0';
1148 hb_ft_font_set_funcs (font);
1150 hb_font_draw_glyph (font, 1, funcs, &draw_data2);
1151 draw_data2.str[draw_data2.consumed] = '\0';
1153 g_assert_cmpstr (draw_data.str, ==, draw_data2.str);
1155 hb_font_destroy (font);
1156 hb_face_destroy (face);
1161 main (int argc, char **argv)
1163 funcs = hb_draw_funcs_create ();
1164 hb_draw_funcs_set_move_to_func (funcs, (hb_draw_move_to_func_t) move_to, NULL, NULL);
1165 hb_draw_funcs_set_line_to_func (funcs, (hb_draw_line_to_func_t) line_to, NULL, NULL);
1166 hb_draw_funcs_set_quadratic_to_func (funcs, (hb_draw_quadratic_to_func_t) quadratic_to, NULL, NULL);
1167 hb_draw_funcs_set_cubic_to_func (funcs, (hb_draw_cubic_to_func_t) cubic_to, NULL, NULL);
1168 hb_draw_funcs_set_close_path_func (funcs, (hb_draw_close_path_func_t) close_path, NULL, NULL);
1169 hb_draw_funcs_make_immutable (funcs);
1171 funcs2 = hb_draw_funcs_create ();
1172 hb_draw_funcs_set_move_to_func (funcs2, (hb_draw_move_to_func_t) move_to, NULL, NULL);
1173 hb_draw_funcs_set_line_to_func (funcs2, (hb_draw_line_to_func_t) line_to, NULL, NULL);
1174 hb_draw_funcs_set_cubic_to_func (funcs2, (hb_draw_cubic_to_func_t) cubic_to, NULL, NULL);
1175 hb_draw_funcs_set_close_path_func (funcs2, (hb_draw_close_path_func_t) close_path, NULL, NULL);
1176 hb_draw_funcs_make_immutable (funcs2);
1178 hb_test_init (&argc, &argv);
1179 hb_test_add (test_itoa);
1180 hb_test_add (test_hb_draw_empty);
1181 hb_test_add (test_hb_draw_glyf);
1182 hb_test_add (test_hb_draw_cff1);
1183 hb_test_add (test_hb_draw_cff1_rline);
1184 hb_test_add (test_hb_draw_cff2);
1185 hb_test_add (test_hb_draw_ttf_parser_tests);
1186 hb_test_add (test_hb_draw_font_kit_glyphs_tests);
1187 hb_test_add (test_hb_draw_font_kit_variations_tests);
1188 hb_test_add (test_hb_draw_estedad_vf);
1189 if(0) hb_test_add (test_hb_draw_stroking);
1190 hb_test_add (test_hb_draw_drawing_funcs);
1191 hb_test_add (test_hb_draw_synthetic_slant);
1192 hb_test_add (test_hb_draw_subfont_scale);
1193 hb_test_add (test_hb_draw_immutable);
1194 #ifdef HAVE_FREETYPE
1195 hb_test_add (test_hb_draw_ft);
1196 hb_test_add (test_hb_draw_compare_ot_ft);
1198 unsigned result = hb_test_run ();
1200 hb_draw_funcs_destroy (funcs);
1201 hb_draw_funcs_destroy (funcs2);