This source file includes following definitions.
- xmalloc
- xrealloc
- xfree
- sfnt_swap16_1
- sfnt_swap32_1
- sfnt_read_table_directory
- sfnt_find_table
- sfnt_read_cmap_format_0
- sfnt_read_cmap_format_2
- sfnt_read_cmap_format_4
- sfnt_read_cmap_format_6
- sfnt_read_cmap_format_8
- sfnt_read_cmap_format_12
- sfnt_read_24
- sfnt_read_cmap_format_14
- sfnt_read_cmap_table_1
- sfnt_read_cmap_table
- sfnt_lookup_glyph_0
- sfnt_lookup_glyph_2
- sfnt_bsearch_above
- sfnt_compare_uint16
- sfnt_lookup_glyph_4_1
- sfnt_lookup_glyph_4
- sfnt_lookup_glyph_6
- sfnt_lookup_glyph_8
- sfnt_lookup_glyph_12
- sfnt_lookup_glyph
- sfnt_read_head_table
- sfnt_read_hhea_table
- sfnt_read_loca_table_short
- sfnt_read_loca_table_long
- sfnt_read_maxp_table
- sfnt_read_glyf_table
- sfnt_map_glyf_table
- sfnt_unmap_glyf_table
- sfnt_read_simple_glyph
- sfnt_read_compound_glyph
- sfnt_read_glyph
- sfnt_free_glyph
- sfnt_transform_coordinates
- sfnt_expand_compound_glyph_context
- sfnt_round_fixed
- sfnt_decompose_compound_glyph
- sfnt_lerp_half
- sfnt_decompose_glyph_1
- sfnt_decompose_glyph_2
- sfnt_decompose_glyph
- sfnt_build_append
- sfnt_multiply_divide_1
- sfnt_count_leading_zero_bits
- sfnt_multiply_divide_2
- sfnt_multiply_divide
- sfnt_large_integer_add
- sfnt_multiply_divide_round
- sfnt_multiply_divide_signed
- sfnt_mul_fixed
- sfnt_mul_fixed_round
- sfnt_move_to_and_build
- sfnt_line_to_and_build
- sfnt_div_fixed
- sfnt_ceil_fixed
- sfnt_floor_fixed
- sfnt_curve_is_flat
- sfnt_curve_to_and_build_1
- sfnt_curve_to_and_build
- sfnt_build_glyph_outline
- sfnt_poly_grid_ceil
- sfnt_prepare_raster
- sfnt_step_edge
- sfnt_build_outline_edges
- sfnt_edge_sort
- sfnt_poly_edges
- sfnt_saturate_short
- sfnt_fill_span
- sfnt_poly_span
- sfnt_raster_span
- sfnt_raster_edge
- sfnt_raster_glyph_outline
- sfnt_read_hmtx_table
- sfnt_lookup_glyph_metrics
- sfnt_scale_metrics
- sfnt_get_scale
- sfnt_read_name_table
- sfnt_find_name
- sfnt_read_meta_table
- sfnt_find_metadata
- sfnt_read_ttc_header
- sfnt_read_cvt_table
- sfnt_read_fpgm_table
- sfnt_read_prep_table
- sfnt_div_f26dot6
- sfnt_mul_f26dot6
- sfnt_mul_f2dot14
- sfnt_mul_f26dot6_fixed
- sfnt_floor_f26dot6
- sfnt_ceil_f26dot6
- sfnt_round_f26dot6
- sfnt_init_graphics_state
- sfnt_make_interpreter
- sfnt_interpret_trap
- sfnt_scale_by_freedom_vector
- sfnt_interpret_utp
- sfnt_save_projection_vector
- sfnt_save_freedom_vector
- sfnt_address_zp2
- sfnt_address_zp1
- sfnt_address_zp0
- sfnt_store_zp2
- sfnt_line_to_standard_form
- sfnt_check_zp2
- sfnt_check_zp0
- sfnt_check_zp1
- sfnt_move_zp0
- sfnt_move_zp1
- sfnt_move_zp2
- sfnt_move_glyph_zone
- sfnt_move_twilight_zone
- sfnt_direct_move_zp2
- sfnt_project_vector
- sfnt_dual_project_vector
- sfnt_interpret_fliprgoff
- sfnt_interpret_fliprgon
- sfnt_interpret_flippt
- sfnt_interpret_scfs
- sfnt_round_symmetric
- sfnt_interpret_miap
- sfnt_interpret_alignrp_1
- sfnt_interpret_alignrp
- sfnt_interpret_alignpts
- sfnt_interpret_isect
- sfnt_sqrt_fixed
- sfnt_normalize_vector
- sfnt_line_to_vector
- sfnt_measure_distance
- sfnt_interpret_msirp
- sfnt_interpret_ip
- sfnt_deltac
- sfnt_interpret_mdap
- sfnt_deltap
- sfnt_interpret_call
- sfnt_set_srounding_state
- sfnt_skip_code
- sfnt_interpret_unimplemented
- sfnt_interpret_fdef
- sfnt_interpret_idef
- sfnt_interpret_if
- sfnt_interpret_else
- sfnt_round_none
- sfnt_round_to_grid
- sfnt_round_to_double_grid
- sfnt_round_down_to_grid
- sfnt_round_up_to_grid
- sfnt_round_to_half_grid
- sfnt_round_super
- sfnt_round_super45
- sfnt_project_onto_x_axis_vector
- sfnt_project_onto_y_axis_vector
- sfnt_dot_fix_14
- sfnt_project_onto_any_vector
- sfnt_dual_project_onto_any_vector
- sfnt_move_x
- sfnt_move_y
- sfnt_move
- sfnt_validate_gs
- sfnt_set_freedom_vector
- sfnt_set_projection_vector
- sfnt_interpret_shz
- sfnt_interpret_shc
- sfnt_interpret_shp
- sfnt_interpret_iup_1
- sfnt_interpret_iup
- sfnt_interpret_mirp
- sfnt_interpret_mdrp
- sfnt_interpret_run
- sfnt_interpret_font_program
- sfnt_interpret_control_value_program
- sfnt_decompose_instructed_outline
- sfnt_build_instructed_outline
- sfnt_compute_phantom_points
- sfnt_interpret_simple_glyph
- sfnt_transform_f26dot6
- sfnt_interpret_compound_glyph_2
- sfnt_interpret_compound_glyph_1
- sfnt_interpret_compound_glyph
- sfnt_read_default_uvs_table
- sfnt_read_nondefault_uvs_table
- sfnt_compare_table_offsets
- sfnt_create_uvs_context
- sfnt_free_uvs_context
- sfnt_compare_uvs_mapping
- sfnt_variation_glyph_for_char
- sfnt_map_table
- sfnt_unmap_table
- sfnt_read_table
- sfnt_read_fvar_table
- sfnt_read_gvar_table
- sfnt_read_avar_table
- sfnt_read_packed_points
- sfnt_read_packed_deltas
- sfnt_read_cvar_table
- sfnt_init_blend
- sfnt_free_blend
- sfnt_normalize_blend
- sfnt_compute_tuple_scale
- sfnt_infer_deltas_1
- sfnt_infer_deltas
- sfnt_vary_simple_glyph
- sfnt_vary_compound_glyph
- sfnt_vary_interpreter
- sfnt_test_move_to
- sfnt_test_line_to
- sfnt_test_curve_to
- sfnt_test_get_glyph
- sfnt_test_free_glyph
- sfnt_test_span
- sfnt_test_edge_ignore
- sfnt_test_edges
- sfnt_debug_edges
- sfnt_test_edge
- sfnt_x_raster
- sfnt_test_raster
- sfnt_make_test_interpreter
- sfnt_run_interpreter_test
- sfnt_generic_check
- sfnt_check_srp0
- sfnt_check_szp0
- sfnt_check_sloop
- sfnt_check_rounding
- sfnt_check_smd
- sfnt_check_scvtci
- sfnt_check_sswci
- sfnt_check_ssw
- sfnt_check_flipon
- sfnt_check_flipoff
- sfnt_check_sdb
- sfnt_check_sds
- sfnt_check_scanctrl
- sfnt_check_instctrl
- sfnt_setup_debugger
- sfnt_name_instruction
- sfnt_draw_debugger
- sfnt_run_hook
- sfnt_identify_instruction
- sfnt_verbose
- sfnt_push_hook
- sfnt_pop_hook
- sfnt_test_uvs
- main
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 #include <config.h>
22
23 #include "sfnt.h"
24
25 #include <assert.h>
26 #include <attribute.h>
27 #include <byteswap.h>
28 #include <fcntl.h>
29 #include <intprops.h>
30 #include <inttypes.h>
31 #include <stdint.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <unistd.h>
36 #include <setjmp.h>
37 #include <errno.h>
38
39 #ifdef HAVE_MMAP
40 #include <sys/mman.h>
41 #endif
42
43 #if defined __GNUC__ && !defined __clang__
44 #pragma GCC diagnostic ignored "-Wstringop-overflow"
45 #endif
46
47 #ifdef TEST
48
49 #include <time.h>
50 #include <timespec.h>
51 #include <sys/wait.h>
52 #include <errno.h>
53
54 #include <X11/Xlib.h>
55 #include <X11/extensions/Xrender.h>
56
57 static void *
58 xmalloc (size_t size)
59 {
60 void *ptr;
61
62 ptr = malloc (size);
63
64 if (!ptr)
65 abort ();
66
67 return ptr;
68 }
69
70 static void *
71 xrealloc (void *ptr, size_t size)
72 {
73 void *new_ptr;
74
75 new_ptr = realloc (ptr, size);
76
77 if (!new_ptr)
78 abort ();
79
80 return new_ptr;
81 }
82
83 static void
84 xfree (void *ptr)
85 {
86 return free (ptr);
87 }
88
89
90
91 #define TEST_STATIC static
92
93
94 #define ARRAYELTS(arr) (sizeof (arr) / sizeof (arr)[0])
95
96 #else
97 #define TEST_STATIC
98 #include "lisp.h"
99 #endif
100
101 #define MIN(a, b) ((a) < (b) ? (a) : (b))
102 #define MAX(a, b) ((a) > (b) ? (a) : (b))
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139 static uint32_t sfnt_table_names[] =
140 {
141 [SFNT_TABLE_CMAP] = 0x636d6170,
142 [SFNT_TABLE_GLYF] = 0x676c7966,
143 [SFNT_TABLE_HEAD] = 0x68656164,
144 [SFNT_TABLE_HHEA] = 0x68686561,
145 [SFNT_TABLE_HMTX] = 0x686d7478,
146 [SFNT_TABLE_LOCA] = 0x6c6f6361,
147 [SFNT_TABLE_MAXP] = 0x6d617870,
148 [SFNT_TABLE_NAME] = 0x6e616d65,
149 [SFNT_TABLE_META] = 0x6d657461,
150 [SFNT_TABLE_CVT ] = 0x63767420,
151 [SFNT_TABLE_FPGM] = 0x6670676d,
152 [SFNT_TABLE_PREP] = 0x70726570,
153 [SFNT_TABLE_FVAR] = 0x66766172,
154 [SFNT_TABLE_GVAR] = 0x67766172,
155 [SFNT_TABLE_CVAR] = 0x63766172,
156 [SFNT_TABLE_AVAR] = 0x61766172,
157 };
158
159
160
161 static void
162 sfnt_swap16_1 (uint16_t *value)
163 {
164 #ifndef WORDS_BIGENDIAN
165 *value = bswap_16 (*value);
166 #endif
167 }
168
169 static void
170 sfnt_swap32_1 (uint32_t *value)
171 {
172 #ifndef WORDS_BIGENDIAN
173 *value = bswap_32 (*value);
174 #endif
175 }
176
177 #define sfnt_swap16(what) (sfnt_swap16_1 ((uint16_t *) (what)))
178 #define sfnt_swap32(what) (sfnt_swap32_1 ((uint32_t *) (what)))
179
180
181
182
183
184
185
186
187
188 TEST_STATIC struct sfnt_offset_subtable *
189 sfnt_read_table_directory (int fd)
190 {
191 struct sfnt_offset_subtable *subtable;
192 ssize_t rc;
193 size_t offset, subtable_size;
194 int i;
195
196 subtable = xmalloc (sizeof *subtable);
197 offset = SFNT_ENDOF (struct sfnt_offset_subtable,
198 range_shift, uint16_t);
199 rc = read (fd, subtable, offset);
200
201 if (rc < offset)
202 {
203 if (rc >= sizeof (uint32_t))
204 {
205
206
207 sfnt_swap32 (&subtable->scaler_type);
208
209 if (subtable->scaler_type == SFNT_TTC_TTCF)
210 {
211 xfree (subtable);
212 return (struct sfnt_offset_subtable *) -1;
213 }
214 }
215
216 xfree (subtable);
217 return NULL;
218 }
219
220 sfnt_swap32 (&subtable->scaler_type);
221
222
223
224
225 if (subtable->scaler_type == SFNT_TTC_TTCF)
226 {
227 xfree (subtable);
228 return (struct sfnt_offset_subtable *) -1;
229 }
230
231 sfnt_swap16 (&subtable->num_tables);
232 sfnt_swap16 (&subtable->search_range);
233 sfnt_swap16 (&subtable->entry_selector);
234 sfnt_swap16 (&subtable->range_shift);
235
236
237
238 subtable_size = (subtable->num_tables
239 * sizeof (struct sfnt_table_directory));
240 subtable = xrealloc (subtable, sizeof *subtable + subtable_size);
241 subtable->subtables
242 = (struct sfnt_table_directory *) (subtable + 1);
243
244 rc = read (fd, subtable->subtables, subtable_size);
245
246 if (rc < offset)
247 {
248 xfree (subtable);
249 return NULL;
250 }
251
252
253
254 for (i = 0; i < subtable->num_tables; ++i)
255 {
256 sfnt_swap32 (&subtable->subtables[i].tag);
257 sfnt_swap32 (&subtable->subtables[i].checksum);
258 sfnt_swap32 (&subtable->subtables[i].offset);
259 sfnt_swap32 (&subtable->subtables[i].length);
260 }
261
262 return subtable;
263 }
264
265
266
267
268 static struct sfnt_table_directory *
269 sfnt_find_table (struct sfnt_offset_subtable *subtable,
270 enum sfnt_table table)
271 {
272 int i;
273
274 for (i = 0; i < subtable->num_tables; ++i)
275 {
276 if (subtable->subtables[i].tag == sfnt_table_names[table])
277 return &subtable->subtables[i];
278 }
279
280 return NULL;
281 }
282
283
284
285
286
287
288
289
290 static struct sfnt_cmap_format_0 *
291 sfnt_read_cmap_format_0 (int fd,
292 struct sfnt_cmap_encoding_subtable_data *header)
293 {
294 struct sfnt_cmap_format_0 *format0;
295 ssize_t rc;
296 size_t wanted_size;
297
298 format0 = xmalloc (sizeof *format0);
299
300
301 format0->format = header->format;
302 format0->length = header->length;
303
304
305 wanted_size = (sizeof *format0
306 - offsetof (struct sfnt_cmap_format_0,
307 language));
308 rc = read (fd, &format0->language, wanted_size);
309
310 if (rc < wanted_size)
311 {
312 xfree (format0);
313 return (struct sfnt_cmap_format_0 *) -1;
314 }
315
316
317 sfnt_swap16 (&format0->language);
318 return format0;
319 }
320
321
322
323
324 static struct sfnt_cmap_format_2 *
325 sfnt_read_cmap_format_2 (int fd,
326 struct sfnt_cmap_encoding_subtable_data *header)
327 {
328 struct sfnt_cmap_format_2 *format2;
329 ssize_t rc;
330 size_t min_bytes;
331 int i, nsub;
332
333
334 min_bytes = SFNT_ENDOF (struct sfnt_cmap_format_2,
335 sub_header_keys, uint16_t[256]);
336 if (header->length < min_bytes)
337 return NULL;
338
339
340
341 format2 = xmalloc (header->length + sizeof *format2);
342 format2->format = header->format;
343 format2->length = header->length;
344
345
346 min_bytes -= offsetof (struct sfnt_cmap_format_2, language);
347 rc = read (fd, &format2->language, min_bytes);
348 if (rc < min_bytes)
349 {
350 xfree (format2);
351 return (struct sfnt_cmap_format_2 *) -1;
352 }
353
354
355
356 sfnt_swap16 (&format2->language);
357
358
359
360
361
362 nsub = 0;
363
364 for (i = 0; i < 256; ++i)
365 {
366 sfnt_swap16 (&format2->sub_header_keys[i]);
367
368 if (format2->sub_header_keys[i] > nsub)
369 nsub = format2->sub_header_keys[i];
370 }
371
372 if (!nsub)
373
374 return format2;
375
376
377
378 min_bytes = (format2->length
379 - SFNT_ENDOF (struct sfnt_cmap_format_2,
380 sub_header_keys, uint16_t[256]));
381 rc = read (fd, format2 + 1, min_bytes);
382 if (rc < min_bytes)
383 {
384 xfree (format2);
385 return (struct sfnt_cmap_format_2 *) -1;
386 }
387
388
389 if (min_bytes < nsub * sizeof *format2->subheaders)
390 {
391 xfree (format2);
392 return (struct sfnt_cmap_format_2 *) -1;
393 }
394
395
396
397
398 format2->subheaders
399 = (struct sfnt_cmap_format_2_subheader *) (format2 + 1);
400 format2->glyph_index_array
401 = (uint16_t *) (format2->subheaders + nsub);
402
403 for (i = 0; i < nsub; ++i)
404 {
405 sfnt_swap16 (&format2->subheaders[i].first_code);
406 sfnt_swap16 (&format2->subheaders[i].entry_count);
407 sfnt_swap16 (&format2->subheaders[i].id_delta);
408 sfnt_swap16 (&format2->subheaders[i].id_range_offset);
409 }
410
411
412
413 format2->num_glyphs
414 = (min_bytes - nsub * sizeof *format2->subheaders) / 2;
415
416 for (i = 0; i < format2->num_glyphs; ++i)
417 sfnt_swap16 (&format2->glyph_index_array[i]);
418
419 return format2;
420 }
421
422
423
424
425 static struct sfnt_cmap_format_4 *
426 sfnt_read_cmap_format_4 (int fd,
427 struct sfnt_cmap_encoding_subtable_data *header)
428 {
429 struct sfnt_cmap_format_4 *format4;
430 size_t min_bytes, variable_size;
431 ssize_t rc;
432 size_t bytes_minus_format4;
433 int seg_count, i;
434
435 min_bytes = SFNT_ENDOF (struct sfnt_cmap_format_4,
436 entry_selector, uint16_t);
437
438
439 if (header->length < min_bytes)
440 return NULL;
441
442
443
444 format4 = xmalloc (header->length + sizeof *format4);
445
446
447 format4->format = header->format;
448 format4->length = header->length;
449
450
451 min_bytes -= offsetof (struct sfnt_cmap_format_4, language);
452 rc = read (fd, &format4->language, min_bytes);
453 if (rc < min_bytes)
454 {
455 xfree (format4);
456 return (struct sfnt_cmap_format_4 *) -1;
457 }
458
459
460 sfnt_swap16 (&format4->language);
461 sfnt_swap16 (&format4->seg_count_x2);
462 sfnt_swap16 (&format4->search_range);
463 sfnt_swap16 (&format4->entry_selector);
464
465
466 seg_count = format4->seg_count_x2 / 2;
467
468
469 bytes_minus_format4
470 = format4->length - SFNT_ENDOF (struct sfnt_cmap_format_4,
471 entry_selector, uint16_t);
472 variable_size = (seg_count * sizeof *format4->end_code
473 + sizeof *format4->reserved_pad
474 + seg_count * sizeof *format4->start_code
475 + seg_count * sizeof *format4->id_delta
476 + seg_count * sizeof *format4->id_range_offset);
477
478 if (bytes_minus_format4 < variable_size)
479 {
480
481
482 xfree (format4);
483 return NULL;
484 }
485
486
487 rc = read (fd, format4 + 1, bytes_minus_format4);
488 if (rc < bytes_minus_format4)
489 {
490 xfree (format4);
491 return (struct sfnt_cmap_format_4 *) -1;
492 }
493
494
495 format4->end_code = (uint16_t *) (format4 + 1);
496 format4->reserved_pad = format4->end_code + seg_count;
497 format4->start_code = format4->reserved_pad + 1;
498 format4->id_delta = (int16_t *) (format4->start_code + seg_count);
499 format4->id_range_offset = format4->id_delta + seg_count;
500 format4->glyph_index_array = (uint16_t *) (format4->id_range_offset
501 + seg_count);
502
503
504
505
506
507 sfnt_swap16 (format4->reserved_pad);
508
509 for (i = 0; i < seg_count; ++i)
510 {
511 sfnt_swap16 (&format4->end_code[i]);
512 sfnt_swap16 (&format4->start_code[i]);
513 sfnt_swap16 (&format4->id_delta[i]);
514 sfnt_swap16 (&format4->id_range_offset[i]);
515 }
516
517 format4->glyph_index_size
518 = (bytes_minus_format4 - variable_size) / 2;
519
520 for (i = 0; i < format4->glyph_index_size; ++i)
521 sfnt_swap16 (&format4->glyph_index_array[i]);
522
523
524 return format4;
525 }
526
527
528
529
530 static struct sfnt_cmap_format_6 *
531 sfnt_read_cmap_format_6 (int fd,
532 struct sfnt_cmap_encoding_subtable_data *header)
533 {
534 struct sfnt_cmap_format_6 *format6;
535 size_t min_size;
536 ssize_t rc;
537 uint16_t i;
538
539 min_size = SFNT_ENDOF (struct sfnt_cmap_format_6, entry_count,
540 uint16_t);
541
542
543 if (header->length < min_size)
544 return NULL;
545
546
547
548 format6 = xmalloc (header->length + sizeof *format6);
549
550
551 format6->format = header->format;
552 format6->length = header->length;
553
554
555 min_size -= offsetof (struct sfnt_cmap_format_6, language);
556 rc = read (fd, &format6->language, min_size);
557 if (rc < min_size)
558 {
559 xfree (format6);
560 return (struct sfnt_cmap_format_6 *) -1;
561 }
562
563
564 sfnt_swap16 (&format6->language);
565 sfnt_swap16 (&format6->first_code);
566 sfnt_swap16 (&format6->entry_count);
567
568
569
570 if (header->length
571 < format6->entry_count * sizeof *format6->glyph_index_array)
572 {
573 xfree (format6);
574 return NULL;
575 }
576
577
578 rc = read (fd, format6 + 1,
579 (format6->entry_count
580 * sizeof *format6->glyph_index_array));
581 if (rc < format6->entry_count * sizeof *format6->glyph_index_array)
582 {
583 xfree (format6);
584 return (struct sfnt_cmap_format_6 *) -1;
585 }
586
587
588 format6->glyph_index_array = (uint16_t *) (format6 + 1);
589 for (i = 0; i < format6->entry_count; ++i)
590 sfnt_swap16 (&format6->glyph_index_array[i]);
591
592
593 return format6;
594 }
595
596
597
598
599 static struct sfnt_cmap_format_8 *
600 sfnt_read_cmap_format_8 (int fd,
601 struct sfnt_cmap_encoding_subtable_data *header)
602 {
603 struct sfnt_cmap_format_8 *format8;
604 size_t min_size, temp;
605 ssize_t rc;
606 uint32_t length, i;
607
608
609 if (read (fd, &length, sizeof (length)) < sizeof (length))
610 return (struct sfnt_cmap_format_8 *) -1;
611
612
613 sfnt_swap32 (&length);
614
615 min_size = SFNT_ENDOF (struct sfnt_cmap_format_8, num_groups,
616 uint32_t);
617
618
619 if (length < min_size)
620 return NULL;
621
622
623 format8 = xmalloc (length + sizeof *format8);
624 format8->format = header->format;
625 format8->reserved = header->length;
626 format8->length = length;
627
628
629 min_size -= offsetof (struct sfnt_cmap_format_8, language);
630 rc = read (fd, &format8->language, min_size);
631 if (rc < min_size)
632 {
633 xfree (format8);
634 return (struct sfnt_cmap_format_8 *) -1;
635 }
636
637
638 sfnt_swap32 (&format8->language);
639 sfnt_swap32 (&format8->num_groups);
640
641
642
643 min_size = SFNT_ENDOF (struct sfnt_cmap_format_8, num_groups,
644 uint32_t);
645
646 if (INT_MULTIPLY_WRAPV (format8->num_groups, sizeof *format8->groups,
647 &temp))
648 {
649 xfree (format8);
650 return NULL;
651 }
652
653 if (INT_ADD_WRAPV (min_size, temp, &min_size))
654 {
655 xfree (format8);
656 return NULL;
657 }
658
659 if (length < min_size)
660 {
661 xfree (format8);
662 return NULL;
663 }
664
665
666 rc = read (fd, format8 + 1, temp);
667 if (rc < temp)
668 {
669 xfree (format8);
670 return (struct sfnt_cmap_format_8 *) -1;
671 }
672
673
674 format8->groups
675 = (struct sfnt_cmap_format_8_or_12_group *) (format8 + 1);
676
677 for (i = 0; i < format8->num_groups; ++i)
678 {
679 sfnt_swap32 (&format8->groups[i].start_char_code);
680 sfnt_swap32 (&format8->groups[i].end_char_code);
681 sfnt_swap32 (&format8->groups[i].start_glyph_code);
682 }
683
684
685 return format8;
686 }
687
688
689
690
691 static struct sfnt_cmap_format_12 *
692 sfnt_read_cmap_format_12 (int fd,
693 struct sfnt_cmap_encoding_subtable_data *header)
694 {
695 struct sfnt_cmap_format_12 *format12;
696 size_t min_size, temp;
697 ssize_t rc;
698 uint32_t length, i;
699
700
701 if (read (fd, &length, sizeof (length)) < sizeof (length))
702 return (struct sfnt_cmap_format_12 *) -1;
703
704
705 sfnt_swap32 (&length);
706
707 min_size = SFNT_ENDOF (struct sfnt_cmap_format_12, num_groups,
708 uint32_t);
709
710
711 if (length < min_size)
712 return NULL;
713
714
715 format12 = xmalloc (length + sizeof *format12);
716 format12->format = header->format;
717 format12->reserved = header->length;
718 format12->length = length;
719
720
721 min_size -= offsetof (struct sfnt_cmap_format_12, language);
722 rc = read (fd, &format12->language, min_size);
723 if (rc < min_size)
724 {
725 xfree (format12);
726 return (struct sfnt_cmap_format_12 *) -1;
727 }
728
729
730 sfnt_swap32 (&format12->language);
731 sfnt_swap32 (&format12->num_groups);
732
733
734
735 min_size = SFNT_ENDOF (struct sfnt_cmap_format_12, num_groups,
736 uint32_t);
737
738 if (INT_MULTIPLY_WRAPV (format12->num_groups, sizeof *format12->groups,
739 &temp))
740 {
741 xfree (format12);
742 return NULL;
743 }
744
745 if (INT_ADD_WRAPV (min_size, temp, &min_size))
746 {
747 xfree (format12);
748 return NULL;
749 }
750
751 if (length < min_size)
752 {
753 xfree (format12);
754 return NULL;
755 }
756
757
758 rc = read (fd, format12 + 1, temp);
759 if (rc < temp)
760 {
761 xfree (format12);
762 return (struct sfnt_cmap_format_12 *) -1;
763 }
764
765
766 format12->groups
767 = (struct sfnt_cmap_format_8_or_12_group *) (format12 + 1);
768
769 for (i = 0; i < format12->num_groups; ++i)
770 {
771 sfnt_swap32 (&format12->groups[i].start_char_code);
772 sfnt_swap32 (&format12->groups[i].end_char_code);
773 sfnt_swap32 (&format12->groups[i].start_glyph_code);
774 }
775
776
777 return format12;
778 }
779
780
781
782 static unsigned int
783 sfnt_read_24 (unsigned char *bytes)
784 {
785 return (bytes[0] << 16u) | (bytes[1] << 8u) | bytes[2];
786 }
787
788
789
790
791
792
793
794
795 static struct sfnt_cmap_format_14 *
796 sfnt_read_cmap_format_14 (int fd,
797 struct sfnt_cmap_encoding_subtable_data *header,
798 off_t offset)
799 {
800 struct sfnt_cmap_format_14 *format14;
801 uint32_t length;
802 uint32_t num_records;
803 uint32_t buffer1[2];
804 size_t size, temp;
805 char buffer[3 + 4 + 4];
806 int i;
807
808
809
810
811 if (read (fd, buffer1, sizeof buffer1) < sizeof buffer1)
812 return NULL;
813
814 length = buffer1[0];
815 num_records = buffer1[1];
816
817 sfnt_swap32 (&length);
818 sfnt_swap32 (&num_records);
819
820
821
822
823 size = sizeof *format14;
824 if (INT_MULTIPLY_WRAPV (num_records, sizeof *format14->records,
825 &temp)
826 || INT_ADD_WRAPV (size, temp, &size))
827 return NULL;
828
829 format14 = xmalloc (size);
830
831
832 format14->format = header->format;
833 format14->length = length;
834 format14->num_var_selector_records = num_records;
835 format14->offset = offset;
836
837
838 format14->records
839 = (struct sfnt_variation_selector_record *) (format14 + 1);
840
841
842
843 for (i = 0; i < num_records; ++i)
844 {
845 if (read (fd, buffer, sizeof buffer) < sizeof buffer)
846 {
847 xfree (format14);
848 return NULL;
849 }
850
851
852 format14->records[i].var_selector
853 = sfnt_read_24 ((unsigned char *) buffer);
854
855
856 memcpy (&format14->records[i].default_uvs_offset,
857 buffer + 3,
858 sizeof format14->records[i].default_uvs_offset);
859 memcpy (&format14->records[i].nondefault_uvs_offset,
860 buffer + 7,
861 sizeof format14->records[i].nondefault_uvs_offset);
862
863
864 sfnt_swap32 (&format14->records[i].default_uvs_offset);
865 sfnt_swap32 (&format14->records[i].nondefault_uvs_offset);
866 }
867
868
869 return format14;
870 }
871
872
873
874
875
876
877 static struct sfnt_cmap_encoding_subtable_data *
878 sfnt_read_cmap_table_1 (int fd, uint32_t directory_offset,
879 uint32_t table_offset)
880 {
881 off_t offset;
882 struct sfnt_cmap_encoding_subtable_data header;
883
884 if (INT_ADD_WRAPV (directory_offset, table_offset, &offset))
885 return (struct sfnt_cmap_encoding_subtable_data *) -1;
886
887 if (lseek (fd, offset, SEEK_SET) == (off_t) -1)
888 return (struct sfnt_cmap_encoding_subtable_data *) -1;
889
890 if (read (fd, &header.format, sizeof header.format)
891 < sizeof header.format)
892 return (struct sfnt_cmap_encoding_subtable_data *) -1;
893
894 sfnt_swap16 (&header.format);
895
896
897
898
899
900 if (header.format != 14)
901 {
902 if (read (fd, &header.length, sizeof header.length)
903 < sizeof header.length)
904 return (struct sfnt_cmap_encoding_subtable_data *) -1;
905
906 sfnt_swap16 (&header.length);
907 }
908 else
909 header.length = 0;
910
911 switch (header.format)
912 {
913 case 0:
914
915
916 if (header.length != 262)
917 return NULL;
918
919 return ((struct sfnt_cmap_encoding_subtable_data *)
920 sfnt_read_cmap_format_0 (fd, &header));
921
922 case 2:
923 return ((struct sfnt_cmap_encoding_subtable_data *)
924 sfnt_read_cmap_format_2 (fd, &header));
925
926 case 4:
927 return ((struct sfnt_cmap_encoding_subtable_data *)
928 sfnt_read_cmap_format_4 (fd, &header));
929
930 case 6:
931 return ((struct sfnt_cmap_encoding_subtable_data *)
932 sfnt_read_cmap_format_6 (fd, &header));
933
934 case 8:
935 return ((struct sfnt_cmap_encoding_subtable_data *)
936 sfnt_read_cmap_format_8 (fd, &header));
937
938 case 12:
939 return ((struct sfnt_cmap_encoding_subtable_data *)
940 sfnt_read_cmap_format_12 (fd, &header));
941
942 case 14:
943 return ((struct sfnt_cmap_encoding_subtable_data *)
944 sfnt_read_cmap_format_14 (fd, &header, offset));
945
946 default:
947 return NULL;
948 }
949 }
950
951
952
953
954
955
956
957
958 TEST_STATIC struct sfnt_cmap_table *
959 sfnt_read_cmap_table (int fd, struct sfnt_offset_subtable *subtable,
960 struct sfnt_cmap_encoding_subtable **subtables,
961 struct sfnt_cmap_encoding_subtable_data ***data)
962 {
963 struct sfnt_table_directory *directory;
964 struct sfnt_cmap_table *cmap;
965 ssize_t rc;
966 int i, j;
967
968
969 directory = sfnt_find_table (subtable, SFNT_TABLE_CMAP);
970
971 if (!directory)
972 return NULL;
973
974
975 if (lseek (fd, directory->offset, SEEK_SET) == (off_t) -1)
976 return NULL;
977
978
979 cmap = xmalloc (sizeof *cmap);
980 rc = read (fd, cmap, sizeof *cmap);
981
982 if (rc < sizeof *cmap)
983 {
984 xfree (cmap);
985 return NULL;
986 }
987
988
989 sfnt_swap16 (&cmap->version);
990 sfnt_swap16 (&cmap->num_subtables);
991
992 if (cmap->version != 0)
993 {
994 xfree (cmap);
995 return NULL;
996 }
997
998 *subtables = xmalloc (cmap->num_subtables
999 * sizeof **subtables);
1000
1001
1002
1003
1004 for (i = 0; i < cmap->num_subtables; ++i)
1005 {
1006
1007 rc = read (fd, &(*subtables)[i], sizeof (*subtables)[i]);
1008
1009 if (rc < sizeof (*subtables))
1010 {
1011 xfree (cmap);
1012 xfree (*subtables);
1013 return NULL;
1014 }
1015
1016 sfnt_swap16 (&(*subtables)[i].platform_id);
1017 sfnt_swap16 (&(*subtables)[i].platform_specific_id);
1018 sfnt_swap32 (&(*subtables)[i].offset);
1019 }
1020
1021
1022
1023 if (!data)
1024 return cmap;
1025
1026
1027 *data = xmalloc (cmap->num_subtables * sizeof *data);
1028
1029 for (i = 0; i < cmap->num_subtables; ++i)
1030 {
1031 (*data)[i] = sfnt_read_cmap_table_1 (fd, directory->offset,
1032 (*subtables)[i].offset);
1033
1034 if ((*data)[i] == (void *) -1)
1035 {
1036
1037
1038
1039 for (j = 0; j < i; ++j)
1040 xfree ((*data)[j]);
1041
1042 xfree (*data);
1043 xfree (*subtables);
1044 xfree (cmap);
1045 return NULL;
1046 }
1047 }
1048
1049 return cmap;
1050 }
1051
1052
1053
1054
1055 static sfnt_glyph
1056 sfnt_lookup_glyph_0 (sfnt_char character,
1057 struct sfnt_cmap_format_0 *format0)
1058 {
1059 if (character >= 256)
1060 return 0;
1061
1062 return format0->glyph_index_array[character];
1063 }
1064
1065
1066
1067
1068 static sfnt_glyph
1069 sfnt_lookup_glyph_2 (sfnt_char character,
1070 struct sfnt_cmap_format_2 *format2)
1071 {
1072 unsigned char i, k, j;
1073 struct sfnt_cmap_format_2_subheader *subheader;
1074 unsigned char *slice;
1075 uint16_t glyph;
1076
1077 if (character > 65335)
1078 return 0;
1079
1080 i = character >> 16;
1081 j = character & 0xff;
1082 k = format2->sub_header_keys[i] / 8;
1083
1084 if (k)
1085 {
1086 subheader = &format2->subheaders[k];
1087
1088 if (subheader->first_code <= j
1089 && j <= ((int) subheader->first_code
1090 + (int) subheader->entry_count))
1091 {
1092
1093
1094
1095 slice = (unsigned char *) &subheader->id_range_offset;
1096 slice += subheader->id_range_offset;
1097 slice += (j - subheader->first_code) * sizeof (uint16_t);
1098
1099 if (slice < (unsigned char *) format2->glyph_index_array
1100 || (slice + 1
1101 > (unsigned char *) (format2->glyph_index_array
1102 + format2->num_glyphs)))
1103
1104 return 0;
1105
1106 memcpy (&glyph, slice, sizeof glyph);
1107 return (glyph + subheader->id_delta) % 65536;
1108 }
1109 else
1110 return 0;
1111 }
1112
1113
1114 return (i < format2->num_glyphs
1115 ? format2->glyph_index_array[i]
1116 : 0);
1117 }
1118
1119
1120
1121
1122 static void *
1123 sfnt_bsearch_above (const void *key, const void *base,
1124 size_t nmemb, size_t size,
1125 int (*compar) (const void *,
1126 const void *))
1127 {
1128 const unsigned char *bytes, *sample;
1129 size_t low, high, mid;
1130
1131 bytes = base;
1132 low = 0;
1133 high = nmemb - 1;
1134
1135 if (!nmemb)
1136 return NULL;
1137
1138 while (low != high)
1139 {
1140 mid = low + (high - low) / 2;
1141 sample = bytes + mid * size;
1142
1143 if (compar (key, sample) > 0)
1144 low = mid + 1;
1145 else
1146 high = mid;
1147 }
1148
1149 return (unsigned char *) bytes + low * size;
1150 }
1151
1152
1153
1154
1155 static int
1156 sfnt_compare_uint16 (const void *a, const void *b)
1157 {
1158 return ((int) *((uint16_t *) a)) - ((int) *((uint16_t *) b));
1159 }
1160
1161
1162
1163
1164
1165 static sfnt_glyph
1166 sfnt_lookup_glyph_4_1 (uint16_t code, uint16_t segment,
1167 struct sfnt_cmap_format_4 *format4)
1168 {
1169 uint16_t *index;
1170
1171 if (format4->id_range_offset[segment])
1172 {
1173
1174
1175 index = (uint16_t *) (&format4->id_range_offset[segment]
1176 + format4->id_range_offset[segment] / 2
1177 + (code - format4->start_code[segment]));
1178
1179
1180 if (index >= (format4->glyph_index_array
1181 + format4->glyph_index_size)
1182 || index < format4->glyph_index_array)
1183 return 0;
1184
1185
1186 return (*index ? (format4->id_delta[segment]
1187 + *index) % 65536 : 0);
1188 }
1189
1190
1191 return (format4->id_delta[segment] + code) % 65536;
1192 }
1193
1194
1195
1196
1197 static sfnt_glyph
1198 sfnt_lookup_glyph_4 (sfnt_char character,
1199 struct sfnt_cmap_format_4 *format4)
1200 {
1201 uint16_t *segment_address;
1202 uint16_t code, segment;
1203 sfnt_glyph glyph;
1204
1205 if (character > 65535)
1206 return 0;
1207
1208 code = character;
1209
1210
1211 segment_address = sfnt_bsearch_above (&code, format4->end_code,
1212 format4->seg_count_x2 / 2,
1213 sizeof code,
1214 sfnt_compare_uint16);
1215 segment = segment_address - format4->end_code;
1216
1217
1218 if (!segment_address || format4->start_code[segment] > character)
1219 return 0;
1220
1221 glyph = sfnt_lookup_glyph_4_1 (character, segment, format4);
1222
1223 if (glyph)
1224 return glyph;
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235 if (!glyph
1236
1237
1238 && code == format4->end_code[segment]
1239
1240 && segment + 1 < format4->seg_count_x2 / 2
1241
1242
1243 && format4->start_code[segment + 1] == format4->end_code[segment])
1244
1245 return sfnt_lookup_glyph_4_1 (character, segment + 1, format4);
1246
1247
1248 return 0;
1249 }
1250
1251
1252
1253
1254 static sfnt_glyph
1255 sfnt_lookup_glyph_6 (sfnt_char character,
1256 struct sfnt_cmap_format_6 *format6)
1257 {
1258 if (character < format6->first_code
1259 || character >= (format6->first_code
1260 + (int) format6->entry_count))
1261 return 0;
1262
1263 return format6->glyph_index_array[character - format6->first_code];
1264 }
1265
1266
1267
1268
1269 static sfnt_glyph
1270 sfnt_lookup_glyph_8 (sfnt_char character,
1271 struct sfnt_cmap_format_8 *format8)
1272 {
1273 uint32_t i;
1274
1275 if (character > 0xffffffff)
1276 return 0;
1277
1278 for (i = 0; i < format8->num_groups; ++i)
1279 {
1280 if (format8->groups[i].start_char_code <= character
1281 && format8->groups[i].end_char_code >= character)
1282 return (format8->groups[i].start_glyph_code
1283 + (character
1284 - format8->groups[i].start_char_code));
1285 }
1286
1287 return 0;
1288 }
1289
1290
1291
1292
1293 static sfnt_glyph
1294 sfnt_lookup_glyph_12 (sfnt_char character,
1295 struct sfnt_cmap_format_12 *format12)
1296 {
1297 uint32_t i;
1298
1299 if (character > 0xffffffff)
1300 return 0;
1301
1302 for (i = 0; i < format12->num_groups; ++i)
1303 {
1304 if (format12->groups[i].start_char_code <= character
1305 && format12->groups[i].end_char_code >= character)
1306 return (format12->groups[i].start_glyph_code
1307 + (character
1308 - format12->groups[i].start_char_code));
1309 }
1310
1311 return 0;
1312 }
1313
1314
1315
1316
1317
1318
1319
1320
1321 TEST_STATIC sfnt_glyph
1322 sfnt_lookup_glyph (sfnt_char character,
1323 struct sfnt_cmap_encoding_subtable_data *data)
1324 {
1325 switch (data->format)
1326 {
1327 case 0:
1328 return sfnt_lookup_glyph_0 (character,
1329 (struct sfnt_cmap_format_0 *) data);
1330
1331 case 2:
1332 return sfnt_lookup_glyph_2 (character,
1333 (struct sfnt_cmap_format_2 *) data);
1334
1335 case 4:
1336 return sfnt_lookup_glyph_4 (character,
1337 (struct sfnt_cmap_format_4 *) data);
1338
1339 case 6:
1340 return sfnt_lookup_glyph_6 (character,
1341 (struct sfnt_cmap_format_6 *) data);
1342
1343 case 8:
1344 return sfnt_lookup_glyph_8 (character,
1345 (struct sfnt_cmap_format_8 *) data);
1346
1347 case 12:
1348 return sfnt_lookup_glyph_12 (character,
1349 (struct sfnt_cmap_format_12 *) data);
1350 }
1351
1352 return 0;
1353 }
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364 TEST_STATIC struct sfnt_head_table *
1365 sfnt_read_head_table (int fd, struct sfnt_offset_subtable *subtable)
1366 {
1367 struct sfnt_table_directory *directory;
1368 struct sfnt_head_table *head;
1369 ssize_t rc;
1370
1371
1372
1373 directory = sfnt_find_table (subtable, SFNT_TABLE_HEAD);
1374
1375 if (!directory)
1376 return NULL;
1377
1378
1379 if (lseek (fd, directory->offset, SEEK_SET) == (off_t) -1)
1380 return NULL;
1381
1382
1383 head = xmalloc (sizeof *head);
1384 rc = read (fd, head, sizeof *head);
1385
1386 if (rc < sizeof *head)
1387 {
1388 xfree (head);
1389 return NULL;
1390 }
1391
1392
1393 sfnt_swap32 (&head->version);
1394 sfnt_swap32 (&head->revision);
1395
1396 if (head->version != 0x00010000)
1397 {
1398 xfree (head);
1399 return NULL;
1400 }
1401
1402
1403 sfnt_swap32 (&head->checksum_adjustment);
1404 sfnt_swap32 (&head->magic);
1405
1406 if (head->magic != 0x5f0f3cf5)
1407 {
1408 xfree (head);
1409 return NULL;
1410 }
1411
1412 sfnt_swap16 (&head->flags);
1413 sfnt_swap16 (&head->units_per_em);
1414 sfnt_swap32 (&head->created_high);
1415 sfnt_swap32 (&head->created_low);
1416 sfnt_swap32 (&head->modified_high);
1417 sfnt_swap32 (&head->modified_low);
1418 sfnt_swap16 (&head->xmin);
1419 sfnt_swap16 (&head->xmax);
1420 sfnt_swap16 (&head->ymin);
1421 sfnt_swap16 (&head->ymax);
1422 sfnt_swap16 (&head->mac_style);
1423 sfnt_swap16 (&head->lowest_rec_ppem);
1424 sfnt_swap16 (&head->font_direction_hint);
1425 sfnt_swap16 (&head->index_to_loc_format);
1426 sfnt_swap16 (&head->glyph_data_format);
1427
1428 return head;
1429 }
1430
1431
1432
1433
1434
1435
1436 TEST_STATIC struct sfnt_hhea_table *
1437 sfnt_read_hhea_table (int fd, struct sfnt_offset_subtable *subtable)
1438 {
1439 struct sfnt_table_directory *directory;
1440 struct sfnt_hhea_table *hhea;
1441 ssize_t rc;
1442
1443
1444
1445 directory = sfnt_find_table (subtable, SFNT_TABLE_HHEA);
1446
1447 if (!directory)
1448 return NULL;
1449
1450
1451 if (directory->length != sizeof *hhea)
1452 return NULL;
1453
1454
1455 if (lseek (fd, directory->offset, SEEK_SET) == (off_t) -1)
1456 return NULL;
1457
1458
1459 hhea = xmalloc (sizeof *hhea);
1460 rc = read (fd, hhea, sizeof *hhea);
1461
1462 if (rc < sizeof *hhea)
1463 {
1464 xfree (hhea);
1465 return NULL;
1466 }
1467
1468
1469 sfnt_swap32 (&hhea->version);
1470
1471 if (hhea->version != 0x00010000)
1472 {
1473 xfree (hhea);
1474 return NULL;
1475 }
1476
1477
1478 sfnt_swap16 (&hhea->ascent);
1479 sfnt_swap16 (&hhea->descent);
1480 sfnt_swap16 (&hhea->line_gap);
1481 sfnt_swap16 (&hhea->advance_width_max);
1482 sfnt_swap16 (&hhea->min_left_side_bearing);
1483 sfnt_swap16 (&hhea->min_right_side_bearing);
1484 sfnt_swap16 (&hhea->x_max_extent);
1485 sfnt_swap16 (&hhea->caret_slope_rise);
1486 sfnt_swap16 (&hhea->caret_slope_run);
1487 sfnt_swap16 (&hhea->reserved1);
1488 sfnt_swap16 (&hhea->reserved2);
1489 sfnt_swap16 (&hhea->reserved3);
1490 sfnt_swap16 (&hhea->reserved4);
1491 sfnt_swap16 (&hhea->metric_data_format);
1492 sfnt_swap16 (&hhea->num_of_long_hor_metrics);
1493
1494 return hhea;
1495 }
1496
1497
1498
1499
1500
1501
1502 TEST_STATIC struct sfnt_loca_table_short *
1503 sfnt_read_loca_table_short (int fd, struct sfnt_offset_subtable *subtable)
1504 {
1505 struct sfnt_table_directory *directory;
1506 struct sfnt_loca_table_short *loca;
1507 ssize_t rc;
1508 int i;
1509
1510
1511
1512 directory = sfnt_find_table (subtable, SFNT_TABLE_LOCA);
1513
1514 if (!directory)
1515 return NULL;
1516
1517
1518 if (lseek (fd, directory->offset, SEEK_SET) == (off_t) -1)
1519 return NULL;
1520
1521
1522 loca = xmalloc (sizeof *loca + directory->length);
1523 loca->offsets = (uint16_t *) (loca + 1);
1524 loca->num_offsets = directory->length / 2;
1525
1526
1527 rc = read (fd, loca->offsets, directory->length);
1528 if (rc < directory->length)
1529 {
1530 xfree (loca);
1531 return NULL;
1532 }
1533
1534
1535 for (i = 0; i < loca->num_offsets; ++i)
1536 sfnt_swap16 (&loca->offsets[i]);
1537
1538
1539 return loca;
1540 }
1541
1542
1543
1544
1545
1546
1547 TEST_STATIC struct sfnt_loca_table_long *
1548 sfnt_read_loca_table_long (int fd, struct sfnt_offset_subtable *subtable)
1549 {
1550 struct sfnt_table_directory *directory;
1551 struct sfnt_loca_table_long *loca;
1552 ssize_t rc;
1553 int i;
1554
1555
1556
1557 directory = sfnt_find_table (subtable, SFNT_TABLE_LOCA);
1558
1559 if (!directory)
1560 return NULL;
1561
1562
1563 if (lseek (fd, directory->offset, SEEK_SET) == (off_t) -1)
1564 return NULL;
1565
1566
1567 loca = xmalloc (sizeof *loca + directory->length);
1568 loca->offsets = (uint32_t *) (loca + 1);
1569 loca->num_offsets = directory->length / 4;
1570
1571
1572 rc = read (fd, loca->offsets, directory->length);
1573 if (rc < directory->length)
1574 {
1575 xfree (loca);
1576 return NULL;
1577 }
1578
1579
1580 for (i = 0; i < loca->num_offsets; ++i)
1581 sfnt_swap32 (&loca->offsets[i]);
1582
1583
1584 return loca;
1585 }
1586
1587
1588
1589
1590
1591
1592
1593 TEST_STATIC struct sfnt_maxp_table *
1594 sfnt_read_maxp_table (int fd, struct sfnt_offset_subtable *subtable)
1595 {
1596 struct sfnt_table_directory *directory;
1597 struct sfnt_maxp_table *maxp;
1598 size_t size;
1599 ssize_t rc;
1600
1601
1602
1603 directory = sfnt_find_table (subtable, SFNT_TABLE_MAXP);
1604
1605 if (!directory)
1606 return NULL;
1607
1608
1609 if (lseek (fd, directory->offset, SEEK_SET) == (off_t) -1)
1610 return NULL;
1611
1612
1613 if (directory->length < SFNT_ENDOF (struct sfnt_maxp_table,
1614 num_glyphs, uint16_t))
1615 return NULL;
1616
1617
1618
1619
1620
1621 maxp = xmalloc (sizeof *maxp);
1622 size = MIN (directory->length, sizeof *maxp);
1623 rc = read (fd, maxp, size);
1624
1625 if (rc < size)
1626 {
1627 xfree (maxp);
1628 return NULL;
1629 }
1630
1631
1632 sfnt_swap32 (&maxp->version);
1633 sfnt_swap16 (&maxp->num_glyphs);
1634
1635
1636 if (maxp->version > 0x00005000 && size < sizeof *maxp)
1637 {
1638 xfree (maxp);
1639 return NULL;
1640 }
1641
1642
1643 if (maxp->version == 0x00005000)
1644 return maxp;
1645 else if (maxp->version != 0x00010000)
1646 {
1647
1648 xfree (maxp);
1649 return NULL;
1650 }
1651
1652
1653 sfnt_swap16 (&maxp->max_points);
1654 sfnt_swap16 (&maxp->max_contours);
1655 sfnt_swap16 (&maxp->max_composite_points);
1656 sfnt_swap16 (&maxp->max_composite_contours);
1657 sfnt_swap16 (&maxp->max_zones);
1658 sfnt_swap16 (&maxp->max_twilight_points);
1659 sfnt_swap16 (&maxp->max_storage);
1660 sfnt_swap16 (&maxp->max_function_defs);
1661 sfnt_swap16 (&maxp->max_instruction_defs);
1662 sfnt_swap16 (&maxp->max_stack_elements);
1663 sfnt_swap16 (&maxp->max_size_of_instructions);
1664 sfnt_swap16 (&maxp->max_component_elements);
1665 sfnt_swap16 (&maxp->max_component_depth);
1666
1667
1668 return maxp;
1669 }
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680 TEST_STATIC struct sfnt_glyf_table *
1681 sfnt_read_glyf_table (int fd, struct sfnt_offset_subtable *subtable)
1682 {
1683 struct sfnt_table_directory *directory;
1684 struct sfnt_glyf_table *glyf;
1685 ssize_t rc;
1686
1687
1688
1689 directory = sfnt_find_table (subtable, SFNT_TABLE_GLYF);
1690
1691 if (!directory)
1692 return NULL;
1693
1694
1695 if (lseek (fd, directory->offset, SEEK_SET) == (off_t) -1)
1696 return NULL;
1697
1698
1699 glyf = xmalloc (sizeof *glyf + directory->length);
1700 glyf->size = directory->length;
1701 glyf->glyphs = (unsigned char *) (glyf + 1);
1702
1703
1704 rc = read (fd, glyf->glyphs, glyf->size);
1705 if (rc < glyf->size)
1706 {
1707 xfree (glyf);
1708 return NULL;
1709 }
1710
1711
1712 return glyf;
1713 }
1714
1715 #if defined HAVE_MMAP && !defined TEST
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725 struct sfnt_glyf_table *
1726 sfnt_map_glyf_table (int fd, struct sfnt_offset_subtable *subtable)
1727 {
1728 struct sfnt_table_directory *directory;
1729 struct sfnt_glyf_table *glyf;
1730 void *glyphs;
1731 size_t offset, page, map_offset;
1732
1733
1734
1735 directory = sfnt_find_table (subtable, SFNT_TABLE_GLYF);
1736
1737 if (!directory)
1738 return NULL;
1739
1740
1741
1742
1743 page = getpagesize ();
1744 offset = directory->offset & ~(page - 1);
1745
1746
1747 map_offset = directory->offset - offset;
1748
1749
1750 glyphs = mmap (NULL, directory->length + map_offset,
1751 PROT_READ, MAP_PRIVATE, fd, offset);
1752
1753 if (glyphs == MAP_FAILED)
1754 return NULL;
1755
1756
1757
1758
1759 #ifdef HAVE_POSIX_MADVISE
1760 posix_madvise (glyphs, directory->length,
1761 POSIX_MADV_WILLNEED);
1762 #elif defined HAVE_MADVISE
1763 madvise (glyphs, directory->length, MADV_WILLNEED);
1764 #endif
1765
1766
1767 glyf = xmalloc (sizeof *glyf);
1768 glyf->size = directory->length;
1769 glyf->glyphs = (unsigned char *) glyphs + map_offset;
1770 glyf->start = glyphs;
1771
1772 return glyf;
1773 }
1774
1775
1776
1777
1778
1779 int
1780 sfnt_unmap_glyf_table (struct sfnt_glyf_table *glyf)
1781 {
1782 int rc;
1783 size_t size;
1784
1785
1786 size = glyf->size + (glyf->glyphs - glyf->start);
1787
1788 rc = munmap (glyf->start, size);
1789 xfree (glyf);
1790
1791 return rc != 0;
1792 }
1793
1794 #endif
1795
1796
1797
1798
1799
1800 static void
1801 sfnt_read_simple_glyph (struct sfnt_glyph *glyph,
1802 struct sfnt_glyf_table *glyf,
1803 size_t offset)
1804 {
1805 struct sfnt_simple_glyph *simple;
1806 ssize_t min_size, min_size_2;
1807 int i, number_of_points, repeat_count;
1808 unsigned char *instructions_start;
1809 unsigned char *flags_start, *flags_end;
1810 unsigned char *vec_start;
1811 int16_t delta, x, y;
1812
1813
1814
1815
1816
1817 min_size = (glyph->number_of_contours * sizeof (uint16_t)
1818 + sizeof (uint16_t));
1819
1820
1821 if (glyf->size < offset + min_size)
1822 {
1823 glyph->simple = NULL;
1824 return;
1825 }
1826
1827
1828 simple = xmalloc (sizeof *simple + min_size);
1829 simple->end_pts_of_contours = (uint16_t *) (simple + 1);
1830 memcpy (simple->end_pts_of_contours, glyf->glyphs + offset,
1831 min_size);
1832
1833
1834
1835 simple->instruction_length
1836 = simple->end_pts_of_contours[glyph->number_of_contours];
1837
1838
1839
1840
1841 for (i = 0; i < glyph->number_of_contours; ++i)
1842 sfnt_swap16 (&simple->end_pts_of_contours[i]);
1843
1844 sfnt_swap16 (&simple->instruction_length);
1845
1846
1847
1848
1849
1850 if (glyph->number_of_contours)
1851 number_of_points
1852 = simple->end_pts_of_contours[glyph->number_of_contours - 1] + 1;
1853 else
1854 number_of_points = 0;
1855
1856 min_size_2 = (simple->instruction_length
1857 + number_of_points
1858 + (number_of_points
1859 * sizeof (uint16_t) * 2));
1860
1861
1862 simple->number_of_points = number_of_points;
1863
1864
1865 simple = xrealloc (simple, sizeof *simple + min_size + min_size_2);
1866 simple->end_pts_of_contours = (uint16_t *) (simple + 1);
1867
1868
1869
1870
1871
1872 simple->instructions = (uint8_t *) (simple->end_pts_of_contours
1873 + glyph->number_of_contours + 1);
1874 simple->flags = simple->instructions + simple->instruction_length;
1875
1876
1877 instructions_start = glyf->glyphs + offset + min_size;
1878
1879 if (instructions_start >= glyf->glyphs + glyf->size
1880 || (instructions_start + simple->instruction_length
1881 >= glyf->glyphs + glyf->size))
1882 {
1883 glyph->simple = NULL;
1884 xfree (simple);
1885 return;
1886 }
1887
1888 memcpy (simple->instructions, instructions_start,
1889 simple->instruction_length);
1890
1891
1892 flags_start = (glyf->glyphs + offset
1893 + min_size + simple->instruction_length);
1894 flags_end = flags_start + number_of_points;
1895
1896 if (flags_start >= glyf->glyphs + glyf->size)
1897 {
1898 glyph->simple = NULL;
1899 xfree (simple);
1900 return;
1901 }
1902
1903 i = 0;
1904
1905 while (flags_start < flags_end)
1906 {
1907 if (i == number_of_points)
1908 break;
1909
1910 if (flags_start >= glyf->glyphs + glyf->size)
1911 break;
1912
1913 simple->flags[i++] = *flags_start;
1914
1915 if (*flags_start & 010)
1916 {
1917
1918
1919
1920 if (flags_start + 1 >= glyf->glyphs + glyf->size)
1921 {
1922 glyph->simple = NULL;
1923 xfree (simple);
1924 return;
1925 }
1926
1927
1928
1929
1930 repeat_count = *(flags_start + 1);
1931
1932 while (i < number_of_points && repeat_count)
1933 {
1934 simple->flags[i++] = *flags_start;
1935 repeat_count--;
1936 }
1937
1938
1939 flags_start++;
1940 }
1941
1942 flags_start++;
1943 }
1944
1945
1946
1947
1948 if (i != number_of_points)
1949 {
1950 glyph->simple = NULL;
1951 xfree (simple);
1952 return;
1953 }
1954
1955
1956
1957 simple->x_coordinates = (int16_t *) (simple->flags + number_of_points);
1958 vec_start = flags_start;
1959 i = 0;
1960 x = 0;
1961
1962
1963
1964 flags_start = simple->flags;
1965
1966 while (i < number_of_points)
1967 {
1968 delta = 0;
1969
1970 if ((*flags_start) & 02)
1971 {
1972
1973
1974
1975 if (vec_start + 1 >= glyf->glyphs + glyf->size)
1976 {
1977 glyph->simple = NULL;
1978 xfree (simple);
1979 return;
1980 }
1981
1982 delta = *vec_start++;
1983
1984 if (!(*flags_start & 020))
1985 delta = -delta;
1986 }
1987 else if (!(*flags_start & 020))
1988 {
1989
1990
1991
1992 if (vec_start + 2 >= glyf->glyphs + glyf->size)
1993 {
1994 glyph->simple = NULL;
1995 xfree (simple);
1996 return;
1997 }
1998
1999
2000 memcpy (&delta, vec_start, sizeof delta);
2001 sfnt_swap16 (&delta);
2002 vec_start += 2;
2003 }
2004
2005
2006 x += delta;
2007 simple->x_coordinates[i++] = x;
2008 flags_start++;
2009 }
2010
2011
2012
2013 flags_start = simple->flags;
2014 y = 0;
2015 simple->y_coordinates = simple->x_coordinates + i;
2016 i = 0;
2017
2018 while (i < number_of_points)
2019 {
2020 delta = 0;
2021
2022 if (*flags_start & 04)
2023 {
2024
2025
2026
2027 if (vec_start + 1 >= glyf->glyphs + glyf->size)
2028 {
2029 glyph->simple = NULL;
2030 xfree (simple);
2031 return;
2032 }
2033
2034 delta = *vec_start++;
2035
2036 if (!(*flags_start & 040))
2037 delta = -delta;
2038 }
2039 else if (!(*flags_start & 040))
2040 {
2041
2042
2043
2044 if (vec_start + 2 >= glyf->glyphs + glyf->size)
2045 {
2046 glyph->simple = NULL;
2047 xfree (simple);
2048 return;
2049 }
2050
2051
2052 memcpy (&delta, vec_start, sizeof delta);
2053 sfnt_swap16 (&delta);
2054 vec_start += 2;
2055 }
2056
2057
2058 y += delta;
2059 simple->y_coordinates[i++] = y;
2060 flags_start++;
2061 }
2062
2063
2064 simple->y_coordinates_end = simple->y_coordinates + i;
2065 glyph->simple = simple;
2066 return;
2067 }
2068
2069
2070
2071
2072
2073 static void
2074 sfnt_read_compound_glyph (struct sfnt_glyph *glyph,
2075 struct sfnt_glyf_table *glyf,
2076 size_t offset)
2077 {
2078 uint16_t flags, instruction_length, words[2], words4[4];
2079 size_t required_bytes, num_components, i;
2080 unsigned char *data, *instruction_base;
2081
2082
2083
2084 glyph->compound = NULL;
2085 required_bytes = 0;
2086 num_components = 0;
2087 data = glyf->glyphs + offset;
2088
2089
2090 do
2091 {
2092 if (data + 2 > glyf->glyphs + glyf->size)
2093 return;
2094
2095 memcpy (&flags, data, sizeof flags);
2096 sfnt_swap16 (&flags);
2097 data += sizeof flags;
2098
2099
2100 required_bytes += sizeof (struct sfnt_compound_glyph_component);
2101 num_components++;
2102
2103
2104 data += 2;
2105
2106 if (flags & 01)
2107 data += sizeof (int16_t) * 2;
2108 else
2109 data += sizeof (int8_t) * 2;
2110
2111 if (flags & 010)
2112 data += sizeof (uint16_t);
2113 else if (flags & 0100)
2114 data += sizeof (uint16_t) * 2;
2115 else if (flags & 0200)
2116 data += sizeof (uint16_t) * 4;
2117 }
2118 while (flags & 040);
2119
2120 if (flags & 0400)
2121 {
2122
2123 if (data + 2 > glyf->glyphs + glyf->size)
2124 return;
2125
2126
2127
2128 memcpy (&instruction_length, data,
2129 sizeof instruction_length);
2130 sfnt_swap16 (&instruction_length);
2131 required_bytes += instruction_length;
2132 data += sizeof data + instruction_length;
2133 }
2134
2135
2136 glyph->compound = xmalloc (sizeof *glyph->compound
2137 + required_bytes);
2138 glyph->compound->components
2139 = (struct sfnt_compound_glyph_component *) (glyph->compound + 1);
2140 glyph->compound->num_components = num_components;
2141
2142
2143
2144 instruction_base
2145 = (unsigned char *) (glyph->compound->components
2146 + glyph->compound->num_components);
2147
2148
2149 i = 0;
2150 data = glyf->glyphs + offset;
2151 do
2152 {
2153 if (data + 4 > glyf->glyphs + glyf->size)
2154 {
2155 xfree (glyph->compound);
2156 glyph->compound = NULL;
2157 return;
2158 }
2159
2160 memcpy (&flags, data, sizeof flags);
2161 sfnt_swap16 (&flags);
2162 data += sizeof flags;
2163 glyph->compound->components[i].flags = flags;
2164
2165 memcpy (&glyph->compound->components[i].glyph_index,
2166 data, sizeof glyph->compound->components[i].glyph_index);
2167 sfnt_swap16 (&glyph->compound->components[i].glyph_index);
2168 data += sizeof glyph->compound->components[i].glyph_index;
2169
2170 if (flags & 01)
2171 {
2172 if (data + 4 > glyf->glyphs + glyf->size)
2173 {
2174 xfree (glyph->compound);
2175 glyph->compound = NULL;
2176 return;
2177 }
2178
2179
2180 memcpy (words, data, sizeof words);
2181 sfnt_swap16 (&words[0]);
2182 sfnt_swap16 (&words[1]);
2183
2184 glyph->compound->components[i].argument1.c = words[0];
2185 glyph->compound->components[i].argument2.c = words[1];
2186 data += sizeof words;
2187 }
2188 else
2189 {
2190 if (data + 2 > glyf->glyphs + glyf->size)
2191 {
2192 xfree (glyph->compound);
2193 glyph->compound = NULL;
2194 return;
2195 }
2196
2197
2198 glyph->compound->components[i].argument1.a = data[0];
2199 glyph->compound->components[i].argument2.a = data[1];
2200 data += 2;
2201 }
2202
2203 if (flags & 010)
2204 {
2205 if (data + 2 > glyf->glyphs + glyf->size)
2206 {
2207 xfree (glyph->compound);
2208 glyph->compound = NULL;
2209 return;
2210 }
2211
2212
2213 memcpy (&glyph->compound->components[i].u.scale, data,
2214 sizeof glyph->compound->components[i].u.scale);
2215 sfnt_swap16 (&glyph->compound->components[i].u.scale);
2216 data += sizeof glyph->compound->components[i].u.scale;
2217 }
2218 else if (flags & 0100)
2219 {
2220 if (data + 4 > glyf->glyphs + glyf->size)
2221 {
2222 xfree (glyph->compound);
2223 glyph->compound = NULL;
2224 return;
2225 }
2226
2227
2228 memcpy (words, data, sizeof words);
2229 sfnt_swap16 (&words[0]);
2230 sfnt_swap16 (&words[1]);
2231
2232 glyph->compound->components[i].u.a.xscale = words[0];
2233 glyph->compound->components[i].u.a.yscale = words[1];
2234 data += sizeof words;
2235 }
2236 else if (flags & 0200)
2237 {
2238 if (data + 8 > glyf->glyphs + glyf->size)
2239 {
2240 xfree (glyph->compound);
2241 glyph->compound = NULL;
2242 return;
2243 }
2244
2245
2246 memcpy (words4, data, sizeof words4);
2247 sfnt_swap16 (&words4[0]);
2248 sfnt_swap16 (&words4[1]);
2249 sfnt_swap16 (&words4[2]);
2250 sfnt_swap16 (&words4[3]);
2251
2252 glyph->compound->components[i].u.b.xscale = words4[0];
2253 glyph->compound->components[i].u.b.scale01 = words4[1];
2254 glyph->compound->components[i].u.b.scale10 = words4[2];
2255 glyph->compound->components[i].u.b.yscale = words4[3];
2256 data += sizeof words4;
2257 }
2258
2259
2260 glyph->compound->components[i].flags = flags;
2261
2262 i++;
2263 }
2264 while (flags & 040);
2265
2266 if (flags & 0400)
2267 {
2268
2269 if (data + 2 > glyf->glyphs + glyf->size)
2270 {
2271 xfree (glyph->compound);
2272 glyph->compound = NULL;
2273 return;
2274 }
2275
2276
2277
2278 memcpy (&glyph->compound->instruction_length,
2279 data,
2280 sizeof glyph->compound->instruction_length);
2281 sfnt_swap16 (&glyph->compound->instruction_length);
2282 data += 2;
2283
2284
2285 glyph->compound->instructions = instruction_base;
2286
2287 if (data + glyph->compound->instruction_length
2288 > glyf->glyphs + glyf->size)
2289 {
2290 xfree (glyph->compound);
2291 glyph->compound = NULL;
2292 return;
2293 }
2294
2295 memcpy (instruction_base, data,
2296 glyph->compound->instruction_length);
2297 }
2298 else
2299 {
2300 glyph->compound->instructions = NULL;
2301 glyph->compound->instruction_length = 0;
2302 }
2303
2304
2305 return;
2306 }
2307
2308
2309
2310
2311
2312 TEST_STATIC struct sfnt_glyph *
2313 sfnt_read_glyph (sfnt_glyph glyph_code,
2314 struct sfnt_glyf_table *glyf,
2315 struct sfnt_loca_table_short *loca_short,
2316 struct sfnt_loca_table_long *loca_long)
2317 {
2318 struct sfnt_glyph glyph, *memory;
2319 size_t offset, next_offset;
2320
2321
2322 if (glyph_code > 65535)
2323 return NULL;
2324
2325 if (loca_short)
2326 {
2327
2328
2329 if (glyph_code + 1 >= loca_short->num_offsets)
2330 return NULL;
2331
2332 offset = loca_short->offsets[glyph_code] * 2;
2333 next_offset = loca_short->offsets[glyph_code + 1] * 2;
2334 }
2335 else if (loca_long)
2336 {
2337 if (glyph_code + 1 >= loca_long->num_offsets)
2338 return NULL;
2339
2340 offset = loca_long->offsets[glyph_code];
2341 next_offset = loca_long->offsets[glyph_code + 1];
2342 }
2343 else
2344 abort ();
2345
2346
2347
2348
2349 if (offset == next_offset)
2350 {
2351 glyph.number_of_contours = 0;
2352 glyph.xmin = 0;
2353 glyph.ymin = 0;
2354 glyph.xmax = 0;
2355 glyph.ymax = 0;
2356 glyph.simple = xmalloc (sizeof *glyph.simple);
2357 glyph.compound = NULL;
2358 memset (glyph.simple, 0, sizeof *glyph.simple);
2359 memory = xmalloc (sizeof *memory);
2360 *memory = glyph;
2361 return memory;
2362 }
2363
2364
2365 if (glyf->size < offset + SFNT_ENDOF (struct sfnt_glyph,
2366 ymax, sfnt_fword))
2367 return NULL;
2368
2369
2370 memcpy (&glyph, glyf->glyphs + offset,
2371 SFNT_ENDOF (struct sfnt_glyph,
2372 ymax, sfnt_fword));
2373
2374
2375 sfnt_swap16 (&glyph.number_of_contours);
2376 sfnt_swap16 (&glyph.xmin);
2377 sfnt_swap16 (&glyph.ymin);
2378 sfnt_swap16 (&glyph.xmax);
2379 sfnt_swap16 (&glyph.ymax);
2380
2381
2382 glyph.advance_distortion = 0;
2383 glyph.origin_distortion = 0;
2384
2385
2386
2387 if (glyph.number_of_contours >= 0)
2388 {
2389
2390
2391 glyph.compound = NULL;
2392 sfnt_read_simple_glyph (&glyph, glyf,
2393 offset + SFNT_ENDOF (struct sfnt_glyph,
2394 ymax, sfnt_fword));
2395
2396 if (glyph.simple)
2397 {
2398 memory = xmalloc (sizeof glyph);
2399 *memory = glyph;
2400
2401 return memory;
2402 }
2403 }
2404 else
2405 {
2406
2407
2408 glyph.simple = NULL;
2409 sfnt_read_compound_glyph (&glyph, glyf,
2410 offset + SFNT_ENDOF (struct sfnt_glyph,
2411 ymax, sfnt_fword));
2412
2413 if (glyph.compound)
2414 {
2415 memory = xmalloc (sizeof glyph);
2416 *memory = glyph;
2417
2418 return memory;
2419 }
2420 }
2421
2422 return NULL;
2423 }
2424
2425
2426
2427 TEST_STATIC void
2428 sfnt_free_glyph (struct sfnt_glyph *glyph)
2429 {
2430 if (!glyph)
2431 return;
2432
2433 xfree (glyph->simple);
2434 xfree (glyph->compound);
2435 xfree (glyph);
2436 }
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452 static void
2453 sfnt_transform_coordinates (struct sfnt_compound_glyph_component *component,
2454 sfnt_fixed *restrict x, sfnt_fixed *restrict y,
2455 size_t num_coordinates,
2456 sfnt_fixed x_off, sfnt_fixed y_off)
2457 {
2458 double m1, m2, m3;
2459 double m4, m5, m6;
2460 size_t i;
2461
2462 if (component->flags & 010)
2463 {
2464 for (i = 0; i < num_coordinates; ++i)
2465 {
2466 x[i] *= component->u.scale / 16384.0;
2467 y[i] *= component->u.scale / 16384.0;
2468 x[i] += x_off;
2469 y[i] += y_off;
2470 }
2471 }
2472 else if (component->flags & 0100)
2473 {
2474 for (i = 0; i < num_coordinates; ++i)
2475 {
2476 x[i] *= component->u.a.xscale / 16384.0;
2477 y[i] *= component->u.a.yscale / 16384.0;
2478 x[i] += x_off;
2479 y[i] += y_off;
2480 }
2481 }
2482 else if (component->flags & 0200)
2483 {
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500 m1 = component->u.b.xscale / 16384.0;
2501 m2 = component->u.b.scale01 / 16384.0;
2502 m3 = 0;
2503 m4 = component->u.b.scale10 / 16384.0;
2504 m5 = component->u.b.yscale / 16384.0;
2505 m6 = 0;
2506
2507 for (i = 0; i < num_coordinates; ++i)
2508 {
2509 x[i] = m1 * x[i] + m2 * y[i] + m3 * 1;
2510 y[i] = m4 * x[i] + m5 * y[i] + m6 * 1;
2511 x[i] += x_off;
2512 y[i] += y_off;
2513 }
2514 }
2515 }
2516
2517 struct sfnt_compound_glyph_context
2518 {
2519
2520
2521 sfnt_fixed *x_coordinates, *y_coordinates;
2522
2523
2524 unsigned char *flags;
2525
2526
2527 size_t num_points, points_size;
2528
2529
2530 size_t *contour_end_points;
2531
2532
2533 size_t num_end_points, end_points_size;
2534 };
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544 static int
2545 sfnt_expand_compound_glyph_context (struct sfnt_compound_glyph_context *context,
2546 size_t number_of_contours,
2547 size_t number_of_points,
2548 sfnt_fixed **x_base, sfnt_fixed **y_base,
2549 unsigned char **flags_base,
2550 size_t **contour_base)
2551 {
2552 size_t size_bytes;
2553
2554
2555 if (INT_ADD_WRAPV (number_of_contours, context->num_end_points,
2556 &context->num_end_points))
2557 return 1;
2558
2559 if (INT_ADD_WRAPV (number_of_points, context->num_points,
2560 &context->num_points))
2561 return 1;
2562
2563
2564 if (context->points_size < context->num_points)
2565 {
2566 if (INT_MULTIPLY_WRAPV (context->num_points, 2,
2567 &context->points_size))
2568 context->points_size = context->num_points;
2569
2570 if (INT_MULTIPLY_WRAPV (context->points_size,
2571 sizeof *context->x_coordinates,
2572 &size_bytes))
2573 return 1;
2574
2575 context->x_coordinates = xrealloc (context->x_coordinates,
2576 size_bytes);
2577 context->y_coordinates = xrealloc (context->y_coordinates,
2578 size_bytes);
2579 context->flags = xrealloc (context->flags,
2580 context->points_size);
2581 }
2582
2583
2584 *x_base = (context->x_coordinates
2585 + context->num_points
2586 - number_of_points);
2587 *y_base = (context->y_coordinates
2588 + context->num_points
2589 - number_of_points);
2590 *flags_base = (context->flags
2591 + context->num_points
2592 - number_of_points);
2593
2594 if (context->end_points_size < context->num_end_points)
2595 {
2596 if (INT_MULTIPLY_WRAPV (context->num_end_points, 2,
2597 &context->end_points_size))
2598 context->end_points_size = context->num_end_points;
2599
2600 if (INT_MULTIPLY_WRAPV (context->end_points_size,
2601 sizeof *context->contour_end_points,
2602 &size_bytes))
2603 return 1;
2604
2605 context->contour_end_points
2606 = xrealloc (context->contour_end_points,
2607 size_bytes);
2608 }
2609
2610
2611 *contour_base = (context->contour_end_points
2612 + context->num_end_points
2613 - number_of_contours);
2614 return 0;
2615 }
2616
2617
2618
2619
2620 static int32_t
2621 sfnt_round_fixed (int32_t number)
2622 {
2623
2624 number += (1 << 15);
2625
2626
2627 return number & ~0xffff;
2628 }
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640 static int
2641 sfnt_decompose_compound_glyph (struct sfnt_glyph *glyph,
2642 struct sfnt_compound_glyph_context *context,
2643 sfnt_get_glyph_proc get_glyph,
2644 sfnt_free_glyph_proc free_glyph,
2645 sfnt_fixed off_x, sfnt_fixed off_y,
2646 int recursion_count,
2647 void *dcontext)
2648 {
2649 struct sfnt_glyph *subglyph;
2650 int i, j, rc;
2651 bool need_free;
2652 struct sfnt_compound_glyph_component *component;
2653 sfnt_fixed x, y, xtemp, ytemp;
2654 size_t point UNINIT, point2 UNINIT, index;
2655 uint16_t last_point, number_of_contours;
2656 sfnt_fixed *x_base, *y_base;
2657 size_t *contour_base;
2658 unsigned char *flags_base;
2659 size_t base_index, contour_start;
2660 bool defer_offsets;
2661
2662
2663
2664
2665
2666
2667 base_index = context->num_points;
2668
2669
2670
2671
2672 if (recursion_count > 16)
2673 return 1;
2674
2675 for (j = 0; j < glyph->compound->num_components; ++j)
2676 {
2677
2678 component = &glyph->compound->components[j];
2679 subglyph = get_glyph (component->glyph_index,
2680 dcontext, &need_free);
2681
2682 if (!subglyph)
2683 return 1;
2684
2685
2686
2687
2688
2689 defer_offsets = false;
2690
2691
2692
2693
2694 contour_start = context->num_points;
2695
2696
2697 if (component->flags & 02)
2698 {
2699
2700
2701
2702 if (!(component->flags & 01))
2703 {
2704
2705 x = component->argument1.b * 65536;
2706 y = component->argument2.b * 65536;
2707 }
2708 else
2709 {
2710
2711 x = component->argument1.d * 65536;
2712 y = component->argument2.d * 65536;
2713 }
2714
2715
2716
2717 if (component->flags & 04000)
2718 sfnt_transform_coordinates (component, &x, &y, 1,
2719 0, 0);
2720
2721 if (component->flags & 04)
2722 {
2723 x = sfnt_round_fixed (x);
2724 y = sfnt_round_fixed (y);
2725 }
2726 }
2727 else
2728 {
2729
2730
2731
2732
2733
2734
2735
2736
2737 if (!(component->flags & 01))
2738 {
2739 point = base_index + component->argument1.a;
2740 point2 = component->argument2.a;
2741 }
2742 else
2743 {
2744 point = base_index + component->argument1.c;
2745 point2 = component->argument2.c;
2746 }
2747
2748
2749
2750
2751 if (point >= contour_start)
2752 {
2753 if (need_free)
2754 free_glyph (subglyph, dcontext);
2755
2756 return 1;
2757 }
2758
2759 if (!subglyph->compound)
2760 {
2761 if (point2 >= subglyph->simple->number_of_points)
2762 {
2763 if (need_free)
2764 free_glyph (subglyph, dcontext);
2765
2766 return 1;
2767 }
2768
2769
2770 xtemp = context->x_coordinates[point];
2771 ytemp = context->y_coordinates[point];
2772 x = (xtemp - subglyph->simple->x_coordinates[point2] * 65536);
2773 y = (ytemp - subglyph->simple->y_coordinates[point2] * 65536);
2774 }
2775 else
2776 {
2777
2778
2779
2780 x = 0;
2781 y = 0;
2782
2783
2784
2785
2786 defer_offsets = true;
2787 }
2788 }
2789
2790 if (subglyph->simple)
2791 {
2792
2793
2794 if (subglyph->number_of_contours)
2795 {
2796 index = subglyph->number_of_contours - 1;
2797 last_point
2798 = subglyph->simple->end_pts_of_contours[index];
2799 number_of_contours = subglyph->number_of_contours;
2800
2801
2802
2803 rc = sfnt_expand_compound_glyph_context (context,
2804
2805
2806
2807 number_of_contours,
2808
2809
2810
2811 last_point + 1,
2812 &x_base,
2813 &y_base,
2814 &flags_base,
2815 &contour_base);
2816 if (rc)
2817 {
2818 if (need_free)
2819 free_glyph (subglyph, dcontext);
2820
2821 return 1;
2822 }
2823
2824 for (i = 0; i <= last_point; ++i)
2825 {
2826 x_base[i] = ((subglyph->simple->x_coordinates[i] * 65536)
2827 + off_x + x);
2828 y_base[i] = ((subglyph->simple->y_coordinates[i] * 65536)
2829 + off_y + y);
2830 flags_base[i] = subglyph->simple->flags[i];
2831 }
2832
2833
2834 sfnt_transform_coordinates (component, x_base, y_base,
2835 last_point + 1, 0, 0);
2836
2837
2838 for (i = 0; i < number_of_contours; ++i)
2839 contour_base[i] = (contour_start
2840 + subglyph->simple->end_pts_of_contours[i]);
2841 }
2842 }
2843 else
2844 {
2845
2846
2847 rc = sfnt_decompose_compound_glyph (subglyph,
2848 context,
2849 get_glyph,
2850 free_glyph,
2851 off_x + x,
2852 off_y + y,
2853 recursion_count + 1,
2854 dcontext);
2855
2856 if (rc)
2857 {
2858 if (need_free)
2859 free_glyph (subglyph, dcontext);
2860
2861 return 1;
2862 }
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875 x = 0;
2876 y = 0;
2877
2878 if (defer_offsets)
2879 {
2880
2881
2882 point2 += contour_start;
2883
2884
2885
2886
2887
2888 if (point2 >= context->num_points)
2889 {
2890 if (need_free)
2891 free_glyph (subglyph, dcontext);
2892
2893 return 1;
2894 }
2895
2896
2897
2898
2899 xtemp = context->x_coordinates[point];
2900 ytemp = context->y_coordinates[point];
2901 x = (xtemp - context->x_coordinates[point2]);
2902 y = (ytemp - context->y_coordinates[point2]);
2903 }
2904
2905 sfnt_transform_coordinates (component,
2906 context->x_coordinates + contour_start,
2907 context->y_coordinates + contour_start,
2908 contour_start - context->num_points,
2909 x, y);
2910 }
2911
2912 if (need_free)
2913 free_glyph (subglyph, dcontext);
2914 }
2915
2916
2917
2918 return 0;
2919 }
2920
2921
2922
2923
2924 static void
2925 sfnt_lerp_half (struct sfnt_point *control1, struct sfnt_point *control2,
2926 struct sfnt_point *result)
2927 {
2928 result->x = control1->x + ((control2->x - control1->x) / 2);
2929 result->y = control1->y + ((control2->y - control1->y) / 2);
2930 }
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940 static int
2941 sfnt_decompose_glyph_1 (size_t here, size_t last,
2942 sfnt_move_to_proc move_to,
2943 sfnt_line_to_proc line_to,
2944 sfnt_curve_to_proc curve_to,
2945 void *dcontext,
2946 sfnt_fword *x,
2947 sfnt_fword *y, unsigned char *flags,
2948 int scale)
2949 {
2950 struct sfnt_point control1, control2, start, mid;
2951 size_t i;
2952
2953
2954
2955 if (here == last)
2956 return 1;
2957
2958
2959
2960
2961
2962 if (flags[here] & 01)
2963 {
2964 control1.x = x[here] * scale;
2965 control1.y = y[here] * scale;
2966 start = control1;
2967 }
2968 else if (flags[last] & 01)
2969 {
2970
2971
2972 control1.x = x[last] * scale;
2973 control1.y = y[last] * scale;
2974 start = control1;
2975
2976
2977 last -= 1;
2978 here -= 1;
2979 }
2980 else
2981 {
2982
2983 control1.x = x[here] * scale;
2984 control1.y = y[here] * scale;
2985 control2.x = x[last] * scale;
2986 control2.y = y[last] * scale;
2987 sfnt_lerp_half (&control1, &control2, &start);
2988
2989
2990
2991
2992 here -= 1;
2993 }
2994
2995
2996 move_to (start, dcontext);
2997
2998
2999
3000 i = here;
3001 while (++i <= last)
3002 {
3003
3004
3005
3006 if (flags[i] & 01)
3007 {
3008 control1.x = x[i] * scale;
3009 control1.y = y[i] * scale;
3010
3011 line_to (control1, dcontext);
3012
3013
3014 continue;
3015 }
3016
3017
3018
3019
3020
3021
3022 control1.x = x[i] * scale;
3023 control1.y = y[i] * scale;
3024
3025 while (++i <= last)
3026 {
3027
3028 control2.x = x[i] * scale;
3029 control2.y = y[i] * scale;
3030
3031
3032
3033
3034 if (flags[i] & 01)
3035 {
3036 curve_to (control1, control2, dcontext);
3037 goto continue_loop;
3038 }
3039
3040
3041
3042 sfnt_lerp_half (&control1, &control2, &mid);
3043
3044
3045 curve_to (control1, mid, dcontext);
3046
3047
3048 control1 = control2;
3049 }
3050
3051
3052 curve_to (control1, start, dcontext);
3053
3054
3055 goto exit;
3056
3057 continue_loop:
3058 continue;
3059 }
3060
3061
3062 line_to (start, dcontext);
3063
3064 exit:
3065 return 0;
3066 }
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079 static int
3080 sfnt_decompose_glyph_2 (size_t here, size_t last,
3081 sfnt_move_to_proc move_to,
3082 sfnt_line_to_proc line_to,
3083 sfnt_curve_to_proc curve_to,
3084 void *dcontext,
3085 sfnt_fixed *x,
3086 sfnt_fixed *y, unsigned char *flags,
3087 int scale)
3088 {
3089 struct sfnt_point control1, control2, start, mid;
3090 size_t i;
3091
3092
3093
3094 if (here == last)
3095 return 1;
3096
3097
3098
3099
3100
3101 if (flags[here] & 01)
3102 {
3103 control1.x = x[here] * scale;
3104 control1.y = y[here] * scale;
3105 start = control1;
3106 }
3107 else if (flags[last] & 01)
3108 {
3109
3110
3111 control1.x = x[last] * scale;
3112 control1.y = y[last] * scale;
3113 start = control1;
3114
3115
3116 last -= 1;
3117 here -= 1;
3118 }
3119 else
3120 {
3121
3122 control1.x = x[here] * scale;
3123 control1.y = y[here] * scale;
3124 control2.x = x[last] * scale;
3125 control2.y = y[last] * scale;
3126 sfnt_lerp_half (&control1, &control2, &start);
3127
3128
3129
3130
3131 here -= 1;
3132 }
3133
3134
3135 move_to (start, dcontext);
3136
3137
3138
3139 i = here;
3140 while (++i <= last)
3141 {
3142
3143
3144
3145 if (flags[i] & 01)
3146 {
3147 control1.x = x[i] * scale;
3148 control1.y = y[i] * scale;
3149
3150 line_to (control1, dcontext);
3151
3152
3153 continue;
3154 }
3155
3156
3157
3158
3159
3160
3161 control1.x = x[i] * scale;
3162 control1.y = y[i] * scale;
3163
3164 while (++i <= last)
3165 {
3166
3167 control2.x = x[i] * scale;
3168 control2.y = y[i] * scale;
3169
3170
3171
3172
3173 if (flags[i] & 01)
3174 {
3175 curve_to (control1, control2, dcontext);
3176 goto continue_loop;
3177 }
3178
3179
3180
3181 sfnt_lerp_half (&control1, &control2, &mid);
3182
3183
3184 curve_to (control1, mid, dcontext);
3185
3186
3187 control1 = control2;
3188 }
3189
3190
3191 curve_to (control1, start, dcontext);
3192
3193
3194 goto exit;
3195
3196 continue_loop:
3197 continue;
3198 }
3199
3200
3201 line_to (start, dcontext);
3202
3203 exit:
3204 return 0;
3205 }
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226 static int
3227 sfnt_decompose_glyph (struct sfnt_glyph *glyph,
3228 sfnt_move_to_proc move_to,
3229 sfnt_line_to_proc line_to,
3230 sfnt_curve_to_proc curve_to,
3231 sfnt_get_glyph_proc get_glyph,
3232 sfnt_free_glyph_proc free_glyph,
3233 void *dcontext)
3234 {
3235 size_t here, last, n;
3236 struct sfnt_compound_glyph_context context;
3237
3238 if (glyph->simple)
3239 {
3240 if (!glyph->number_of_contours)
3241
3242 return 0;
3243
3244 here = 0;
3245
3246 for (n = 0; n < glyph->number_of_contours; ++n)
3247 {
3248
3249
3250
3251 last = glyph->simple->end_pts_of_contours[n];
3252
3253
3254
3255 if (here > last || last >= glyph->simple->number_of_points)
3256 return 1;
3257
3258
3259 if (sfnt_decompose_glyph_1 (here, last, move_to,
3260 line_to, curve_to,
3261 dcontext,
3262 glyph->simple->x_coordinates,
3263 glyph->simple->y_coordinates,
3264 glyph->simple->flags,
3265 65536))
3266 return 1;
3267
3268
3269 here = last + 1;
3270 }
3271
3272 return 0;
3273 }
3274
3275
3276 memset (&context, 0, sizeof context);
3277
3278 if (sfnt_decompose_compound_glyph (glyph, &context,
3279 get_glyph, free_glyph,
3280 0, 0, 0, dcontext))
3281 {
3282 xfree (context.x_coordinates);
3283 xfree (context.y_coordinates);
3284 xfree (context.flags);
3285 xfree (context.contour_end_points);
3286
3287 return 1;
3288 }
3289
3290
3291
3292 if (!context.num_end_points)
3293
3294 goto early;
3295
3296 here = 0;
3297
3298 for (n = 0; n < context.num_end_points; ++n)
3299 {
3300
3301
3302
3303 last = context.contour_end_points[n];
3304
3305
3306
3307 if (here > last || last >= context.num_points)
3308 goto fail;
3309
3310
3311 if (sfnt_decompose_glyph_2 (here, last, move_to,
3312 line_to, curve_to,
3313 dcontext,
3314 context.x_coordinates,
3315 context.y_coordinates,
3316 context.flags, 1))
3317 goto fail;
3318
3319
3320 here = last + 1;
3321 }
3322
3323 early:
3324 xfree (context.x_coordinates);
3325 xfree (context.y_coordinates);
3326 xfree (context.flags);
3327 xfree (context.contour_end_points);
3328 return 0;
3329
3330 fail:
3331 xfree (context.x_coordinates);
3332 xfree (context.y_coordinates);
3333 xfree (context.flags);
3334 xfree (context.contour_end_points);
3335 return 1;
3336 }
3337
3338 struct sfnt_build_glyph_outline_context
3339 {
3340
3341 struct sfnt_glyph_outline *outline;
3342
3343
3344 sfnt_fixed factor;
3345
3346
3347 sfnt_fixed x, y;
3348 };
3349
3350
3351
3352 static struct sfnt_build_glyph_outline_context build_outline_context;
3353
3354
3355
3356
3357
3358 static struct sfnt_glyph_outline *
3359 sfnt_build_append (int flags, sfnt_fixed x, sfnt_fixed y)
3360 {
3361 struct sfnt_glyph_outline *outline;
3362
3363 if (x == build_outline_context.x
3364 && y == build_outline_context.y)
3365
3366 return build_outline_context.outline;
3367
3368 outline = build_outline_context.outline;
3369 outline->outline_used++;
3370
3371
3372
3373
3374 if (outline->outline_used > outline->outline_size)
3375 {
3376 outline->outline_size = outline->outline_used * 2;
3377
3378
3379 outline = xrealloc (outline, (sizeof *outline
3380 + (outline->outline_size
3381 * sizeof *outline->outline)));
3382 outline->outline
3383 = (struct sfnt_glyph_outline_command *) (outline + 1);
3384 }
3385
3386
3387 outline->outline[outline->outline_used - 1].flags = flags;
3388 outline->outline[outline->outline_used - 1].x = x;
3389 outline->outline[outline->outline_used - 1].y = y;
3390
3391
3392
3393 if (outline->outline_used == 1)
3394 {
3395
3396 outline->xmin = outline->xmax = x;
3397 outline->ymin = outline->ymax = y;
3398 }
3399 else
3400 {
3401 outline->xmin = MIN ((sfnt_fixed) x, outline->xmin);
3402 outline->ymin = MIN ((sfnt_fixed) y, outline->ymin);
3403 outline->xmax = MAX ((sfnt_fixed) x, outline->xmax);
3404 outline->ymax = MAX ((sfnt_fixed) y, outline->ymax);
3405 }
3406
3407 return outline;
3408 }
3409
3410 #ifndef INT64_MAX
3411
3412
3413
3414 struct sfnt_large_integer
3415 {
3416 unsigned int high, low;
3417 };
3418
3419
3420
3421 static void
3422 sfnt_multiply_divide_1 (unsigned int a, unsigned int b,
3423 struct sfnt_large_integer *value)
3424 {
3425 unsigned int lo1, hi1, lo2, hi2, lo, hi, i1, i2;
3426
3427 lo1 = a & 0x0000ffffu;
3428 hi1 = a >> 16;
3429 lo2 = b & 0x0000ffffu;
3430 hi2 = b >> 16;
3431
3432 lo = lo1 * lo2;
3433 i1 = lo1 * hi2;
3434 i2 = lo2 * hi1;
3435 hi = hi1 * hi2;
3436
3437
3438 i1 += i2;
3439 hi += (unsigned int) (i1 < i2) << 16;
3440
3441 hi += i1 >> 16;
3442 i1 = i1 << 16;
3443
3444
3445 lo += i1;
3446 hi += (lo < i1);
3447
3448 value->low = lo;
3449 value->high = hi;
3450 }
3451
3452
3453
3454 static unsigned int
3455 sfnt_count_leading_zero_bits (unsigned int n)
3456 {
3457 int shift;
3458
3459 shift = 0;
3460
3461 if (n & 0xffff0000ul)
3462 {
3463 n >>= 16;
3464 shift += 16;
3465 }
3466
3467 if (n & 0x0000ff00ul)
3468 {
3469 n >>= 8;
3470 shift += 8;
3471 }
3472
3473 if (n & 0x000000f0ul)
3474 {
3475 n >>= 4;
3476 shift += 4;
3477 }
3478
3479 if (n & 0x0000000cul)
3480 {
3481 n >>= 2;
3482 shift += 2;
3483 }
3484
3485 if (n & 0x00000002ul)
3486 shift += 1;
3487
3488 return shift;
3489 }
3490
3491
3492
3493 static unsigned int
3494 sfnt_multiply_divide_2 (struct sfnt_large_integer *ab,
3495 unsigned int c)
3496 {
3497 unsigned int hi, lo;
3498 int i;
3499 unsigned int r, q;
3500
3501 hi = ab->high;
3502 lo = ab->low;
3503
3504 i = 31 - sfnt_count_leading_zero_bits (hi);
3505 r = (hi << i) | (lo >> (32 - i));
3506 lo <<= i;
3507 q = r / c;
3508 r -= q * c;
3509 i = 32 - i;
3510
3511 do
3512 {
3513 q <<= 1;
3514 r = (r << 1) | (lo >> 31);
3515 lo <<= 1;
3516
3517 if (r >= c)
3518 {
3519 r -= c;
3520 q |= 1;
3521 }
3522 }
3523 while (--i);
3524
3525 return q;
3526 }
3527
3528 #endif
3529
3530
3531
3532
3533 static unsigned int
3534 sfnt_multiply_divide (unsigned int a, unsigned int b, unsigned int c)
3535 {
3536 #ifndef INT64_MAX
3537 struct sfnt_large_integer temp;
3538
3539 sfnt_multiply_divide_1 (a, b, &temp);
3540 return sfnt_multiply_divide_2 (&temp, c);
3541 #else
3542 uint64_t temp;
3543
3544 temp = (uint64_t) a * (uint64_t) b;
3545 return temp / c;
3546 #endif
3547 }
3548
3549 #ifndef INT64_MAX
3550
3551
3552
3553
3554 static void
3555 sfnt_large_integer_add (struct sfnt_large_integer *integer,
3556 uint32_t n)
3557 {
3558 struct sfnt_large_integer number;
3559
3560 number.low = integer->low + n;
3561 number.high = integer->high + (number.low
3562 < integer->low);
3563
3564 *integer = number;
3565 }
3566
3567
3568
3569
3570 static unsigned int
3571 sfnt_multiply_divide_round (unsigned int a, unsigned int b,
3572 unsigned int n, unsigned int c)
3573 {
3574 struct sfnt_large_integer temp;
3575
3576 sfnt_multiply_divide_1 (a, b, &temp);
3577 sfnt_large_integer_add (&temp, n);
3578 return sfnt_multiply_divide_2 (&temp, c);
3579 }
3580
3581 #endif
3582
3583
3584
3585
3586 MAYBE_UNUSED static int
3587 sfnt_multiply_divide_signed (int a, int b, int c)
3588 {
3589 int sign;
3590
3591 sign = 1;
3592
3593 if (a < 0)
3594 sign = -sign;
3595
3596 if (b < 0)
3597 sign = -sign;
3598
3599 if (c < 0)
3600 sign = -sign;
3601
3602 return (sfnt_multiply_divide (abs (a), abs (b), abs (c))
3603 * sign);
3604 }
3605
3606
3607
3608
3609 static sfnt_fixed
3610 sfnt_mul_fixed (sfnt_fixed x, sfnt_fixed y)
3611 {
3612 #ifdef INT64_MAX
3613 int64_t product;
3614
3615 product = (int64_t) x * (int64_t) y;
3616
3617
3618 return product / (int64_t) 65536;
3619 #else
3620 int sign;
3621
3622 sign = 1;
3623
3624 if (x < 0)
3625 sign = -sign;
3626
3627 if (y < 0)
3628 sign = -sign;
3629
3630 return sfnt_multiply_divide (abs (x), abs (y),
3631 65536) * sign;
3632 #endif
3633 }
3634
3635
3636
3637
3638 static sfnt_fixed
3639 sfnt_mul_fixed_round (sfnt_fixed x, sfnt_fixed y)
3640 {
3641 #ifdef INT64_MAX
3642 int64_t product, round;
3643
3644 product = (int64_t) x * (int64_t) y;
3645 round = product < 0 ? -32768 : 32768;
3646
3647
3648 return (product + round) / (int64_t) 65536;
3649 #else
3650 int sign;
3651
3652 sign = 1;
3653
3654 if (x < 0)
3655 sign = -sign;
3656
3657 if (y < 0)
3658 sign = -sign;
3659
3660 return sfnt_multiply_divide_round (abs (x), abs (y),
3661 32768, 65536) * sign;
3662 #endif
3663 }
3664
3665
3666
3667
3668 static void
3669 sfnt_move_to_and_build (struct sfnt_point point, void *dcontext)
3670 {
3671 sfnt_fixed x, y;
3672
3673 x = sfnt_mul_fixed (build_outline_context.factor, point.x);
3674 y = sfnt_mul_fixed (build_outline_context.factor, point.y);
3675
3676 build_outline_context.outline = sfnt_build_append (0, x, y);
3677 build_outline_context.x = x;
3678 build_outline_context.y = y;
3679 }
3680
3681
3682
3683
3684 static void
3685 sfnt_line_to_and_build (struct sfnt_point point, void *dcontext)
3686 {
3687 sfnt_fixed x, y;
3688
3689 x = sfnt_mul_fixed (build_outline_context.factor, point.x);
3690 y = sfnt_mul_fixed (build_outline_context.factor, point.y);
3691
3692 build_outline_context.outline
3693 = sfnt_build_append (SFNT_GLYPH_OUTLINE_LINETO,
3694 x, y);
3695 build_outline_context.x = x;
3696 build_outline_context.y = y;
3697 }
3698
3699
3700
3701
3702 static sfnt_fixed
3703 sfnt_div_fixed (sfnt_fixed x, sfnt_fixed y)
3704 {
3705 #ifdef INT64_MAX
3706 int64_t result;
3707
3708 result = ((int64_t) x * 65536) / y;
3709
3710 return result;
3711 #else
3712 int sign;
3713 unsigned int a, b;
3714
3715 sign = 1;
3716
3717 if (x < 0)
3718 sign = -sign;
3719
3720 if (y < 0)
3721 sign = -sign;
3722
3723 a = abs (x);
3724 b = abs (y);
3725
3726 return sfnt_multiply_divide (a, 65536, b) * sign;
3727 #endif
3728 }
3729
3730
3731
3732 static sfnt_fixed
3733 sfnt_ceil_fixed (sfnt_fixed x)
3734 {
3735 return (x + 0177777) & 037777600000;
3736 }
3737
3738
3739
3740 static sfnt_fixed
3741 sfnt_floor_fixed (sfnt_fixed x)
3742 {
3743 return x & 037777600000;
3744 }
3745
3746
3747
3748
3749
3750 static bool
3751 sfnt_curve_is_flat (struct sfnt_point control0,
3752 struct sfnt_point control1,
3753 struct sfnt_point endpoint)
3754 {
3755 struct sfnt_point g, h;
3756
3757 g.x = control1.x - control0.x;
3758 g.y = control1.y - control0.y;
3759 h.x = endpoint.x - control0.x;
3760 h.y = endpoint.y - control0.y;
3761
3762
3763
3764 return (abs (sfnt_mul_fixed (g.x, h.y)
3765 - sfnt_mul_fixed (g.y, h.x))
3766 <= 0400000);
3767 }
3768
3769
3770
3771
3772
3773
3774 static void
3775 sfnt_curve_to_and_build_1 (struct sfnt_point control0,
3776 struct sfnt_point control1,
3777 struct sfnt_point endpoint)
3778 {
3779 struct sfnt_point ab, bc, abbc;
3780
3781
3782
3783 if (sfnt_curve_is_flat (control0, control1, endpoint))
3784 {
3785
3786 build_outline_context.outline
3787 = sfnt_build_append (SFNT_GLYPH_OUTLINE_LINETO,
3788 endpoint.x, endpoint.y);
3789 build_outline_context.x = endpoint.x;
3790 build_outline_context.y = endpoint.y;
3791 }
3792 else
3793 {
3794
3795
3796 sfnt_lerp_half (&control0, &control1, &ab);
3797 sfnt_lerp_half (&control1, &endpoint, &bc);
3798 sfnt_lerp_half (&ab, &bc, &abbc);
3799
3800
3801 sfnt_curve_to_and_build_1 (control0, ab, abbc);
3802
3803
3804 sfnt_curve_to_and_build_1 (abbc, bc, endpoint);
3805 }
3806 }
3807
3808
3809
3810
3811
3812 static void
3813 sfnt_curve_to_and_build (struct sfnt_point control,
3814 struct sfnt_point endpoint,
3815 void *dcontext)
3816 {
3817 struct sfnt_point control0;
3818
3819 control0.x = build_outline_context.x;
3820 control0.y = build_outline_context.y;
3821 control.x = sfnt_mul_fixed (control.x,
3822 build_outline_context.factor);
3823 control.y = sfnt_mul_fixed (control.y,
3824 build_outline_context.factor);
3825 endpoint.x = sfnt_mul_fixed (endpoint.x,
3826 build_outline_context.factor);
3827 endpoint.y = sfnt_mul_fixed (endpoint.y,
3828 build_outline_context.factor);
3829
3830 sfnt_curve_to_and_build_1 (control0, control, endpoint);
3831 }
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846 TEST_STATIC struct sfnt_glyph_outline *
3847 sfnt_build_glyph_outline (struct sfnt_glyph *glyph,
3848 sfnt_fixed scale,
3849 struct sfnt_glyph_metrics *metrics,
3850 sfnt_get_glyph_proc get_glyph,
3851 sfnt_free_glyph_proc free_glyph,
3852 void *dcontext)
3853 {
3854 struct sfnt_glyph_outline *outline;
3855 int rc;
3856 sfnt_fword origin;
3857
3858 memset (&build_outline_context, 0, sizeof build_outline_context);
3859
3860
3861 outline = xmalloc (sizeof *outline + 40 * sizeof (*outline->outline));
3862 outline->outline_size = 40;
3863 outline->outline_used = 0;
3864 outline->refcount = 0;
3865 outline->outline
3866 = (struct sfnt_glyph_outline_command *) (outline + 1);
3867
3868
3869
3870
3871 build_outline_context.outline = outline;
3872
3873
3874 outline->xmin = 0;
3875 outline->ymin = 0;
3876 outline->xmax = 0;
3877 outline->ymax = 0;
3878
3879
3880 build_outline_context.factor = scale;
3881
3882
3883 rc = sfnt_decompose_glyph (glyph, sfnt_move_to_and_build,
3884 sfnt_line_to_and_build,
3885 sfnt_curve_to_and_build,
3886 get_glyph, free_glyph, dcontext);
3887
3888
3889
3890 outline = build_outline_context.outline;
3891
3892 if (rc)
3893 {
3894 xfree (outline);
3895 return NULL;
3896 }
3897
3898
3899
3900
3901
3902 origin = glyph->xmin - metrics->lbearing + glyph->origin_distortion;
3903 outline->origin = sfnt_mul_fixed (origin, scale);
3904
3905 return outline;
3906 }
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918 static const unsigned char sfnt_poly_coverage[8][9] =
3919 {
3920 { 0, 4, 8, 12, 16, 20, 24, 28, 32, },
3921 { 0, 4, 8, 12, 16, 20, 24, 28, 32, },
3922 { 0, 4, 8, 12, 16, 20, 24, 28, 32, },
3923 { 0, 3, 7, 11, 15, 19, 23, 27, 31, },
3924 { 0, 4, 8, 12, 16, 20, 24, 28, 32, },
3925 { 0, 4, 8, 12, 16, 20, 24, 28, 32, },
3926 { 0, 4, 8, 12, 16, 20, 24, 28, 32, },
3927 { 0, 4, 8, 12, 16, 20, 24, 28, 32, },
3928 };
3929
3930
3931
3932
3933 static sfnt_fixed
3934 sfnt_poly_grid_ceil (sfnt_fixed f)
3935 {
3936 return (((f + (SFNT_POLY_START - 1))
3937 & ~(SFNT_POLY_STEP - 1)) + SFNT_POLY_START);
3938 }
3939
3940 enum
3941 {
3942 SFNT_POLY_ALIGNMENT = 4,
3943 };
3944
3945
3946
3947
3948
3949
3950 TEST_STATIC void
3951 sfnt_prepare_raster (struct sfnt_raster *raster,
3952 struct sfnt_glyph_outline *outline)
3953 {
3954 raster->width
3955 = (sfnt_ceil_fixed (outline->xmax)
3956 - sfnt_floor_fixed (outline->xmin)) / 65536;
3957 raster->height
3958 = (sfnt_ceil_fixed (outline->ymax)
3959 - sfnt_floor_fixed (outline->ymin)) / 65536;
3960 raster->refcount = 0;
3961
3962
3963 raster->stride = ((raster->width
3964 + (SFNT_POLY_ALIGNMENT - 1))
3965 & ~(SFNT_POLY_ALIGNMENT - 1));
3966
3967
3968
3969
3970 raster->offx = sfnt_floor_fixed (outline->xmin
3971 - outline->origin) / 65536;
3972 raster->offy = sfnt_floor_fixed (outline->ymin) / 65536;
3973 }
3974
3975 typedef void (*sfnt_edge_proc) (struct sfnt_edge *, size_t,
3976 void *);
3977 typedef void (*sfnt_span_proc) (struct sfnt_edge *, sfnt_fixed, void *);
3978
3979
3980
3981
3982 static void
3983 sfnt_step_edge (struct sfnt_edge *edge)
3984 {
3985
3986 edge->x += edge->step_x;
3987 }
3988
3989
3990
3991
3992
3993
3994 static void
3995 sfnt_build_outline_edges (struct sfnt_glyph_outline *outline,
3996 sfnt_edge_proc edge_proc, void *dcontext)
3997 {
3998 struct sfnt_edge *edges;
3999 size_t i, edge, next_vertex;
4000 sfnt_fixed dx, dy, bot, step_x, ymin, xmin;
4001 size_t top, bottom, y;
4002
4003 edges = alloca (outline->outline_used * sizeof *edges);
4004 edge = 0;
4005
4006
4007
4008 ymin = sfnt_floor_fixed (outline->ymin);
4009 xmin = sfnt_floor_fixed (outline->xmin);
4010
4011 for (i = 0; i < outline->outline_used; ++i)
4012 {
4013
4014
4015
4016
4017 next_vertex = i + 1;
4018
4019 if (next_vertex == outline->outline_used
4020 || !(outline->outline[next_vertex].flags
4021 & SFNT_GLYPH_OUTLINE_LINETO))
4022 continue;
4023
4024
4025 if (outline->outline[next_vertex].y == outline->outline[i].y)
4026 continue;
4027
4028
4029 if (outline->outline[next_vertex].y < outline->outline[i].y)
4030
4031
4032 edges[edge].winding = 1;
4033 else
4034
4035 edges[edge].winding = -1;
4036
4037
4038
4039
4040
4041
4042 if (outline->outline[next_vertex].y < outline->outline[i].y)
4043 {
4044
4045
4046
4047 top = i;
4048 bottom = next_vertex;
4049 }
4050 else
4051 {
4052
4053 bottom = i;
4054 top = next_vertex;
4055 }
4056
4057 bot = (outline->outline[bottom].y - ymin);
4058 edges[edge].top = (outline->outline[top].y - ymin);
4059
4060
4061
4062 edges[edge].x = (outline->outline[bottom].x - xmin);
4063 dx = (outline->outline[top].x - outline->outline[bottom].x);
4064 dy = abs (outline->outline[top].y
4065 - outline->outline[bottom].y);
4066
4067
4068 y = sfnt_poly_grid_ceil (bot);
4069
4070
4071
4072
4073 if (y >= edges[edge].top)
4074 continue;
4075
4076
4077
4078
4079 step_x = sfnt_div_fixed (dx, dy);
4080 edges[edge].next = NULL;
4081
4082
4083 edges[edge].step_x
4084 = sfnt_mul_fixed (step_x, SFNT_POLY_STEP);
4085
4086
4087 edges[edge].x += sfnt_mul_fixed (step_x, bot - y);
4088
4089
4090 edges[edge].bottom = y;
4091
4092 edge++;
4093 }
4094
4095 if (edge)
4096 edge_proc (edges, edge, dcontext);
4097 }
4098
4099
4100
4101
4102
4103
4104
4105 static void
4106 sfnt_edge_sort (struct sfnt_edge *edges, size_t size)
4107 {
4108 ssize_t i, j;
4109 struct sfnt_edge edge;
4110
4111 for (i = 1; i < size; ++i)
4112 {
4113 edge = edges[i];
4114 j = i - 1;
4115
4116 while (j >= 0 && (edges[j].bottom > edge.bottom))
4117 {
4118 edges[j + 1] = edges[j];
4119 j--;
4120 }
4121
4122 edges[j + 1] = edge;
4123 }
4124 }
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150 static void
4151 sfnt_poly_edges (struct sfnt_edge *edges, size_t size,
4152 sfnt_span_proc span_func, void *dcontext)
4153 {
4154 sfnt_fixed y;
4155 size_t e;
4156 struct sfnt_edge *active, **prev, *a, *n;
4157
4158 if (!size)
4159 return;
4160
4161
4162
4163 sfnt_edge_sort (edges, size);
4164
4165
4166
4167 y = edges[0].bottom;
4168 active = 0;
4169 active = NULL;
4170 e = 0;
4171
4172 for (;;)
4173 {
4174
4175 for (; e < size && edges[e].bottom <= y; ++e)
4176 {
4177
4178 for (prev = &active; (a = *prev); prev = &(a->next))
4179 {
4180 if (a->x > edges[e].x)
4181 break;
4182 }
4183
4184 edges[e].next = *prev;
4185 *prev = &edges[e];
4186 }
4187
4188
4189
4190 span_func (active, y, dcontext);
4191
4192
4193 y += SFNT_POLY_STEP;
4194
4195
4196
4197 for (prev = &active; (a = *prev);)
4198 {
4199 if (a->top <= y)
4200 *prev = a->next;
4201 else
4202 prev = &a->next;
4203 }
4204
4205
4206 if (!active && e == size)
4207 break;
4208
4209
4210 for (a = active; a; a = a->next)
4211 sfnt_step_edge (a);
4212
4213
4214 for (prev = &active; (a = *prev) && (n = a->next);)
4215 {
4216 if (a->x > n->x)
4217 {
4218 a->next = n->next;
4219 n->next = a;
4220 *prev = n;
4221 prev = &active;
4222 }
4223 else
4224 prev = &a->next;
4225 }
4226 }
4227 }
4228
4229
4230
4231
4232 static unsigned char
4233 sfnt_saturate_short (unsigned short x)
4234 {
4235 if (x > 255)
4236 return 255;
4237
4238 return x;
4239 }
4240
4241
4242
4243
4244 static void
4245 sfnt_fill_span (struct sfnt_raster *raster, sfnt_fixed y,
4246 sfnt_fixed x0, sfnt_fixed x1)
4247 {
4248 unsigned char *start;
4249 const unsigned char *coverage;
4250 sfnt_fixed left, right, end;
4251 unsigned short w, a;
4252 int row;
4253 #ifndef NDEBUG
4254 unsigned char *row_end;
4255 #endif
4256
4257
4258
4259 if (x0 < 0)
4260 x0 = 0;
4261
4262
4263
4264
4265 if (x1 > raster->width * 65536)
4266 x1 = raster->width * 65536;
4267
4268
4269 if (x1 <= x0)
4270 return;
4271
4272
4273 coverage = sfnt_poly_coverage[(y >> (16 - SFNT_POLY_SHIFT))
4274 & SFNT_POLY_MASK];
4275 row = y >> 16;
4276
4277
4278 if (row < 0 || row >= raster->height)
4279 return;
4280
4281
4282
4283 left = x0 >> (16 - SFNT_POLY_SHIFT);
4284 right = x1 >> (16 - SFNT_POLY_SHIFT);
4285 start = raster->cells + row * raster->stride;
4286 #ifndef NDEBUG
4287 row_end = start + raster->width;
4288 #endif
4289 start += left >> SFNT_POLY_SHIFT;
4290
4291
4292
4293
4294 if ((left & ~SFNT_POLY_MASK) == (right & ~SFNT_POLY_MASK))
4295 {
4296
4297 assert (start <= row_end);
4298
4299 w = coverage[right - left];
4300 a = *start + w;
4301
4302 *start = sfnt_saturate_short (a);
4303 return;
4304 }
4305
4306
4307
4308
4309
4310 if (left & SFNT_POLY_MASK)
4311 {
4312
4313 assert (start <= row_end);
4314
4315
4316
4317
4318
4319 end = (left + SFNT_POLY_SAMPLE - 1) & ~SFNT_POLY_MASK;
4320 end = MIN (right, end);
4321
4322 w = coverage[end - left];
4323 a = *start + w;
4324
4325
4326 left = end;
4327 *start++ = sfnt_saturate_short (a);
4328 }
4329
4330
4331
4332
4333
4334 w = coverage[SFNT_POLY_SAMPLE];
4335
4336
4337 while (left + SFNT_POLY_MASK < right)
4338 {
4339
4340 assert (start <= row_end);
4341
4342 a = *start + w;
4343 *start++ = sfnt_saturate_short (a);
4344 left += SFNT_POLY_SAMPLE;
4345 }
4346
4347
4348
4349 if (right & SFNT_POLY_MASK)
4350 {
4351
4352 assert (start <= row_end);
4353
4354 w = coverage[right - left];
4355 a = *start + w;
4356 *start = sfnt_saturate_short (a);
4357 }
4358 }
4359
4360
4361
4362
4363
4364
4365 static void
4366 sfnt_poly_span (struct sfnt_edge *start, sfnt_fixed y,
4367 struct sfnt_raster *raster)
4368 {
4369 struct sfnt_edge *edge;
4370 int winding;
4371 sfnt_fixed x0, x1;
4372
4373
4374
4375 x0 = x1 = 0;
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388 winding = 0;
4389
4390 for (edge = start; edge; edge = edge->next)
4391 {
4392 if (!winding)
4393 {
4394 if (edge != start && x0 != x1)
4395
4396 sfnt_fill_span (raster, (raster->height << 16) - y,
4397 x0, x1);
4398
4399 x0 = x1 = edge->x;
4400 }
4401 else
4402 x1 = edge->x;
4403
4404 winding += edge->winding;
4405 }
4406
4407
4408
4409 if (!winding && edge != start && x0 != x1)
4410 sfnt_fill_span (raster, (raster->height << 16) - y,
4411 x0, x1);
4412 }
4413
4414
4415
4416
4417
4418
4419
4420
4421 static void
4422 sfnt_raster_span (struct sfnt_edge *start, sfnt_fixed y,
4423 void *dcontext)
4424 {
4425 sfnt_poly_span (start, y, dcontext);
4426 }
4427
4428
4429
4430
4431 static void
4432 sfnt_raster_edge (struct sfnt_edge *edges, size_t num_edges,
4433 void *dcontext)
4434 {
4435 sfnt_poly_edges (edges, num_edges, sfnt_raster_span,
4436 dcontext);
4437 }
4438
4439
4440
4441
4442 TEST_STATIC struct sfnt_raster *
4443 sfnt_raster_glyph_outline (struct sfnt_glyph_outline *outline)
4444 {
4445 struct sfnt_raster raster, *data;
4446
4447
4448 sfnt_prepare_raster (&raster, outline);
4449
4450
4451 data = xmalloc (sizeof *data + raster.stride * raster.height);
4452 *data = raster;
4453 data->cells = (unsigned char *) (data + 1);
4454 memset (data->cells, 0, raster.stride * raster.height);
4455
4456
4457
4458 sfnt_build_outline_edges (outline, sfnt_raster_edge, data);
4459
4460
4461 return data;
4462 }
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478 TEST_STATIC struct sfnt_hmtx_table *
4479 sfnt_read_hmtx_table (int fd, struct sfnt_offset_subtable *subtable,
4480 struct sfnt_hhea_table *hhea,
4481 struct sfnt_maxp_table *maxp)
4482 {
4483 struct sfnt_table_directory *directory;
4484 struct sfnt_hmtx_table *hmtx;
4485 size_t size;
4486 ssize_t rc;
4487 int i;
4488
4489
4490
4491 directory = sfnt_find_table (subtable, SFNT_TABLE_HMTX);
4492
4493 if (!directory)
4494 return NULL;
4495
4496
4497 size = ((hhea->num_of_long_hor_metrics
4498 * sizeof (struct sfnt_long_hor_metric))
4499 + (MAX (0, ((int) maxp->num_glyphs
4500 - hhea->num_of_long_hor_metrics))
4501 * sizeof (int16_t)));
4502
4503
4504 if (directory->length != size)
4505 return NULL;
4506
4507
4508 if (lseek (fd, directory->offset, SEEK_SET) == (off_t) -1)
4509 return NULL;
4510
4511
4512
4513
4514 hmtx = xmalloc (sizeof *hmtx + size);
4515
4516
4517 rc = read (fd, hmtx + 1, size);
4518 if (rc < size)
4519 {
4520 xfree (hmtx);
4521 return NULL;
4522 }
4523
4524
4525 hmtx->h_metrics = (struct sfnt_long_hor_metric *) (hmtx + 1);
4526 hmtx->left_side_bearing
4527 = (int16_t *) (hmtx->h_metrics
4528 + hhea->num_of_long_hor_metrics);
4529
4530
4531
4532 for (i = 0; i < hhea->num_of_long_hor_metrics; ++i)
4533 {
4534 sfnt_swap16 (&hmtx->h_metrics[i].advance_width);
4535 sfnt_swap16 (&hmtx->h_metrics[i].left_side_bearing);
4536 }
4537
4538 for (; i < maxp->num_glyphs; ++i)
4539 sfnt_swap16 (&hmtx->left_side_bearing[i - hhea->num_of_long_hor_metrics]);
4540
4541
4542 return hmtx;
4543 }
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555 TEST_STATIC int
4556 sfnt_lookup_glyph_metrics (sfnt_glyph glyph, int pixel_size,
4557 struct sfnt_glyph_metrics *metrics,
4558 struct sfnt_hmtx_table *hmtx,
4559 struct sfnt_hhea_table *hhea,
4560 struct sfnt_head_table *head,
4561 struct sfnt_maxp_table *maxp)
4562 {
4563 short lbearing;
4564 unsigned short advance;
4565 sfnt_fixed factor;
4566
4567 if (glyph < hhea->num_of_long_hor_metrics)
4568 {
4569
4570 lbearing = hmtx->h_metrics[glyph].left_side_bearing;
4571 advance = hmtx->h_metrics[glyph].advance_width;
4572 }
4573 else if (hhea->num_of_long_hor_metrics
4574 && glyph < maxp->num_glyphs)
4575 {
4576
4577 lbearing
4578 = hmtx->left_side_bearing[glyph
4579 - hhea->num_of_long_hor_metrics];
4580 advance
4581 = hmtx->h_metrics[hhea->num_of_long_hor_metrics - 1].advance_width;
4582 }
4583 else
4584
4585 return 1;
4586
4587 if (pixel_size == -1)
4588 {
4589
4590 metrics->lbearing = lbearing;
4591 metrics->advance = advance;
4592 return 0;
4593 }
4594
4595
4596 factor = sfnt_div_fixed (pixel_size, head->units_per_em);
4597
4598
4599 metrics->lbearing = sfnt_mul_fixed (lbearing * 65536, factor);
4600 metrics->advance = sfnt_mul_fixed (advance * 65536, factor);
4601
4602
4603 return 0;
4604 }
4605
4606
4607
4608
4609
4610 MAYBE_UNUSED TEST_STATIC void
4611 sfnt_scale_metrics (struct sfnt_glyph_metrics *metrics,
4612 sfnt_fixed factor)
4613 {
4614 metrics->lbearing
4615 = sfnt_mul_fixed (metrics->lbearing * 65536, factor);
4616 metrics->advance
4617 = sfnt_mul_fixed (metrics->advance * 65536, factor);
4618 }
4619
4620
4621
4622
4623 MAYBE_UNUSED TEST_STATIC sfnt_fixed
4624 sfnt_get_scale (struct sfnt_head_table *head, int ppem)
4625 {
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637 return sfnt_div_fixed (ppem, head->units_per_em);
4638 }
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649 TEST_STATIC struct sfnt_name_table *
4650 sfnt_read_name_table (int fd, struct sfnt_offset_subtable *subtable)
4651 {
4652 struct sfnt_table_directory *directory;
4653 struct sfnt_name_table *name;
4654 size_t required;
4655 ssize_t rc;
4656 int i;
4657
4658
4659
4660 directory = sfnt_find_table (subtable, SFNT_TABLE_NAME);
4661
4662 if (!directory)
4663 return NULL;
4664
4665
4666 if (lseek (fd, directory->offset, SEEK_SET) == (off_t) -1)
4667 return NULL;
4668
4669
4670 required = SFNT_ENDOF (struct sfnt_name_table,
4671 string_offset, uint16_t);
4672
4673 if (directory->length < required)
4674 return NULL;
4675
4676
4677
4678 name = xmalloc (sizeof *name + directory->length);
4679
4680
4681 rc = read (fd, name, required);
4682 if (rc < required)
4683 {
4684 xfree (name);
4685 return NULL;
4686 }
4687
4688
4689 sfnt_swap16 (&name->format);
4690 sfnt_swap16 (&name->count);
4691 sfnt_swap16 (&name->string_offset);
4692
4693
4694 if (name->format)
4695 {
4696 xfree (name);
4697 return NULL;
4698 }
4699
4700
4701 name->name_records
4702 = (struct sfnt_name_record *) (name + 1);
4703
4704
4705 required = directory->length - required;
4706 if (required < name->count * sizeof *name->name_records)
4707 {
4708 xfree (name);
4709 return NULL;
4710 }
4711
4712
4713 rc = read (fd, name->name_records,
4714 (name->count
4715 * sizeof *name->name_records));
4716 if (rc < (name->count
4717 * sizeof *name->name_records))
4718 {
4719 xfree (name);
4720 return NULL;
4721 }
4722
4723
4724 for (i = 0; i < name->count; ++i)
4725 {
4726 sfnt_swap16 (&name->name_records[i].platform_id);
4727 sfnt_swap16 (&name->name_records[i].platform_specific_id);
4728 sfnt_swap16 (&name->name_records[i].language_id);
4729 sfnt_swap16 (&name->name_records[i].name_id);
4730 sfnt_swap16 (&name->name_records[i].length);
4731 sfnt_swap16 (&name->name_records[i].offset);
4732 }
4733
4734
4735
4736 if (name->string_offset > directory->length)
4737 {
4738 xfree (name);
4739 return NULL;
4740 }
4741
4742 required = directory->length - name->string_offset;
4743
4744
4745
4746
4747
4748 if (required > (directory->length
4749 - (name->count
4750 * sizeof *name->name_records)))
4751 {
4752 name = xrealloc (name, (sizeof *name
4753 + (name->count
4754 * sizeof *name->name_records)
4755 + required));
4756 name->name_records = (struct sfnt_name_record *) (name + 1);
4757 }
4758
4759
4760
4761
4762 if (lseek (fd, directory->offset + name->string_offset,
4763 SEEK_SET) == (off_t) -1)
4764 {
4765 xfree (name);
4766 return NULL;
4767 }
4768
4769
4770 name->data = (unsigned char *) (name->name_records
4771 + name->count);
4772 rc = read (fd, name->data, required);
4773 if (rc < required)
4774 {
4775 xfree (name);
4776 return NULL;
4777 }
4778
4779
4780 for (i = 0; i < name->count; ++i)
4781 {
4782 if (((int) name->name_records[i].offset
4783 + name->name_records[i].length) > required)
4784 {
4785
4786 xfree (name);
4787 return NULL;
4788 }
4789 }
4790
4791
4792 return name;
4793 }
4794
4795
4796
4797
4798
4799 TEST_STATIC unsigned char *
4800 sfnt_find_name (struct sfnt_name_table *name,
4801 enum sfnt_name_identifier_code code,
4802 struct sfnt_name_record *record)
4803 {
4804 int i;
4805
4806 for (i = 0; i < name->count; ++i)
4807 {
4808 if (name->name_records[i].name_id == code)
4809 {
4810
4811 *record = name->name_records[i];
4812 return name->data + record->offset;
4813 }
4814 }
4815
4816 return NULL;
4817 }
4818
4819
4820
4821
4822
4823
4824 TEST_STATIC struct sfnt_meta_table *
4825 sfnt_read_meta_table (int fd, struct sfnt_offset_subtable *subtable)
4826 {
4827 struct sfnt_table_directory *directory;
4828 struct sfnt_meta_table *meta;
4829 size_t required, i, data_size, map_size, offset;
4830 ssize_t rc;
4831
4832
4833
4834 directory = sfnt_find_table (subtable, SFNT_TABLE_META);
4835
4836 if (!directory)
4837 return NULL;
4838
4839
4840 if (lseek (fd, directory->offset, SEEK_SET) == (off_t) -1)
4841 return NULL;
4842
4843
4844 required = SFNT_ENDOF (struct sfnt_meta_table,
4845 num_data_maps, uint32_t);
4846
4847 if (directory->length < required)
4848 return NULL;
4849
4850
4851 meta = xmalloc (sizeof *meta);
4852
4853
4854 rc = read (fd, meta, required);
4855 if (rc < required)
4856 {
4857 xfree (meta);
4858 return NULL;
4859 }
4860
4861
4862 sfnt_swap32 (&meta->version);
4863 sfnt_swap32 (&meta->flags);
4864 sfnt_swap32 (&meta->data_offset);
4865 sfnt_swap32 (&meta->num_data_maps);
4866
4867
4868 if (meta->version != 1)
4869 {
4870 xfree (meta);
4871 return NULL;
4872 }
4873
4874
4875
4876
4877
4878
4879
4880 if (INT_MULTIPLY_WRAPV (sizeof *meta->data_maps, meta->num_data_maps,
4881 &map_size)
4882
4883 || INT_ADD_WRAPV (map_size, sizeof *meta, &data_size)
4884 || INT_ADD_WRAPV (data_size, directory->length, &data_size))
4885 {
4886 xfree (meta);
4887 return NULL;
4888 }
4889
4890
4891 meta = xrealloc (meta, data_size);
4892
4893
4894
4895 if (directory->length - required < map_size)
4896 {
4897 xfree (meta);
4898 return NULL;
4899 }
4900
4901
4902 meta->data_maps = (struct sfnt_meta_data_map *) (meta + 1);
4903 meta->data = (unsigned char *) (meta->data_maps
4904 + meta->num_data_maps);
4905
4906
4907 if (lseek (fd, directory->offset, SEEK_SET) == (off_t) -1)
4908 {
4909 xfree (meta);
4910 return NULL;
4911 }
4912
4913 rc = read (fd, meta->data, directory->length);
4914 if (rc < directory->length)
4915 {
4916 xfree (meta);
4917 return NULL;
4918 }
4919
4920
4921
4922 memcpy (meta->data_maps, meta->data + required,
4923 map_size);
4924
4925 for (i = 0; i < meta->num_data_maps; ++i)
4926 {
4927 sfnt_swap32 (&meta->data_maps[i].tag);
4928 sfnt_swap32 (&meta->data_maps[i].data_offset);
4929 sfnt_swap32 (&meta->data_maps[i].data_length);
4930
4931
4932
4933
4934 if (INT_ADD_WRAPV (meta->data_maps[i].data_offset,
4935 meta->data_maps[i].data_length,
4936 &offset))
4937 {
4938 xfree (meta);
4939 return NULL;
4940 }
4941
4942 if (offset > directory->length)
4943 {
4944 xfree (meta);
4945 return NULL;
4946 }
4947 }
4948
4949
4950 return meta;
4951 }
4952
4953
4954
4955
4956
4957 MAYBE_UNUSED TEST_STATIC char *
4958 sfnt_find_metadata (struct sfnt_meta_table *meta,
4959 enum sfnt_meta_data_tag tag,
4960 struct sfnt_meta_data_map *map)
4961 {
4962 int i;
4963
4964 for (i = 0; i < meta->num_data_maps; ++i)
4965 {
4966 if (meta->data_maps[i].tag == tag)
4967 {
4968 *map = meta->data_maps[i];
4969 return (char *) meta->data + map->data_offset;
4970 }
4971 }
4972
4973 return NULL;
4974 }
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985 TEST_STATIC struct sfnt_ttc_header *
4986 sfnt_read_ttc_header (int fd)
4987 {
4988 struct sfnt_ttc_header *ttc;
4989 size_t size, i;
4990 ssize_t rc;
4991
4992
4993
4994 ttc = xmalloc (sizeof *ttc);
4995
4996
4997
4998 size = SFNT_ENDOF (struct sfnt_ttc_header, num_fonts,
4999 uint32_t);
5000 rc = read (fd, ttc, size);
5001 if (rc < size)
5002 {
5003 xfree (ttc);
5004 return NULL;
5005 }
5006
5007
5008 sfnt_swap32 (&ttc->ttctag);
5009 sfnt_swap32 (&ttc->version);
5010 sfnt_swap32 (&ttc->num_fonts);
5011
5012
5013 if (ttc->ttctag != SFNT_TTC_TTCF)
5014 {
5015 xfree (ttc);
5016 return NULL;
5017 }
5018
5019
5020
5021
5022 if (INT_MULTIPLY_WRAPV (ttc->num_fonts,
5023 sizeof *ttc->offset_table,
5024 &size))
5025 {
5026 xfree (ttc);
5027 return NULL;
5028 }
5029
5030 ttc = xrealloc (ttc, sizeof *ttc + size);
5031 ttc->offset_table = (uint32_t *) (ttc + 1);
5032 rc = read (fd, ttc->offset_table, size);
5033 if (rc < size)
5034 {
5035 xfree (ttc);
5036 return NULL;
5037 }
5038
5039
5040 for (i = 0; i < ttc->num_fonts; ++i)
5041 sfnt_swap32 (&ttc->offset_table[i]);
5042
5043
5044
5045
5046 if (ttc->version < 0x00020000)
5047 return ttc;
5048
5049
5050
5051
5052 size = (SFNT_ENDOF (struct sfnt_ttc_header, ul_dsig_offset,
5053 uint32_t)
5054 - offsetof (struct sfnt_ttc_header, ul_dsig_tag));
5055 rc = read (fd, &ttc->ul_dsig_offset, size);
5056 if (rc < size)
5057 {
5058 xfree (ttc);
5059 return NULL;
5060 }
5061
5062
5063 sfnt_swap32 (&ttc->ul_dsig_tag);
5064 sfnt_swap32 (&ttc->ul_dsig_length);
5065 sfnt_swap32 (&ttc->ul_dsig_offset);
5066
5067
5068 return ttc;
5069 }
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123 TEST_STATIC struct sfnt_cvt_table *
5124 sfnt_read_cvt_table (int fd, struct sfnt_offset_subtable *subtable)
5125 {
5126 struct sfnt_table_directory *directory;
5127 size_t required, i;
5128 ssize_t rc;
5129 struct sfnt_cvt_table *cvt;
5130
5131
5132
5133 directory = sfnt_find_table (subtable, SFNT_TABLE_CVT );
5134
5135 if (!directory)
5136 return NULL;
5137
5138
5139 if (lseek (fd, directory->offset, SEEK_SET) == (off_t) -1)
5140 return NULL;
5141
5142
5143 if (INT_ADD_WRAPV (sizeof *cvt, directory->length, &required))
5144 return NULL;
5145
5146
5147 cvt = xmalloc (required);
5148
5149
5150
5151 cvt->num_elements = directory->length / 2;
5152 cvt->values = (sfnt_fword *) (cvt + 1);
5153
5154
5155 rc = read (fd, cvt->values, directory->length);
5156 if (rc != directory->length)
5157 {
5158 xfree (cvt);
5159 return NULL;
5160 }
5161
5162
5163 for (i = 0; i < cvt->num_elements; ++i)
5164 sfnt_swap16 (&cvt->values[i]);
5165
5166
5167 return cvt;
5168 }
5169
5170
5171
5172
5173
5174 TEST_STATIC struct sfnt_fpgm_table *
5175 sfnt_read_fpgm_table (int fd, struct sfnt_offset_subtable *subtable)
5176 {
5177 struct sfnt_table_directory *directory;
5178 size_t required;
5179 ssize_t rc;
5180 struct sfnt_fpgm_table *fpgm;
5181
5182
5183
5184 directory = sfnt_find_table (subtable, SFNT_TABLE_FPGM);
5185
5186 if (!directory)
5187 return NULL;
5188
5189
5190 if (lseek (fd, directory->offset, SEEK_SET) == (off_t) -1)
5191 return NULL;
5192
5193
5194 if (INT_ADD_WRAPV (sizeof *fpgm, directory->length, &required))
5195 return NULL;
5196
5197
5198 fpgm = xmalloc (sizeof *fpgm + directory->length);
5199
5200
5201
5202
5203 fpgm->num_instructions = directory->length;
5204 fpgm->instructions = (unsigned char *) (fpgm + 1);
5205
5206
5207 rc = read (fd, fpgm->instructions, directory->length);
5208 if (rc != directory->length)
5209 {
5210 xfree (fpgm);
5211 return NULL;
5212 }
5213
5214
5215 return fpgm;
5216 }
5217
5218
5219
5220
5221
5222 TEST_STATIC struct sfnt_prep_table *
5223 sfnt_read_prep_table (int fd, struct sfnt_offset_subtable *subtable)
5224 {
5225 struct sfnt_table_directory *directory;
5226 size_t required;
5227 ssize_t rc;
5228 struct sfnt_prep_table *prep;
5229
5230
5231
5232 directory = sfnt_find_table (subtable, SFNT_TABLE_PREP);
5233
5234 if (!directory)
5235 return NULL;
5236
5237
5238 if (lseek (fd, directory->offset, SEEK_SET) == (off_t) -1)
5239 return NULL;
5240
5241
5242 if (INT_ADD_WRAPV (sizeof *prep, directory->length, &required))
5243 return NULL;
5244
5245
5246 prep = xmalloc (sizeof *prep + directory->length);
5247
5248
5249
5250
5251 prep->num_instructions = directory->length;
5252 prep->instructions = (unsigned char *) (prep + 1);
5253
5254
5255 rc = read (fd, prep->instructions, directory->length);
5256 if (rc != directory->length)
5257 {
5258 xfree (prep);
5259 return NULL;
5260 }
5261
5262
5263 return prep;
5264 }
5265
5266
5267
5268
5269
5270
5271
5272
5273 static sfnt_f26dot6
5274 sfnt_div_f26dot6 (sfnt_f26dot6 x, sfnt_f26dot6 y)
5275 {
5276 #ifdef INT64_MAX
5277 int64_t result;
5278
5279 result = ((int64_t) x * 64) / y;
5280
5281 return result;
5282 #else
5283 int sign;
5284 unsigned int a, b;
5285
5286 sign = 1;
5287
5288 if (x < 0)
5289 sign = -sign;
5290
5291 if (y < 0)
5292 sign = -sign;
5293
5294 a = abs (x);
5295 b = abs (y);
5296
5297 return sfnt_multiply_divide (a, 64, b) * sign;
5298 #endif
5299 }
5300
5301
5302
5303
5304 static sfnt_f26dot6
5305 sfnt_mul_f26dot6 (sfnt_f26dot6 a, sfnt_f26dot6 b)
5306 {
5307 #ifdef INT64_MAX
5308 int64_t product;
5309
5310 product = (int64_t) a * (int64_t) b;
5311
5312
5313 return product / (int64_t) 64;
5314 #else
5315 int sign;
5316
5317 sign = 1;
5318
5319 if (a < 0)
5320 sign = -sign;
5321
5322 if (b < 0)
5323 sign = -sign;
5324
5325 return sfnt_multiply_divide (abs (a), abs (b),
5326 64) * sign;
5327 #endif
5328 }
5329
5330
5331
5332
5333 static int32_t
5334 sfnt_mul_f2dot14 (sfnt_f2dot14 a, int32_t b)
5335 {
5336 #ifdef INT64_MAX
5337 int64_t product;
5338
5339 product = (int64_t) a * (int64_t) b;
5340
5341 return product / (int64_t) 16384;
5342 #else
5343 int sign;
5344
5345 sign = 1;
5346
5347 if (a < 0)
5348 sign = -sign;
5349
5350 if (b < 0)
5351 sign = -sign;
5352
5353 return sfnt_multiply_divide (abs (a), abs (b),
5354 16384) * sign;
5355 #endif
5356 }
5357
5358
5359
5360
5361
5362
5363
5364 static sfnt_f26dot6
5365 sfnt_mul_f26dot6_fixed (sfnt_f26dot6 x, sfnt_fixed y)
5366 {
5367 #ifdef INT64_MAX
5368 uint64_t product;
5369 int sign;
5370
5371 sign = 1;
5372
5373 if (x < 0)
5374 {
5375 x = -x;
5376 sign = -sign;
5377 }
5378
5379 if (y < 0)
5380 {
5381 y = -y;
5382 sign = -sign;
5383 }
5384
5385 product = (uint64_t) y * (uint64_t) x;
5386
5387
5388 return ((int64_t) (product + 32676) / (int64_t) 65536) * sign;
5389 #else
5390 struct sfnt_large_integer temp;
5391 int sign;
5392
5393 sign = 1;
5394
5395 if (x < 0)
5396 sign = -sign;
5397
5398 if (y < 0)
5399 sign = -sign;
5400
5401 sfnt_multiply_divide_1 (abs (x), abs (y), &temp);
5402 sfnt_large_integer_add (&temp, 32676);
5403 return sfnt_multiply_divide_2 (&temp, 65536) * sign;
5404 #endif
5405 }
5406
5407
5408
5409 static sfnt_f26dot6
5410 sfnt_floor_f26dot6 (sfnt_f26dot6 x)
5411 {
5412 return x & 037777777700;
5413 }
5414
5415
5416
5417 static sfnt_f26dot6
5418 sfnt_ceil_f26dot6 (sfnt_f26dot6 x)
5419 {
5420 return (x + 077) & ~077;
5421 }
5422
5423
5424
5425
5426 static sfnt_f26dot6
5427 sfnt_round_f26dot6 (sfnt_f26dot6 x)
5428 {
5429
5430 x += 040;
5431
5432
5433 return x & ~077;
5434 }
5435
5436
5437
5438 static void sfnt_validate_gs (struct sfnt_graphics_state *);
5439
5440
5441
5442
5443 static void
5444 sfnt_init_graphics_state (struct sfnt_graphics_state *state)
5445 {
5446 state->auto_flip = true;
5447 state->cvt_cut_in = 0104;
5448 state->delta_base = 9;
5449 state->delta_shift = 3;
5450 state->dual_projection_vector.x = 040000;
5451 state->dual_projection_vector.y = 0;
5452 state->freedom_vector.x = 040000;
5453 state->freedom_vector.y = 0;
5454 state->instruct_control = 0;
5455 state->loop = 1;
5456 state->minimum_distance = 0100;
5457 state->projection_vector.x = 040000;
5458 state->projection_vector.y = 0;
5459 state->round_state = 1;
5460 state->rp0 = 0;
5461 state->rp1 = 0;
5462 state->rp2 = 0;
5463 state->scan_control = 0;
5464 state->sw_cut_in = 0;
5465 state->single_width_value = 0;
5466 state->zp0 = 1;
5467 state->zp1 = 1;
5468 state->zp2 = 1;
5469
5470
5471 sfnt_validate_gs (state);
5472 }
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485 TEST_STATIC struct sfnt_interpreter *
5486 sfnt_make_interpreter (struct sfnt_maxp_table *maxp,
5487 struct sfnt_cvt_table *cvt,
5488 struct sfnt_head_table *head,
5489 struct sfnt_fvar_table *fvar,
5490 int pixel_size, int point_size)
5491 {
5492 size_t size, temp, i, storage_size, pad;
5493 struct sfnt_interpreter *interpreter;
5494
5495
5496 if (maxp->version != 0x00010000)
5497 return NULL;
5498
5499
5500
5501 size = sizeof (*interpreter);
5502
5503
5504 if (INT_ADD_WRAPV ((maxp->max_stack_elements
5505 * sizeof *interpreter->stack),
5506 size, &size))
5507 return NULL;
5508
5509
5510
5511 if (INT_ADD_WRAPV ((maxp->max_twilight_points
5512 * sizeof *interpreter->twilight_x),
5513 size, &size))
5514 return NULL;
5515
5516 if (INT_ADD_WRAPV ((maxp->max_twilight_points
5517 * sizeof *interpreter->twilight_y),
5518 size, &size))
5519 return NULL;
5520
5521 if (INT_ADD_WRAPV ((maxp->max_twilight_points
5522 * sizeof *interpreter->twilight_y),
5523 size, &size))
5524 return NULL;
5525
5526 if (INT_ADD_WRAPV ((maxp->max_twilight_points
5527 * sizeof *interpreter->twilight_y),
5528 size, &size))
5529 return NULL;
5530
5531
5532 storage_size = maxp->max_storage * sizeof *interpreter->storage;
5533 if (INT_ADD_WRAPV (storage_size, size, &size))
5534 return NULL;
5535
5536
5537 pad = alignof (struct sfnt_interpreter_definition);
5538 pad -= size & (pad - 1);
5539 if (INT_ADD_WRAPV (pad, size, &size))
5540 return NULL;
5541
5542
5543 if (INT_ADD_WRAPV ((((int) maxp->max_instruction_defs
5544 + maxp->max_function_defs)
5545 * sizeof *interpreter->function_defs),
5546 size, &size))
5547 return NULL;
5548
5549
5550
5551 if (cvt)
5552 {
5553 if (INT_MULTIPLY_WRAPV (cvt->num_elements,
5554 sizeof *interpreter->cvt,
5555 &temp)
5556 || INT_ADD_WRAPV (temp, size, &size))
5557 return NULL;
5558 }
5559
5560
5561 interpreter = xmalloc (size);
5562
5563 #ifdef TEST
5564 interpreter->run_hook = NULL;
5565 interpreter->push_hook = NULL;
5566 interpreter->pop_hook = NULL;
5567 #endif
5568
5569
5570 interpreter->max_stack_elements = maxp->max_stack_elements;
5571 interpreter->num_instructions = 0;
5572 interpreter->IP = 0;
5573 interpreter->storage_size = maxp->max_storage;
5574 interpreter->function_defs_size = maxp->max_function_defs;
5575 interpreter->instruction_defs_size = maxp->max_instruction_defs;
5576 interpreter->twilight_zone_size = maxp->max_twilight_points;
5577 interpreter->scale = 0;
5578
5579 interpreter->stack = (uint32_t *) (interpreter + 1);
5580 interpreter->SP = interpreter->stack;
5581 interpreter->instructions = NULL;
5582 interpreter->twilight_x
5583 = (sfnt_f26dot6 *) (interpreter->stack
5584 + maxp->max_stack_elements);
5585 interpreter->twilight_y = (interpreter->twilight_x
5586 + maxp->max_twilight_points);
5587 interpreter->twilight_original_x = (interpreter->twilight_y
5588 + maxp->max_twilight_points);
5589 interpreter->twilight_original_y
5590 = (interpreter->twilight_original_x
5591 + maxp->max_twilight_points);
5592 interpreter->glyph_zone = NULL;
5593 interpreter->advance_width = 0;
5594 interpreter->storage
5595 = (uint32_t *) (interpreter->twilight_original_y
5596 + maxp->max_twilight_points);
5597 interpreter->function_defs
5598 = (struct sfnt_interpreter_definition *) (interpreter->storage
5599 + maxp->max_storage);
5600 interpreter->function_defs
5601 = ((struct sfnt_interpreter_definition *)
5602 ((unsigned char *) interpreter->function_defs + pad));
5603 interpreter->instruction_defs = (interpreter->function_defs
5604 + maxp->max_function_defs);
5605 interpreter->cvt
5606 = (sfnt_f26dot6 *) (interpreter->instruction_defs
5607 + maxp->max_instruction_defs);
5608
5609 if (cvt)
5610 interpreter->cvt_size = cvt->num_elements;
5611 else
5612 interpreter->cvt_size = 0;
5613
5614
5615
5616 interpreter->scale
5617 = sfnt_div_fixed (pixel_size, head->units_per_em);
5618
5619
5620 interpreter->ppem = pixel_size;
5621 interpreter->point_size = point_size;
5622
5623
5624
5625 memset (interpreter->stack, 0, size - sizeof *interpreter);
5626
5627
5628 sfnt_init_graphics_state (&interpreter->state);
5629
5630
5631 for (i = 0; i < interpreter->cvt_size; ++i)
5632 interpreter->cvt[i]
5633 = sfnt_mul_f26dot6_fixed (cvt->values[i] * 64,
5634 interpreter->scale);
5635
5636
5637 interpreter->period = 64;
5638 interpreter->phase = 0;
5639 interpreter->threshold = 0;
5640
5641
5642 interpreter->call_depth = 0;
5643
5644
5645
5646 interpreter->n_axis = 0;
5647 interpreter->norm_coords = NULL;
5648
5649
5650
5651
5652
5653 if (fvar)
5654 interpreter->n_axis = fvar->axis_count;
5655
5656
5657 return interpreter;
5658 }
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669 enum sfnt_interpreter_run_context
5670 {
5671 SFNT_RUN_CONTEXT_FONT_PROGRAM,
5672 SFNT_RUN_CONTEXT_CONTROL_VALUE_PROGRAM,
5673 SFNT_RUN_CONTEXT_GLYPH_PROGRAM,
5674 #ifdef TEST
5675 SFNT_RUN_CONTEXT_TEST,
5676 #endif
5677 };
5678
5679
5680
5681
5682
5683
5684
5685 _Noreturn static void
5686 sfnt_interpret_trap (struct sfnt_interpreter *interpreter,
5687 const char *reason)
5688 {
5689 interpreter->trap_reason = reason;
5690 interpreter->call_depth = 0;
5691 interpreter->state.loop = 1;
5692 longjmp (interpreter->trap, 1);
5693 }
5694
5695 #define STACKSIZE() \
5696 (interpreter->SP - interpreter->stack)
5697
5698 #define TRAP(why) \
5699 sfnt_interpret_trap (interpreter, (why))
5700
5701 #define MOVE(a, b, n) \
5702 memmove (a, b, (n) * sizeof (uint32_t))
5703
5704 #define CHECK_STACK_ELEMENTS(n) \
5705 { \
5706 if ((interpreter->SP \
5707 - interpreter->stack) < n) \
5708 TRAP ("stack underflow"); \
5709 }
5710
5711 #define CHECK_STACK_AVAILABLE(n) \
5712 { \
5713 char *stack_end; \
5714 \
5715 stack_end \
5716 = (char *) interpreter->twilight_x; \
5717 if (((char *) (interpreter->SP + (n)) \
5718 > stack_end)) \
5719 TRAP ("stack overflow"); \
5720 }
5721
5722 #define CHECK_PREP() \
5723 if (!is_prep) \
5724 TRAP ("instruction executed not valid" \
5725 " outside control value program") \
5726
5727 #define sfnt_add(a, b) \
5728 ((int) ((unsigned int) (a) + (unsigned int) (b)))
5729
5730 #define sfnt_sub(a, b) \
5731 ((int) ((unsigned int) (a) - (unsigned int) (b)))
5732
5733 #define sfnt_mul(a, b) \
5734 ((int) ((unsigned int) (a) * (unsigned int) (b)))
5735
5736
5737
5738
5739
5740 #ifndef TEST
5741
5742 #define POP() \
5743 (interpreter->SP == interpreter->stack \
5744 ? (TRAP ("stack underflow"), 0) \
5745 : (*(--interpreter->SP)))
5746
5747 #define POP_UNCHECKED() (*(--interpreter->SP))
5748
5749 #else
5750
5751 #define POP() \
5752 (interpreter->SP == interpreter->stack \
5753 ? (TRAP ("stack underflow"), 0) \
5754 : ({uint32_t _value; \
5755 _value = *(--interpreter->SP); \
5756 if (interpreter->pop_hook) \
5757 interpreter->pop_hook (interpreter, \
5758 _value); \
5759 _value;}))
5760
5761 #define POP_UNCHECKED() POP ()
5762
5763 #endif
5764
5765 #define LOOK() \
5766 (interpreter->SP == interpreter->stack \
5767 ? (TRAP ("stack underflow"), 0) \
5768 : *(interpreter->SP - 1))
5769
5770 #if !defined TEST || !0
5771
5772 #define PUSH(value) \
5773 { \
5774 if ((char *) (interpreter->SP + 1) \
5775 > (char *) interpreter->twilight_x) \
5776 TRAP ("stack overflow"); \
5777 \
5778 *interpreter->SP = (value); \
5779 interpreter->SP++; \
5780 }
5781
5782 #define PUSH_UNCHECKED(value) \
5783 { \
5784 *interpreter->SP = (value); \
5785 interpreter->SP++; \
5786 }
5787
5788 #else
5789
5790 #define PUSH(value) \
5791 { \
5792 if ((char *) (interpreter->SP + 1) \
5793 > (char *) interpreter->twilight_x) \
5794 TRAP ("stack overflow"); \
5795 \
5796 if (interpreter->push_hook) \
5797 interpreter->push_hook (interpreter, \
5798 value); \
5799 \
5800 *interpreter->SP = value; \
5801 interpreter->SP++; \
5802 }
5803
5804 #define PUSH_UNCHECKED(value) PUSH (value)
5805
5806 #endif
5807
5808 #define PUSH2_UNCHECKED(high, low) \
5809 { \
5810 int16_t word; \
5811 \
5812 word = (((int8_t) high) << 8 | low); \
5813 PUSH_UNCHECKED (word); \
5814 } \
5815
5816 #define SRP0() \
5817 { \
5818 uint32_t p; \
5819 \
5820 p = POP (); \
5821 interpreter->state.rp0 = p; \
5822 }
5823
5824 #define SRP1() \
5825 { \
5826 uint32_t p; \
5827 \
5828 p = POP (); \
5829 interpreter->state.rp1 = p; \
5830 }
5831
5832 #define SRP2() \
5833 { \
5834 uint32_t p; \
5835 \
5836 p = POP (); \
5837 interpreter->state.rp2 = p; \
5838 }
5839
5840 #define SZP0() \
5841 { \
5842 uint32_t zone; \
5843 \
5844 zone = POP (); \
5845 \
5846 if (zone > 1) \
5847 TRAP ("invalid zone"); \
5848 \
5849 interpreter->state.zp0 = zone; \
5850 }
5851
5852 #define SZP1() \
5853 { \
5854 uint32_t zone; \
5855 \
5856 zone = POP (); \
5857 \
5858 if (zone > 1) \
5859 TRAP ("invalid zone"); \
5860 \
5861 interpreter->state.zp1 = zone; \
5862 }
5863
5864 #define SZP2() \
5865 { \
5866 uint32_t zone; \
5867 \
5868 zone = POP (); \
5869 \
5870 if (zone > 1) \
5871 TRAP ("invalid zone"); \
5872 \
5873 interpreter->state.zp2 = zone; \
5874 }
5875
5876 #define SZPS() \
5877 { \
5878 uint32_t zone; \
5879 \
5880 zone = POP (); \
5881 \
5882 if (zone > 1) \
5883 TRAP ("invalid zone"); \
5884 \
5885 interpreter->state.zp0 = zone; \
5886 interpreter->state.zp1 = zone; \
5887 interpreter->state.zp2 = zone; \
5888 }
5889
5890 #define SLOOP() \
5891 { \
5892 uint32_t loop; \
5893 \
5894 loop = POP (); \
5895 \
5896 if (!loop) \
5897 TRAP ("loop set to 0"); \
5898 \
5899 interpreter->state.loop = loop; \
5900 }
5901
5902 #define SMD() \
5903 { \
5904 sfnt_f26dot6 md; \
5905 \
5906 md = POP (); \
5907 \
5908 interpreter->state.minimum_distance = md; \
5909 }
5910
5911 #define ELSE() \
5912 { \
5913 sfnt_interpret_else (interpreter); \
5914 goto skip_step; \
5915 }
5916
5917 #define JMPR() \
5918 { \
5919 int32_t offset; \
5920 \
5921 offset = POP (); \
5922 \
5923 if (interpreter->IP + offset < 0 \
5924 || (interpreter->IP + offset \
5925 > interpreter->num_instructions)) \
5926 TRAP ("JMPR out of bounds"); \
5927 \
5928 interpreter->IP += offset; \
5929 goto skip_step; \
5930 }
5931
5932 #define SCVTCI() \
5933 { \
5934 sfnt_f26dot6 cutin; \
5935 \
5936 cutin = POP (); \
5937 \
5938 interpreter->state.cvt_cut_in = cutin; \
5939 }
5940
5941 #define SSWCI() \
5942 { \
5943 sfnt_f26dot6 cutin; \
5944 \
5945 cutin = POP (); \
5946 \
5947 interpreter->state.sw_cut_in = cutin; \
5948 }
5949
5950 #define SSW() \
5951 { \
5952 int32_t single_width; \
5953 \
5954 single_width = POP (); \
5955 \
5956 interpreter->state.single_width_value \
5957 = (interpreter->scale * single_width \
5958 / 1024); \
5959 }
5960
5961 #define DUP() \
5962 { \
5963 uint32_t value; \
5964 \
5965 value = LOOK (); \
5966 PUSH (value); \
5967 }
5968
5969 #define CLEAR() \
5970 { \
5971 interpreter->SP = interpreter->stack; \
5972 }
5973
5974 #define SWAP() \
5975 { \
5976 uint32_t a, b; \
5977 \
5978 a = POP (); \
5979 b = POP (); \
5980 \
5981 PUSH_UNCHECKED (a); \
5982 PUSH_UNCHECKED (b); \
5983 }
5984
5985 #define DEPTH() \
5986 { \
5987 ptrdiff_t diff; \
5988 \
5989 diff = (interpreter->SP \
5990 - interpreter->stack); \
5991 PUSH (diff); \
5992 }
5993
5994 #define CINDEX() \
5995 { \
5996 int32_t index; \
5997 \
5998 index = POP (); \
5999 \
6000 if (index <= 0 || index > STACKSIZE ()) \
6001 TRAP ("stack overflow"); \
6002 \
6003 PUSH_UNCHECKED (*(interpreter->SP \
6004 - index)); \
6005 }
6006
6007 #define MINDEX() \
6008 { \
6009 int32_t index, what; \
6010 \
6011 index = POP (); \
6012 \
6013 if (index <= 0 || index > STACKSIZE ()) \
6014 TRAP ("stack overflow"); \
6015 \
6016 what = *(interpreter->SP - index); \
6017 MOVE (interpreter->SP - index, \
6018 interpreter->SP - index + 1, \
6019 index - 1); \
6020 *(interpreter->SP - 1) = what; \
6021 }
6022
6023 #define RAW() \
6024 { \
6025 if (why != SFNT_RUN_CONTEXT_GLYPH_PROGRAM) \
6026 TRAP ("Read Advance Width without loaded" \
6027 " glyph"); \
6028 PUSH (interpreter->advance_width); \
6029 }
6030
6031 #define CALL() \
6032 { \
6033 uint32_t id, i; \
6034 struct sfnt_interpreter_definition *def; \
6035 \
6036 id = POP (); \
6037 \
6038 for (i = 0; \
6039 i < interpreter->function_defs_size; \
6040 ++i) \
6041 { \
6042 def = &interpreter->function_defs[i]; \
6043 \
6044 if (!def->instructions) \
6045 TRAP ("invalid function"); \
6046 \
6047 if (def->opcode == id) \
6048 { \
6049 sfnt_interpret_call (def, \
6050 interpreter, \
6051 why); \
6052 goto next_instruction; \
6053 } \
6054 } \
6055 \
6056 TRAP ("invalid function"); \
6057 }
6058
6059 #define LOOPCALL() \
6060 { \
6061 uint32_t id; \
6062 int32_t n; \
6063 int i; \
6064 struct sfnt_interpreter_definition *def; \
6065 \
6066 id = POP (); \
6067 n = POP (); \
6068 \
6069 if (n > 65535) \
6070 TRAP ("invalid LOOPCALL count"); \
6071 \
6072 for (i = 0; \
6073 i < interpreter->function_defs_size; \
6074 ++i) \
6075 { \
6076 def = &interpreter->function_defs[i]; \
6077 \
6078 if (!def->instructions) \
6079 TRAP ("invalid function"); \
6080 \
6081 if (def->opcode == id) \
6082 goto loopcall_begin; \
6083 } \
6084 \
6085 TRAP ("invalid function"); \
6086 \
6087 loopcall_begin: \
6088 if (n-- <= 0) \
6089 break; \
6090 \
6091 sfnt_interpret_call (def, interpreter, \
6092 why); \
6093 goto loopcall_begin; \
6094 }
6095
6096 #define FDEF() \
6097 { \
6098 if (why == SFNT_RUN_CONTEXT_GLYPH_PROGRAM) \
6099 TRAP ("FDEF inside glyph program"); \
6100 \
6101 sfnt_interpret_fdef (interpreter, POP ()); \
6102 goto skip_step; \
6103 }
6104
6105 #define ENDF() \
6106 { \
6107 TRAP ("stray ENDF"); \
6108 }
6109
6110 #define NPUSHB() \
6111 { \
6112 int b, nbytes, IP; \
6113 unsigned char *ip; \
6114 \
6115 if ((IP = interpreter->IP + 1) \
6116 >= interpreter->num_instructions) \
6117 TRAP ("Missing arg to NPUSHB"); \
6118 \
6119 nbytes \
6120 = interpreter->instructions[IP]; \
6121 \
6122 if (IP + 1 + nbytes \
6123 > interpreter->num_instructions) \
6124 TRAP ("args to NPUSHB lie outside IS"); \
6125 \
6126 CHECK_STACK_AVAILABLE (nbytes); \
6127 ip = interpreter->instructions; \
6128 for (b = IP + 1; b < IP + 1 + nbytes; ++b) \
6129 PUSH_UNCHECKED (ip[b]); \
6130 \
6131 interpreter->IP += nbytes + 1; \
6132 }
6133
6134 #define NPUSHW() \
6135 { \
6136 int b, nbytes, IP; \
6137 unsigned char *ip; \
6138 \
6139 if ((IP = interpreter->IP + 1) \
6140 >= interpreter->num_instructions) \
6141 TRAP ("Missing arg to NPUSHW"); \
6142 \
6143 nbytes \
6144 = interpreter->instructions[IP] * 2; \
6145 \
6146 if (IP + 1 + nbytes \
6147 > interpreter->num_instructions) \
6148 TRAP ("args to NPUSHW lie outside IS"); \
6149 \
6150 CHECK_STACK_AVAILABLE (nbytes / 2); \
6151 ip = interpreter->instructions; \
6152 for (b = IP + 1; b < IP + 1 + nbytes; \
6153 b += 2) \
6154 PUSH2_UNCHECKED (ip[b], ip[b + 1]); \
6155 \
6156 interpreter->IP += nbytes + 1; \
6157 }
6158
6159 #define WS() \
6160 { \
6161 uint32_t address, value; \
6162 \
6163 value = POP (); \
6164 address = POP (); \
6165 \
6166 if (address >= interpreter->storage_size) \
6167 TRAP ("invalid WS"); \
6168 \
6169 interpreter->storage[address] = value; \
6170 }
6171
6172 #define RS() \
6173 { \
6174 uint32_t address, value; \
6175 \
6176 address = POP (); \
6177 \
6178 if (address >= interpreter->storage_size) \
6179 TRAP ("invalid RS"); \
6180 \
6181 value = interpreter->storage[address]; \
6182 PUSH_UNCHECKED (value); \
6183 }
6184
6185 #define WCVTP() \
6186 { \
6187 sfnt_f26dot6 value; \
6188 uint32_t location; \
6189 \
6190 value = POP (); \
6191 location = POP (); \
6192 \
6193 if (location >= interpreter->cvt_size) \
6194 TRAP ("WCVTP out of bounds"); \
6195 \
6196 interpreter->cvt[location] = value; \
6197 }
6198
6199 #define RCVT() \
6200 { \
6201 sfnt_f26dot6 value; \
6202 uint32_t location; \
6203 \
6204 location = POP (); \
6205 \
6206 if (location >= interpreter->cvt_size) \
6207 TRAP ("out of bounds RCVT"); \
6208 \
6209 value = interpreter->cvt[location]; \
6210 PUSH_UNCHECKED (value); \
6211 }
6212
6213 #define MPPEM() \
6214 { \
6215 PUSH (interpreter->ppem); \
6216 }
6217
6218 #define MPS() \
6219 { \
6220 PUSH (interpreter->point_size); \
6221 }
6222
6223 #define FLIPON() \
6224 { \
6225 interpreter->state.auto_flip = true; \
6226 }
6227
6228 #define FLIPOFF() \
6229 { \
6230 interpreter->state.auto_flip = false; \
6231 }
6232
6233 #define DEBUG() \
6234 { \
6235 POP (); \
6236 }
6237
6238 #define LT() \
6239 { \
6240 int32_t e1, e2; \
6241 \
6242 e2 = POP (); \
6243 e1 = POP (); \
6244 \
6245 PUSH_UNCHECKED (e1 < e2 ? 1 : 0); \
6246 }
6247
6248 #define LTEQ() \
6249 { \
6250 int32_t e1, e2; \
6251 \
6252 e2 = POP (); \
6253 e1 = POP (); \
6254 \
6255 PUSH_UNCHECKED (e1 <= e2 ? 1 : 0); \
6256 }
6257
6258 #define GT() \
6259 { \
6260 int32_t e1, e2; \
6261 \
6262 e2 = POP (); \
6263 e1 = POP (); \
6264 \
6265 PUSH_UNCHECKED (e1 > e2 ? 1 : 0); \
6266 }
6267
6268 #define GTEQ() \
6269 { \
6270 int32_t e1, e2; \
6271 \
6272 e2 = POP (); \
6273 e1 = POP (); \
6274 \
6275 PUSH_UNCHECKED (e1 >= e2 ? 1 : 0); \
6276 }
6277
6278 #define EQ() \
6279 { \
6280 uint32_t e1, e2; \
6281 \
6282 e1 = POP (); \
6283 e2 = POP (); \
6284 \
6285 PUSH_UNCHECKED (e1 == e2 ? 1 : 0); \
6286 }
6287
6288 #define NEQ() \
6289 { \
6290 uint32_t e1, e2; \
6291 \
6292 e1 = POP (); \
6293 e2 = POP (); \
6294 \
6295 PUSH_UNCHECKED (e1 != e2 ? 1 : 0); \
6296 }
6297
6298 #define ODD() \
6299 { \
6300 sfnt_f26dot6 e1, result; \
6301 \
6302 e1 = POP (); \
6303 result = abs (e1); \
6304 \
6305 result \
6306 = interpreter->state.round (result, \
6307 interpreter); \
6308 PUSH_UNCHECKED (((result & 127) \
6309 == 64) ? 1 : 0); \
6310 }
6311
6312 #define EVEN() \
6313 { \
6314 sfnt_f26dot6 e1, result; \
6315 uint32_t value; \
6316 \
6317 e1 = POP (); \
6318 result = abs (e1); \
6319 \
6320 result \
6321 = interpreter->state.round (result, \
6322 interpreter); \
6323 value = ((result & 127) == 64) ? 0 : 1; \
6324 PUSH_UNCHECKED (value); \
6325 }
6326
6327 #define IF() \
6328 { \
6329 uint32_t condition; \
6330 \
6331 condition = POP (); \
6332 sfnt_interpret_if (interpreter, condition); \
6333 goto skip_step; \
6334 }
6335
6336 #define EIF() \
6337 { \
6338 \
6339 }
6340
6341 #define AND() \
6342 { \
6343 uint32_t e1, e2; \
6344 \
6345 e1 = POP (); \
6346 e2 = POP (); \
6347 \
6348 PUSH_UNCHECKED (e1 && e2 ? 1 : 0); \
6349 }
6350
6351 #define OR() \
6352 { \
6353 uint32_t e1, e2; \
6354 \
6355 e1 = POP (); \
6356 e2 = POP (); \
6357 \
6358 PUSH_UNCHECKED (e1 || e2 ? 1 : 0); \
6359 }
6360
6361 #define NOT() \
6362 { \
6363 uint32_t e1; \
6364 \
6365 e1 = POP (); \
6366 \
6367 PUSH_UNCHECKED (!e1 ? 1 : 0); \
6368 }
6369
6370 #define SDB() \
6371 { \
6372 uint32_t base; \
6373 \
6374 base = POP (); \
6375 \
6376 interpreter->state.delta_base = base; \
6377 }
6378
6379 #define SDS() \
6380 { \
6381 uint32_t shift; \
6382 \
6383 shift = POP (); \
6384 \
6385 if (shift > 6) \
6386 TRAP ("invalid delta shift"); \
6387 \
6388 interpreter->state.delta_shift = shift; \
6389 }
6390
6391 #define ADD() \
6392 { \
6393 sfnt_f26dot6 n1, n2; \
6394 \
6395 n1 = POP (); \
6396 n2 = POP (); \
6397 \
6398 PUSH_UNCHECKED (sfnt_add (n1, n2)); \
6399 }
6400
6401 #define SUB() \
6402 { \
6403 sfnt_f26dot6 n2, n1; \
6404 \
6405 n2 = POP (); \
6406 n1 = POP (); \
6407 \
6408 PUSH_UNCHECKED (sfnt_sub (n1, n2)); \
6409 }
6410
6411 #define DIV() \
6412 { \
6413 sfnt_f26dot6 n2, n1; \
6414 \
6415 n2 = POP (); \
6416 n1 = POP (); \
6417 \
6418 if (!n2) \
6419 TRAP ("DIV by 0"); \
6420 \
6421 PUSH_UNCHECKED (sfnt_div_f26dot6 (n1, n2)); \
6422 }
6423
6424 #define MUL() \
6425 { \
6426 sfnt_f26dot6 n2, n1; \
6427 \
6428 n2 = POP (); \
6429 n1 = POP (); \
6430 \
6431 PUSH_UNCHECKED (sfnt_mul_f26dot6 (n2, n1)); \
6432 }
6433
6434 #define ABS() \
6435 { \
6436 sfnt_f26dot6 n; \
6437 \
6438 n = POP (); \
6439 \
6440 if (n == INT32_MIN) \
6441 PUSH_UNCHECKED (0) \
6442 else \
6443 PUSH_UNCHECKED (n < 0 ? -n : n) \
6444 }
6445
6446 #define NEG() \
6447 { \
6448 sfnt_f26dot6 n; \
6449 \
6450 n = POP (); \
6451 \
6452 if (n == INT32_MIN) \
6453 PUSH_UNCHECKED (0) \
6454 else \
6455 PUSH_UNCHECKED (-n) \
6456 }
6457
6458 #define FLOOR() \
6459 { \
6460 sfnt_f26dot6 n; \
6461 \
6462 n = POP (); \
6463 PUSH_UNCHECKED (sfnt_floor_f26dot6 (n)); \
6464 }
6465
6466 #define CEILING() \
6467 { \
6468 sfnt_f26dot6 n; \
6469 \
6470 n = POP (); \
6471 PUSH_UNCHECKED (sfnt_ceil_f26dot6 (n)); \
6472 }
6473
6474 #define WCVTF() \
6475 { \
6476 int32_t value; \
6477 uint32_t location; \
6478 \
6479 value = POP (); \
6480 location = POP (); \
6481 \
6482 if (location >= interpreter->cvt_size) \
6483 TRAP ("WCVTF out of bounds"); \
6484 \
6485 interpreter->cvt[location] \
6486 = (interpreter->scale * value \
6487 / 1024); \
6488 }
6489
6490 #define JROT() \
6491 { \
6492 uint32_t e; \
6493 int32_t offset; \
6494 \
6495 e = POP (); \
6496 offset = POP (); \
6497 \
6498 if (!e) \
6499 break; \
6500 \
6501 if (interpreter->IP + offset < 0 \
6502 || (interpreter->IP + offset \
6503 > interpreter->num_instructions)) \
6504 TRAP ("JMPR out of bounds"); \
6505 \
6506 interpreter->IP += offset; \
6507 goto skip_step; \
6508 }
6509
6510 #define JROF() \
6511 { \
6512 uint32_t e; \
6513 int32_t offset; \
6514 \
6515 e = POP (); \
6516 offset = POP (); \
6517 \
6518 if (e) \
6519 break; \
6520 \
6521 if (interpreter->IP + offset < 0 \
6522 || (interpreter->IP + offset \
6523 > interpreter->num_instructions)) \
6524 TRAP ("JMPR out of bounds"); \
6525 \
6526 interpreter->IP += offset; \
6527 goto skip_step; \
6528 }
6529
6530 #define ILLEGAL_INSTRUCTION() \
6531 { \
6532 TRAP ("MS reserved illegal instruction"); \
6533 }
6534
6535 #define SCANCTRL() \
6536 { \
6537 uint32_t value; \
6538 \
6539 value = POP (); \
6540 interpreter->state.scan_control = value; \
6541 }
6542
6543
6544
6545
6546
6547 #define GETINFO() \
6548 { \
6549 uint32_t selector, k; \
6550 \
6551 selector = POP (); \
6552 \
6553 k = 0; \
6554 \
6555 if (selector & 1) \
6556 k |= 02; \
6557 \
6558 if (selector & 8 \
6559 && interpreter->norm_coords) \
6560 k |= 02000; \
6561 \
6562 PUSH_UNCHECKED (k); \
6563 }
6564
6565 #define IDEF() \
6566 { \
6567 if (why == SFNT_RUN_CONTEXT_GLYPH_PROGRAM) \
6568 TRAP ("IDEF inside glyph program"); \
6569 \
6570 sfnt_interpret_idef (interpreter, POP ()); \
6571 goto skip_step; \
6572 }
6573
6574 #define ROLL() \
6575 { \
6576 uint32_t a, b, c; \
6577 \
6578 CHECK_STACK_ELEMENTS (3); \
6579 \
6580 a = POP_UNCHECKED (); \
6581 b = POP_UNCHECKED (); \
6582 c = POP_UNCHECKED (); \
6583 \
6584 PUSH_UNCHECKED (b); \
6585 PUSH_UNCHECKED (a); \
6586 PUSH_UNCHECKED (c); \
6587 }
6588
6589 #define _MAX() \
6590 { \
6591 int32_t e1, e2; \
6592 \
6593 e1 = POP (); \
6594 e2 = POP (); \
6595 \
6596 PUSH_UNCHECKED (MAX (e1, e2)); \
6597 }
6598
6599 #define _MIN() \
6600 { \
6601 int32_t e1, e2; \
6602 \
6603 e1 = POP (); \
6604 e2 = POP (); \
6605 \
6606 PUSH_UNCHECKED (MIN (e1, e2)); \
6607 }
6608
6609 #define SCANTYPE() \
6610 { \
6611 POP (); \
6612 }
6613
6614 #define INSTCTRL() \
6615 { \
6616 uint32_t s, v; \
6617 \
6618 CHECK_PREP (); \
6619 s = POP (); \
6620 v = POP (); \
6621 \
6622 if (!s || s > 2) \
6623 break; \
6624 \
6625 interpreter->state.instruct_control \
6626 &= ~(1 << s); \
6627 \
6628 if (v) \
6629 interpreter->state.instruct_control \
6630 |= (1 << s); \
6631 }
6632
6633
6634
6635
6636 #define GXAXIS() \
6637 { \
6638 uint32_t v; \
6639 int i; \
6640 \
6641 for (i = 0; i < interpreter->n_axis; ++i) \
6642 { \
6643 if (interpreter->norm_coords) \
6644 v = interpreter->norm_coords[i] / 4; \
6645 else \
6646 v = 0; \
6647 \
6648 PUSH (v); \
6649 } \
6650 }
6651
6652 #define PUSHB() \
6653 { \
6654 int b, nbytes, IP; \
6655 unsigned char *ip; \
6656 \
6657 IP = interpreter->IP; \
6658 nbytes = opcode - 0xb0 + 1; \
6659 \
6660 if (IP + nbytes + 1 \
6661 > interpreter->num_instructions) \
6662 TRAP ("args to PUSHB lie outside IS"); \
6663 \
6664 CHECK_STACK_AVAILABLE (nbytes); \
6665 ip = interpreter->instructions; \
6666 for (b = IP + 1; b < IP + nbytes + 1; ++b) \
6667 PUSH_UNCHECKED (ip[b]); \
6668 \
6669 interpreter->IP += nbytes; \
6670 }
6671
6672 #define PUSHW() \
6673 { \
6674 int b, nbytes, IP; \
6675 unsigned char *ip; \
6676 \
6677 IP = interpreter->IP; \
6678 nbytes = (opcode - 0xb8 + 1) * 2; \
6679 \
6680 if (IP + 1 + nbytes \
6681 > interpreter->num_instructions) \
6682 TRAP ("args to PUSHW lie outside IS"); \
6683 \
6684 CHECK_STACK_AVAILABLE (nbytes / 2); \
6685 ip = interpreter->instructions; \
6686 for (b = IP + 1; b < IP + nbytes + 1; \
6687 b += 2) \
6688 PUSH2_UNCHECKED (ip[b], ip[b + 1]); \
6689 \
6690 interpreter->IP += nbytes; \
6691 }
6692
6693
6694
6695
6696
6697 #define ROUND() \
6698 { \
6699 sfnt_f26dot6 n, result; \
6700 \
6701 n = POP (); \
6702 result = abs (n); \
6703 \
6704 result \
6705 = interpreter->state.round (result, \
6706 interpreter); \
6707 PUSH_UNCHECKED (n < 0 ? -result : result); \
6708 }
6709
6710 #define NROUND() \
6711 { \
6712 sfnt_f26dot6 n; \
6713 \
6714 n = POP (); \
6715 PUSH_UNCHECKED (n); \
6716 }
6717
6718 #define ROFF() \
6719 { \
6720 interpreter->state.round_state = 5; \
6721 sfnt_validate_gs (&interpreter->state); \
6722 }
6723
6724 #define RUTG() \
6725 { \
6726 interpreter->state.round_state = 4; \
6727 sfnt_validate_gs (&interpreter->state); \
6728 }
6729
6730 #define RDTG() \
6731 { \
6732 interpreter->state.round_state = 3; \
6733 sfnt_validate_gs (&interpreter->state); \
6734 }
6735
6736 #define RTG() \
6737 { \
6738 interpreter->state.round_state = 1; \
6739 sfnt_validate_gs (&interpreter->state); \
6740 }
6741
6742 #define RTHG() \
6743 { \
6744 interpreter->state.round_state = 0; \
6745 sfnt_validate_gs (&interpreter->state); \
6746 }
6747
6748 #define RTDG() \
6749 { \
6750 interpreter->state.round_state = 2; \
6751 sfnt_validate_gs (&interpreter->state); \
6752 }
6753
6754 #define SROUND() \
6755 { \
6756 uint32_t operand; \
6757 \
6758 operand = POP (); \
6759 sfnt_set_srounding_state (interpreter, \
6760 operand, \
6761 0x4000); \
6762 interpreter->state.round_state = 6; \
6763 sfnt_validate_gs (&interpreter->state); \
6764 }
6765
6766 #define S45ROUND() \
6767 { \
6768 uint32_t operand; \
6769 \
6770 operand = POP (); \
6771 sfnt_set_srounding_state (interpreter, \
6772 operand, \
6773 0x5a82); \
6774 interpreter->state.round_state = 7; \
6775 sfnt_validate_gs (&interpreter->state); \
6776 }
6777
6778
6779
6780
6781
6782
6783
6784
6785 #define DELTAC1() \
6786 { \
6787 uint32_t operand1, operand2, n; \
6788 \
6789 n = POP (); \
6790 \
6791 deltac1_start: \
6792 if (!n) \
6793 break; \
6794 \
6795 operand1 = POP (); \
6796 operand2 = POP (); \
6797 sfnt_deltac (1, interpreter, operand1, \
6798 operand2); \
6799 n--; \
6800 goto deltac1_start; \
6801 }
6802
6803 #define DELTAC2() \
6804 { \
6805 uint32_t operand1, operand2, n; \
6806 \
6807 n = POP (); \
6808 \
6809 deltac2_start: \
6810 if (!n) \
6811 break; \
6812 \
6813 operand1 = POP (); \
6814 operand2 = POP (); \
6815 sfnt_deltac (2, interpreter, operand1, \
6816 operand2); \
6817 n--; \
6818 goto deltac2_start; \
6819 }
6820
6821 #define DELTAC3() \
6822 { \
6823 uint32_t operand1, operand2, n; \
6824 \
6825 n = POP (); \
6826 \
6827 deltac3_start: \
6828 if (!n) \
6829 break; \
6830 \
6831 operand1 = POP (); \
6832 operand2 = POP (); \
6833 sfnt_deltac (3, interpreter, operand1, \
6834 operand2); \
6835 n--; \
6836 goto deltac3_start; \
6837 }
6838
6839 #define DELTAP1() \
6840 { \
6841 uint32_t n, argn, pn; \
6842 \
6843 n = POP (); \
6844 \
6845 deltap1_start: \
6846 if (!n) \
6847 break; \
6848 \
6849 pn = POP (); \
6850 argn = POP (); \
6851 sfnt_deltap (1, interpreter, argn, pn); \
6852 n--; \
6853 goto deltap1_start; \
6854 }
6855
6856 #define DELTAP2() \
6857 { \
6858 uint32_t n, argn, pn; \
6859 \
6860 n = POP (); \
6861 \
6862 deltap2_start: \
6863 if (!n) \
6864 break; \
6865 \
6866 pn = POP (); \
6867 argn = POP (); \
6868 sfnt_deltap (2, interpreter, argn, pn); \
6869 n--; \
6870 goto deltap2_start; \
6871 }
6872
6873 #define DELTAP3() \
6874 { \
6875 uint32_t n, argn, pn; \
6876 \
6877 n = POP (); \
6878 \
6879 deltap3_start: \
6880 if (!n) \
6881 break; \
6882 \
6883 pn = POP (); \
6884 argn = POP (); \
6885 sfnt_deltap (3, interpreter, argn, pn); \
6886 n--; \
6887 goto deltap3_start; \
6888 }
6889
6890
6891
6892
6893
6894 #define AA() \
6895 { \
6896 POP (); \
6897 }
6898
6899 #define SANGW() \
6900 { \
6901 POP (); \
6902 }
6903
6904
6905
6906
6907
6908 #define PROJECT(x, y) \
6909 sfnt_project_vector (interpreter, x, y)
6910
6911 #define DUAL_PROJECT(x, y) \
6912 sfnt_dual_project_vector (interpreter, x, y)
6913
6914 #define SVTCAy() \
6915 { \
6916 sfnt_set_freedom_vector (interpreter, \
6917 0, 040000); \
6918 sfnt_set_projection_vector (interpreter, \
6919 0, 040000); \
6920 }
6921
6922 #define SVTCAx() \
6923 { \
6924 sfnt_set_freedom_vector (interpreter, \
6925 040000, 0); \
6926 sfnt_set_projection_vector (interpreter, \
6927 040000, 0); \
6928 }
6929
6930 #define SPvTCAy() \
6931 { \
6932 sfnt_set_projection_vector (interpreter, \
6933 0, 040000); \
6934 }
6935
6936 #define SPvTCAx() \
6937 { \
6938 sfnt_set_projection_vector (interpreter, \
6939 040000, 0); \
6940 }
6941
6942 #define SFvTCAy() \
6943 { \
6944 sfnt_set_freedom_vector (interpreter, \
6945 0, 040000); \
6946 }
6947
6948 #define SFvTCAx() \
6949 { \
6950 sfnt_set_freedom_vector (interpreter, \
6951 040000, 0); \
6952 }
6953
6954 #define SPVTL() \
6955 { \
6956 struct sfnt_unit_vector vector; \
6957 uint32_t p2, p1; \
6958 \
6959 p2 = POP (); \
6960 p1 = POP (); \
6961 \
6962 sfnt_line_to_vector (interpreter, \
6963 p2, p1, &vector, \
6964 opcode == 0x07, \
6965 false); \
6966 \
6967 sfnt_save_projection_vector (interpreter, \
6968 &vector, \
6969 false); \
6970 }
6971
6972 #define SFVTL() \
6973 { \
6974 struct sfnt_unit_vector vector; \
6975 uint32_t p2, p1; \
6976 \
6977 p2 = POP (); \
6978 p1 = POP (); \
6979 \
6980 sfnt_line_to_vector (interpreter, \
6981 p2, p1, &vector, \
6982 opcode == 0x09, \
6983 false); \
6984 \
6985 sfnt_save_freedom_vector (interpreter, \
6986 &vector); \
6987 }
6988
6989 #define SPVFS() \
6990 { \
6991 uint32_t y, x; \
6992 \
6993 y = POP (); \
6994 x = POP (); \
6995 \
6996 sfnt_set_projection_vector (interpreter, x, \
6997 y); \
6998 }
6999
7000 #define SFVFS() \
7001 { \
7002 uint16_t y, x; \
7003 \
7004 y = POP (); \
7005 x = POP (); \
7006 \
7007 sfnt_set_freedom_vector (interpreter, x, \
7008 y); \
7009 }
7010
7011 #define GPV() \
7012 { \
7013 struct sfnt_unit_vector vector; \
7014 \
7015 vector \
7016 = interpreter->state.projection_vector; \
7017 \
7018 PUSH ((uint16_t) vector.x); \
7019 PUSH ((uint16_t) vector.y); \
7020 }
7021
7022 #define GFV() \
7023 { \
7024 struct sfnt_unit_vector vector; \
7025 \
7026 vector \
7027 = interpreter->state.freedom_vector; \
7028 \
7029 PUSH ((uint16_t) vector.x); \
7030 PUSH ((uint16_t) vector.y); \
7031 }
7032
7033 #define SFVTPV() \
7034 { \
7035 interpreter->state.freedom_vector \
7036 = interpreter->state.projection_vector; \
7037 \
7038 sfnt_validate_gs (&interpreter->state); \
7039 }
7040
7041 #define ISECT() \
7042 { \
7043 uint32_t a0, a1, b0, b1, p; \
7044 \
7045 CHECK_STACK_ELEMENTS (5); \
7046 \
7047 a0 = POP_UNCHECKED (); \
7048 a1 = POP_UNCHECKED (); \
7049 b0 = POP_UNCHECKED (); \
7050 b1 = POP_UNCHECKED (); \
7051 p = POP_UNCHECKED (); \
7052 \
7053 sfnt_interpret_isect (interpreter, \
7054 a0, a1, b0, b1, p); \
7055 }
7056
7057 #define ALIGNPTS() \
7058 { \
7059 uint32_t p1, p2; \
7060 \
7061 p1 = POP (); \
7062 p2 = POP (); \
7063 \
7064 sfnt_interpret_alignpts (interpreter, p1, \
7065 p2); \
7066 }
7067
7068 #define UTP() \
7069 { \
7070 uint32_t p; \
7071 \
7072 p = POP (); \
7073 sfnt_interpret_utp (interpreter, p); \
7074 }
7075
7076 #define MDAP() \
7077 { \
7078 uint32_t p; \
7079 \
7080 p = POP (); \
7081 sfnt_interpret_mdap (interpreter, p, \
7082 opcode); \
7083 }
7084
7085 #define IUP() \
7086 { \
7087 sfnt_interpret_iup (interpreter, opcode); \
7088 }
7089
7090 #define SHP() \
7091 { \
7092 sfnt_interpret_shp (interpreter, opcode); \
7093 }
7094
7095 #define SHC() \
7096 { \
7097 uint32_t contour; \
7098 \
7099 contour = POP (); \
7100 \
7101 sfnt_interpret_shc (interpreter, contour, \
7102 opcode); \
7103 }
7104
7105 #define SHZ() \
7106 { \
7107 uint32_t e; \
7108 \
7109 e = POP (); \
7110 \
7111 if (e > 1) \
7112 TRAP ("invalid zone!"); \
7113 \
7114 sfnt_interpret_shz (interpreter, e, \
7115 opcode); \
7116 }
7117
7118 #define SHPIX() \
7119 { \
7120 sfnt_f26dot6 pixels, dx, dy; \
7121 uint32_t p; \
7122 \
7123 pixels = POP (); \
7124 sfnt_scale_by_freedom_vector (interpreter, \
7125 pixels, &dx, \
7126 &dy); \
7127 \
7128 while (interpreter->state.loop--) \
7129 { \
7130 p = POP (); \
7131 sfnt_direct_move_zp2 (interpreter, \
7132 p, dx, dy); \
7133 } \
7134 \
7135 interpreter->state.loop = 1; \
7136 }
7137
7138 #define IP() \
7139 { \
7140 sfnt_interpret_ip (interpreter); \
7141 }
7142
7143 #define MSIRP() \
7144 { \
7145 sfnt_f26dot6 d; \
7146 uint32_t p; \
7147 \
7148 d = POP (); \
7149 p = POP (); \
7150 \
7151 sfnt_interpret_msirp (interpreter, d, p, \
7152 opcode); \
7153 }
7154
7155 #define ALIGNRP() \
7156 { \
7157 sfnt_interpret_alignrp (interpreter); \
7158 }
7159
7160 #define MIAP() \
7161 { \
7162 uint32_t cvt; \
7163 uint32_t p; \
7164 \
7165 cvt = POP (); \
7166 p = POP (); \
7167 \
7168 sfnt_interpret_miap (interpreter, cvt, p, \
7169 opcode); \
7170 }
7171
7172 #define GC() \
7173 { \
7174 uint32_t p; \
7175 sfnt_f26dot6 x, y, value; \
7176 sfnt_f26dot6 org_x, org_y; \
7177 \
7178 p = POP (); \
7179 \
7180 sfnt_address_zp2 (interpreter, p, &x, &y, \
7181 &org_x, &org_y); \
7182 \
7183 if (opcode == 0x47) \
7184 value = DUAL_PROJECT (org_x, org_y); \
7185 else \
7186 value = PROJECT (x, y); \
7187 \
7188 PUSH_UNCHECKED (value); \
7189 }
7190
7191 #define SCFS() \
7192 { \
7193 uint32_t p; \
7194 sfnt_f26dot6 c; \
7195 \
7196 c = POP (); \
7197 p = POP (); \
7198 \
7199 sfnt_interpret_scfs (interpreter, p, c); \
7200 }
7201
7202 #define MD() \
7203 { \
7204 uint32_t p1, p2; \
7205 sfnt_f26dot6 distance; \
7206 \
7207 p2 = POP (); \
7208 p1 = POP (); \
7209 \
7210 distance \
7211 = sfnt_measure_distance (interpreter, \
7212 p1, p2, \
7213 opcode); \
7214 PUSH_UNCHECKED (distance); \
7215 }
7216
7217 #define FLIPPT() \
7218 { \
7219 sfnt_interpret_flippt (interpreter); \
7220 }
7221
7222 #define FLIPRGOFF() \
7223 { \
7224 uint32_t h, l; \
7225 \
7226 h = POP (); \
7227 l = POP (); \
7228 \
7229 sfnt_interpret_fliprgoff (interpreter, \
7230 h, l); \
7231 }
7232
7233 #define FLIPRGON() \
7234 { \
7235 uint32_t h, l; \
7236 \
7237 h = POP (); \
7238 l = POP (); \
7239 \
7240 sfnt_interpret_fliprgon (interpreter, \
7241 h, l); \
7242 }
7243
7244 #define SDPVTL() \
7245 { \
7246 struct sfnt_unit_vector vector; \
7247 uint32_t p2, p1; \
7248 \
7249 p2 = POP (); \
7250 p1 = POP (); \
7251 \
7252 sfnt_line_to_vector (interpreter, \
7253 p2, p1, &vector, \
7254 opcode == 0x87, \
7255 false); \
7256 \
7257 sfnt_save_projection_vector (interpreter, \
7258 &vector, \
7259 false); \
7260 \
7261 sfnt_line_to_vector (interpreter, \
7262 p2, p1, &vector, \
7263 opcode == 0x87, \
7264 true); \
7265 \
7266 sfnt_save_projection_vector (interpreter, \
7267 &vector, \
7268 true); \
7269 }
7270
7271 #define MIRP() \
7272 { \
7273 sfnt_interpret_mirp (interpreter, opcode); \
7274 }
7275
7276 #define MDRP() \
7277 { \
7278 sfnt_interpret_mdrp (interpreter, opcode); \
7279 }
7280
7281
7282
7283 #define NOT_IMPLEMENTED() \
7284 sfnt_interpret_unimplemented (interpreter, \
7285 opcode, why)
7286
7287
7288
7289
7290
7291
7292 static void
7293 sfnt_scale_by_freedom_vector (struct sfnt_interpreter *interpreter,
7294 sfnt_f26dot6 magnitude, sfnt_f26dot6 *dx,
7295 sfnt_f26dot6 *dy)
7296 {
7297 struct sfnt_unit_vector *vector;
7298
7299 vector = &interpreter->state.freedom_vector;
7300 *dx = sfnt_mul_f2dot14 (vector->x, magnitude);
7301 *dy = sfnt_mul_f2dot14 (vector->y, magnitude);
7302 }
7303
7304
7305
7306
7307
7308
7309
7310 static void
7311 sfnt_interpret_utp (struct sfnt_interpreter *interpreter,
7312 uint32_t p)
7313 {
7314 if (!interpreter->state.zp0)
7315 {
7316 if (p >= interpreter->twilight_zone_size)
7317 TRAP ("UTP[] p lies outside twilight zone");
7318
7319
7320 return;
7321 }
7322
7323 if (!interpreter->glyph_zone
7324 || p >= interpreter->glyph_zone->num_points)
7325 TRAP ("UTP[] p lies outside glyph zone");
7326
7327 interpreter->glyph_zone->flags[p] &= ~SFNT_POINT_TOUCHED_X;
7328 }
7329
7330
7331
7332
7333
7334
7335
7336
7337 static void
7338 sfnt_save_projection_vector (struct sfnt_interpreter *interpreter,
7339 struct sfnt_unit_vector *vector,
7340 bool dual_only)
7341 {
7342 if (!dual_only)
7343 interpreter->state.projection_vector = *vector;
7344
7345 interpreter->state.dual_projection_vector = *vector;
7346
7347 sfnt_validate_gs (&interpreter->state);
7348 }
7349
7350
7351
7352
7353 static void
7354 sfnt_save_freedom_vector (struct sfnt_interpreter *interpreter,
7355 struct sfnt_unit_vector *vector)
7356 {
7357 interpreter->state.freedom_vector = *vector;
7358
7359 sfnt_validate_gs (&interpreter->state);
7360 }
7361
7362
7363
7364
7365
7366
7367
7368
7369
7370 static void
7371 sfnt_address_zp2 (struct sfnt_interpreter *interpreter,
7372 uint32_t number,
7373 sfnt_f26dot6 *x, sfnt_f26dot6 *y,
7374 sfnt_f26dot6 *x_org, sfnt_f26dot6 *y_org)
7375 {
7376 if (!interpreter->state.zp2)
7377 {
7378
7379 if (number >= interpreter->twilight_zone_size)
7380 TRAP ("address to ZP2 (twilight zone) out of bounds");
7381
7382 *x = interpreter->twilight_x[number];
7383 *y = interpreter->twilight_y[number];
7384
7385 if (!x_org || !y_org)
7386 return;
7387
7388
7389
7390 *x_org = interpreter->twilight_original_x[number];
7391 *y_org = interpreter->twilight_original_y[number];
7392 return;
7393 }
7394
7395
7396 if (!interpreter->glyph_zone)
7397 TRAP ("address to ZP2 (glyph zone) points into unset"
7398 " zone");
7399
7400 if (number >= interpreter->glyph_zone->num_points)
7401 TRAP ("address to ZP2 (glyph zone) out of bounds");
7402
7403 *x = interpreter->glyph_zone->x_current[number];
7404 *y = interpreter->glyph_zone->y_current[number];
7405
7406 if (x_org && y_org)
7407 {
7408 *x_org = interpreter->glyph_zone->x_points[number];
7409 *y_org = interpreter->glyph_zone->y_points[number];
7410 }
7411 }
7412
7413
7414
7415
7416
7417
7418 static void
7419 sfnt_address_zp1 (struct sfnt_interpreter *interpreter,
7420 uint32_t number,
7421 sfnt_f26dot6 *x, sfnt_f26dot6 *y,
7422 sfnt_f26dot6 *x_org, sfnt_f26dot6 *y_org)
7423 {
7424 if (!interpreter->state.zp1)
7425 {
7426
7427 if (number >= interpreter->twilight_zone_size)
7428 TRAP ("address to ZP1 (twilight zone) out of bounds");
7429
7430 *x = interpreter->twilight_x[number];
7431 *y = interpreter->twilight_y[number];
7432
7433 if (!x_org || !y_org)
7434 return;
7435
7436
7437
7438 *x_org = interpreter->twilight_original_x[number];
7439 *y_org = interpreter->twilight_original_y[number];
7440 return;
7441 }
7442
7443
7444 if (!interpreter->glyph_zone)
7445 TRAP ("address to ZP1 (glyph zone) points into unset"
7446 " zone");
7447
7448 if (number >= interpreter->glyph_zone->num_points)
7449 TRAP ("address to ZP1 (glyph zone) out of bounds");
7450
7451 *x = interpreter->glyph_zone->x_current[number];
7452 *y = interpreter->glyph_zone->y_current[number];
7453
7454 if (x_org && y_org)
7455 {
7456 *x_org = interpreter->glyph_zone->x_points[number];
7457 *y_org = interpreter->glyph_zone->y_points[number];
7458 }
7459 }
7460
7461
7462
7463
7464
7465
7466 static void
7467 sfnt_address_zp0 (struct sfnt_interpreter *interpreter,
7468 uint32_t number,
7469 sfnt_f26dot6 *x, sfnt_f26dot6 *y,
7470 sfnt_f26dot6 *x_org, sfnt_f26dot6 *y_org)
7471 {
7472 if (!interpreter->state.zp0)
7473 {
7474
7475 if (number >= interpreter->twilight_zone_size)
7476 TRAP ("address to ZP0 (twilight zone) out of bounds");
7477
7478 *x = interpreter->twilight_x[number];
7479 *y = interpreter->twilight_y[number];
7480
7481 if (!x_org || !y_org)
7482 return;
7483
7484
7485
7486 *x_org = interpreter->twilight_original_x[number];
7487 *y_org = interpreter->twilight_original_y[number];
7488 return;
7489 }
7490
7491
7492 if (!interpreter->glyph_zone)
7493 TRAP ("address to ZP0 (glyph zone) points into unset"
7494 " zone");
7495
7496 if (number >= interpreter->glyph_zone->num_points)
7497 TRAP ("address to ZP0 (glyph zone) out of bounds");
7498
7499 *x = interpreter->glyph_zone->x_current[number];
7500 *y = interpreter->glyph_zone->y_current[number];
7501
7502 if (x_org && y_org)
7503 {
7504 *x_org = interpreter->glyph_zone->x_points[number];
7505 *y_org = interpreter->glyph_zone->y_points[number];
7506 }
7507 }
7508
7509
7510
7511
7512
7513
7514
7515 static void
7516 sfnt_store_zp2 (struct sfnt_interpreter *interpreter,
7517 uint32_t number, sfnt_f26dot6 x, sfnt_f26dot6 y,
7518 int flags)
7519 {
7520 if (!interpreter->state.zp2)
7521 {
7522
7523 if (number >= interpreter->twilight_zone_size)
7524 TRAP ("address to ZP2 (twilight zone) out of bounds");
7525
7526 interpreter->twilight_x[number] = x;
7527 interpreter->twilight_y[number] = y;
7528 return;
7529 }
7530
7531
7532 if (!interpreter->glyph_zone)
7533 TRAP ("address to ZP0 (glyph zone) points into unset"
7534 " zone");
7535
7536 if (number >= interpreter->glyph_zone->num_points)
7537 TRAP ("address to ZP0 (glyph zone) out of bounds");
7538
7539 interpreter->glyph_zone->x_current[number] = x;
7540 interpreter->glyph_zone->y_current[number] = y;
7541 interpreter->glyph_zone->flags[number] |= flags;
7542 }
7543
7544 #if 0
7545
7546
7547
7548
7549
7550
7551
7552 static void
7553 sfnt_line_to_standard_form (sfnt_f26dot6 x1, sfnt_f26dot6 y1,
7554 sfnt_f26dot6 x2, sfnt_f26dot6 y2,
7555 sfnt_f26dot6 *a, sfnt_f26dot6 *b,
7556 sfnt_f26dot6 *c)
7557 {
7558 sfnt_f26dot6 a_temp, b_temp, c_temp;
7559
7560 a_temp = sfnt_sub (y2, y1);
7561 b_temp = sfnt_sub (x1, x2);
7562 c_temp = sfnt_sub (sfnt_mul_f26dot6 (x1, y2),
7563 sfnt_mul_f26dot6 (x2, y1));
7564
7565 *a = a_temp;
7566 *b = b_temp;
7567 *c = c_temp;
7568 }
7569
7570 #endif
7571
7572
7573
7574
7575 static void
7576 sfnt_check_zp2 (struct sfnt_interpreter *interpreter, uint32_t point)
7577 {
7578 if (!interpreter->state.zp2)
7579 {
7580 if (point >= interpreter->twilight_zone_size)
7581 TRAP ("point lies outside twilight zone (ZP2)");
7582 }
7583 else if (!interpreter->glyph_zone
7584 || point >= interpreter->glyph_zone->num_points)
7585 TRAP ("point lies outside glyph zone (ZP2)");
7586 }
7587
7588
7589
7590
7591 static void
7592 sfnt_check_zp0 (struct sfnt_interpreter *interpreter, uint32_t point)
7593 {
7594 if (!interpreter->state.zp0)
7595 {
7596 if (point >= interpreter->twilight_zone_size)
7597 TRAP ("point lies outside twilight zone (ZP0)");
7598 }
7599 else if (!interpreter->glyph_zone
7600 || point >= interpreter->glyph_zone->num_points)
7601 TRAP ("point lies outside glyph zone (ZP0)");
7602 }
7603
7604
7605
7606
7607 static void
7608 sfnt_check_zp1 (struct sfnt_interpreter *interpreter, uint32_t point)
7609 {
7610 if (!interpreter->state.zp1)
7611 {
7612 if (point >= interpreter->twilight_zone_size)
7613 TRAP ("point lies outside twilight zone (ZP0)");
7614 }
7615 else if (!interpreter->glyph_zone
7616 || point >= interpreter->glyph_zone->num_points)
7617 TRAP ("point lies outside glyph zone (ZP0)");
7618 }
7619
7620
7621
7622
7623
7624
7625
7626
7627 static void
7628 sfnt_move_zp0 (struct sfnt_interpreter *interpreter, uint32_t point,
7629 size_t n, sfnt_f26dot6 distance)
7630 {
7631 if (!interpreter->state.zp0)
7632 interpreter->state.move (&interpreter->twilight_x[point],
7633 &interpreter->twilight_y[point],
7634 n, interpreter, distance, NULL);
7635 else
7636 interpreter->state.move (&interpreter->glyph_zone->x_current[point],
7637 &interpreter->glyph_zone->y_current[point],
7638 n, interpreter, distance,
7639 &interpreter->glyph_zone->flags[point]);
7640 }
7641
7642
7643
7644
7645
7646
7647
7648
7649 static void
7650 sfnt_move_zp1 (struct sfnt_interpreter *interpreter, uint32_t point,
7651 size_t n, sfnt_f26dot6 distance)
7652 {
7653 if (!interpreter->state.zp1)
7654 interpreter->state.move (&interpreter->twilight_x[point],
7655 &interpreter->twilight_y[point],
7656 n, interpreter, distance, NULL);
7657 else
7658 interpreter->state.move (&interpreter->glyph_zone->x_current[point],
7659 &interpreter->glyph_zone->y_current[point],
7660 n, interpreter, distance,
7661 &interpreter->glyph_zone->flags[point]);
7662 }
7663
7664
7665
7666
7667
7668
7669
7670
7671 static void
7672 sfnt_move_zp2 (struct sfnt_interpreter *interpreter, uint32_t point,
7673 size_t n, sfnt_f26dot6 distance)
7674 {
7675 if (!interpreter->state.zp2)
7676 interpreter->state.move (&interpreter->twilight_x[point],
7677 &interpreter->twilight_y[point],
7678 n, interpreter, distance, NULL);
7679 else
7680 interpreter->state.move (&interpreter->glyph_zone->x_current[point],
7681 &interpreter->glyph_zone->y_current[point],
7682 n, interpreter, distance,
7683 &interpreter->glyph_zone->flags[point]);
7684 }
7685
7686
7687
7688
7689
7690
7691
7692
7693
7694 static void
7695 sfnt_move_glyph_zone (struct sfnt_interpreter *interpreter, uint32_t point,
7696 size_t n, sfnt_f26dot6 distance)
7697 {
7698 interpreter->state.move (&interpreter->glyph_zone->x_current[point],
7699 &interpreter->glyph_zone->y_current[point],
7700 n, interpreter, distance, NULL);
7701 }
7702
7703
7704
7705
7706
7707
7708
7709
7710
7711 static void
7712 sfnt_move_twilight_zone (struct sfnt_interpreter *interpreter, uint32_t point,
7713 size_t n, sfnt_f26dot6 distance)
7714 {
7715 interpreter->state.move (&interpreter->twilight_x[point],
7716 &interpreter->twilight_y[point],
7717 n, interpreter, distance, NULL);
7718 }
7719
7720
7721
7722
7723
7724
7725
7726
7727
7728
7729 static void
7730 sfnt_direct_move_zp2 (struct sfnt_interpreter *interpreter, uint32_t p,
7731 sfnt_f26dot6 dx, sfnt_f26dot6 dy)
7732 {
7733 if (!interpreter->state.zp2)
7734 {
7735 if (p >= interpreter->twilight_zone_size)
7736 TRAP ("point out of bounds");
7737
7738 interpreter->twilight_x[p]
7739 = sfnt_add (interpreter->twilight_x[p], dx);
7740 interpreter->twilight_y[p]
7741 = sfnt_add (interpreter->twilight_y[p], dy);
7742 }
7743 else
7744 {
7745 if (!interpreter->glyph_zone
7746 || p >= interpreter->glyph_zone->num_points)
7747 TRAP ("point out of bounds");
7748
7749 interpreter->glyph_zone->x_current[p]
7750 = sfnt_add (interpreter->glyph_zone->x_current[p], dx);
7751 interpreter->glyph_zone->y_current[p]
7752 = sfnt_add (interpreter->glyph_zone->y_current[p], dy);
7753
7754 if (dx)
7755 interpreter->glyph_zone->flags[p] |= SFNT_POINT_TOUCHED_X;
7756
7757 if (dy)
7758 interpreter->glyph_zone->flags[p] |= SFNT_POINT_TOUCHED_Y;
7759 }
7760 }
7761
7762
7763
7764
7765 static sfnt_f26dot6
7766 sfnt_project_vector (struct sfnt_interpreter *interpreter,
7767 sfnt_f26dot6 vx, sfnt_f26dot6 vy)
7768 {
7769 return interpreter->state.project (vx, vy, interpreter);
7770 }
7771
7772
7773
7774
7775 static sfnt_f26dot6
7776 sfnt_dual_project_vector (struct sfnt_interpreter *interpreter,
7777 sfnt_f26dot6 vx, sfnt_f26dot6 vy)
7778 {
7779 return interpreter->state.dual_project (vx, vy, interpreter);
7780 }
7781
7782
7783
7784
7785 static void
7786 sfnt_interpret_fliprgoff (struct sfnt_interpreter *interpreter,
7787 uint32_t l, uint32_t h)
7788 {
7789 uint32_t i;
7790
7791 sfnt_check_zp0 (interpreter, l);
7792 sfnt_check_zp0 (interpreter, h);
7793
7794 if (!interpreter->state.zp0)
7795 return;
7796
7797 for (i = l; i < h; ++i)
7798 interpreter->glyph_zone->flags[i] &= ~01;
7799 }
7800
7801
7802
7803
7804 static void
7805 sfnt_interpret_fliprgon (struct sfnt_interpreter *interpreter,
7806 uint32_t l, uint32_t h)
7807 {
7808 uint32_t i;
7809
7810 sfnt_check_zp0 (interpreter, l);
7811 sfnt_check_zp0 (interpreter, h);
7812
7813 if (!interpreter->state.zp0)
7814 return;
7815
7816 for (i = l; i < h; ++i)
7817 interpreter->glyph_zone->flags[i] |= ~01;
7818 }
7819
7820
7821
7822
7823
7824 static void
7825 sfnt_interpret_flippt (struct sfnt_interpreter *interpreter)
7826 {
7827 uint32_t point;
7828
7829 while (interpreter->state.loop--)
7830 {
7831 point = POP ();
7832
7833
7834
7835
7836 sfnt_check_zp0 (interpreter, point);
7837
7838 if (!interpreter->state.zp0)
7839 continue;
7840
7841
7842
7843
7844 if (interpreter->glyph_zone->flags[point] & 01)
7845 interpreter->glyph_zone->flags[point] &= ~01;
7846 else
7847 interpreter->glyph_zone->flags[point] |= 01;
7848 }
7849
7850
7851 interpreter->state.loop = 1;
7852 }
7853
7854
7855
7856
7857
7858
7859
7860
7861 static void
7862 sfnt_interpret_scfs (struct sfnt_interpreter *interpreter,
7863 uint32_t p, sfnt_f26dot6 c)
7864 {
7865 sfnt_f26dot6 x, y, distance;
7866
7867 sfnt_address_zp2 (interpreter, p, &x, &y, NULL, NULL);
7868 distance = PROJECT (x, y);
7869 sfnt_move_zp2 (interpreter, p, 1, sfnt_sub (c, distance));
7870
7871 if (!interpreter->state.zp2)
7872 {
7873 interpreter->twilight_original_x[p] = interpreter->twilight_x[p];
7874 interpreter->twilight_original_y[p] = interpreter->twilight_y[p];
7875 }
7876 }
7877
7878
7879
7880
7881 static sfnt_f26dot6
7882 sfnt_round_symmetric (struct sfnt_interpreter *interpreter, sfnt_f26dot6 x)
7883 {
7884 int sign;
7885
7886 sign = 1;
7887
7888 if (x < 0)
7889 {
7890 sign = -1;
7891 x = -x;
7892 }
7893
7894 return interpreter->state.round (x, interpreter) * sign;
7895 }
7896
7897
7898
7899
7900
7901
7902
7903
7904
7905
7906
7907
7908
7909
7910
7911
7912 static void
7913 sfnt_interpret_miap (struct sfnt_interpreter *interpreter,
7914 uint32_t cvt, uint32_t p, unsigned char opcode)
7915 {
7916 sfnt_f26dot6 x, y, distance, value, delta;
7917
7918
7919
7920 if (cvt >= interpreter->cvt_size)
7921 TRAP ("out of bounds read to cvt");
7922
7923 value = interpreter->cvt[cvt];
7924
7925
7926 sfnt_address_zp0 (interpreter, p, &x, &y, NULL, NULL);
7927
7928
7929
7930
7931 if (!interpreter->state.zp0)
7932 {
7933 x = interpreter->twilight_x[p]
7934 = interpreter->twilight_original_x[p]
7935 = sfnt_mul_f2dot14 (interpreter->state.projection_vector.x,
7936 value);
7937
7938 y = interpreter->twilight_y[p]
7939 = interpreter->twilight_original_y[p]
7940 = sfnt_mul_f2dot14 (interpreter->state.projection_vector.y,
7941 value);
7942 }
7943
7944
7945 distance = sfnt_project_vector (interpreter, x, y);
7946
7947
7948
7949 if (opcode == 0x3f)
7950 {
7951 delta = sfnt_sub (value, distance);
7952
7953 if (delta < 0)
7954 delta = -delta;
7955
7956
7957
7958
7959 if (delta > interpreter->state.cvt_cut_in)
7960 value = distance;
7961
7962
7963 value = sfnt_round_symmetric (interpreter, value);
7964 }
7965
7966
7967 sfnt_move_zp0 (interpreter, p, 1, sfnt_sub (value, distance));
7968
7969
7970 interpreter->state.rp0 = p;
7971 interpreter->state.rp1 = p;
7972 }
7973
7974
7975
7976
7977 static void
7978 sfnt_interpret_alignrp_1 (struct sfnt_interpreter *interpreter,
7979 sfnt_f26dot6 rp0x, sfnt_f26dot6 rp0y)
7980 {
7981 sfnt_f26dot6 distance, x, y;
7982 uint32_t point;
7983
7984 point = POP ();
7985
7986
7987 sfnt_address_zp1 (interpreter, point, &x, &y, NULL, NULL);
7988
7989
7990 distance = sfnt_project_vector (interpreter, sfnt_sub (x, rp0x),
7991 sfnt_sub (y, rp0y));
7992
7993
7994 sfnt_move_zp1 (interpreter, point, 1, -distance);
7995 }
7996
7997
7998
7999
8000
8001 static void
8002 sfnt_interpret_alignrp (struct sfnt_interpreter *interpreter)
8003 {
8004 sfnt_f26dot6 rp0x, rp0y;
8005
8006 sfnt_address_zp0 (interpreter, interpreter->state.rp0,
8007 &rp0x, &rp0y, NULL, NULL);
8008
8009 while (interpreter->state.loop--)
8010 {
8011 sfnt_interpret_alignrp_1 (interpreter, rp0x, rp0y);
8012
8013
8014 if (interpreter->state.zp0 == interpreter->state.zp1)
8015 sfnt_address_zp0 (interpreter, interpreter->state.rp0,
8016 &rp0x, &rp0y, NULL, NULL);
8017 }
8018
8019 interpreter->state.loop = 1;
8020 }
8021
8022
8023
8024
8025
8026
8027
8028
8029
8030 static void
8031 sfnt_interpret_alignpts (struct sfnt_interpreter *interpreter,
8032 uint32_t p1, uint32_t p2)
8033 {
8034 sfnt_f26dot6 p1x, p1y, p2x, p2y;
8035 sfnt_f26dot6 magnitude;
8036
8037 sfnt_address_zp0 (interpreter, p1, &p1x, &p1y, NULL, NULL);
8038 sfnt_address_zp1 (interpreter, p2, &p2x, &p2y, NULL, NULL);
8039
8040 magnitude = sfnt_project_vector (interpreter,
8041 sfnt_sub (p1x, p2x),
8042 sfnt_sub (p1y, p2y));
8043 magnitude = magnitude / 2;
8044
8045
8046 sfnt_move_zp0 (interpreter, p1, 1, magnitude);
8047 sfnt_move_zp1 (interpreter, p2, 1, -magnitude);
8048 }
8049
8050
8051
8052
8053
8054
8055
8056
8057 static void
8058 sfnt_interpret_isect (struct sfnt_interpreter *interpreter,
8059 uint32_t point_a0, uint32_t point_a1,
8060 uint32_t point_b0, uint32_t point_b1,
8061 uint32_t p)
8062 {
8063 sfnt_f26dot6 a0x, a0y, a1x, a1y;
8064 sfnt_f26dot6 b0x, b0y, b1x, b1y;
8065 #if 0
8066 sfnt_f26dot6 determinant, dx, dy;
8067 sfnt_f26dot6 a0, b0, a1, b1;
8068 sfnt_f26dot6 c0, c1, px, py;
8069 #else
8070 sfnt_f26dot6 dx, dy, dax, day, dbx, dby;
8071 sfnt_f26dot6 discriminant, val, dot_product;
8072 sfnt_f26dot6 px, py;
8073 #endif
8074
8075
8076 sfnt_address_zp0 (interpreter, point_a0, &a0x, &a0y, NULL, NULL);
8077 sfnt_address_zp0 (interpreter, point_a1, &a1x, &a1y, NULL, NULL);
8078 sfnt_address_zp1 (interpreter, point_b0, &b0x, &b0y, NULL, NULL);
8079 sfnt_address_zp1 (interpreter, point_b1, &b1x, &b1y, NULL, NULL);
8080
8081 #if 0
8082
8083
8084
8085
8086
8087
8088
8089
8090
8091
8092
8093
8094
8095
8096
8097
8098
8099
8100
8101
8102
8103
8104
8105
8106
8107
8108
8109
8110
8111
8112
8113
8114
8115
8116
8117
8118
8119
8120
8121
8122
8123 sfnt_line_to_standard_form (a0x, a0y, a1x, a1y,
8124 &a0, &b0, &c0);
8125 sfnt_line_to_standard_form (b0x, b0y, b1x, b1y,
8126 &a1, &b1, &c1);
8127
8128
8129
8130 determinant = sfnt_sub (sfnt_mul_fixed (a0, b1),
8131 sfnt_mul_fixed (b0, a1));
8132 dx = sfnt_sub (sfnt_mul_fixed (c0, b1),
8133 sfnt_mul_fixed (a1, c1));
8134 dy = sfnt_sub (sfnt_mul_fixed (a0, c1),
8135 sfnt_mul_fixed (c0, b0));
8136
8137
8138
8139 if (determinant == 0)
8140 goto degenerate_case;
8141 #else
8142
8143
8144
8145
8146
8147
8148 dbx = sfnt_sub (b1x, b0x);
8149 dby = sfnt_sub (b1y, b0y);
8150 dax = sfnt_sub (a1x, a0x);
8151 day = sfnt_sub (a1y, a0y);
8152
8153
8154 discriminant = sfnt_add (sfnt_mul_f26dot6 (dax, -dby),
8155 sfnt_mul_f26dot6 (day, dbx));
8156 dot_product = sfnt_add (sfnt_mul_f26dot6 (dax, dbx),
8157 sfnt_mul_f26dot6 (day, dby));
8158
8159
8160 if (!(sfnt_mul (19, abs (discriminant)) > abs (dot_product)))
8161 return;
8162
8163
8164 if (!discriminant)
8165 goto degenerate_case;
8166
8167 dx = sfnt_sub (b0x, a0x);
8168 dy = sfnt_sub (b0y, a0y);
8169 val = sfnt_add (sfnt_mul_f26dot6 (dx, -dby),
8170 sfnt_mul_f26dot6 (dy, dbx));
8171
8172
8173 dx = sfnt_add (a0x, sfnt_multiply_divide_signed (val, dax,
8174 discriminant));
8175 dy = sfnt_add (a0y, sfnt_multiply_divide_signed (val, day,
8176 discriminant));
8177 #endif
8178
8179 sfnt_store_zp2 (interpreter, p,
8180 #if 0
8181 sfnt_div_fixed (dx, determinant),
8182 sfnt_div_fixed (dy, determinant),
8183 #else
8184 dx, dy,
8185 #endif
8186 SFNT_POINT_TOUCHED_BOTH);
8187 return;
8188
8189 degenerate_case:
8190
8191
8192
8193
8194
8195
8196
8197
8198
8199
8200 px = (sfnt_add (a0x, a1x) / 2 + sfnt_add (b0x, b1x) / 2) / 2;
8201 py = (sfnt_add (a0y, a1y) / 2 + sfnt_add (b0y, b1y) / 2) / 2;
8202 sfnt_store_zp2 (interpreter, p, px, py,
8203 SFNT_POINT_TOUCHED_BOTH);
8204 }
8205
8206
8207
8208 static sfnt_fixed
8209 sfnt_sqrt_fixed (sfnt_fixed n)
8210 {
8211 int count;
8212 unsigned int root, rem_hi, rem_lo, possible;
8213
8214 root = 0;
8215
8216 if (n > 0)
8217 {
8218 rem_hi = 0;
8219 rem_lo = n;
8220 count = 24;
8221
8222 do
8223 {
8224 rem_hi = (rem_hi << 2) | (rem_lo >> 30);
8225 rem_lo <<= 2;
8226 root <<= 1;
8227 possible = (root << 1) + 1;
8228
8229 if (rem_hi >= possible)
8230 {
8231 rem_hi -= possible;
8232 root += 1;
8233 }
8234 }
8235 while (--count);
8236 }
8237
8238 return root;
8239 }
8240
8241
8242
8243
8244 static void
8245 sfnt_normalize_vector (sfnt_f26dot6 vx, sfnt_f26dot6 vy,
8246 struct sfnt_unit_vector *vector)
8247 {
8248 sfnt_f26dot6 x_squared, y_squared;
8249 sfnt_fixed n, magnitude;
8250
8251 if (!vx && !vy)
8252 {
8253
8254
8255
8256 fail:
8257 vector->x = 04000;
8258 vector->y = 0;
8259 return;
8260 }
8261
8262
8263
8264 while (!(vx < -32 || vx > 32) && !(vy < -32 || vy > 32))
8265 {
8266 vx = vx * 2;
8267 vy = vy * 2;
8268 }
8269
8270
8271 x_squared = sfnt_mul_f26dot6 (vx, vx);
8272 y_squared = sfnt_mul_f26dot6 (vy, vy);
8273
8274
8275
8276
8277 while (x_squared > 0x200000 || y_squared > 0x200000
8278 || x_squared < -0x200000 || y_squared < -0x200000)
8279 {
8280 x_squared /= 2;
8281 y_squared /= 2;
8282 }
8283
8284
8285 n = sfnt_add (x_squared, y_squared) * 1024;
8286
8287
8288 magnitude = sfnt_sqrt_fixed (n);
8289
8290
8291 if (!magnitude)
8292 goto fail;
8293
8294
8295 vector->x = (sfnt_div_fixed (vx * 1024, magnitude) / 4);
8296 vector->y = (sfnt_div_fixed (vy * 1024, magnitude) / 4);
8297 }
8298
8299
8300
8301
8302
8303
8304
8305
8306
8307
8308
8309
8310
8311
8312
8313
8314 static void
8315 sfnt_line_to_vector (struct sfnt_interpreter *interpreter,
8316 uint32_t p2, uint32_t p1,
8317 struct sfnt_unit_vector *vector,
8318 bool perpendicular, bool original)
8319 {
8320 sfnt_f26dot6 x2, y2, original_x2, original_y2;
8321 sfnt_f26dot6 x1, y1, original_x1, original_y1;
8322 sfnt_f26dot6 a, b, temp;
8323
8324 sfnt_address_zp2 (interpreter, p2, &x2, &y2, &original_x2,
8325 &original_y2);
8326 sfnt_address_zp1 (interpreter, p1, &x1, &y1, &original_x1,
8327 &original_y1);
8328
8329
8330
8331 if (original)
8332 {
8333 x2 = original_x2;
8334 y2 = original_y2;
8335 x1 = original_x1;
8336 y1 = original_y1;
8337 }
8338
8339
8340 a = sfnt_sub (x1, x2);
8341 b = sfnt_sub (y1, y2);
8342
8343
8344
8345 if (perpendicular)
8346 {
8347 temp = b;
8348 b = a;
8349 a = -temp;
8350 }
8351
8352
8353 sfnt_normalize_vector (a, b, vector);
8354 }
8355
8356
8357
8358
8359
8360
8361
8362
8363 static sfnt_f26dot6
8364 sfnt_measure_distance (struct sfnt_interpreter *interpreter,
8365 uint32_t p1, uint32_t p2,
8366 unsigned char opcode)
8367 {
8368 sfnt_f26dot6 p1x, p1y, p1_original_x, p1_original_y;
8369 sfnt_f26dot6 p2x, p2y, p2_original_x, p2_original_y;
8370
8371
8372
8373
8374 sfnt_address_zp0 (interpreter, p1, &p1x, &p1y,
8375 &p1_original_x, &p1_original_y);
8376 sfnt_address_zp1 (interpreter, p2, &p2x, &p2y,
8377 &p2_original_x, &p2_original_y);
8378
8379 if (opcode == 0x4A)
8380 return DUAL_PROJECT (sfnt_sub (p1_original_x, p2_original_x),
8381 sfnt_sub (p1_original_y, p2_original_y));
8382
8383 return PROJECT (sfnt_sub (p1x, p2x),
8384 sfnt_sub (p1y, p2y));
8385 }
8386
8387
8388
8389
8390
8391
8392
8393
8394
8395
8396 static void
8397 sfnt_interpret_msirp (struct sfnt_interpreter *interpreter,
8398 sfnt_f26dot6 d, uint32_t p, unsigned char opcode)
8399 {
8400 sfnt_f26dot6 rp0x, rp0y, rp0_original_x, rp0_original_y;
8401 sfnt_f26dot6 x, y;
8402 sfnt_f26dot6 old_distance, temp;
8403
8404 sfnt_address_zp0 (interpreter, interpreter->state.rp0,
8405 &rp0x, &rp0y, &rp0_original_x,
8406 &rp0_original_y);
8407 sfnt_address_zp1 (interpreter, p, &x, &y, NULL, NULL);
8408
8409 if (!interpreter->state.zp1)
8410 {
8411
8412
8413 x = interpreter->twilight_x[p] = rp0x;
8414 y = interpreter->twilight_y[p] = rp0y;
8415
8416
8417
8418 temp = sfnt_mul_f2dot14 (interpreter->state.projection_vector.x, d);
8419 temp = sfnt_add (temp, rp0_original_x);
8420 interpreter->twilight_original_x[p] = temp;
8421
8422 temp = sfnt_mul_f2dot14 (interpreter->state.projection_vector.y, d);
8423 temp = sfnt_add (temp, rp0_original_y);
8424 interpreter->twilight_original_y[p] = temp;
8425 }
8426
8427
8428 old_distance = sfnt_project_vector (interpreter,
8429 sfnt_sub (x, rp0x),
8430 sfnt_sub (y, rp0y));
8431
8432
8433 sfnt_move_zp1 (interpreter, p, 1, sfnt_sub (d, old_distance));
8434
8435
8436
8437
8438
8439
8440 interpreter->state.rp1 = interpreter->state.rp0;
8441 interpreter->state.rp2 = p;
8442
8443 if (opcode == 0x3b)
8444 interpreter->state.rp0 = p;
8445 }
8446
8447
8448
8449
8450
8451
8452 static void
8453 sfnt_interpret_ip (struct sfnt_interpreter *interpreter)
8454 {
8455 sfnt_f26dot6 rp1x, rp1y, rp1_original_x, rp1_original_y;
8456 sfnt_f26dot6 rp2x, rp2y, rp2_original_x, rp2_original_y;
8457 sfnt_f26dot6 range, new_range, org_distance, cur_distance;
8458 sfnt_f26dot6 new_distance;
8459 uint32_t p;
8460 sfnt_f26dot6 x, y, original_x, original_y;
8461
8462
8463 sfnt_address_zp0 (interpreter, interpreter->state.rp1,
8464 &rp1x, &rp1y, &rp1_original_x,
8465 &rp1_original_y);
8466 sfnt_address_zp1 (interpreter, interpreter->state.rp2,
8467 &rp2x, &rp2y, &rp2_original_x,
8468 &rp2_original_y);
8469
8470
8471
8472 range = sfnt_dual_project_vector (interpreter,
8473 sfnt_sub (rp2_original_x,
8474 rp1_original_x),
8475 sfnt_sub (rp2_original_y,
8476 rp1_original_y));
8477
8478
8479 new_range = sfnt_dual_project_vector (interpreter,
8480 sfnt_sub (rp2x, rp1x),
8481 sfnt_sub (rp2y, rp1y));
8482
8483 while (interpreter->state.loop--)
8484 {
8485 p = POP ();
8486
8487
8488 sfnt_address_zp2 (interpreter, p, &x, &y, &original_x,
8489 &original_y);
8490
8491
8492 org_distance
8493 = sfnt_dual_project_vector (interpreter,
8494 sfnt_sub (original_x,
8495 rp1_original_x),
8496 sfnt_sub (original_y,
8497 rp1_original_y));
8498
8499
8500
8501 cur_distance
8502 = sfnt_project_vector (interpreter,
8503 sfnt_sub (x, rp1x),
8504 sfnt_sub (y, rp1y));
8505
8506
8507
8508
8509
8510
8511
8512
8513 if (org_distance)
8514 {
8515 if (range)
8516 new_distance
8517 = sfnt_multiply_divide_signed (org_distance,
8518 new_range, range);
8519 else
8520 new_distance = org_distance;
8521 }
8522 else
8523 new_distance = 0;
8524
8525
8526
8527 sfnt_move_zp2 (interpreter, p, 1,
8528 sfnt_sub (new_distance, cur_distance));
8529 }
8530
8531 interpreter->state.loop = 1;
8532 }
8533
8534
8535
8536
8537
8538
8539
8540
8541
8542 static void
8543 sfnt_deltac (int number, struct sfnt_interpreter *interpreter,
8544 unsigned int index, unsigned char operand)
8545 {
8546 int ppem, delta;
8547
8548
8549
8550 if (index >= interpreter->cvt_size)
8551 TRAP ("DELTACn instruction out of bounds");
8552
8553
8554
8555
8556
8557
8558 ppem = (operand >> 4) + interpreter->state.delta_base;
8559
8560 switch (number)
8561 {
8562 case 1:
8563 break;
8564
8565 case 2:
8566 ppem += 16;
8567 break;
8568
8569 case 3:
8570 ppem += 32;
8571 break;
8572 }
8573
8574
8575
8576 if (interpreter->ppem != ppem)
8577 return;
8578
8579
8580
8581
8582
8583 switch (operand & 0xf)
8584 {
8585 case 0:
8586 delta = -8;
8587 break;
8588
8589 case 1:
8590 delta = -7;
8591 break;
8592
8593 case 2:
8594 delta = -6;
8595 break;
8596
8597 case 3:
8598 delta = -5;
8599 break;
8600
8601 case 4:
8602 delta = -4;
8603 break;
8604
8605 case 5:
8606 delta = -3;
8607 break;
8608
8609 case 6:
8610 delta = -2;
8611 break;
8612
8613 case 7:
8614 delta = -1;
8615 break;
8616
8617 case 8:
8618 delta = 1;
8619 break;
8620
8621 case 9:
8622 delta = 2;
8623 break;
8624
8625 case 10:
8626 delta = 3;
8627 break;
8628
8629 case 11:
8630 delta = 4;
8631 break;
8632
8633 case 12:
8634 delta = 5;
8635 break;
8636
8637 case 13:
8638 delta = 6;
8639 break;
8640
8641 case 14:
8642 delta = 7;
8643 break;
8644
8645 case 15:
8646 delta = 8;
8647 break;
8648
8649
8650 default:
8651 abort ();
8652 }
8653
8654
8655
8656 delta *= 1l << (6 - interpreter->state.delta_shift);
8657
8658
8659 interpreter->cvt[index] = sfnt_add (interpreter->cvt[index],
8660 delta);
8661 }
8662
8663
8664
8665
8666
8667
8668
8669
8670
8671
8672
8673 static void
8674 sfnt_interpret_mdap (struct sfnt_interpreter *interpreter,
8675 uint32_t p, uint32_t opcode)
8676 {
8677 sfnt_f26dot6 here, distance, px, py;
8678
8679 sfnt_address_zp0 (interpreter, p, &px, &py, NULL, NULL);
8680
8681
8682 here = sfnt_project_vector (interpreter, px, py);
8683
8684 if (opcode == 0x7f)
8685 {
8686
8687 distance = sfnt_project_vector (interpreter, px, py);
8688 distance = sfnt_round_symmetric (interpreter, distance);
8689 distance = sfnt_sub (distance, here);
8690 }
8691 else
8692
8693 distance = 0;
8694
8695 sfnt_move_zp0 (interpreter, p, 1, distance);
8696
8697 interpreter->state.rp0 = p;
8698 interpreter->state.rp1 = p;
8699 }
8700
8701
8702
8703
8704
8705
8706
8707
8708
8709 static void
8710 sfnt_deltap (int number, struct sfnt_interpreter *interpreter,
8711 unsigned char operand, unsigned int index)
8712 {
8713 int ppem, delta;
8714
8715 return;
8716
8717
8718
8719
8720 ppem = (operand >> 4) + interpreter->state.delta_base;
8721
8722 switch (number)
8723 {
8724 case 1:
8725 break;
8726
8727 case 2:
8728 ppem += 16;
8729 break;
8730
8731 case 3:
8732 ppem += 32;
8733 break;
8734 }
8735
8736
8737
8738 if (interpreter->ppem != ppem)
8739 return;
8740
8741
8742
8743
8744 switch (operand & 0xf)
8745 {
8746 case 0:
8747 delta = -8;
8748 break;
8749
8750 case 1:
8751 delta = -7;
8752 break;
8753
8754 case 2:
8755 delta = -6;
8756 break;
8757
8758 case 3:
8759 delta = -5;
8760 break;
8761
8762 case 4:
8763 delta = -4;
8764 break;
8765
8766 case 5:
8767 delta = -3;
8768 break;
8769
8770 case 6:
8771 delta = -2;
8772 break;
8773
8774 case 7:
8775 delta = -1;
8776 break;
8777
8778 case 8:
8779 delta = 1;
8780 break;
8781
8782 case 9:
8783 delta = 2;
8784 break;
8785
8786 case 10:
8787 delta = 3;
8788 break;
8789
8790 case 11:
8791 delta = 4;
8792 break;
8793
8794 case 12:
8795 delta = 5;
8796 break;
8797
8798 case 13:
8799 delta = 6;
8800 break;
8801
8802 case 14:
8803 delta = 7;
8804 break;
8805
8806 case 15:
8807 delta = 8;
8808 break;
8809
8810
8811 default:
8812 abort ();
8813 }
8814
8815
8816
8817 delta *= 1l << (6 - interpreter->state.delta_shift);
8818
8819
8820 sfnt_check_zp0 (interpreter, index);
8821 sfnt_move_zp0 (interpreter, index, 1, delta);
8822 }
8823
8824
8825 static void sfnt_interpret_run (struct sfnt_interpreter *,
8826 enum sfnt_interpreter_run_context);
8827
8828
8829
8830
8831
8832
8833
8834
8835
8836
8837
8838 static void
8839 sfnt_interpret_call (struct sfnt_interpreter_definition *definition,
8840 struct sfnt_interpreter *interpreter,
8841 enum sfnt_interpreter_run_context context)
8842 {
8843 uint16_t num_instructions;
8844 int IP;
8845 unsigned char *instructions;
8846
8847
8848 if (interpreter->call_depth++ >= 128)
8849 TRAP ("CALL called CALL more than 127 times");
8850
8851
8852 num_instructions = interpreter->num_instructions;
8853 IP = interpreter->IP;
8854 instructions = interpreter->instructions;
8855
8856
8857 interpreter->num_instructions = definition->instruction_count;
8858 interpreter->instructions = definition->instructions;
8859 interpreter->IP = 0;
8860 sfnt_interpret_run (interpreter, context);
8861
8862
8863 interpreter->num_instructions = num_instructions;
8864 interpreter->IP = IP;
8865 interpreter->instructions = instructions;
8866 interpreter->call_depth--;
8867 }
8868
8869
8870
8871
8872
8873
8874
8875
8876
8877 static void
8878 sfnt_set_srounding_state (struct sfnt_interpreter *interpreter,
8879 uint32_t operand, sfnt_f18dot14 grid_period)
8880 {
8881 sfnt_f18dot14 period, phase, threshold;
8882
8883
8884
8885
8886 switch ((operand & 0xc0) >> 6)
8887 {
8888 case 0:
8889 period = grid_period / 2;
8890 break;
8891
8892 case 1:
8893 period = grid_period;
8894 break;
8895
8896 case 2:
8897 period = grid_period * 2;
8898 break;
8899
8900 case 3:
8901 default:
8902 TRAP ("reserved period given to SROUND");
8903 }
8904
8905
8906
8907 switch ((operand & 0x30) >> 4)
8908 {
8909 case 0:
8910 phase = 0;
8911 break;
8912
8913 case 1:
8914 phase = period / 4;
8915 break;
8916
8917 case 2:
8918 phase = period / 2;
8919 break;
8920
8921 case 3:
8922 default:
8923 phase = period * 3 / 2;
8924 break;
8925 }
8926
8927
8928
8929 if (operand & 0x0f)
8930 threshold = (((int) (operand & 0x0f) - 4)
8931 * period / 8);
8932 else
8933 threshold = period - 1;
8934
8935
8936 interpreter->period = period >> 8;
8937 interpreter->phase = phase >> 8;
8938 interpreter->threshold = threshold >> 8;
8939 }
8940
8941
8942
8943
8944 static unsigned char
8945 sfnt_skip_code (struct sfnt_interpreter *interpreter)
8946 {
8947 unsigned char opcode;
8948 int nbytes;
8949
8950 if (interpreter->IP == interpreter->num_instructions)
8951 TRAP ("IP at end of instruction stream");
8952
8953
8954 opcode = interpreter->instructions[interpreter->IP];
8955
8956 if (opcode == 0x40 || opcode == 0x41)
8957 {
8958 if (interpreter->IP + 1 >= interpreter->num_instructions)
8959 TRAP ("Missing arg to NPUSHB or NPUSHW");
8960
8961
8962
8963 nbytes = interpreter->instructions[interpreter->IP + 1];
8964
8965 if (opcode == 0x41)
8966 nbytes *= 2;
8967
8968 if (interpreter->IP + 2 + nbytes > interpreter->num_instructions)
8969 TRAP ("args to NPUSH instruction lie outside IS");
8970
8971
8972 interpreter->IP += 2 + nbytes;
8973 }
8974 else if (opcode >= 0xb0 && opcode <= 0xb7)
8975 {
8976 nbytes = opcode - 0xb0 + 1;
8977
8978 if (interpreter->IP + 1 + nbytes > interpreter->num_instructions)
8979 TRAP ("args to PUSHB instruction lie outide IS");
8980
8981 interpreter->IP += 1 + nbytes;
8982 }
8983 else if (opcode >= 0xb8 && opcode <= 0xbf)
8984 {
8985 nbytes = (opcode - 0xb8 + 1) * 2;
8986
8987 if (interpreter->IP + 1 + nbytes > interpreter->num_instructions)
8988 TRAP ("args to PUSHW instruction lie outide IS");
8989
8990 interpreter->IP += 1 + nbytes;
8991 }
8992 else
8993 interpreter->IP++;
8994
8995 return opcode;
8996 }
8997
8998
8999
9000
9001
9002 static void
9003 sfnt_interpret_unimplemented (struct sfnt_interpreter *interpreter,
9004 unsigned char opcode,
9005 enum sfnt_interpreter_run_context why)
9006 {
9007 uint32_t i;
9008 struct sfnt_interpreter_definition *def;
9009
9010 for (i = 0; i < interpreter->instruction_defs_size; ++i)
9011 {
9012 def = &interpreter->instruction_defs[i];
9013
9014 if (def->opcode == opcode)
9015 {
9016 if (!def->instructions)
9017 TRAP ("** ERROR ** malformed internal instruction"
9018 " definition");
9019
9020 sfnt_interpret_call (def, interpreter, why);
9021 return;
9022 }
9023 }
9024
9025 TRAP ("invalid instruction");
9026 }
9027
9028
9029
9030
9031 static void
9032 sfnt_interpret_fdef (struct sfnt_interpreter *interpreter,
9033 uint32_t opcode)
9034 {
9035 size_t i, num_fdefs;
9036 int IP;
9037 unsigned char instruction;
9038
9039 IP = interpreter->IP + 1;
9040 num_fdefs = 0;
9041
9042
9043
9044 while ((instruction = sfnt_skip_code (interpreter)) != 0x2d)
9045 {
9046 if (interpreter->IP >= interpreter->num_instructions)
9047 TRAP ("missing ENDF");
9048
9049
9050
9051 if (instruction == 0x2c || instruction == 0x89)
9052 ++num_fdefs;
9053
9054 if (num_fdefs > 1)
9055 TRAP ("IDEF or FDEF before ENDF");
9056 }
9057
9058
9059
9060
9061
9062 for (i = 0; i < interpreter->function_defs_size; ++i)
9063 {
9064 if (interpreter->function_defs[i].opcode == opcode
9065 || !interpreter->function_defs[i].instructions)
9066 break;
9067 }
9068
9069 if (i == interpreter->function_defs_size)
9070 TRAP ("number of fdefs exceeded maxp->max_function_defs");
9071
9072
9073 interpreter->function_defs[i].opcode = opcode;
9074
9075
9076 interpreter->function_defs[i].instruction_count
9077 = interpreter->IP - IP - 1;
9078
9079
9080 interpreter->function_defs[i].instructions = interpreter->instructions + IP;
9081 }
9082
9083
9084
9085
9086 static void
9087 sfnt_interpret_idef (struct sfnt_interpreter *interpreter,
9088 uint32_t opcode)
9089 {
9090 size_t i, num_fdefs;
9091 int IP;
9092 unsigned char instruction;
9093
9094 IP = interpreter->IP + 1;
9095 num_fdefs = 0;
9096
9097
9098
9099 while ((instruction = sfnt_skip_code (interpreter)) != 0x2d)
9100 {
9101 if (interpreter->IP >= interpreter->num_instructions)
9102 TRAP ("missing ENDF");
9103
9104
9105
9106 if (instruction == 0x2c || instruction == 0x89)
9107 ++num_fdefs;
9108
9109 if (num_fdefs > 1)
9110 TRAP ("IDEF or FDEF before ENDF");
9111 }
9112
9113
9114
9115
9116
9117 for (i = 0; i < interpreter->instruction_defs_size; ++i)
9118 {
9119 if (interpreter->instruction_defs[i].opcode == opcode
9120 || !interpreter->instruction_defs[i].instructions)
9121 break;
9122 }
9123
9124 if (i == interpreter->instruction_defs_size)
9125 TRAP ("number of defs exceeded maxp->max_instruction_defs");
9126
9127
9128 interpreter->instruction_defs[i].opcode = opcode;
9129
9130
9131 interpreter->instruction_defs[i].instruction_count
9132 = interpreter->IP - IP - 1;
9133
9134
9135 interpreter->instruction_defs[i].instructions
9136 = interpreter->instructions + IP;
9137 }
9138
9139
9140
9141
9142
9143
9144 static void
9145 sfnt_interpret_if (struct sfnt_interpreter *interpreter,
9146 bool condition)
9147 {
9148 int nifs;
9149 bool need_break;
9150 unsigned char opcode;
9151
9152 if (condition)
9153 {
9154 interpreter->IP++;
9155 return;
9156 }
9157
9158
9159 nifs = 0;
9160 need_break = false;
9161
9162
9163 do
9164 {
9165
9166 opcode = sfnt_skip_code (interpreter);
9167
9168 if (interpreter->IP >= interpreter->num_instructions)
9169 break;
9170
9171 switch (opcode)
9172 {
9173 case 0x58:
9174 nifs++;
9175 break;
9176
9177 case 0x1B:
9178 if (nifs == 1)
9179 need_break = true;
9180
9181 break;
9182
9183 case 0x59:
9184 nifs--;
9185 if (nifs == 0)
9186 need_break = true;
9187
9188 break;
9189 }
9190 }
9191 while (!need_break);
9192 }
9193
9194
9195
9196
9197
9198
9199
9200 static void
9201 sfnt_interpret_else (struct sfnt_interpreter *interpreter)
9202 {
9203 int nifs;
9204 unsigned char opcode;
9205
9206
9207 nifs = 1;
9208
9209
9210 do
9211 {
9212
9213 opcode = sfnt_skip_code (interpreter);
9214
9215 if (interpreter->IP >= interpreter->num_instructions)
9216 break;
9217
9218 switch (opcode)
9219 {
9220 case 0x58:
9221 nifs++;
9222 break;
9223
9224 case 0x59:
9225 nifs--;
9226
9227 break;
9228 }
9229 }
9230 while (nifs > 0);
9231 }
9232
9233
9234
9235
9236
9237 static sfnt_f26dot6
9238 sfnt_round_none (sfnt_f26dot6 x, struct sfnt_interpreter *interpreter)
9239 {
9240 return x;
9241 }
9242
9243
9244
9245
9246 static sfnt_f26dot6
9247 sfnt_round_to_grid (sfnt_f26dot6 x, struct sfnt_interpreter *interpreter)
9248 {
9249 return sfnt_round_f26dot6 (x);
9250 }
9251
9252
9253
9254
9255 static sfnt_f26dot6
9256 sfnt_round_to_double_grid (sfnt_f26dot6 x,
9257 struct sfnt_interpreter *interpreter)
9258 {
9259 return (x + 020) & ~037;
9260 }
9261
9262
9263
9264
9265 static sfnt_f26dot6
9266 sfnt_round_down_to_grid (sfnt_f26dot6 x,
9267 struct sfnt_interpreter *interpreter)
9268 {
9269 return sfnt_floor_f26dot6 (x);
9270 }
9271
9272
9273
9274
9275 static sfnt_f26dot6
9276 sfnt_round_up_to_grid (sfnt_f26dot6 x,
9277 struct sfnt_interpreter *interpreter)
9278 {
9279 return sfnt_ceil_f26dot6 (x);
9280 }
9281
9282
9283
9284
9285 static sfnt_f26dot6
9286 sfnt_round_to_half_grid (sfnt_f26dot6 x,
9287 struct sfnt_interpreter *interpreter)
9288 {
9289 return sfnt_floor_f26dot6 (x) + 32;
9290 }
9291
9292
9293
9294
9295 static sfnt_f26dot6
9296 sfnt_round_super (sfnt_f26dot6 x,
9297 struct sfnt_interpreter *interpreter)
9298 {
9299 sfnt_f26dot6 value;
9300
9301
9302 value = sfnt_add ((interpreter->threshold
9303 - interpreter->phase), x);
9304 value = sfnt_add (value & -interpreter->period,
9305 interpreter->phase);
9306
9307
9308
9309
9310
9311 return value < 0 ? interpreter->phase : value;
9312 }
9313
9314
9315
9316
9317
9318 static sfnt_f26dot6
9319 sfnt_round_super45 (sfnt_f26dot6 x,
9320 struct sfnt_interpreter *interpreter)
9321 {
9322 sfnt_f26dot6 value;
9323
9324
9325
9326 value = ((sfnt_add (x, (interpreter->threshold
9327 - interpreter->phase))
9328 / interpreter->period)
9329 * interpreter->period);
9330 value = sfnt_add (value, interpreter->phase);
9331
9332
9333
9334
9335
9336 return value < 0 ? interpreter->phase : value;
9337 }
9338
9339
9340
9341
9342
9343
9344
9345 static sfnt_f26dot6
9346 sfnt_project_onto_x_axis_vector (sfnt_f26dot6 vx, sfnt_f26dot6 vy,
9347 struct sfnt_interpreter *interpreter)
9348 {
9349 return vx;
9350 }
9351
9352
9353
9354
9355
9356
9357
9358 static sfnt_f26dot6
9359 sfnt_project_onto_y_axis_vector (sfnt_f26dot6 vx, sfnt_f26dot6 vy,
9360 struct sfnt_interpreter *interpreter)
9361 {
9362 return vy;
9363 }
9364
9365
9366
9367 static int32_t
9368 sfnt_dot_fix_14 (int32_t ax, int32_t ay, int bx, int by)
9369 {
9370 #ifndef INT64_MAX
9371 int32_t m, s, hi1, hi2, hi;
9372 uint32_t l, lo1, lo2, lo;
9373
9374
9375
9376 l = (uint32_t) ((ax & 0xffffu) * bx);
9377 m = (ax >> 16) * bx;
9378
9379 lo1 = l + ((uint32_t) m << 16);
9380 hi1 = (m >> 16) + ((int32_t) l >> 31) + (lo1 < l);
9381
9382
9383 l = (uint32_t) ((ay & 0xffffu) * by);
9384 m = (ay >> 16) * by;
9385
9386 lo2 = l + ((uint32_t) m << 16);
9387 hi2 = (m >> 16) + ((int32_t) l >> 31) + (lo2 < l);
9388
9389
9390 lo = lo1 + lo2;
9391 hi = hi1 + hi2 + (lo < lo1);
9392
9393
9394 s = hi >> 31;
9395 l = lo + (uint32_t) s;
9396 hi += s + (l < lo);
9397 lo = l;
9398
9399 l = lo + 0x2000u;
9400 hi += (l < lo);
9401
9402 return (int32_t) (((uint32_t) hi << 18) | (l >> 14));
9403 #else
9404 int64_t xx, yy;
9405
9406 xx = (int64_t) ax * bx;
9407 yy = (int64_t) ay * by;
9408
9409 xx += yy;
9410 yy = xx >> 63;
9411 xx += 0x2000 + yy;
9412
9413 return (int32_t) (xx / (2 << 14));
9414 #endif
9415 }
9416
9417
9418
9419
9420
9421
9422
9423 static sfnt_f26dot6
9424 sfnt_project_onto_any_vector (sfnt_f26dot6 vx, sfnt_f26dot6 vy,
9425 struct sfnt_interpreter *interpreter)
9426 {
9427 return sfnt_dot_fix_14 (vx, vy,
9428 interpreter->state.projection_vector.x,
9429 interpreter->state.projection_vector.y);
9430 }
9431
9432
9433
9434
9435
9436
9437
9438
9439
9440
9441
9442 static sfnt_f26dot6
9443 sfnt_dual_project_onto_any_vector (sfnt_f26dot6 vx, sfnt_f26dot6 vy,
9444 struct sfnt_interpreter *interpreter)
9445 {
9446 return sfnt_dot_fix_14 (vx, vy,
9447 interpreter->state.dual_projection_vector.x,
9448 interpreter->state.dual_projection_vector.y);
9449 }
9450
9451
9452
9453
9454
9455
9456 static void
9457 sfnt_move_x (sfnt_f26dot6 *restrict x, sfnt_f26dot6 *restrict y,
9458 size_t n, struct sfnt_interpreter *interpreter,
9459 sfnt_f26dot6 distance, unsigned char *flags)
9460 {
9461 while (n--)
9462 {
9463 *x = sfnt_add (*x, distance);
9464 x++;
9465
9466 if (flags)
9467 *flags++ |= SFNT_POINT_TOUCHED_X;
9468 }
9469 }
9470
9471
9472
9473
9474
9475
9476 static void
9477 sfnt_move_y (sfnt_f26dot6 *restrict x, sfnt_f26dot6 *restrict y,
9478 size_t n, struct sfnt_interpreter *interpreter,
9479 sfnt_f26dot6 distance, unsigned char *flags)
9480 {
9481 while (n--)
9482 {
9483 *y = sfnt_add (*y, distance);
9484 y++;
9485
9486 if (flags)
9487 *flags++ |= SFNT_POINT_TOUCHED_Y;
9488 }
9489 }
9490
9491
9492
9493
9494
9495 static void
9496 sfnt_move (sfnt_f26dot6 *restrict x, sfnt_f26dot6 *restrict y,
9497 size_t n, struct sfnt_interpreter *interpreter,
9498 sfnt_f26dot6 distance, unsigned char *flags)
9499 {
9500 sfnt_f26dot6 versor, k;
9501 sfnt_f2dot14 dot_product;
9502 size_t num;
9503
9504 dot_product = interpreter->state.vector_dot_product;
9505
9506
9507
9508 if (!dot_product)
9509 return;
9510
9511
9512
9513 versor = interpreter->state.freedom_vector.x;
9514
9515 if (versor)
9516 {
9517
9518
9519 num = n;
9520 k = sfnt_multiply_divide_signed (distance,
9521 versor,
9522 dot_product);
9523
9524 while (num--)
9525 {
9526 *x = sfnt_add (*x, k);
9527 x++;
9528
9529 if (flags)
9530 *flags++ |= SFNT_POINT_TOUCHED_X;
9531 }
9532 }
9533
9534 versor = interpreter->state.freedom_vector.y;
9535
9536 if (versor)
9537 {
9538
9539
9540 num = n;
9541 k = sfnt_multiply_divide_signed (distance,
9542 versor,
9543 dot_product);
9544
9545 while (num--)
9546 {
9547 *y = sfnt_add (*y, k);
9548 y++;
9549
9550 if (flags)
9551 *flags++ |= SFNT_POINT_TOUCHED_Y;
9552 }
9553 }
9554 }
9555
9556
9557
9558
9559
9560
9561 static void
9562 sfnt_validate_gs (struct sfnt_graphics_state *gs)
9563 {
9564
9565
9566
9567 switch (gs->round_state)
9568 {
9569 case 5:
9570 gs->round = sfnt_round_none;
9571 break;
9572
9573 case 0:
9574 gs->round = sfnt_round_to_half_grid;
9575 break;
9576
9577 case 1:
9578 gs->round = sfnt_round_to_grid;
9579 break;
9580
9581 case 2:
9582 gs->round = sfnt_round_to_double_grid;
9583 break;
9584
9585 case 4:
9586 gs->round = sfnt_round_up_to_grid;
9587 break;
9588
9589 case 3:
9590 gs->round = sfnt_round_down_to_grid;
9591 break;
9592
9593 case 6:
9594 gs->round = sfnt_round_super;
9595 break;
9596
9597 case 7:
9598 gs->round = sfnt_round_super45;
9599 break;
9600 }
9601
9602
9603
9604
9605
9606 if (gs->projection_vector.x == 040000)
9607 gs->project = sfnt_project_onto_x_axis_vector;
9608 else if (gs->projection_vector.y == 040000)
9609 gs->project = sfnt_project_onto_y_axis_vector;
9610 else
9611 gs->project = sfnt_project_onto_any_vector;
9612
9613
9614
9615 if (gs->dual_projection_vector.x == 040000)
9616 gs->dual_project = sfnt_project_onto_x_axis_vector;
9617 else if (gs->dual_projection_vector.y == 040000)
9618 gs->dual_project = sfnt_project_onto_y_axis_vector;
9619 else
9620 gs->dual_project = sfnt_dual_project_onto_any_vector;
9621
9622
9623
9624
9625
9626 if (gs->freedom_vector.x == 040000)
9627 gs->vector_dot_product = gs->projection_vector.x;
9628 else if (gs->freedom_vector.y == 040000)
9629 gs->vector_dot_product = gs->projection_vector.y;
9630 else
9631
9632 gs->vector_dot_product = ((((long) gs->projection_vector.x
9633 * gs->freedom_vector.x)
9634 + ((long) gs->projection_vector.y
9635 * gs->freedom_vector.y))
9636 / 16384);
9637
9638
9639
9640
9641
9642 if (gs->freedom_vector.x == 040000
9643 && gs->projection_vector.x == 040000)
9644 gs->move = sfnt_move_x;
9645 else if (gs->freedom_vector.y == 040000
9646 && gs->projection_vector.y == 040000)
9647 gs->move = sfnt_move_y;
9648 else
9649 gs->move = sfnt_move;
9650 }
9651
9652
9653
9654
9655
9656 static void
9657 sfnt_set_freedom_vector (struct sfnt_interpreter *interpreter,
9658 sfnt_f2dot14 x, sfnt_f2dot14 y)
9659 {
9660 interpreter->state.freedom_vector.x = x;
9661 interpreter->state.freedom_vector.y = y;
9662
9663 sfnt_validate_gs (&interpreter->state);
9664 }
9665
9666
9667
9668
9669
9670 static void
9671 sfnt_set_projection_vector (struct sfnt_interpreter *interpreter,
9672 sfnt_f2dot14 x, sfnt_f2dot14 y)
9673 {
9674 interpreter->state.projection_vector.x = x;
9675 interpreter->state.projection_vector.y = y;
9676 interpreter->state.dual_projection_vector.x = x;
9677 interpreter->state.dual_projection_vector.y = y;
9678
9679 sfnt_validate_gs (&interpreter->state);
9680 }
9681
9682
9683
9684
9685
9686 static void
9687 sfnt_interpret_shz (struct sfnt_interpreter *interpreter,
9688 uint32_t zone, unsigned int opcode)
9689 {
9690 sfnt_f26dot6 x, y, original_x, original_y;
9691 sfnt_f26dot6 magnitude;
9692
9693 if (zone != 0 && !interpreter->glyph_zone)
9694
9695 return;
9696
9697 if (opcode == 0x37)
9698 sfnt_address_zp0 (interpreter, interpreter->state.rp1,
9699 &x, &y, &original_x, &original_y);
9700 else
9701 sfnt_address_zp1 (interpreter, interpreter->state.rp2,
9702 &x, &y, &original_x, &original_y);
9703
9704 magnitude = sfnt_project_vector (interpreter,
9705 sfnt_sub (x, original_x),
9706 sfnt_sub (y, original_y));
9707
9708 if (zone == 0)
9709 sfnt_move_twilight_zone (interpreter, 0,
9710 interpreter->twilight_zone_size,
9711 magnitude);
9712 else
9713 sfnt_move_glyph_zone (interpreter, 0,
9714 interpreter->glyph_zone->num_points,
9715 magnitude);
9716 }
9717
9718
9719
9720
9721
9722 static void
9723 sfnt_interpret_shc (struct sfnt_interpreter *interpreter,
9724 uint32_t contour, unsigned int opcode)
9725 {
9726 sfnt_f26dot6 x, y, original_x, original_y;
9727 sfnt_f26dot6 magnitude;
9728 size_t start, end, n;
9729
9730 if (!interpreter->glyph_zone)
9731 TRAP ("SHC without glyph zone");
9732
9733
9734 if (contour >= interpreter->glyph_zone->num_contours)
9735 TRAP ("contour out of bounds");
9736
9737
9738
9739
9740 if (opcode == 0x35)
9741 sfnt_address_zp0 (interpreter, interpreter->state.rp1,
9742 &x, &y, &original_x, &original_y);
9743 else
9744 sfnt_address_zp1 (interpreter, interpreter->state.rp2,
9745 &x, &y, &original_x, &original_y);
9746
9747 magnitude = sfnt_project_vector (interpreter,
9748 sfnt_sub (x, original_x),
9749 sfnt_sub (y, original_y));
9750
9751
9752
9753
9754 if (contour)
9755 start = interpreter->glyph_zone->contour_end_points[contour - 1];
9756 else
9757 start = 0;
9758
9759 end = interpreter->glyph_zone->contour_end_points[contour];
9760
9761 if (start > end || end >= interpreter->glyph_zone->num_points)
9762 TRAP ("invalid contour data in glyph");
9763
9764
9765 n = end - start + 1;
9766
9767
9768 sfnt_move_glyph_zone (interpreter, start, n, magnitude);
9769 }
9770
9771
9772
9773
9774
9775
9776
9777
9778
9779 static void
9780 sfnt_interpret_shp (struct sfnt_interpreter *interpreter,
9781 unsigned int opcode)
9782 {
9783 sfnt_f26dot6 x, y, original_x, original_y;
9784 sfnt_f26dot6 magnitude;
9785 uint32_t point;
9786
9787
9788
9789
9790 if (opcode == 0x33)
9791 sfnt_address_zp0 (interpreter, interpreter->state.rp1,
9792 &x, &y, &original_x, &original_y);
9793 else
9794 sfnt_address_zp1 (interpreter, interpreter->state.rp2,
9795 &x, &y, &original_x, &original_y);
9796
9797 magnitude = sfnt_project_vector (interpreter,
9798 sfnt_sub (x, original_x),
9799 sfnt_sub (y, original_y));
9800
9801
9802
9803
9804 while (interpreter->state.loop--)
9805 {
9806 point = POP ();
9807
9808 sfnt_check_zp2 (interpreter, point);
9809 sfnt_move_zp2 (interpreter, point, 1, magnitude);
9810 }
9811
9812
9813 interpreter->state.loop = 1;
9814 }
9815
9816 #define load_point(p) \
9817 (opcode == 0x31 \
9818 ? interpreter->glyph_zone->x_current[p] \
9819 : interpreter->glyph_zone->y_current[p])
9820
9821 #define store_point(p, val) \
9822 (opcode == 0x31 \
9823 ? (interpreter->glyph_zone->x_current[p] = (val)) \
9824 : (interpreter->glyph_zone->y_current[p] = (val)))
9825
9826 #define load_original(p) \
9827 (opcode == 0x31 \
9828 ? interpreter->glyph_zone->x_points[p] \
9829 : interpreter->glyph_zone->y_points[p])
9830
9831 #define IUP_SINGLE_PAIR() \
9832
9833 \
9834 \
9835 if (touch_start == start) \
9836 touch_start = end; \
9837 else \
9838 touch_start = touch_start - 1; \
9839 \
9840
9841 \
9842 \
9843 if (load_original (touch_start) < load_original (touch_end)) \
9844 { \
9845 point_min = touch_start; \
9846 point_max = touch_end; \
9847 } \
9848 else \
9849 { \
9850 point_max = touch_start; \
9851 point_min = touch_end; \
9852 } \
9853 \
9854 min_pos = load_point (point_min); \
9855 max_pos = load_point (point_max); \
9856 \
9857 \
9858 original_max_pos = load_original (point_max); \
9859 original_min_pos = load_original (point_min); \
9860 \
9861 \
9862 \
9863 i = touch_start + 1; \
9864 \
9865 \
9866 \
9867 if (i > end) \
9868 i = start; \
9869 \
9870 while (i != touch_end) \
9871 { \
9872
9873 \
9874 position = load_original (i); \
9875 \
9876 \
9877 if (position >= original_min_pos \
9878 && position <= original_max_pos) \
9879 { \
9880
9881
9882 \
9883 if (original_min_pos == original_max_pos) \
9884 ratio = 077777; \
9885 else \
9886
9887 \
9888 ratio = sfnt_div_fixed ((sfnt_sub (position, \
9889 original_min_pos) \
9890 * 1024), \
9891 (sfnt_sub (original_max_pos, \
9892 original_min_pos) \
9893 * 1024)); \
9894 \
9895 delta = sfnt_sub (max_pos, min_pos); \
9896 delta = sfnt_mul_fixed (ratio, delta); \
9897 store_point (i, sfnt_add (min_pos, delta)); \
9898 } \
9899 else \
9900 { \
9901
9902 \
9903 \
9904 if (position >= original_max_pos) \
9905 delta = sfnt_sub (max_pos, original_max_pos); \
9906 else \
9907 delta = sfnt_sub (min_pos, original_min_pos); \
9908 \
9909 store_point (i, sfnt_add (position, delta)); \
9910 } \
9911 \
9912 if (++i > end) \
9913 i = start; \
9914 } \
9915
9916
9917
9918
9919
9920
9921 static void
9922 sfnt_interpret_iup_1 (struct sfnt_interpreter *interpreter,
9923 size_t start, size_t end,
9924 unsigned char opcode, int mask)
9925 {
9926 size_t point;
9927 size_t touch_start, touch_end;
9928 size_t first_point;
9929 size_t point_min, point_max, i;
9930 sfnt_f26dot6 position, min_pos, max_pos, delta, ratio;
9931 sfnt_f26dot6 original_max_pos;
9932 sfnt_f26dot6 original_min_pos;
9933
9934
9935
9936
9937 for (point = start; point <= end; ++point)
9938 {
9939 if (interpreter->glyph_zone->flags[point] & mask)
9940 goto touched;
9941 }
9942
9943 goto untouched;
9944
9945 touched:
9946
9947 point = start;
9948
9949
9950 while (!(interpreter->glyph_zone->flags[point] & mask))
9951 {
9952 point++;
9953
9954
9955 if (point > end)
9956 goto untouched;
9957 }
9958
9959 first_point = point;
9960
9961 while (point <= end)
9962 {
9963
9964 while (interpreter->glyph_zone->flags[point] & mask)
9965 {
9966 point++;
9967
9968 if (point > end)
9969 goto wraparound;
9970 }
9971
9972
9973 touch_start = point;
9974
9975
9976 while (!(interpreter->glyph_zone->flags[point] & mask))
9977 {
9978 point++;
9979
9980
9981
9982 if (point > end)
9983 goto wraparound_1;
9984 }
9985
9986
9987 touch_end = point;
9988
9989
9990 IUP_SINGLE_PAIR ();
9991 }
9992
9993 goto untouched;
9994
9995 wraparound:
9996
9997
9998
9999
10000 touch_start = start;
10001
10002 wraparound_1:
10003
10004
10005
10006 touch_end = first_point;
10007 IUP_SINGLE_PAIR ();
10008
10009 untouched:
10010
10011
10012 return;
10013 }
10014
10015 #undef load_point
10016 #undef store_point
10017 #undef load_original
10018
10019
10020
10021
10022
10023 static void
10024 sfnt_interpret_iup (struct sfnt_interpreter *interpreter,
10025 unsigned char opcode)
10026 {
10027 int mask;
10028 size_t i, point, end, first_point;
10029
10030
10031
10032 if (!interpreter->state.zp2)
10033 TRAP ("trying to iup in twilight zone");
10034
10035 if (!interpreter->glyph_zone)
10036 TRAP ("iup without loaded glyph!");
10037
10038
10039 if (opcode == 0x30)
10040 mask = SFNT_POINT_TOUCHED_Y;
10041 else
10042 mask = SFNT_POINT_TOUCHED_X;
10043
10044
10045 point = 0;
10046 for (i = 0; i < interpreter->glyph_zone->num_contours; ++i)
10047 {
10048 first_point = point;
10049 end = interpreter->glyph_zone->contour_end_points[i];
10050
10051 if (point >= interpreter->glyph_zone->num_points
10052 || end >= interpreter->glyph_zone->num_points)
10053 TRAP ("glyph contains out of bounds contour end point"
10054 " data!");
10055
10056 sfnt_interpret_iup_1 (interpreter, first_point, end,
10057 opcode, mask);
10058 point = end + 1;
10059
10060
10061
10062
10063 while (point < interpreter->glyph_zone->num_points
10064 && interpreter->glyph_zone->flags[point] & SFNT_POINT_PHANTOM)
10065 point++;
10066 }
10067 }
10068
10069
10070
10071
10072
10073
10074
10075
10076
10077
10078 static void
10079 sfnt_interpret_mirp (struct sfnt_interpreter *interpreter,
10080 uint32_t opcode)
10081 {
10082 uint32_t n;
10083 uint32_t p;
10084 sfnt_f26dot6 distance, delta, temp;
10085 sfnt_f26dot6 current_projection, original_projection;
10086 sfnt_f26dot6 x, y, org_x, org_y;
10087 sfnt_f26dot6 rx, ry, org_rx, org_ry;
10088
10089
10090 n = POP ();
10091
10092
10093 p = POP ();
10094
10095
10096 if (n >= interpreter->cvt_size)
10097 TRAP ("cvt index out of bounds");
10098
10099 distance = interpreter->cvt[n];
10100
10101
10102
10103 delta = sfnt_sub (distance,
10104 interpreter->state.single_width_value);
10105
10106 if (delta < 0)
10107 delta = -delta;
10108
10109 if (delta < interpreter->state.sw_cut_in)
10110 {
10111
10112
10113
10114 if (distance >= 0)
10115 distance = interpreter->state.single_width_value;
10116 else
10117 distance = -interpreter->state.single_width_value;
10118 }
10119
10120
10121 sfnt_address_zp0 (interpreter, interpreter->state.rp0,
10122 &rx, &ry, &org_rx, &org_ry);
10123
10124
10125
10126 if (!interpreter->state.zp1)
10127 {
10128
10129
10130 sfnt_check_zp1 (interpreter, p);
10131
10132 interpreter->twilight_x[p] = rx;
10133 interpreter->twilight_y[p] = ry;
10134
10135 temp = sfnt_mul_f2dot14 (interpreter->state.projection_vector.x,
10136 distance);
10137 temp = sfnt_add (temp, org_rx);
10138 interpreter->twilight_original_x[p] = temp;
10139
10140 temp = sfnt_mul_f2dot14 (interpreter->state.projection_vector.y,
10141 distance);
10142 temp = sfnt_add (temp, org_ry);
10143 interpreter->twilight_original_y[p] = temp;
10144 }
10145
10146
10147 sfnt_address_zp1 (interpreter, p, &x, &y, &org_x, &org_y);
10148
10149
10150
10151 original_projection = DUAL_PROJECT (org_x - org_rx,
10152 org_y - org_ry);
10153 current_projection = PROJECT (x - rx, y - ry);
10154
10155 if (interpreter->state.auto_flip)
10156 {
10157 if ((original_projection ^ distance) < 0)
10158 distance = -distance;
10159 }
10160
10161
10162
10163
10164 if (opcode & 4)
10165 {
10166 delta = sfnt_sub (distance, original_projection);
10167
10168 if (delta < 0)
10169 delta = -delta;
10170
10171 if (delta > interpreter->state.cvt_cut_in)
10172 distance = original_projection;
10173
10174
10175 distance = sfnt_round_symmetric (interpreter, distance);
10176 }
10177
10178
10179
10180 if (opcode & 8)
10181 {
10182 if (original_projection >= 0
10183 && distance < interpreter->state.minimum_distance)
10184 distance = interpreter->state.minimum_distance;
10185 else if (original_projection < 0
10186 && distance > -interpreter->state.minimum_distance)
10187 distance = -interpreter->state.minimum_distance;
10188 }
10189
10190
10191 sfnt_move_zp1 (interpreter, p, 1,
10192 sfnt_sub (distance, current_projection));
10193
10194
10195
10196 interpreter->state.rp1 = interpreter->state.rp0;
10197 interpreter->state.rp2 = p;
10198
10199 if (opcode & 16)
10200 interpreter->state.rp0 = p;
10201 }
10202
10203
10204
10205
10206
10207
10208
10209
10210
10211
10212 static void
10213 sfnt_interpret_mdrp (struct sfnt_interpreter *interpreter,
10214 uint32_t opcode)
10215 {
10216 uint32_t p;
10217 sfnt_f26dot6 distance, delta;
10218 sfnt_f26dot6 current_projection, original_projection;
10219 sfnt_f26dot6 x, y, org_x, org_y;
10220 sfnt_f26dot6 rx, ry, org_rx, org_ry;
10221
10222
10223 p = POP ();
10224
10225
10226 sfnt_address_zp1 (interpreter, p, &x, &y, &org_x, &org_y);
10227 sfnt_address_zp0 (interpreter, interpreter->state.rp0,
10228 &rx, &ry, &org_rx, &org_ry);
10229
10230 distance = DUAL_PROJECT (org_x - org_rx,
10231 org_y - org_ry);
10232 original_projection = distance;
10233 current_projection = PROJECT (x - rx, y - ry);
10234
10235
10236
10237 delta = sfnt_sub (distance,
10238 interpreter->state.single_width_value);
10239
10240 if (delta < 0)
10241 delta = -delta;
10242
10243 if (delta < interpreter->state.sw_cut_in)
10244 {
10245
10246
10247
10248 if (distance >= 0)
10249 distance = interpreter->state.single_width_value;
10250 else
10251 distance = -interpreter->state.single_width_value;
10252 }
10253
10254
10255
10256
10257 if (opcode & 4)
10258 {
10259 delta = sfnt_sub (distance, original_projection);
10260
10261 if (delta < 0)
10262 delta = -delta;
10263
10264 if (delta > interpreter->state.cvt_cut_in)
10265 distance = original_projection;
10266
10267
10268 distance = sfnt_round_symmetric (interpreter, distance);
10269 }
10270
10271
10272
10273 if (opcode & 8)
10274 {
10275 if (original_projection >= 0
10276 && distance < interpreter->state.minimum_distance)
10277 distance = interpreter->state.minimum_distance;
10278 else if (original_projection < 0
10279 && distance > -interpreter->state.minimum_distance)
10280 distance = -interpreter->state.minimum_distance;
10281 }
10282
10283
10284 sfnt_move_zp1 (interpreter, p, 1,
10285 sfnt_sub (distance, current_projection));
10286
10287
10288
10289 interpreter->state.rp1 = interpreter->state.rp0;
10290 interpreter->state.rp2 = p;
10291
10292 if (opcode & 16)
10293 interpreter->state.rp0 = p;
10294 }
10295
10296
10297
10298
10299
10300
10301
10302
10303
10304
10305
10306
10307 static void
10308 sfnt_interpret_run (struct sfnt_interpreter *interpreter,
10309 enum sfnt_interpreter_run_context why)
10310 {
10311 unsigned char opcode;
10312 bool is_prep;
10313
10314
10315 is_prep = (why == SFNT_RUN_CONTEXT_CONTROL_VALUE_PROGRAM);
10316
10317 #ifdef TEST
10318
10319 if (why == SFNT_RUN_CONTEXT_TEST)
10320 is_prep = true;
10321 #endif
10322
10323 while (interpreter->IP < interpreter->num_instructions)
10324 {
10325 opcode = interpreter->instructions[interpreter->IP];
10326
10327 #ifdef TEST
10328 if (interpreter->run_hook)
10329 interpreter->run_hook (interpreter);
10330 #endif
10331
10332 switch (opcode)
10333 {
10334 case 0x00:
10335 SVTCAy ();
10336 break;
10337
10338 case 0x01:
10339 SVTCAx ();
10340 break;
10341
10342 case 0x02:
10343 SPvTCAy ();
10344 break;
10345
10346 case 0x03:
10347 SPvTCAx ();
10348 break;
10349
10350 case 0x04:
10351 SFvTCAy ();
10352 break;
10353
10354 case 0x05:
10355 SFvTCAx ();
10356 break;
10357
10358 case 0x06:
10359 case 0x07:
10360 SPVTL ();
10361 break;
10362
10363 case 0x08:
10364 case 0x09:
10365 SFVTL ();
10366 break;
10367
10368 case 0x0A:
10369 SPVFS ();
10370 break;
10371
10372 case 0x0B:
10373 SFVFS ();
10374 break;
10375
10376 case 0x0C:
10377 GPV ();
10378 break;
10379
10380 case 0x0D:
10381 GFV ();
10382 break;
10383
10384 case 0x0E:
10385 SFVTPV ();
10386 break;
10387
10388 case 0x0F:
10389 ISECT ();
10390 break;
10391
10392 case 0x10:
10393 SRP0 ();
10394 break;
10395
10396 case 0x11:
10397 SRP1 ();
10398 break;
10399
10400 case 0x12:
10401 SRP2 ();
10402 break;
10403
10404 case 0x13:
10405 SZP0 ();
10406 break;
10407
10408 case 0x14:
10409 SZP1 ();
10410 break;
10411
10412 case 0x15:
10413 SZP2 ();
10414 break;
10415
10416 case 0x16:
10417 SZPS ();
10418 break;
10419
10420 case 0x17:
10421 SLOOP ();
10422 break;
10423
10424 case 0x18:
10425 RTG ();
10426 break;
10427
10428 case 0x19:
10429 RTHG ();
10430 break;
10431
10432 case 0x1A:
10433 SMD ();
10434 break;
10435
10436 case 0x1B:
10437 ELSE ();
10438 break;
10439
10440 case 0x1C:
10441 JMPR ();
10442 break;
10443
10444 case 0x1D:
10445 SCVTCI ();
10446 break;
10447
10448 case 0x1E:
10449 SSWCI ();
10450 break;
10451
10452 case 0x1F:
10453 SSW ();
10454 break;
10455
10456 case 0x20:
10457 DUP ();
10458 break;
10459
10460 case 0x21:
10461 POP ();
10462 break;
10463
10464 case 0x22:
10465 CLEAR ();
10466 break;
10467
10468 case 0x23:
10469 SWAP ();
10470 break;
10471
10472 case 0x24:
10473 DEPTH ();
10474 break;
10475
10476 case 0x25:
10477 CINDEX ();
10478 break;
10479
10480 case 0x26:
10481 MINDEX ();
10482 break;
10483
10484 case 0x27:
10485 ALIGNPTS ();
10486 break;
10487
10488 case 0x28:
10489 RAW ();
10490 break;
10491
10492 case 0x29:
10493 UTP ();
10494 break;
10495
10496 case 0x2A:
10497 LOOPCALL ();
10498 break;
10499
10500 case 0x2B:
10501 CALL ();
10502 break;
10503
10504 case 0x2C:
10505 FDEF ();
10506 break;
10507
10508 case 0x2D:
10509 ENDF ();
10510 break;
10511
10512 case 0x2E:
10513 case 0x2F:
10514 MDAP ();
10515 break;
10516
10517 case 0x30:
10518 case 0x31:
10519 IUP ();
10520 break;
10521
10522 case 0x32:
10523 case 0x33:
10524 SHP ();
10525 break;
10526
10527 case 0x34:
10528 case 0x35:
10529 SHC ();
10530 break;
10531
10532 case 0x36:
10533 case 0x37:
10534 SHZ ();
10535 break;
10536
10537 case 0x38:
10538 SHPIX ();
10539 break;
10540
10541 case 0x39:
10542 IP ();
10543 break;
10544
10545 case 0x3A:
10546 case 0x3B:
10547 MSIRP ();
10548 break;
10549
10550 case 0x3C:
10551 ALIGNRP ();
10552 break;
10553
10554 case 0x3D:
10555 RTDG ();
10556 break;
10557
10558 case 0x3E:
10559 case 0x3F:
10560 MIAP ();
10561 break;
10562
10563 case 0x40:
10564 NPUSHB ();
10565 break;
10566
10567 case 0x41:
10568 NPUSHW ();
10569 break;
10570
10571 case 0x42:
10572 WS ();
10573 break;
10574
10575 case 0x43:
10576 RS ();
10577 break;
10578
10579 case 0x44:
10580 WCVTP ();
10581 break;
10582
10583 case 0x45:
10584 RCVT ();
10585 break;
10586
10587 case 0x46:
10588 case 0x47:
10589 GC ();
10590 break;
10591
10592 case 0x48:
10593 SCFS ();
10594 break;
10595
10596 case 0x49:
10597 case 0x4A:
10598 MD ();
10599 break;
10600
10601 case 0x4B:
10602 MPPEM ();
10603 break;
10604
10605 case 0x4C:
10606 MPS ();
10607 break;
10608
10609 case 0x4D:
10610 FLIPON ();
10611 break;
10612
10613 case 0x4E:
10614 FLIPOFF ();
10615 break;
10616
10617 case 0x4F:
10618 DEBUG ();
10619 break;
10620
10621 case 0x50:
10622 LT ();
10623 break;
10624
10625 case 0x51:
10626 LTEQ ();
10627 break;
10628
10629 case 0x52:
10630 GT ();
10631 break;
10632
10633 case 0x53:
10634 GTEQ ();
10635 break;
10636
10637 case 0x54:
10638 EQ ();
10639 break;
10640
10641 case 0x55:
10642 NEQ ();
10643 break;
10644
10645 case 0x56:
10646 ODD ();
10647 break;
10648
10649 case 0x57:
10650 EVEN ();
10651 break;
10652
10653 case 0x58:
10654 IF ();
10655 break;
10656
10657 case 0x59:
10658 EIF ();
10659 break;
10660
10661 case 0x5A:
10662 AND ();
10663 break;
10664
10665 case 0x5B:
10666 OR ();
10667 break;
10668
10669 case 0x5C:
10670 NOT ();
10671 break;
10672
10673 case 0x5D:
10674 DELTAP1 ();
10675 break;
10676
10677 case 0x5E:
10678 SDB ();
10679 break;
10680
10681 case 0x5F:
10682 SDS ();
10683 break;
10684
10685 case 0x60:
10686 ADD ();
10687 break;
10688
10689 case 0x61:
10690 SUB ();
10691 break;
10692
10693 case 0x62:
10694 DIV ();
10695 break;
10696
10697 case 0x63:
10698 MUL ();
10699 break;
10700
10701 case 0x64:
10702 ABS ();
10703 break;
10704
10705 case 0x65:
10706 NEG ();
10707 break;
10708
10709 case 0x66:
10710 FLOOR ();
10711 break;
10712
10713 case 0x67:
10714 CEILING ();
10715 break;
10716
10717 case 0x68:
10718 case 0x69:
10719 case 0x6A:
10720 case 0x6B:
10721 ROUND ();
10722 break;
10723
10724 case 0x6C:
10725 case 0x6D:
10726 case 0x6E:
10727 case 0x6F:
10728 NROUND ();
10729 break;
10730
10731 case 0x70:
10732 WCVTF ();
10733 break;
10734
10735 case 0x71:
10736 DELTAP2 ();
10737 break;
10738
10739 case 0x72:
10740 DELTAP3 ();
10741 break;
10742
10743 case 0x73:
10744 DELTAC1 ();
10745 break;
10746
10747 case 0x74:
10748 DELTAC2 ();
10749 break;
10750
10751 case 0x75:
10752 DELTAC3 ();
10753 break;
10754
10755 case 0x76:
10756 SROUND ();
10757 break;
10758
10759 case 0x77:
10760 S45ROUND ();
10761 break;
10762
10763 case 0x78:
10764 JROT ();
10765 break;
10766
10767 case 0x79:
10768 JROF ();
10769 break;
10770
10771 case 0x7A:
10772 ROFF ();
10773 break;
10774
10775 case 0x7B:
10776 ILLEGAL_INSTRUCTION ();
10777 break;
10778
10779 case 0x7C:
10780 RUTG ();
10781 break;
10782
10783 case 0x7D:
10784 RDTG ();
10785 break;
10786
10787 case 0x7E:
10788 SANGW ();
10789 break;
10790
10791 case 0x7F:
10792 AA ();
10793 break;
10794
10795 case 0x80:
10796 FLIPPT ();
10797 break;
10798
10799 case 0x81:
10800 FLIPRGON ();
10801 break;
10802
10803 case 0x82:
10804 FLIPRGOFF ();
10805 break;
10806
10807 case 0x83:
10808 case 0x84:
10809 NOT_IMPLEMENTED ();
10810 break;
10811
10812 case 0x85:
10813 SCANCTRL ();
10814 break;
10815
10816 case 0x86:
10817 case 0x87:
10818 SDPVTL ();
10819 break;
10820
10821 case 0x88:
10822 GETINFO ();
10823 break;
10824
10825 case 0x89:
10826 IDEF ();
10827 break;
10828
10829 case 0x8A:
10830 ROLL ();
10831 break;
10832
10833 case 0x8B:
10834 _MAX ();
10835 break;
10836
10837 case 0x8C:
10838 _MIN ();
10839 break;
10840
10841
10842
10843
10844 case 0x8D:
10845 SCANTYPE ();
10846 break;
10847
10848 case 0x8E:
10849 INSTCTRL ();
10850 break;
10851
10852 case 0x8F:
10853 case 0x90:
10854 NOT_IMPLEMENTED ();
10855 break;
10856
10857 case 0x91:
10858 GXAXIS ();
10859 break;
10860
10861 default:
10862 if (opcode >= 0xE0)
10863 {
10864 MIRP ();
10865 }
10866 else if (opcode >= 0xC0)
10867 {
10868 MDRP ();
10869 }
10870 else if (opcode >= 0xB8)
10871 {
10872 PUSHW ();
10873 }
10874 else if (opcode >= 0xB0)
10875 {
10876 PUSHB ();
10877 }
10878 else
10879 NOT_IMPLEMENTED ();
10880 }
10881
10882 next_instruction:
10883
10884
10885
10886
10887 interpreter->IP++;
10888
10889
10890
10891
10892 skip_step:
10893 continue;
10894 }
10895 }
10896
10897
10898
10899
10900
10901
10902
10903
10904
10905
10906
10907 TEST_STATIC const char *
10908 sfnt_interpret_font_program (struct sfnt_interpreter *interpreter,
10909 struct sfnt_fpgm_table *fpgm)
10910 {
10911 if (setjmp (interpreter->trap))
10912 return interpreter->trap_reason;
10913
10914
10915 interpreter->IP = 0;
10916 interpreter->SP = interpreter->stack;
10917 interpreter->instructions = fpgm->instructions;
10918 interpreter->num_instructions = fpgm->num_instructions;
10919 interpreter->glyph_zone = NULL;
10920
10921 sfnt_interpret_run (interpreter, SFNT_RUN_CONTEXT_FONT_PROGRAM);
10922 return NULL;
10923 }
10924
10925
10926
10927
10928
10929
10930
10931
10932
10933
10934
10935 TEST_STATIC const char *
10936 sfnt_interpret_control_value_program (struct sfnt_interpreter *interpreter,
10937 struct sfnt_prep_table *prep,
10938 struct sfnt_graphics_state *state)
10939 {
10940 if (setjmp (interpreter->trap))
10941 return interpreter->trap_reason;
10942
10943
10944 interpreter->IP = 0;
10945 interpreter->SP = interpreter->stack;
10946 interpreter->instructions = prep->instructions;
10947 interpreter->num_instructions = prep->num_instructions;
10948 interpreter->glyph_zone = NULL;
10949
10950 sfnt_interpret_run (interpreter,
10951 SFNT_RUN_CONTEXT_CONTROL_VALUE_PROGRAM);
10952
10953
10954
10955
10956 if (interpreter->state.instruct_control & 4)
10957 sfnt_init_graphics_state (&interpreter->state);
10958
10959
10960 memcpy (state, &interpreter->state, sizeof *state);
10961 return NULL;
10962 }
10963
10964
10965
10966
10967
10968
10969
10970
10971
10972
10973
10974
10975
10976
10977
10978
10979
10980
10981
10982
10983
10984
10985
10986
10987
10988
10989
10990
10991
10992
10993
10994
10995
10996 static int
10997 sfnt_decompose_instructed_outline (struct sfnt_instructed_outline *outline,
10998 sfnt_move_to_proc move_to,
10999 sfnt_line_to_proc line_to,
11000 sfnt_curve_to_proc curve_to,
11001 void *dcontext)
11002 {
11003 size_t here, last, n;
11004
11005 if (!outline->num_contours)
11006 return 0;
11007
11008 here = 0;
11009
11010 for (n = 0; n < outline->num_contours; ++n)
11011 {
11012
11013
11014
11015 last = outline->contour_end_points[n];
11016
11017
11018
11019 if (here > last || last >= outline->num_points)
11020 goto fail;
11021
11022 if (sfnt_decompose_glyph_2 (here, last, move_to,
11023 line_to, curve_to, dcontext,
11024 outline->x_points,
11025 outline->y_points,
11026 outline->flags, 1024))
11027 goto fail;
11028
11029
11030 here = last + 1;
11031
11032
11033
11034
11035
11036
11037 while (here < outline->num_points
11038 && outline->flags[here] & SFNT_POINT_PHANTOM)
11039 here++;
11040 }
11041
11042 return 0;
11043
11044 fail:
11045 return 1;
11046 }
11047
11048
11049
11050
11051
11052
11053
11054 TEST_STATIC struct sfnt_glyph_outline *
11055 sfnt_build_instructed_outline (struct sfnt_instructed_outline *instructed)
11056 {
11057 struct sfnt_glyph_outline *outline;
11058 int rc;
11059
11060 memset (&build_outline_context, 0, sizeof build_outline_context);
11061
11062
11063 outline = xmalloc (sizeof *outline + 40 * sizeof (*outline->outline));
11064 outline->outline_size = 40;
11065 outline->outline_used = 0;
11066 outline->refcount = 0;
11067 outline->outline
11068 = (struct sfnt_glyph_outline_command *) (outline + 1);
11069
11070
11071 outline->xmin = 0;
11072 outline->ymin = 0;
11073 outline->xmax = 0;
11074 outline->ymax = 0;
11075
11076
11077 build_outline_context.outline = outline;
11078 build_outline_context.factor = 0177777;
11079
11080
11081 rc = sfnt_decompose_instructed_outline (instructed,
11082 sfnt_move_to_and_build,
11083 sfnt_line_to_and_build,
11084 sfnt_curve_to_and_build,
11085 NULL);
11086
11087
11088
11089 outline = build_outline_context.outline;
11090
11091
11092
11093
11094 if (instructed->num_points > 1)
11095 outline->origin
11096 = instructed->x_points[instructed->num_points - 2];
11097 else
11098 outline->origin = 0;
11099
11100 if (rc)
11101 {
11102 xfree (outline);
11103 return NULL;
11104 }
11105
11106 return outline;
11107 }
11108
11109
11110
11111
11112
11113
11114
11115
11116
11117
11118 static void
11119 sfnt_compute_phantom_points (struct sfnt_glyph *glyph,
11120 struct sfnt_glyph_metrics *metrics,
11121 sfnt_fixed scale,
11122 sfnt_f26dot6 *x1, sfnt_f26dot6 *y1,
11123 sfnt_f26dot6 *x2, sfnt_f26dot6 *y2)
11124 {
11125 sfnt_fword f1, f2;
11126
11127
11128
11129
11130
11131
11132
11133
11134
11135 f1 = glyph->xmin - metrics->lbearing;
11136 f2 = f1 + metrics->advance;
11137
11138
11139 f1 += glyph->origin_distortion;
11140 f2 += glyph->advance_distortion;
11141
11142
11143 *x1 = sfnt_mul_f26dot6_fixed (f1 * 64, scale);
11144 *x2 = sfnt_mul_f26dot6_fixed (f2 * 64, scale);
11145
11146
11147 *y1 = 0;
11148 *y2 = 0;
11149 }
11150
11151
11152
11153
11154
11155
11156
11157
11158 TEST_STATIC const char *
11159 sfnt_interpret_simple_glyph (struct sfnt_glyph *glyph,
11160 struct sfnt_interpreter *interpreter,
11161 struct sfnt_glyph_metrics *metrics,
11162 struct sfnt_instructed_outline **value)
11163 {
11164 size_t zone_size, temp, outline_size, i;
11165 struct sfnt_interpreter_zone *zone;
11166 struct sfnt_interpreter_zone *volatile preserved_zone;
11167 sfnt_f26dot6 phantom_point_1_x;
11168 sfnt_f26dot6 phantom_point_1_y;
11169 sfnt_f26dot6 phantom_point_2_x;
11170 sfnt_f26dot6 phantom_point_2_y;
11171 sfnt_f26dot6 tem;
11172 volatile bool zone_was_allocated;
11173 struct sfnt_instructed_outline *outline;
11174
11175 zone_size = 0;
11176 zone_was_allocated = false;
11177
11178
11179
11180 if (INT_MULTIPLY_WRAPV (glyph->simple->number_of_points + 2,
11181 sizeof *zone->x_points * 4,
11182 &temp)
11183 || INT_ADD_WRAPV (temp, zone_size, &zone_size)
11184 || INT_MULTIPLY_WRAPV (glyph->number_of_contours,
11185 sizeof *zone->contour_end_points,
11186 &temp)
11187 || INT_ADD_WRAPV (temp, zone_size, &zone_size)
11188 || INT_MULTIPLY_WRAPV (glyph->simple->number_of_points + 2,
11189 sizeof *zone->flags,
11190 &temp)
11191 || INT_ADD_WRAPV (temp, zone_size, &zone_size)
11192 || INT_ADD_WRAPV (sizeof *zone, zone_size, &zone_size))
11193 return "Glyph exceeded maximum permissible size";
11194
11195
11196
11197 if (zone_size <= 1024 * 16)
11198 zone = alloca (zone_size);
11199 else
11200 {
11201 zone = xmalloc (zone_size);
11202 zone_was_allocated = true;
11203 }
11204
11205
11206 zone->num_points = glyph->simple->number_of_points + 2;
11207 zone->num_contours = glyph->number_of_contours;
11208 zone->contour_end_points = (size_t *) (zone + 1);
11209 zone->x_points = (sfnt_f26dot6 *) (zone->contour_end_points
11210 + zone->num_contours);
11211 zone->x_current = zone->x_points + zone->num_points;
11212 zone->y_points = zone->x_current + zone->num_points;
11213 zone->y_current = zone->y_points + zone->num_points;
11214 zone->flags = (unsigned char *) (zone->y_current
11215 + zone->num_points);
11216
11217
11218 for (i = 0; i < glyph->simple->number_of_points; ++i)
11219 {
11220
11221 tem = glyph->simple->x_coordinates[i];
11222
11223
11224 tem = sfnt_mul_f26dot6_fixed (tem * 64, interpreter->scale);
11225
11226
11227 zone->x_points[i] = tem;
11228 zone->x_current[i] = tem;
11229 }
11230
11231
11232 sfnt_compute_phantom_points (glyph, metrics, interpreter->scale,
11233 &phantom_point_1_x, &phantom_point_1_y,
11234 &phantom_point_2_x, &phantom_point_2_y);
11235
11236
11237 zone->x_points[i] = phantom_point_1_x;
11238 zone->x_points[i + 1] = phantom_point_2_x;
11239 zone->x_current[i] = phantom_point_1_x;
11240 zone->x_current[i + 1] = phantom_point_2_x;
11241
11242
11243 for (i = 0; i < glyph->simple->number_of_points; ++i)
11244 {
11245
11246 tem = glyph->simple->y_coordinates[i];
11247
11248
11249
11250 tem = sfnt_mul_fixed (tem * 64, interpreter->scale);
11251
11252
11253 zone->y_points[i] = tem;
11254 zone->y_current[i] = tem;
11255
11256
11257 zone->flags[i] = (glyph->simple->flags[i]
11258 & ~SFNT_POINT_TOUCHED_BOTH);
11259
11260
11261 zone->flags[i] &= ~SFNT_POINT_PHANTOM;
11262 }
11263
11264
11265 zone->y_points[i] = phantom_point_1_y;
11266 zone->y_points[i + 1] = phantom_point_2_y;
11267 zone->y_current[i] = phantom_point_1_x;
11268 zone->y_current[i + 1] = phantom_point_2_x;
11269
11270
11271 zone->flags[i] = SFNT_POINT_PHANTOM;
11272 zone->flags[i + 1] = SFNT_POINT_PHANTOM;
11273
11274
11275 for (i = 0; i < zone->num_contours; ++i)
11276 zone->contour_end_points[i]
11277 = glyph->simple->end_pts_of_contours[i];
11278
11279
11280 interpreter->IP = 0;
11281 interpreter->SP = interpreter->stack;
11282 interpreter->instructions = glyph->simple->instructions;
11283 interpreter->num_instructions = glyph->simple->instruction_length;
11284 interpreter->glyph_zone = zone;
11285
11286
11287 preserved_zone = zone;
11288
11289 if (setjmp (interpreter->trap))
11290 {
11291 if (zone_was_allocated)
11292 xfree (preserved_zone);
11293
11294 interpreter->glyph_zone = NULL;
11295 return interpreter->trap_reason;
11296 }
11297
11298 sfnt_interpret_run (interpreter, SFNT_RUN_CONTEXT_GLYPH_PROGRAM);
11299 interpreter->glyph_zone = NULL;
11300
11301
11302 zone = preserved_zone;
11303
11304
11305
11306 outline_size = sizeof (*outline);
11307 outline_size += (zone->num_contours
11308 * sizeof *outline->contour_end_points);
11309 outline_size += (zone->num_points
11310 * sizeof *outline->x_points * 2);
11311 outline_size += zone->num_points;
11312
11313
11314 outline = xmalloc (outline_size);
11315 outline->num_points = zone->num_points;
11316 outline->num_contours = zone->num_contours;
11317 outline->contour_end_points = (size_t *) (outline + 1);
11318 outline->x_points = (sfnt_f26dot6 *) (outline->contour_end_points
11319 + outline->num_contours);
11320 outline->y_points = outline->x_points + outline->num_points;
11321 outline->flags = (unsigned char *) (outline->y_points
11322 + outline->num_points);
11323
11324
11325 memcpy (outline->contour_end_points, zone->contour_end_points,
11326 zone->num_contours * sizeof *outline->contour_end_points);
11327 memcpy (outline->x_points, zone->x_current,
11328 zone->num_points * sizeof *outline->x_points);
11329 memcpy (outline->y_points, zone->y_current,
11330 zone->num_points * sizeof *outline->y_points);
11331 memcpy (outline->flags, zone->flags, zone->num_points);
11332
11333
11334 if (zone_was_allocated)
11335 xfree (zone);
11336
11337
11338 *value = outline;
11339 return NULL;
11340 }
11341
11342
11343
11344
11345
11346
11347
11348
11349
11350
11351
11352
11353
11354 static void
11355 sfnt_transform_f26dot6 (struct sfnt_compound_glyph_component *component,
11356 sfnt_f26dot6 *restrict x, sfnt_f26dot6 *restrict y,
11357 size_t num_coordinates,
11358 sfnt_f26dot6 x_off, sfnt_f26dot6 y_off)
11359 {
11360 double m1, m2, m3;
11361 double m4, m5, m6;
11362 size_t i;
11363
11364 if (component->flags & 010)
11365 {
11366 for (i = 0; i < num_coordinates; ++i)
11367 {
11368 x[i] *= component->u.scale / 16384.0;
11369 y[i] *= component->u.scale / 16384.0;
11370 x[i] += x_off;
11371 y[i] += y_off;
11372 }
11373 }
11374 else if (component->flags & 0100)
11375 {
11376 for (i = 0; i < num_coordinates; ++i)
11377 {
11378 x[i] *= component->u.a.xscale / 16384.0;
11379 y[i] *= component->u.a.yscale / 16384.0;
11380 x[i] += x_off;
11381 y[i] += y_off;
11382 }
11383 }
11384 else if (component->flags & 0200)
11385 {
11386
11387
11388
11389
11390
11391
11392
11393
11394
11395
11396
11397
11398
11399
11400
11401
11402 m1 = component->u.b.xscale / 16384.0;
11403 m2 = component->u.b.scale01 / 16384.0;
11404 m3 = 0;
11405 m4 = component->u.b.scale10 / 16384.0;
11406 m5 = component->u.b.yscale / 16384.0;
11407 m6 = 0;
11408
11409 for (i = 0; i < num_coordinates; ++i)
11410 {
11411 x[i] = m1 * x[i] + m2 * y[i] + m3 * 1;
11412 y[i] = m4 * x[i] + m5 * y[i] + m6 * 1;
11413 x[i] += x_off;
11414 y[i] += y_off;
11415 }
11416 }
11417 }
11418
11419
11420
11421
11422
11423
11424
11425
11426
11427
11428
11429
11430
11431
11432
11433 static const char *
11434 sfnt_interpret_compound_glyph_2 (struct sfnt_glyph *glyph,
11435 struct sfnt_interpreter *interpreter,
11436 struct sfnt_compound_glyph_context *context,
11437 size_t base_index, size_t base_contour,
11438 struct sfnt_glyph_metrics *metrics)
11439 {
11440 size_t num_points, num_contours, i;
11441 size_t zone_size, temp;
11442 struct sfnt_interpreter_zone *zone;
11443 struct sfnt_interpreter_zone *volatile preserved_zone;
11444 sfnt_f26dot6 phantom_point_1_x;
11445 sfnt_f26dot6 phantom_point_1_y;
11446 sfnt_f26dot6 phantom_point_2_x;
11447 sfnt_f26dot6 phantom_point_2_y;
11448 volatile bool zone_was_allocated;
11449 int rc;
11450 sfnt_f26dot6 *x_base, *y_base;
11451 size_t *contour_base;
11452 unsigned char *flags_base;
11453
11454
11455
11456 num_points = context->num_points - base_index;
11457 num_contours = context->num_end_points - base_contour;
11458
11459
11460 if (!num_points && !num_contours)
11461 return NULL;
11462
11463
11464
11465
11466 zone_size = 0;
11467 zone_was_allocated = false;
11468
11469 if (INT_MULTIPLY_WRAPV (num_points + 2,
11470 sizeof *zone->x_points * 4,
11471 &temp)
11472 || INT_ADD_WRAPV (temp, zone_size, &zone_size)
11473 || INT_MULTIPLY_WRAPV (num_contours,
11474 sizeof *zone->contour_end_points,
11475 &temp)
11476 || INT_ADD_WRAPV (temp, zone_size, &zone_size)
11477 || INT_MULTIPLY_WRAPV (num_points + 2,
11478 sizeof *zone->flags,
11479 &temp)
11480 || INT_ADD_WRAPV (temp, zone_size, &zone_size)
11481 || INT_ADD_WRAPV (sizeof *zone, zone_size, &zone_size))
11482 return "Glyph exceeded maximum permissible size";
11483
11484
11485
11486 if (zone_size <= 1024 * 16)
11487 zone = alloca (zone_size);
11488 else
11489 {
11490 zone = xmalloc (zone_size);
11491 zone_was_allocated = true;
11492 }
11493
11494
11495 zone->num_points = num_points + 2;
11496 zone->num_contours = num_contours;
11497 zone->contour_end_points = (size_t *) (zone + 1);
11498 zone->x_points = (sfnt_f26dot6 *) (zone->contour_end_points
11499 + zone->num_contours);
11500 zone->x_current = zone->x_points + zone->num_points;
11501 zone->y_points = zone->x_current + zone->num_points;
11502 zone->y_current = zone->y_points + zone->num_points;
11503 zone->flags = (unsigned char *) (zone->y_current
11504 + zone->num_points);
11505
11506
11507
11508
11509 for (i = 0; i < zone->num_contours; ++i)
11510 zone->contour_end_points[i]
11511 = (context->contour_end_points[base_contour + i]
11512 - base_index);
11513
11514
11515
11516 for (i = 0; i < num_points; ++i)
11517 {
11518 zone->x_current[i] = context->x_coordinates[i + base_index];
11519 zone->x_points[i] = context->x_coordinates[i + base_index];
11520 }
11521
11522
11523 sfnt_compute_phantom_points (glyph, metrics, interpreter->scale,
11524 &phantom_point_1_x, &phantom_point_1_y,
11525 &phantom_point_2_x, &phantom_point_2_y);
11526
11527
11528 zone->x_points[i] = phantom_point_1_x;
11529 zone->x_points[i + 1] = phantom_point_2_x;
11530 zone->x_current[i] = phantom_point_1_x;
11531 zone->x_current[i + 1] = phantom_point_2_x;
11532
11533 for (i = 0; i < num_points; ++i)
11534 {
11535 zone->y_current[i] = context->y_coordinates[i + base_index];
11536 zone->y_points[i] = context->y_coordinates[i + base_index];
11537
11538
11539 zone->flags[i] = (context->flags[i + base_index]
11540 & ~SFNT_POINT_TOUCHED_BOTH);
11541 }
11542
11543
11544 zone->y_points[i] = phantom_point_1_y;
11545 zone->y_points[i + 1] = phantom_point_2_y;
11546 zone->y_current[i] = phantom_point_1_x;
11547 zone->y_current[i + 1] = phantom_point_2_x;
11548
11549
11550 zone->flags[i] = SFNT_POINT_PHANTOM;
11551 zone->flags[i + 1] = SFNT_POINT_PHANTOM;
11552
11553
11554 interpreter->IP = 0;
11555 interpreter->SP = interpreter->stack;
11556 interpreter->instructions = glyph->compound->instructions;
11557 interpreter->num_instructions = glyph->compound->instruction_length;
11558 interpreter->glyph_zone = zone;
11559
11560
11561 preserved_zone = zone;
11562
11563 if (setjmp (interpreter->trap))
11564 {
11565 if (zone_was_allocated)
11566 xfree (preserved_zone);
11567
11568 interpreter->glyph_zone = NULL;
11569 return interpreter->trap_reason;
11570 }
11571
11572 sfnt_interpret_run (interpreter, SFNT_RUN_CONTEXT_GLYPH_PROGRAM);
11573 interpreter->glyph_zone = NULL;
11574
11575
11576 zone = preserved_zone;
11577
11578
11579
11580
11581 for (i = 0; i < num_points; ++i)
11582 {
11583 context->x_coordinates[base_index + i] = zone->x_current[i];
11584 context->y_coordinates[base_index + i] = zone->y_current[i];
11585 }
11586
11587
11588 rc = sfnt_expand_compound_glyph_context (context, 0, 2,
11589 &x_base, &y_base,
11590 &flags_base,
11591 &contour_base);
11592
11593 if (rc)
11594 {
11595 if (zone_was_allocated)
11596 xfree (zone);
11597
11598 return "Failed to expand arrays for phantom points";
11599 }
11600
11601
11602 x_base[0] = zone->x_current[num_points - 2];
11603 x_base[1] = zone->x_current[num_points - 1];
11604 y_base[0] = zone->y_current[num_points - 2];
11605 y_base[1] = zone->y_current[num_points - 1];
11606 flags_base[0] = zone->flags[num_points - 2];
11607 flags_base[1] = zone->flags[num_points - 1];
11608
11609
11610 if (zone_was_allocated)
11611 xfree (zone);
11612
11613 return NULL;
11614 }
11615
11616
11617
11618
11619
11620
11621
11622
11623
11624
11625
11626 static const char *
11627 sfnt_interpret_compound_glyph_1 (struct sfnt_glyph *glyph,
11628 struct sfnt_interpreter *interpreter,
11629 struct sfnt_graphics_state *state,
11630 struct sfnt_compound_glyph_context *context,
11631 sfnt_get_glyph_proc get_glyph,
11632 sfnt_free_glyph_proc free_glyph,
11633 struct sfnt_hmtx_table *hmtx,
11634 struct sfnt_hhea_table *hhea,
11635 struct sfnt_maxp_table *maxp,
11636 struct sfnt_glyph_metrics *metrics,
11637 sfnt_fixed off_x, sfnt_fixed off_y,
11638 int recursion_count,
11639 void *dcontext)
11640 {
11641 struct sfnt_glyph *subglyph;
11642 int i, j, rc;
11643 const char *error;
11644 bool need_free;
11645 struct sfnt_compound_glyph_component *component;
11646 sfnt_f26dot6 x, y, xtemp, ytemp;
11647 size_t point, point2;
11648 size_t last_point, number_of_contours;
11649 sfnt_f26dot6 *x_base, *y_base;
11650 size_t *contour_base;
11651 unsigned char *flags_base;
11652 size_t base_index, contour_start, base_contour;
11653 bool defer_offsets;
11654 struct sfnt_instructed_outline *value;
11655 struct sfnt_glyph_metrics sub_metrics;
11656
11657 error = NULL;
11658
11659
11660
11661
11662
11663
11664 base_index = context->num_points;
11665
11666
11667 base_contour = context->num_end_points;
11668
11669
11670
11671
11672 if (recursion_count > 16)
11673 return "Overly deep recursion in compound glyph data";
11674
11675
11676 point = point2 = 0;
11677
11678 for (j = 0; j < glyph->compound->num_components; ++j)
11679 {
11680
11681 component = &glyph->compound->components[j];
11682 subglyph = get_glyph (component->glyph_index,
11683 dcontext, &need_free);
11684
11685 if (!subglyph)
11686 return "Failed to obtain component glyph";
11687
11688
11689
11690
11691
11692 defer_offsets = false;
11693
11694
11695
11696
11697 contour_start = context->num_points;
11698
11699
11700 if (component->flags & 02)
11701 {
11702
11703
11704
11705 if (!(component->flags & 01))
11706 {
11707
11708 x = component->argument1.b * 64;
11709 y = component->argument2.b * 64;
11710 }
11711 else
11712 {
11713
11714 x = component->argument1.d * 64;
11715 y = component->argument2.d * 64;
11716 }
11717
11718
11719 x = sfnt_mul_f26dot6_fixed (x, interpreter->scale);
11720 y = sfnt_mul_f26dot6_fixed (y, interpreter->scale);
11721
11722
11723
11724 if (component->flags & 04000)
11725 sfnt_transform_f26dot6 (component, &x, &y, 1,
11726 0, 0);
11727
11728 if (component->flags & 04)
11729 {
11730 x = sfnt_round_f26dot6 (x);
11731 y = sfnt_round_f26dot6 (y);
11732 }
11733 }
11734 else
11735 {
11736
11737
11738
11739
11740
11741
11742
11743
11744 if (!(component->flags & 01))
11745 {
11746 point = base_index + component->argument1.a;
11747 point2 = component->argument2.a;
11748 }
11749 else
11750 {
11751 point = base_index + component->argument1.c;
11752 point2 = component->argument2.c;
11753 }
11754
11755
11756
11757
11758 if (point >= contour_start)
11759 {
11760 if (need_free)
11761 free_glyph (subglyph, dcontext);
11762
11763 return "Invalid anchor point";
11764 }
11765
11766 if (!subglyph->compound)
11767 {
11768 if (point2 >= subglyph->simple->number_of_points)
11769 {
11770 if (need_free)
11771 free_glyph (subglyph, dcontext);
11772
11773 return "Invalid anchored point";
11774 }
11775
11776
11777 xtemp = context->x_coordinates[point];
11778 ytemp = context->y_coordinates[point];
11779 x = (xtemp - subglyph->simple->x_coordinates[point2] * 64);
11780 y = (ytemp - subglyph->simple->y_coordinates[point2] * 64);
11781 }
11782 else
11783 {
11784
11785
11786
11787 x = 0;
11788 y = 0;
11789
11790
11791
11792
11793 defer_offsets = true;
11794 }
11795 }
11796
11797
11798
11799
11800 if (sfnt_lookup_glyph_metrics (component->glyph_index,
11801 -1, &sub_metrics,
11802 hmtx, hhea, NULL, maxp))
11803 {
11804 if (need_free)
11805 free_glyph (subglyph, dcontext);
11806
11807 return "Failed to obtain component metrics";
11808 }
11809
11810 if (subglyph->simple)
11811 {
11812
11813
11814
11815
11816
11817 if (subglyph->number_of_contours)
11818 {
11819
11820
11821 interpreter->state = *state;
11822 error = sfnt_interpret_simple_glyph (subglyph, interpreter,
11823 &sub_metrics, &value);
11824
11825
11826
11827 if (error)
11828 {
11829 if (need_free)
11830 free_glyph (subglyph, dcontext);
11831
11832 return error;
11833 }
11834
11835
11836
11837
11838
11839 last_point = value->num_points;
11840 number_of_contours = value->num_contours;
11841
11842
11843 rc = sfnt_expand_compound_glyph_context (context,
11844
11845
11846
11847 number_of_contours,
11848
11849
11850
11851 last_point,
11852 &x_base,
11853 &y_base,
11854 &flags_base,
11855 &contour_base);
11856 if (rc)
11857 {
11858 xfree (value);
11859
11860 if (need_free)
11861 free_glyph (subglyph, dcontext);
11862
11863 return "Failed to grow arrays";
11864 }
11865
11866
11867
11868
11869 for (i = 0; i < last_point; ++i)
11870 {
11871 x_base[i] = value->x_points[i] + off_x + x;
11872 y_base[i] = value->y_points[i] + off_y + y;
11873 flags_base[i] = value->flags[i];
11874 }
11875
11876
11877 for (i = 0; i < number_of_contours; ++i)
11878 contour_base[i] = (contour_start
11879 + value->contour_end_points[i]);
11880
11881 xfree (value);
11882
11883
11884 sfnt_transform_f26dot6 (component, x_base, y_base,
11885 last_point, 0, 0);
11886 }
11887 }
11888 else
11889 {
11890
11891
11892
11893 error = sfnt_interpret_compound_glyph_1 (subglyph, interpreter,
11894 state,
11895 context, get_glyph,
11896 free_glyph, hmtx, hhea,
11897 maxp, &sub_metrics,
11898 off_x + x, off_y + y,
11899 recursion_count + 1,
11900 dcontext);
11901
11902 if (error)
11903 {
11904 if (need_free)
11905 free_glyph (subglyph, dcontext);
11906
11907 return error;
11908 }
11909
11910
11911
11912
11913
11914
11915
11916
11917
11918
11919
11920
11921 x = 0;
11922 y = 0;
11923
11924 if (defer_offsets)
11925 {
11926
11927
11928 point2 += contour_start;
11929
11930
11931
11932
11933
11934 if (point2 >= context->num_points)
11935 {
11936 if (need_free)
11937 free_glyph (subglyph, dcontext);
11938
11939 return "Invalid point2";
11940 }
11941
11942
11943
11944
11945 xtemp = context->x_coordinates[point];
11946 ytemp = context->y_coordinates[point];
11947 x = (xtemp - context->x_coordinates[point2]);
11948 y = (ytemp - context->y_coordinates[point2]);
11949 }
11950
11951 sfnt_transform_f26dot6 (component,
11952 context->x_coordinates + contour_start,
11953 context->y_coordinates + contour_start,
11954 contour_start - context->num_points,
11955 x, y);
11956 }
11957
11958
11959 if (need_free)
11960 free_glyph (subglyph, dcontext);
11961 }
11962
11963
11964
11965 if (glyph->compound->instruction_length)
11966 {
11967 interpreter->state = *state;
11968 error = sfnt_interpret_compound_glyph_2 (glyph, interpreter,
11969 context, base_index,
11970 base_contour,
11971 metrics);
11972 }
11973
11974 return error;
11975 }
11976
11977
11978
11979
11980
11981
11982
11983
11984
11985
11986
11987
11988
11989
11990
11991
11992
11993
11994
11995
11996
11997
11998
11999
12000
12001
12002
12003 TEST_STATIC const char *
12004 sfnt_interpret_compound_glyph (struct sfnt_glyph *glyph,
12005 struct sfnt_interpreter *interpreter,
12006 struct sfnt_graphics_state *state,
12007 sfnt_get_glyph_proc get_glyph,
12008 sfnt_free_glyph_proc free_glyph,
12009 struct sfnt_hmtx_table *hmtx,
12010 struct sfnt_hhea_table *hhea,
12011 struct sfnt_maxp_table *maxp,
12012 struct sfnt_glyph_metrics *metrics,
12013 void *dcontext,
12014 struct sfnt_instructed_outline **value)
12015 {
12016 struct sfnt_compound_glyph_context context;
12017 const char *error;
12018 struct sfnt_instructed_outline *outline;
12019 size_t outline_size, temp;
12020
12021
12022 memset (&context, 0, sizeof context);
12023
12024
12025 error = sfnt_interpret_compound_glyph_1 (glyph, interpreter,
12026 state, &context,
12027 get_glyph, free_glyph,
12028 hmtx, hhea, maxp,
12029 metrics, 0, 0, 0,
12030 dcontext);
12031
12032
12033
12034 if (error)
12035 {
12036 xfree (context.x_coordinates);
12037 xfree (context.y_coordinates);
12038 xfree (context.flags);
12039 xfree (context.contour_end_points);
12040 return error;
12041 }
12042
12043
12044 outline_size = sizeof (*outline);
12045
12046 if (INT_MULTIPLY_WRAPV (context.num_end_points,
12047 sizeof *outline->contour_end_points,
12048 &temp)
12049 || INT_ADD_WRAPV (outline_size, temp, &outline_size)
12050 || INT_MULTIPLY_WRAPV (context.num_points,
12051 sizeof *outline->x_points * 2,
12052 &temp)
12053 || INT_ADD_WRAPV (outline_size, temp, &outline_size)
12054 || INT_ADD_WRAPV (context.num_points, outline_size,
12055 &outline_size))
12056 {
12057 xfree (context.x_coordinates);
12058 xfree (context.y_coordinates);
12059 xfree (context.flags);
12060 xfree (context.contour_end_points);
12061 return "Glyph exceeds maximum permissible size";
12062 }
12063
12064
12065 outline = xmalloc (outline_size);
12066 outline->num_points = context.num_points;
12067 outline->num_contours = context.num_end_points;
12068 outline->contour_end_points = (size_t *) (outline + 1);
12069 outline->x_points = (sfnt_f26dot6 *) (outline->contour_end_points
12070 + outline->num_contours);
12071 outline->y_points = outline->x_points + outline->num_points;
12072 outline->flags = (unsigned char *) (outline->y_points
12073 + outline->num_points);
12074
12075
12076
12077
12078
12079 if (context.num_end_points)
12080 memcpy (outline->contour_end_points, context.contour_end_points,
12081 outline->num_contours * sizeof *outline->contour_end_points);
12082
12083 if (context.num_points)
12084 {
12085 memcpy (outline->x_points, context.x_coordinates,
12086 outline->num_points * sizeof *outline->x_points);
12087 memcpy (outline->y_points, context.y_coordinates,
12088 outline->num_points * sizeof *outline->y_points);
12089 memcpy (outline->flags, context.flags, context.num_points);
12090 }
12091
12092
12093 xfree (context.x_coordinates);
12094 xfree (context.y_coordinates);
12095 xfree (context.flags);
12096 xfree (context.contour_end_points);
12097
12098 *value = outline;
12099 return NULL;
12100 }
12101
12102
12103
12104
12105
12106
12107
12108
12109
12110
12111
12112
12113
12114
12115
12116
12117
12118
12119
12120
12121
12122
12123
12124 static struct sfnt_default_uvs_table *
12125 sfnt_read_default_uvs_table (int fd, off_t offset)
12126 {
12127 struct sfnt_default_uvs_table *uvs;
12128 uint32_t num_ranges, i, j;
12129 size_t size, temp;
12130 char data[512];
12131
12132
12133
12134 if (lseek (fd, offset, SEEK_SET) != offset)
12135 return NULL;
12136
12137
12138
12139 if (read (fd, &num_ranges, sizeof num_ranges) != sizeof num_ranges)
12140 return NULL;
12141
12142
12143 sfnt_swap32 (&num_ranges);
12144
12145
12146
12147 size = sizeof *uvs;
12148 if (INT_MULTIPLY_WRAPV (sizeof *uvs->ranges, num_ranges,
12149 &temp)
12150 || INT_ADD_WRAPV (temp, size, &size))
12151 return NULL;
12152
12153 uvs = xmalloc (size);
12154
12155
12156 uvs->num_unicode_value_ranges = num_ranges;
12157
12158
12159 uvs->ranges = (struct sfnt_unicode_value_range *) (uvs + 1);
12160 i = 0;
12161
12162
12163
12164
12165 while (num_ranges)
12166 {
12167 size = (num_ranges > 128 ? 512 : num_ranges * 4);
12168
12169 if (read (fd, data, size) != size)
12170 {
12171 xfree (uvs);
12172 return NULL;
12173 }
12174
12175 for (j = 0; j < size / 4; ++j)
12176 {
12177 uvs->ranges[i + j].start_unicode_value
12178 = sfnt_read_24 ((unsigned char *) data + j * 4);
12179 uvs->ranges[i + j].additional_count = data[j * 4 + 1];
12180 }
12181
12182 i += j;
12183 num_ranges -= size / 4;
12184 }
12185
12186
12187 return uvs;
12188 }
12189
12190
12191
12192
12193
12194 static struct sfnt_nondefault_uvs_table *
12195 sfnt_read_nondefault_uvs_table (int fd, off_t offset)
12196 {
12197 struct sfnt_nondefault_uvs_table *uvs;
12198 uint32_t num_mappings, i, j;
12199 size_t size, temp;
12200 char data[500];
12201
12202
12203
12204 if (lseek (fd, offset, SEEK_SET) != offset)
12205 return NULL;
12206
12207
12208
12209 if (read (fd, &num_mappings, sizeof num_mappings)
12210 != sizeof num_mappings)
12211 return NULL;
12212
12213
12214 sfnt_swap32 (&num_mappings);
12215
12216
12217
12218 size = sizeof *uvs;
12219 if (INT_MULTIPLY_WRAPV (sizeof *uvs->mappings, num_mappings,
12220 &temp)
12221 || INT_ADD_WRAPV (temp, size, &size))
12222 return NULL;
12223
12224 uvs = xmalloc (size);
12225
12226
12227 uvs->num_uvs_mappings = num_mappings;
12228
12229
12230 uvs->mappings = (struct sfnt_uvs_mapping *) (uvs + 1);
12231
12232 i = 0;
12233
12234
12235
12236
12237 while (num_mappings)
12238 {
12239 size = (num_mappings > 100 ? 500 : num_mappings * 5);
12240
12241 if (read (fd, data, size) != size)
12242 {
12243 xfree (uvs);
12244 return NULL;
12245 }
12246
12247 for (j = 0; j < size / 5; ++j)
12248 {
12249 uvs->mappings[i + j].unicode_value
12250 = sfnt_read_24 ((unsigned char *) data + j * 5);
12251 memcpy (&uvs->mappings[i + j].base_character_value,
12252 data + j * 5 + 3,
12253 sizeof uvs->mappings[i + j].base_character_value);
12254 sfnt_swap16 (&uvs->mappings[i + j].base_character_value);
12255 }
12256
12257 i += j;
12258 num_mappings -= size / 5;
12259 }
12260
12261
12262 return uvs;
12263 }
12264
12265
12266
12267 static int
12268 sfnt_compare_table_offsets (const void *a, const void *b)
12269 {
12270 const struct sfnt_table_offset_rec *rec_a, *rec_b;
12271
12272 rec_a = a;
12273 rec_b = b;
12274
12275 if (rec_a->offset < rec_b->offset)
12276 return -1;
12277 else if (rec_a->offset > rec_b->offset)
12278 return 1;
12279
12280 return 0;
12281 }
12282
12283
12284
12285
12286
12287
12288
12289
12290
12291
12292
12293 TEST_STATIC struct sfnt_uvs_context *
12294 sfnt_create_uvs_context (struct sfnt_cmap_format_14 *cmap, int fd)
12295 {
12296 struct sfnt_table_offset_rec *table_offsets, *rec, template;
12297 size_t size, i, nmemb, j;
12298 off_t offset;
12299 struct sfnt_uvs_context *context;
12300
12301 if (INT_MULTIPLY_WRAPV (cmap->num_var_selector_records,
12302 sizeof *table_offsets, &size)
12303 || INT_MULTIPLY_WRAPV (size, 2, &size))
12304 return NULL;
12305
12306 context = NULL;
12307
12308
12309
12310
12311 table_offsets = xmalloc (size);
12312 memset (table_offsets, 0, size);
12313 nmemb = cmap->num_var_selector_records * 2;
12314 j = 0;
12315
12316 for (i = 0; i < cmap->num_var_selector_records; ++i)
12317 {
12318
12319
12320
12321 if (cmap->records[i].default_uvs_offset)
12322 {
12323 if (INT_ADD_WRAPV (cmap->offset,
12324 cmap->records[i].default_uvs_offset,
12325 &table_offsets[j].offset))
12326 goto bail;
12327
12328 table_offsets[j++].is_nondefault_table = false;
12329 }
12330
12331 if (cmap->records[i].nondefault_uvs_offset)
12332 {
12333 if (INT_ADD_WRAPV (cmap->offset,
12334 cmap->records[i].nondefault_uvs_offset,
12335 &table_offsets[j].offset))
12336 goto bail;
12337
12338 table_offsets[j++].is_nondefault_table = true;
12339 }
12340 }
12341
12342
12343 nmemb = j;
12344
12345 qsort (table_offsets, nmemb, sizeof *table_offsets,
12346 sfnt_compare_table_offsets);
12347
12348
12349
12350
12351 offset = -1;
12352
12353 for (i = 0; i < nmemb; ++i)
12354 {
12355
12356
12357 while (table_offsets[i].offset == offset && i < nmemb)
12358 {
12359 nmemb--;
12360 table_offsets[i] = table_offsets[i + 1];
12361 }
12362
12363
12364
12365
12366 if (i == nmemb)
12367 break;
12368
12369
12370
12371
12372
12373
12374
12375 offset = table_offsets[i].offset;
12376
12377 if (table_offsets[i].is_nondefault_table)
12378 table_offsets[i].table
12379 = sfnt_read_nondefault_uvs_table (fd, offset);
12380 else
12381 table_offsets[i].table
12382 = sfnt_read_default_uvs_table (fd, offset);
12383 }
12384
12385
12386 context = xmalloc (sizeof *context);
12387 context->num_records = cmap->num_var_selector_records;
12388 context->nmemb = nmemb;
12389 context->records = xmalloc (sizeof *context->records
12390 * cmap->num_var_selector_records);
12391
12392 for (i = 0; i < cmap->num_var_selector_records; ++i)
12393 {
12394 context->records[i].selector = cmap->records[i].var_selector;
12395
12396
12397
12398
12399
12400 if (cmap->records[i].default_uvs_offset)
12401 {
12402
12403 template.offset = (cmap->records[i].default_uvs_offset
12404 + cmap->offset);
12405 rec = bsearch (&template, table_offsets,
12406 nmemb, sizeof *table_offsets,
12407 sfnt_compare_table_offsets);
12408
12409
12410 if (!rec || rec->is_nondefault_table || !rec->table)
12411 goto bail;
12412
12413 context->records[i].default_uvs = rec->table;
12414 }
12415 else
12416 context->records[i].default_uvs = NULL;
12417
12418 if (cmap->records[i].nondefault_uvs_offset)
12419 {
12420
12421 template.offset = (cmap->records[i].nondefault_uvs_offset
12422 + cmap->offset);
12423 rec = bsearch (&template, table_offsets,
12424 nmemb, sizeof *table_offsets,
12425 sfnt_compare_table_offsets);
12426
12427 if (!rec)
12428 goto bail;
12429
12430
12431 if (!rec || !rec->is_nondefault_table || !rec->table)
12432 goto bail;
12433
12434 context->records[i].nondefault_uvs = rec->table;
12435 }
12436 else
12437 context->records[i].nondefault_uvs = NULL;
12438 }
12439
12440 context->tables = table_offsets;
12441 return context;
12442
12443 bail:
12444
12445 if (context)
12446 {
12447 xfree (context->records);
12448 xfree (context);
12449 }
12450
12451
12452
12453
12454 for (i = 0; i < nmemb; ++i)
12455 xfree (table_offsets[i].table);
12456
12457 xfree (table_offsets);
12458 return NULL;
12459 }
12460
12461
12462
12463 TEST_STATIC void
12464 sfnt_free_uvs_context (struct sfnt_uvs_context *c)
12465 {
12466 size_t i;
12467
12468 xfree (c->records);
12469
12470 for (i = 0; i < c->nmemb; ++i)
12471 xfree (c->tables[i].table);
12472
12473 xfree (c->tables);
12474 xfree (c);
12475 }
12476
12477
12478
12479
12480 static int
12481 sfnt_compare_uvs_mapping (const void *k, const void *v)
12482 {
12483 const sfnt_char *key;
12484 const struct sfnt_uvs_mapping *value;
12485
12486 key = k;
12487 value = v;
12488
12489 if (*key < value->unicode_value)
12490 return -1;
12491 else if (*key == value->unicode_value)
12492 return 0;
12493
12494 return 1;
12495 }
12496
12497
12498
12499
12500
12501
12502
12503 TEST_STATIC sfnt_glyph
12504 sfnt_variation_glyph_for_char (struct sfnt_nondefault_uvs_table *uvs,
12505 sfnt_char c)
12506 {
12507 struct sfnt_uvs_mapping *mapping;
12508
12509 mapping = bsearch (&c, uvs->mappings, uvs->num_uvs_mappings,
12510 sizeof *uvs->mappings,
12511 sfnt_compare_uvs_mapping);
12512
12513 return mapping ? mapping->base_character_value : 0;
12514 }
12515
12516
12517
12518 #if defined HAVE_MMAP && !defined TEST
12519
12520
12521
12522
12523
12524
12525
12526
12527
12528
12529
12530
12531
12532
12533
12534
12535
12536
12537 int
12538 sfnt_map_table (int fd, struct sfnt_offset_subtable *subtable,
12539 uint32_t tag, struct sfnt_mapped_table *table)
12540 {
12541 struct sfnt_table_directory *directory;
12542 size_t offset, page, map_offset;
12543 void *data;
12544 int i;
12545
12546
12547
12548 for (i = 0; i < subtable->num_tables; ++i)
12549 {
12550 if (subtable->subtables[i].tag == tag)
12551 {
12552 directory = &subtable->subtables[i];
12553 break;
12554 }
12555 }
12556
12557 if (i == subtable->num_tables)
12558 return 1;
12559
12560
12561
12562
12563 page = getpagesize ();
12564 offset = directory->offset & ~(page - 1);
12565
12566
12567 map_offset = directory->offset - offset;
12568
12569
12570 data = mmap (NULL, directory->length + map_offset,
12571 PROT_READ, MAP_PRIVATE, fd, offset);
12572
12573 if (data == MAP_FAILED)
12574 return 1;
12575
12576
12577 table->data = (unsigned char *) data + map_offset;
12578 table->mapping = data;
12579 table->length = directory->length;
12580 table->size = directory->length + map_offset;
12581 return 0;
12582 }
12583
12584
12585
12586
12587 int
12588 sfnt_unmap_table (struct sfnt_mapped_table *table)
12589 {
12590 return munmap (table->mapping, table->size) != 0;
12591 }
12592
12593 #endif
12594
12595
12596
12597 #ifndef TEST
12598
12599
12600
12601
12602
12603
12604
12605 void *
12606 sfnt_read_table (int fd, struct sfnt_offset_subtable *subtable,
12607 uint32_t tag, size_t *length)
12608 {
12609 struct sfnt_table_directory *directory;
12610 void *data;
12611 int i;
12612
12613
12614
12615 for (i = 0; i < subtable->num_tables; ++i)
12616 {
12617 if (subtable->subtables[i].tag == tag)
12618 {
12619 directory = &subtable->subtables[i];
12620 break;
12621 }
12622 }
12623
12624 if (i == subtable->num_tables)
12625 return NULL;
12626
12627
12628
12629 if (lseek (fd, directory->offset, SEEK_SET) != directory->offset)
12630 return NULL;
12631
12632
12633
12634 data = xmalloc (directory->length);
12635 if (read (fd, data, directory->length) != directory->length)
12636 {
12637 xfree (data);
12638 return NULL;
12639 }
12640
12641
12642 *length = directory->length;
12643 return data;
12644 }
12645
12646 #endif
12647
12648
12649
12650
12651
12652
12653
12654
12655
12656
12657
12658
12659
12660
12661
12662
12663
12664
12665 TEST_STATIC struct sfnt_fvar_table *
12666 sfnt_read_fvar_table (int fd, struct sfnt_offset_subtable *subtable)
12667 {
12668 struct sfnt_table_directory *directory;
12669 struct sfnt_fvar_table *fvar;
12670 ssize_t rc;
12671 size_t min_bytes, ps_size, non_ps_size, temp, pad;
12672 off_t offset;
12673 int i, j;
12674 char *buffer;
12675 sfnt_fixed *coords;
12676
12677
12678
12679 directory = sfnt_find_table (subtable, SFNT_TABLE_FVAR);
12680
12681 if (!directory)
12682 return NULL;
12683
12684 min_bytes = SFNT_ENDOF (struct sfnt_fvar_table,
12685 instance_size, uint16_t);
12686
12687
12688 if (directory->length < min_bytes)
12689 return NULL;
12690
12691
12692 if (lseek (fd, directory->offset, SEEK_SET) == (off_t) -1)
12693 return NULL;
12694
12695
12696 fvar = xmalloc (sizeof *fvar);
12697
12698
12699 buffer = NULL;
12700 rc = read (fd, fvar, min_bytes);
12701 if (rc != min_bytes)
12702 goto bail;
12703
12704
12705 sfnt_swap16 (&fvar->major_version);
12706 sfnt_swap16 (&fvar->minor_version);
12707 sfnt_swap16 (&fvar->offset_to_data);
12708 sfnt_swap16 (&fvar->count_size_pairs);
12709 sfnt_swap16 (&fvar->axis_count);
12710 sfnt_swap16 (&fvar->axis_size);
12711 sfnt_swap16 (&fvar->instance_count);
12712 sfnt_swap16 (&fvar->instance_size);
12713
12714
12715
12716 if (fvar->major_version != 1 || fvar->minor_version)
12717 goto bail;
12718
12719
12720
12721 if (fvar->count_size_pairs < 2)
12722 goto bail;
12723
12724
12725
12726 if (fvar->axis_size != 20)
12727 goto bail;
12728
12729
12730
12731
12732
12733
12734 if (INT_MULTIPLY_WRAPV (fvar->axis_count, sizeof (sfnt_fixed),
12735 &temp)
12736 || INT_ADD_WRAPV (2 * sizeof (uint16_t), temp, &non_ps_size))
12737 goto bail;
12738
12739 if (INT_MULTIPLY_WRAPV (fvar->axis_count, sizeof (sfnt_fixed),
12740 &temp)
12741 || INT_ADD_WRAPV (3 * sizeof (uint16_t), temp, &ps_size))
12742 goto bail;
12743
12744 if (fvar->instance_size != non_ps_size
12745 && fvar->instance_size != ps_size)
12746 goto bail;
12747
12748
12749
12750
12751 if (INT_ADD_WRAPV (fvar->offset_to_data, directory->offset,
12752 &offset))
12753 goto bail;
12754
12755
12756
12757 if (lseek (fd, offset, SEEK_SET) != offset)
12758 goto bail;
12759
12760 min_bytes = sizeof *fvar;
12761
12762
12763
12764
12765
12766
12767
12768
12769 if (INT_MULTIPLY_WRAPV (fvar->axis_count, sizeof *fvar->axis,
12770 &temp)
12771 || INT_ADD_WRAPV (min_bytes, temp, &min_bytes))
12772 goto bail;
12773
12774 pad = alignof (struct sfnt_variation_axis);
12775 pad -= min_bytes & (pad - 1);
12776
12777 if (INT_ADD_WRAPV (min_bytes, pad, &min_bytes))
12778 goto bail;
12779
12780 if (INT_MULTIPLY_WRAPV (fvar->instance_count,
12781 sizeof *fvar->instance,
12782 &temp)
12783 || INT_ADD_WRAPV (min_bytes, temp, &min_bytes))
12784 goto bail;
12785
12786 if (INT_MULTIPLY_WRAPV (fvar->instance_count,
12787 sizeof *fvar->instance->coords,
12788 &temp)
12789 || INT_MULTIPLY_WRAPV (temp, fvar->axis_count, &temp)
12790 || INT_ADD_WRAPV (min_bytes, temp, &min_bytes))
12791 goto bail;
12792
12793
12794 fvar = xrealloc (fvar, min_bytes);
12795
12796
12797 fvar->axis = (struct sfnt_variation_axis *) (fvar + 1);
12798 fvar->instance
12799 = (struct sfnt_instance *) (((char *) (fvar->axis
12800 + fvar->axis_count))
12801 + pad);
12802
12803
12804
12805 if (directory->length - SFNT_ENDOF (struct sfnt_fvar_table,
12806 instance_size, uint16_t)
12807 < sizeof *fvar->axis * fvar->axis_count)
12808 goto bail;
12809
12810 rc = read (fd, fvar->axis, sizeof *fvar->axis * fvar->axis_count);
12811 if (rc != sizeof *fvar->axis * fvar->axis_count)
12812 goto bail;
12813
12814
12815
12816 for (i = 0; i < fvar->axis_count; ++i)
12817 {
12818 sfnt_swap32 (&fvar->axis[i].axis_tag);
12819 sfnt_swap32 (&fvar->axis[i].min_value);
12820 sfnt_swap32 (&fvar->axis[i].default_value);
12821 sfnt_swap32 (&fvar->axis[i].max_value);
12822 sfnt_swap16 (&fvar->axis[i].flags);
12823 sfnt_swap16 (&fvar->axis[i].name_id);
12824 }
12825
12826
12827
12828 if (fvar->instance_size < 1024 * 16)
12829 buffer = alloca (fvar->instance_size);
12830 else
12831 buffer = xmalloc (fvar->instance_size);
12832
12833 coords = (sfnt_fixed *) (fvar->instance + fvar->instance_count);
12834
12835 for (i = 0; i < fvar->instance_count; ++i)
12836 {
12837 rc = read (fd, buffer, fvar->instance_size);
12838 if (rc != fvar->instance_size)
12839 goto bail;
12840
12841
12842
12843 fvar->instance[i].name_id = *((uint16_t *) buffer);
12844 fvar->instance[i].flags = *((uint16_t *) buffer + 1);
12845 fvar->instance[i].ps_name_id = 0;
12846
12847 sfnt_swap16 (&fvar->instance[i].name_id);
12848 sfnt_swap16 (&fvar->instance[i].flags);
12849
12850
12851
12852 fvar->instance[i].coords = coords;
12853 coords += fvar->axis_count;
12854
12855 memcpy (fvar->instance[i].coords, buffer + 4,
12856 sizeof *fvar->instance[i].coords * fvar->axis_count);
12857
12858
12859
12860 for (j = 0; j < fvar->axis_count; ++j)
12861 sfnt_swap32 (&fvar->instance[i].coords[j]);
12862
12863
12864
12865
12866 if (fvar->instance_size == ps_size)
12867 {
12868 fvar->instance[i].ps_name_id
12869 = *(uint16_t *) (buffer + 4 + (sizeof *fvar->instance[i].coords
12870 * fvar->axis_count));
12871 sfnt_swap16 (&fvar->instance[i].ps_name_id);
12872 }
12873 }
12874
12875
12876 if (buffer && fvar->instance_size >= 1024 * 16)
12877 xfree (buffer);
12878
12879
12880 return fvar;
12881
12882 bail:
12883 if (buffer && fvar->instance_size >= 1024 * 16)
12884 xfree (buffer);
12885
12886 xfree (fvar);
12887 return NULL;
12888 }
12889
12890
12891
12892
12893
12894
12895
12896
12897 TEST_STATIC struct sfnt_gvar_table *
12898 sfnt_read_gvar_table (int fd, struct sfnt_offset_subtable *subtable)
12899 {
12900 struct sfnt_table_directory *directory;
12901 struct sfnt_gvar_table *gvar;
12902 ssize_t rc;
12903 size_t min_bytes, off_size, coordinate_size, data_size;
12904 int i;
12905 off_t offset;
12906
12907
12908
12909 directory = sfnt_find_table (subtable, SFNT_TABLE_GVAR);
12910
12911 if (!directory)
12912 return NULL;
12913
12914 min_bytes = SFNT_ENDOF (struct sfnt_gvar_table,
12915 offset_to_data, uint32_t);
12916
12917
12918 if (directory->length < min_bytes)
12919 return NULL;
12920
12921
12922 if (lseek (fd, directory->offset, SEEK_SET) == (off_t) -1)
12923 return NULL;
12924
12925
12926 gvar = xmalloc (sizeof *gvar);
12927
12928
12929 rc = read (fd, gvar, min_bytes);
12930 if (rc != min_bytes)
12931 goto bail;
12932
12933
12934 sfnt_swap16 (&gvar->version);
12935 sfnt_swap16 (&gvar->reserved);
12936 sfnt_swap16 (&gvar->axis_count);
12937 sfnt_swap16 (&gvar->shared_coord_count);
12938 sfnt_swap32 (&gvar->offset_to_coord);
12939 sfnt_swap16 (&gvar->glyph_count);
12940 sfnt_swap16 (&gvar->flags);
12941 sfnt_swap32 (&gvar->offset_to_data);
12942
12943 if (gvar->version != 1)
12944 goto bail;
12945
12946 if (gvar->offset_to_data > directory->length)
12947 goto bail;
12948
12949
12950
12951
12952
12953 if (gvar->flags & 1)
12954
12955 off_size = sizeof (uint32_t) * (gvar->glyph_count + 1);
12956 else
12957
12958 off_size = sizeof (uint16_t) * (gvar->glyph_count + 1);
12959
12960
12961 coordinate_size = (gvar->shared_coord_count * gvar->axis_count
12962 * sizeof (uint16_t));
12963
12964
12965 data_size = directory->length - gvar->offset_to_data;
12966
12967
12968 if (data_size > directory->length)
12969 goto bail;
12970
12971
12972 if (INT_ADD_WRAPV (sizeof *gvar, coordinate_size, &min_bytes)
12973 || INT_ADD_WRAPV (min_bytes, off_size, &min_bytes)
12974 || INT_ADD_WRAPV (min_bytes, data_size, &min_bytes))
12975 goto bail;
12976
12977
12978 gvar = xrealloc (gvar, min_bytes);
12979
12980
12981
12982 if (!(gvar->flags & 1))
12983 {
12984 gvar->u.offset_word = (uint16_t *) (gvar + 1);
12985 rc = read (fd, gvar->u.offset_word, off_size);
12986 if (rc != off_size)
12987 goto bail;
12988
12989 for (i = 0; i <= gvar->glyph_count; ++i)
12990 sfnt_swap16 (&gvar->u.offset_word[i]);
12991 }
12992 else
12993 {
12994 gvar->u.offset_long = (uint32_t *) (gvar + 1);
12995 rc = read (fd, gvar->u.offset_long, off_size);
12996 if (rc != off_size)
12997 goto bail;
12998
12999 for (i = 0; i <= gvar->glyph_count; ++i)
13000 sfnt_swap32 (&gvar->u.offset_long[i]);
13001 }
13002
13003
13004
13005 gvar->global_coords = ((sfnt_f2dot14 *) ((char *) gvar + off_size));
13006
13007 if (gvar->shared_coord_count)
13008 {
13009 if (INT_ADD_WRAPV (gvar->offset_to_coord, directory->offset,
13010 &offset))
13011 goto bail;
13012
13013 if (lseek (fd, offset, SEEK_SET) != offset)
13014 goto bail;
13015
13016 if (read (fd, gvar->global_coords, coordinate_size)
13017 != coordinate_size)
13018 goto bail;
13019
13020 for (i = 0; i <= coordinate_size / sizeof *gvar->global_coords; ++i)
13021 sfnt_swap16 (&gvar->global_coords[i]);
13022 }
13023
13024
13025 gvar->data_size = data_size;
13026 gvar->glyph_variation_data
13027 = (unsigned char *) (gvar->global_coords
13028 + (coordinate_size
13029 / sizeof *gvar->global_coords));
13030
13031 if (gvar->data_size)
13032 {
13033 if (INT_ADD_WRAPV (gvar->offset_to_data, directory->offset,
13034 &offset))
13035 goto bail;
13036
13037 if (lseek (fd, offset, SEEK_SET) != offset)
13038 goto bail;
13039
13040 if (read (fd, gvar->glyph_variation_data,
13041 gvar->data_size) != gvar->data_size)
13042 goto bail;
13043 }
13044
13045
13046 return gvar;
13047
13048 bail:
13049 xfree (gvar);
13050 return NULL;
13051 }
13052
13053
13054
13055
13056
13057
13058
13059
13060 TEST_STATIC struct sfnt_avar_table *
13061 sfnt_read_avar_table (int fd, struct sfnt_offset_subtable *subtable)
13062 {
13063 struct sfnt_table_directory *directory;
13064 struct sfnt_avar_table *avar;
13065 ssize_t rc;
13066 size_t min_size, size, i, k, j;
13067 uint16_t *buffer;
13068 struct sfnt_short_frac_correspondence *correspondences;
13069
13070
13071
13072 directory = sfnt_find_table (subtable, SFNT_TABLE_AVAR);
13073
13074 if (!directory)
13075 return NULL;
13076
13077 min_size = SFNT_ENDOF (struct sfnt_avar_table, axis_count, uint32_t);
13078
13079
13080 if (directory->length < min_size)
13081 return NULL;
13082
13083
13084 if (lseek (fd, directory->offset, SEEK_SET) == (off_t) -1)
13085 return NULL;
13086
13087
13088 avar = xmalloc (sizeof *avar);
13089
13090
13091 rc = read (fd, avar, min_size);
13092 if (rc != min_size)
13093 goto bail;
13094
13095
13096 sfnt_swap32 (&avar->version);
13097 sfnt_swap32 (&avar->axis_count);
13098
13099 if (avar->version != 0x00010000)
13100 goto bail;
13101
13102 if (avar->axis_count < 0)
13103 goto bail;
13104
13105
13106 size = directory->length - min_size;
13107 buffer = xmalloc (size);
13108 rc = read (fd, buffer, size);
13109 if (rc != size)
13110 goto bail1;
13111
13112
13113 for (i = 0; i < size / sizeof *buffer; ++i)
13114 sfnt_swap16 (&buffer[i]);
13115
13116
13117
13118
13119 k = 0;
13120 min_size = sizeof *avar;
13121 for (i = 0; i < avar->axis_count; ++i)
13122 {
13123
13124 if (k >= size / sizeof *buffer)
13125 goto bail1;
13126
13127
13128
13129 if (INT_ADD_WRAPV (sizeof (struct sfnt_short_frac_segment),
13130 min_size, &min_size)
13131 || INT_ADD_WRAPV (sizeof (struct sfnt_short_frac_correspondence)
13132 * buffer[k], min_size, &min_size))
13133 goto bail1;
13134
13135
13136
13137 j = k + 1 + buffer[k] * 2;
13138 if (j > size / sizeof *buffer)
13139 goto bail1;
13140
13141
13142 k = j;
13143 }
13144
13145
13146
13147 avar = xrealloc (avar, min_size);
13148 avar->segments = (struct sfnt_short_frac_segment *) (avar + 1);
13149 correspondences
13150 = ((struct sfnt_short_frac_correspondence *) (avar->segments
13151 + avar->axis_count));
13152
13153 k = 0;
13154 for (i = 0; i < avar->axis_count; ++i)
13155 {
13156 avar->segments[i].pair_count = buffer[k++];
13157 avar->segments[i].correspondence = correspondences;
13158
13159 for (j = 0; j < avar->segments[i].pair_count; ++j)
13160 {
13161 correspondences->from_coord = buffer[k++];
13162 correspondences->to_coord = buffer[k++];
13163 correspondences++;
13164 }
13165 }
13166
13167
13168 xfree (buffer);
13169 return avar;
13170
13171 bail1:
13172 xfree (buffer);
13173 bail:
13174 xfree (avar);
13175 return NULL;
13176 }
13177
13178
13179
13180
13181
13182
13183
13184
13185
13186
13187
13188
13189
13190
13191
13192
13193 static uint16_t *
13194 sfnt_read_packed_points (unsigned char *restrict data,
13195 uint16_t *npoints_return,
13196 unsigned char *restrict end,
13197 unsigned char *restrict *location)
13198 {
13199 int npoints;
13200 uint16_t *points;
13201 int i, first, control;
13202
13203 points = NULL;
13204 npoints = 0;
13205
13206 if (data >= end)
13207 return NULL;
13208
13209
13210 control = *data++;
13211
13212 if (!control)
13213 {
13214 *npoints_return = UINT16_MAX;
13215 *location = data;
13216 return (uint16_t *) -1;
13217 }
13218
13219
13220
13221 if (control & 0x80)
13222 {
13223 npoints = control & 0x7f;
13224 npoints <<= 8;
13225
13226 if (data >= end)
13227 return NULL;
13228
13229 npoints |= *data++;
13230 }
13231 else
13232 npoints = control;
13233
13234
13235 first = 0;
13236 i = 0;
13237 points = xmalloc (sizeof *points * npoints);
13238
13239 while (i < npoints)
13240 {
13241 if (data >= end)
13242 goto bail;
13243
13244 control = *data++;
13245
13246 if (control & 0x80)
13247 {
13248
13249
13250 control &= 0x7f;
13251
13252 while (control != -1 && i < npoints)
13253 {
13254 if (data >= end || data + 1 >= end)
13255 goto bail;
13256
13257 first += *data++ << 8u;
13258 first += *data++;
13259 points[i] = first;
13260 control -= 1, ++i;
13261 }
13262 }
13263 else
13264 {
13265
13266
13267 while (control != -1 && i < npoints)
13268 {
13269 if (data >= end)
13270 goto bail;
13271
13272 first += *data++;
13273 points[i] = first;
13274 control -= 1, ++i;
13275 }
13276 }
13277 }
13278
13279
13280 *npoints_return = npoints;
13281 *location = data;
13282 return points;
13283
13284 bail:
13285 xfree (points);
13286 return NULL;
13287 }
13288
13289
13290
13291
13292
13293
13294
13295 static sfnt_fword *
13296 sfnt_read_packed_deltas (unsigned char *restrict data,
13297 unsigned char *restrict end,
13298 int n,
13299 unsigned char *restrict *data_return)
13300 {
13301 sfnt_fword *deltas;
13302 int i, count;
13303 unsigned char control;
13304 uint16_t value;
13305
13306 if (data >= end)
13307 return NULL;
13308
13309 deltas = xmalloc (sizeof *deltas * n);
13310 i = 0;
13311
13312 while (i < n)
13313 {
13314 if (data >= end)
13315 goto fail;
13316
13317 control = *data++;
13318 count = control & 0x3f;
13319
13320 while (count != -1 && i < n)
13321 {
13322 if (control & 0x80)
13323 deltas[i++] = 0;
13324 else if (control & 0x40)
13325 {
13326 if (data + 1 >= end)
13327 goto fail;
13328
13329 value = *data++ << 8;
13330 value |= *data++;
13331 deltas[i++] = value;
13332 }
13333 else
13334 {
13335 if (data >= end)
13336 goto fail;
13337
13338 deltas[i++] = (signed char) *data++;
13339 }
13340
13341 --count;
13342 }
13343 }
13344
13345 *data_return = data;
13346 return deltas;
13347
13348 fail:
13349 xfree (deltas);
13350 return NULL;
13351 }
13352
13353
13354
13355
13356
13357
13358
13359 TEST_STATIC struct sfnt_cvar_table *
13360 sfnt_read_cvar_table (int fd, struct sfnt_offset_subtable *subtable,
13361 struct sfnt_fvar_table *fvar,
13362 struct sfnt_cvt_table *cvt)
13363 {
13364 struct sfnt_table_directory *directory;
13365 struct sfnt_cvar_table *cvar;
13366 ssize_t rc;
13367 size_t ntuples, size;
13368 int i, j;
13369 sfnt_f2dot14 *coords;
13370 uint16_t *local, *points, npoints, data_size, min_size, index;
13371 unsigned char *buffer, *data, *end, *tuple;
13372 ptrdiff_t data_offset;
13373 sfnt_fword *deltas;
13374
13375
13376
13377 directory = sfnt_find_table (subtable, SFNT_TABLE_CVAR);
13378
13379 if (!directory)
13380 return NULL;
13381
13382 min_size = SFNT_ENDOF (struct sfnt_cvar_table, data_offset,
13383 uint16_t);
13384
13385
13386 if (directory->length < min_size)
13387 return NULL;
13388
13389
13390 if (lseek (fd, directory->offset, SEEK_SET) == (off_t) -1)
13391 return NULL;
13392
13393
13394 cvar = xmalloc (sizeof *cvar);
13395
13396
13397 rc = read (fd, cvar, min_size);
13398 if (rc != min_size)
13399 goto bail;
13400
13401
13402 sfnt_swap32 (&cvar->version);
13403 sfnt_swap16 (&cvar->tuple_count);
13404 sfnt_swap16 (&cvar->data_offset);
13405
13406
13407 size = directory->length - min_size;
13408 buffer = xmalloc (size);
13409 rc = read (fd, buffer, size);
13410 if (rc != size)
13411 goto bail;
13412
13413
13414
13415 ntuples = cvar->tuple_count & 0x0fff;
13416 data_offset = ((ptrdiff_t) cvar->data_offset
13417 - (ptrdiff_t) min_size);
13418 end = buffer + size;
13419
13420 if (data_offset < 0)
13421 goto bail1;
13422
13423
13424
13425 data = buffer + data_offset;
13426 tuple = buffer;
13427 points = NULL;
13428
13429
13430
13431
13432
13433
13434 npoints = 0;
13435
13436
13437 size = 0;
13438
13439 if (cvar->tuple_count & 0x8000)
13440 {
13441 points = sfnt_read_packed_points (data, &npoints, end,
13442 &tuple);
13443 if (!points)
13444 goto bail1;
13445
13446
13447
13448
13449 if (npoints != UINT16_MAX)
13450 size = npoints * sizeof *points;
13451 }
13452
13453 while (ntuples--)
13454 {
13455 data = buffer + data_offset;
13456
13457
13458 if (tuple + 3 >= end)
13459 goto bail2;
13460
13461 memcpy (&data_size, tuple, sizeof data_size);
13462 tuple += sizeof data_size;
13463 memcpy (&index, tuple, sizeof index);
13464 tuple += sizeof index;
13465 sfnt_swap16 (&data_size);
13466 sfnt_swap16 (&index);
13467
13468
13469
13470 data_offset += data_size;
13471
13472 if (index & 0x8000)
13473 {
13474
13475
13476
13477 if (tuple + fvar->axis_count * sizeof *coords - 1 >= end)
13478 goto bail2;
13479
13480 tuple += sizeof *coords * fvar->axis_count;
13481 if (INT_ADD_WRAPV (size, sizeof *coords * fvar->axis_count,
13482 &size))
13483 goto bail2;
13484 }
13485 else
13486
13487
13488 goto bail2;
13489
13490
13491 if (index & 0x4000)
13492 {
13493 tuple += fvar->axis_count * 4;
13494 if (INT_ADD_WRAPV (size, fvar->axis_count * 4, &size))
13495 goto bail2;
13496 }
13497
13498
13499 if (INT_ADD_WRAPV (size, cvt->num_elements * 4, &size))
13500 goto bail2;
13501
13502
13503 if (INT_ADD_WRAPV (size, sizeof *cvar->variation, &size))
13504 goto bail2;
13505 }
13506
13507 if (INT_ADD_WRAPV (sizeof *cvar, size, &size))
13508 goto bail2;
13509
13510
13511 cvar = xrealloc (cvar, size);
13512 ntuples = cvar->tuple_count & 0x0fff;
13513 cvar->variation = (struct sfnt_tuple_variation *) (cvar + 1);
13514 coords = (sfnt_f2dot14 *) (cvar->variation + ntuples);
13515 tuple = buffer;
13516
13517 data_offset = ((ptrdiff_t) cvar->data_offset
13518 - (ptrdiff_t) min_size);
13519
13520
13521 for (i = 0; i < ntuples; ++i)
13522 {
13523 data = buffer + data_offset;
13524
13525
13526 if (tuple + 3 >= end)
13527 goto bail2;
13528
13529 memcpy (&data_size, tuple, sizeof data_size);
13530 tuple += sizeof data_size;
13531 memcpy (&index, tuple, sizeof index);
13532 tuple += sizeof index;
13533 sfnt_swap16 (&data_size);
13534 sfnt_swap16 (&index);
13535
13536
13537
13538 data_offset += data_size;
13539
13540 cvar->variation[i].intermediate_start = NULL;
13541 cvar->variation[i].intermediate_end = NULL;
13542
13543 if (index & 0x8000)
13544 {
13545
13546
13547 cvar->variation[i].coordinates = coords;
13548
13549 for (j = 0; j < fvar->axis_count; ++j)
13550 {
13551 if (tuple + 1 >= end)
13552 goto bail2;
13553
13554 memcpy (coords++, tuple, sizeof *coords);
13555 tuple += sizeof *coords;
13556 sfnt_swap16 (coords);
13557 }
13558 }
13559 else
13560 goto bail2;
13561
13562
13563 if (index & 0x4000)
13564 {
13565 cvar->variation[i].intermediate_start = coords;
13566
13567 for (j = 0; j < fvar->axis_count; ++j)
13568 {
13569 if (tuple + 1 >= end)
13570 goto bail2;
13571
13572 memcpy (coords++, tuple, sizeof *coords);
13573 tuple += sizeof *coords;
13574 sfnt_swap16 (coords);
13575 }
13576
13577 cvar->variation[i].intermediate_end = coords;
13578
13579 for (j = 0; j < fvar->axis_count; ++j)
13580 {
13581 if (tuple + 1 >= end)
13582 goto bail2;
13583
13584 memcpy (coords++, tuple, sizeof *coords);
13585 tuple += sizeof *coords;
13586 sfnt_swap16 (coords);
13587 }
13588 }
13589
13590
13591
13592
13593
13594
13595
13596 if (index & 0x2000)
13597 {
13598 local = sfnt_read_packed_points (data, &cvar->variation[i].num_points,
13599 end, &data);
13600 if (!local)
13601 goto bail2;
13602
13603
13604
13605 if (cvar->variation[i].num_points != UINT16_MAX)
13606 {
13607 if (cvar->variation[i].num_points > cvt->num_elements)
13608 cvar->variation[i].num_points = cvt->num_elements;
13609
13610 cvar->variation[i].points = (uint16_t *) coords;
13611 for (j = 0; j < cvar->variation[i].num_points; ++j)
13612 *coords++ = local[j];
13613 xfree (local);
13614 }
13615 else
13616 cvar->variation[i].points = NULL;
13617 }
13618 else
13619 {
13620
13621 cvar->variation[i].num_points = npoints;
13622
13623 if (npoints != UINT16_MAX)
13624 {
13625 if (cvar->variation[i].num_points > cvt->num_elements)
13626 cvar->variation[i].num_points = cvt->num_elements;
13627
13628 cvar->variation[i].points = (uint16_t *) coords;
13629 for (j = 0; j < cvar->variation[i].num_points; ++j)
13630 *coords++ = points[j];
13631 }
13632 else
13633 cvar->variation[i].points = NULL;
13634 }
13635
13636
13637
13638
13639
13640 if (cvar->variation[i].num_points == UINT16_MAX)
13641 {
13642 deltas = sfnt_read_packed_deltas (data, end, cvt->num_elements,
13643 &data);
13644
13645 if (!deltas)
13646 goto bail2;
13647
13648 cvar->variation[i].deltas = coords;
13649
13650 for (j = 0; j < cvt->num_elements; ++j)
13651 *coords++ = deltas[j];
13652 xfree (deltas);
13653 }
13654 else
13655 {
13656 deltas = sfnt_read_packed_deltas (data, end,
13657 cvar->variation[i].num_points,
13658 &data);
13659 if (!deltas)
13660 goto bail2;
13661
13662 cvar->variation[i].deltas = coords;
13663
13664 for (j = 0; j < cvar->variation[i].num_points; ++j)
13665 *coords++ = deltas[j];
13666 xfree (deltas);
13667 }
13668 }
13669
13670
13671 if (points != (void *) -1)
13672 xfree (points);
13673 xfree (buffer);
13674 return cvar;
13675
13676 bail2:
13677 if (points != (void *) -1)
13678 xfree (points);
13679 bail1:
13680 xfree (buffer);
13681 bail:
13682 xfree (cvar);
13683 return NULL;
13684 }
13685
13686
13687
13688
13689
13690
13691
13692
13693 TEST_STATIC void
13694 sfnt_init_blend (struct sfnt_blend *blend, struct sfnt_fvar_table *fvar,
13695 struct sfnt_gvar_table *gvar, struct sfnt_avar_table *avar,
13696 struct sfnt_cvar_table *cvar)
13697 {
13698 size_t size;
13699
13700 blend->fvar = fvar;
13701 blend->gvar = gvar;
13702 blend->avar = avar;
13703 blend->cvar = cvar;
13704
13705
13706 size = (fvar->axis_count * sizeof *blend->coords * 2);
13707 blend->coords = xmalloc (size);
13708 blend->norm_coords = blend->coords + fvar->axis_count;
13709 }
13710
13711
13712
13713 TEST_STATIC void
13714 sfnt_free_blend (struct sfnt_blend *blend)
13715 {
13716 xfree (blend->coords);
13717 }
13718
13719
13720
13721
13722 TEST_STATIC void
13723 sfnt_normalize_blend (struct sfnt_blend *blend)
13724 {
13725 struct sfnt_variation_axis *axis;
13726 int i, j;
13727 sfnt_fixed from, coord, j0, j1, j2;
13728 sfnt_fixed from_last, coord_last;
13729 struct sfnt_short_frac_segment *segment;
13730
13731
13732 for (i = 0; i < blend->fvar->axis_count; ++i)
13733 {
13734
13735 axis = &blend->fvar->axis[i];
13736
13737
13738 coord = blend->coords[i];
13739
13740
13741
13742 if (coord > axis->max_value)
13743 coord = axis->max_value;
13744 else if (coord < axis->min_value)
13745 coord = axis->min_value;
13746
13747 if (coord > axis->default_value)
13748 {
13749
13750 if (axis->max_value != axis->default_value)
13751 blend->norm_coords[i]
13752 = sfnt_div_fixed (sfnt_sub (coord, axis->default_value),
13753 sfnt_sub (axis->max_value,
13754 axis->default_value));
13755 else
13756 blend->norm_coords[i] = 0;
13757 }
13758 else if (coord < axis->default_value)
13759 {
13760 if (axis->default_value != axis->min_value)
13761 blend->norm_coords[i]
13762 = sfnt_div_fixed (sfnt_sub (coord, axis->default_value),
13763 sfnt_sub (axis->default_value,
13764 axis->min_value));
13765 else
13766 blend->norm_coords[i] = 0;
13767 }
13768 else
13769 blend->norm_coords[i] = 0;
13770 }
13771
13772
13773
13774
13775 if (blend->avar && (blend->fvar->axis_count
13776 == blend->avar->axis_count))
13777 {
13778 for (i = 0; i < blend->fvar->axis_count; ++i)
13779 {
13780 segment = &blend->avar->segments[i];
13781
13782
13783
13784
13785 for (j = 1; j < segment->pair_count; ++j)
13786 {
13787 from = segment->correspondence[j].from_coord * 4;
13788 coord = segment->correspondence[j].to_coord * 4;
13789
13790 if (blend->norm_coords[i] < from)
13791 {
13792 from_last
13793 = segment->correspondence[j - 1].from_coord * 4;
13794 coord_last
13795 = segment->correspondence[j - 1].to_coord * 4;
13796
13797 j0 = blend->norm_coords[i] - from_last;
13798 j1 = coord - coord_last;
13799 j2 = from - from_last;
13800
13801 blend->norm_coords[i]
13802 = (sfnt_multiply_divide_signed (j0, j1, j2) + coord_last);
13803 break;
13804 }
13805 }
13806 }
13807 }
13808 }
13809
13810
13811
13812 struct sfnt_gvar_glyph_header
13813 {
13814
13815
13816
13817 uint16_t tuple_count;
13818
13819
13820
13821 uint16_t data_offset;
13822 };
13823
13824
13825
13826
13827
13828
13829
13830 static sfnt_fixed
13831 sfnt_compute_tuple_scale (struct sfnt_blend *blend, bool intermediate_p,
13832 sfnt_f2dot14 *coords,
13833 sfnt_f2dot14 *intermediate_start,
13834 sfnt_f2dot14 *intermediate_end)
13835 {
13836 int i;
13837 sfnt_fixed coord, start UNINIT, end UNINIT;
13838 sfnt_fixed scale;
13839
13840
13841 scale = 0200000;
13842
13843 for (i = 0; i < blend->gvar->axis_count; ++i)
13844 {
13845
13846 coord = coords[i] * 4;
13847
13848
13849
13850
13851 if (intermediate_p)
13852 {
13853 start = intermediate_start[i] * 4;
13854 end = intermediate_start[i] * 4;
13855 }
13856
13857
13858
13859 if (!coord)
13860 continue;
13861
13862
13863
13864
13865 if (!blend->norm_coords[i])
13866 return 0;
13867
13868
13869
13870 if (blend->norm_coords[i] == coord)
13871 continue;
13872
13873 if (!intermediate_p)
13874 {
13875
13876
13877
13878
13879
13880 if (blend->norm_coords[i] < MIN (0, coord)
13881 || blend->norm_coords[i] > MAX (0, coord))
13882 return 0;
13883
13884 scale = sfnt_multiply_divide_signed (scale,
13885 blend->norm_coords[i],
13886 coord);
13887 }
13888 else
13889 {
13890
13891
13892 if (blend->norm_coords[i] < start
13893 || blend->norm_coords[i] > end)
13894 return 0;
13895
13896 if (blend->norm_coords[i] < coord)
13897 scale = sfnt_multiply_divide (scale,
13898 blend->norm_coords[i] - start,
13899 coord - start);
13900 else
13901 scale = sfnt_multiply_divide (scale,
13902 end - blend->norm_coords[i],
13903 end - coord);
13904 }
13905 }
13906
13907 return scale;
13908 }
13909
13910
13911
13912
13913 static void
13914 sfnt_infer_deltas_1 (struct sfnt_glyph *glyph, size_t start,
13915 size_t end, bool *touched, sfnt_fword *x,
13916 sfnt_fword *y)
13917 {
13918 size_t i, pair_start, pair_end, pair_first, j;
13919 sfnt_fword min_pos, max_pos, position;
13920 sfnt_fixed ratio, delta;
13921
13922 pair_start = pair_first = -1;
13923
13924
13925
13926 for (i = start; i <= end; ++i)
13927 {
13928 if (!touched[i])
13929 continue;
13930
13931 if (pair_start == -1)
13932 {
13933 pair_first = i;
13934 goto next;
13935 }
13936
13937 pair_end = i;
13938
13939
13940
13941
13942 for (j = pair_start + 1; j < pair_end; ++j)
13943 {
13944
13945
13946 min_pos = MIN (x[pair_start], x[pair_end]);
13947 max_pos = MAX (x[pair_start], x[pair_end]);
13948
13949
13950
13951 if (x[j] >= min_pos && x[j] <= max_pos)
13952 {
13953
13954
13955
13956
13957 if (min_pos == max_pos)
13958 {
13959 if ((glyph->simple->x_coordinates[pair_start]
13960 - x[pair_start])
13961 == (glyph->simple->x_coordinates[pair_end]
13962 - x[pair_end]))
13963 glyph->simple->x_coordinates[j]
13964 += (glyph->simple->x_coordinates[pair_start]
13965 - x[pair_start]);
13966
13967 continue;
13968 }
13969
13970
13971 ratio = sfnt_div_fixed ((sfnt_sub (x[j], min_pos)
13972 * 65536),
13973 (sfnt_sub (max_pos, min_pos)
13974 * 65536));
13975
13976
13977
13978 min_pos = MIN (glyph->simple->x_coordinates[pair_start],
13979 glyph->simple->x_coordinates[pair_end]);
13980 max_pos = MAX (glyph->simple->x_coordinates[pair_start],
13981 glyph->simple->x_coordinates[pair_end]);
13982
13983
13984 delta = sfnt_sub (max_pos, min_pos);
13985 delta = sfnt_mul_fixed (ratio, delta);
13986 glyph->simple->x_coordinates[j] = min_pos + delta;
13987 }
13988 else
13989 {
13990
13991
13992
13993 if (x[j] >= max_pos)
13994 {
13995 position = MAX (glyph->simple->x_coordinates[pair_start],
13996 glyph->simple->x_coordinates[pair_end]);
13997 delta = position - max_pos;
13998 }
13999 else
14000 {
14001 position = MIN (glyph->simple->x_coordinates[pair_start],
14002 glyph->simple->x_coordinates[pair_end]);
14003 delta = position - min_pos;
14004 }
14005
14006 glyph->simple->x_coordinates[j] = x[j] + delta;
14007 }
14008
14009
14010 min_pos = MIN (y[pair_start], y[pair_end]);
14011 max_pos = MAX (y[pair_start], y[pair_end]);
14012
14013
14014
14015 if (y[j] >= min_pos && y[j] <= max_pos)
14016 {
14017
14018
14019
14020
14021 if (min_pos == max_pos)
14022 {
14023 if ((glyph->simple->y_coordinates[pair_start]
14024 - y[pair_start])
14025 == (glyph->simple->y_coordinates[pair_end]
14026 - y[pair_end]))
14027 glyph->simple->y_coordinates[j]
14028 += (glyph->simple->y_coordinates[pair_start]
14029 - y[pair_start]);
14030
14031 continue;
14032 }
14033
14034
14035 ratio = sfnt_div_fixed ((sfnt_sub (y[j], min_pos)
14036 * 65536),
14037 (sfnt_sub (max_pos, min_pos)
14038 * 65536));
14039
14040
14041
14042 min_pos = MIN (glyph->simple->y_coordinates[pair_start],
14043 glyph->simple->y_coordinates[pair_end]);
14044 max_pos = MAX (glyph->simple->y_coordinates[pair_start],
14045 glyph->simple->y_coordinates[pair_end]);
14046
14047
14048 delta = sfnt_sub (max_pos, min_pos);
14049 delta = sfnt_mul_fixed (ratio, delta);
14050 glyph->simple->y_coordinates[j] = min_pos + delta;
14051 }
14052 else
14053 {
14054
14055
14056
14057 if (y[j] >= max_pos)
14058 {
14059 position = MAX (glyph->simple->y_coordinates[pair_start],
14060 glyph->simple->y_coordinates[pair_end]);
14061 delta = position - max_pos;
14062 }
14063 else
14064 {
14065 position = MIN (glyph->simple->y_coordinates[pair_start],
14066 glyph->simple->y_coordinates[pair_end]);
14067 delta = position - min_pos;
14068 }
14069
14070 glyph->simple->y_coordinates[j] = y[j] + delta;
14071 }
14072 }
14073
14074 next:
14075 pair_start = i;
14076 }
14077
14078
14079
14080
14081 if (pair_start != (size_t) -1)
14082 {
14083 j = pair_start + 1;
14084
14085 if (j > end)
14086 j = start;
14087
14088 pair_end = pair_first;
14089
14090 while (j != pair_first)
14091 {
14092
14093
14094 min_pos = MIN (x[pair_start], x[pair_end]);
14095 max_pos = MAX (x[pair_start], x[pair_end]);
14096
14097
14098
14099 if (x[j] >= min_pos && x[j] <= max_pos)
14100 {
14101
14102
14103
14104
14105 if (min_pos == max_pos)
14106 {
14107 if ((glyph->simple->x_coordinates[pair_start]
14108 - x[pair_start])
14109 == (glyph->simple->x_coordinates[pair_end]
14110 - x[pair_end]))
14111 glyph->simple->x_coordinates[j]
14112 += (glyph->simple->x_coordinates[pair_start]
14113 - x[pair_start]);
14114
14115 goto next_1;
14116 }
14117
14118
14119 ratio = sfnt_div_fixed ((sfnt_sub (x[j], min_pos)
14120 * 65536),
14121 (sfnt_sub (max_pos, min_pos)
14122 * 65536));
14123
14124
14125
14126 min_pos = MIN (glyph->simple->x_coordinates[pair_start],
14127 glyph->simple->x_coordinates[pair_end]);
14128 max_pos = MAX (glyph->simple->x_coordinates[pair_start],
14129 glyph->simple->x_coordinates[pair_end]);
14130
14131
14132 delta = sfnt_sub (max_pos, min_pos);
14133 delta = sfnt_mul_fixed (ratio, delta);
14134 glyph->simple->x_coordinates[j] = min_pos + delta;
14135 }
14136 else
14137 {
14138
14139
14140
14141 if (x[j] >= max_pos)
14142 {
14143 position = MAX (glyph->simple->x_coordinates[pair_start],
14144 glyph->simple->x_coordinates[pair_end]);
14145 delta = position - max_pos;
14146 }
14147 else
14148 {
14149 position = MIN (glyph->simple->x_coordinates[pair_start],
14150 glyph->simple->x_coordinates[pair_end]);
14151 delta = position - min_pos;
14152 }
14153
14154 glyph->simple->x_coordinates[j] = x[j] + delta;
14155 }
14156
14157
14158 min_pos = MIN (y[pair_start], y[pair_end]);
14159 max_pos = MAX (y[pair_start], y[pair_end]);
14160
14161
14162
14163 if (y[j] >= min_pos && y[j] <= max_pos)
14164 {
14165
14166
14167
14168
14169 if (min_pos == max_pos)
14170 {
14171 if ((glyph->simple->y_coordinates[pair_start]
14172 - y[pair_start])
14173 == (glyph->simple->y_coordinates[pair_end]
14174 - y[pair_end]))
14175 glyph->simple->y_coordinates[j]
14176 += (glyph->simple->y_coordinates[pair_start]
14177 - y[pair_start]);
14178
14179 goto next_1;
14180 }
14181
14182
14183 ratio = sfnt_div_fixed ((sfnt_sub (y[j], min_pos)
14184 * 65536),
14185 (sfnt_sub (max_pos, min_pos)
14186 * 65536));
14187
14188
14189
14190 min_pos = MIN (glyph->simple->y_coordinates[pair_start],
14191 glyph->simple->y_coordinates[pair_end]);
14192 max_pos = MAX (glyph->simple->y_coordinates[pair_start],
14193 glyph->simple->y_coordinates[pair_end]);
14194
14195
14196 delta = sfnt_sub (max_pos, min_pos);
14197 delta = sfnt_mul_fixed (ratio, delta);
14198 glyph->simple->y_coordinates[j] = min_pos + delta;
14199 }
14200 else
14201 {
14202
14203
14204
14205 if (y[j] >= max_pos)
14206 {
14207 position = MAX (glyph->simple->y_coordinates[pair_start],
14208 glyph->simple->y_coordinates[pair_end]);
14209 delta = position - max_pos;
14210 }
14211 else
14212 {
14213 position = MIN (glyph->simple->y_coordinates[pair_start],
14214 glyph->simple->y_coordinates[pair_end]);
14215 delta = position - min_pos;
14216 }
14217
14218 glyph->simple->y_coordinates[j] = y[j] + delta;
14219 }
14220
14221 next_1:
14222 j++;
14223 if (j > end)
14224 j = start;
14225 }
14226 }
14227 }
14228
14229
14230
14231
14232
14233
14234
14235
14236
14237
14238
14239
14240
14241
14242
14243
14244
14245
14246
14247
14248
14249
14250
14251
14252
14253
14254
14255 static void
14256 sfnt_infer_deltas (struct sfnt_glyph *glyph, bool *touched,
14257 sfnt_fword *x, sfnt_fword *y)
14258 {
14259 size_t i;
14260 int point, first, end;
14261
14262 point = 0;
14263 for (i = 0; i < glyph->number_of_contours; ++i)
14264 {
14265 first = point;
14266 end = glyph->simple->end_pts_of_contours[i];
14267
14268
14269
14270 if (first >= glyph->simple->number_of_points
14271 || end >= glyph->simple->number_of_points
14272 || first > end)
14273 return;
14274
14275 sfnt_infer_deltas_1 (glyph, first, end, touched, x, y);
14276 point = end + 1;
14277 }
14278 }
14279
14280
14281
14282
14283
14284
14285
14286
14287
14288
14289
14290
14291
14292
14293
14294
14295
14296
14297
14298
14299
14300
14301
14302
14303
14304
14305
14306
14307
14308
14309 TEST_STATIC int
14310 sfnt_vary_simple_glyph (struct sfnt_blend *blend, sfnt_glyph id,
14311 struct sfnt_glyph *glyph,
14312 struct sfnt_metrics_distortion *distortion)
14313 {
14314 uint32_t offset;
14315 struct sfnt_gvar_glyph_header header;
14316 uint16_t *points, npoints;
14317 int i, ntuples, j, point_count;
14318 unsigned char *tuple, *end, *data;
14319 uint16_t data_size, index, *glyph_points;
14320 sfnt_f2dot14 *restrict coords;
14321 sfnt_f2dot14 *restrict intermediate_start;
14322 sfnt_f2dot14 *restrict intermediate_end;
14323 sfnt_fword *restrict dx, *restrict dy, fword;
14324 struct sfnt_gvar_table *gvar;
14325 uint16_t *local_points, n_local_points;
14326 sfnt_fixed scale;
14327 ptrdiff_t data_offset;
14328 bool *touched;
14329 sfnt_fword *restrict original_x, *restrict original_y;
14330
14331 gvar = blend->gvar;
14332
14333 if (gvar->axis_count != blend->fvar->axis_count)
14334 return 1;
14335
14336 if (gvar->glyph_count <= id)
14337 return 1;
14338
14339 if (gvar->flags & 1)
14340 offset = gvar->u.offset_long[id];
14341 else
14342 offset = gvar->u.offset_word[id] * 2u;
14343
14344 if (offset >= gvar->data_size)
14345 return 1;
14346
14347 end = gvar->glyph_variation_data + gvar->data_size;
14348
14349
14350
14351 if (offset + sizeof header > gvar->data_size)
14352 return 1;
14353
14354
14355 distortion->origin = 0;
14356 distortion->advance = 0;
14357
14358 memcpy (&header, gvar->glyph_variation_data + offset,
14359 sizeof header);
14360
14361
14362 sfnt_swap16 (&header.tuple_count);
14363 sfnt_swap16 (&header.data_offset);
14364
14365
14366 ntuples = header.tuple_count & 0x0fff;
14367
14368
14369
14370 data_offset = header.data_offset;
14371
14372
14373
14374
14375
14376
14377
14378 npoints = 0;
14379
14380 if (header.tuple_count & 0x8000)
14381 {
14382 data = gvar->glyph_variation_data + offset + data_offset;
14383 points = sfnt_read_packed_points (data, &npoints, end,
14384 &tuple);
14385
14386 if (!points)
14387 return 1;
14388
14389
14390
14391
14392
14393 data_offset += tuple - data;
14394 }
14395 else
14396 points = NULL;
14397
14398
14399 tuple = gvar->glyph_variation_data + offset + sizeof header;
14400
14401 if (gvar->axis_count * sizeof *coords * 3 >= 1024 * 16)
14402 coords = xmalloc (gvar->axis_count * sizeof *coords * 3);
14403 else
14404 coords = alloca (gvar->axis_count * sizeof *coords * 3);
14405
14406 intermediate_start = coords + gvar->axis_count;
14407 intermediate_end = coords + gvar->axis_count;
14408
14409
14410
14411 touched = NULL;
14412 original_x = NULL;
14413 original_y = NULL;
14414
14415 while (ntuples--)
14416 {
14417 data = gvar->glyph_variation_data + offset + data_offset;
14418
14419 if (tuple + 3 >= end)
14420 goto fail1;
14421
14422 memcpy (&data_size, tuple, sizeof data_size);
14423 tuple += sizeof data_size;
14424 memcpy (&index, tuple, sizeof index);
14425 tuple += sizeof index;
14426 sfnt_swap16 (&data_size);
14427 sfnt_swap16 (&index);
14428
14429
14430
14431 data_offset += data_size;
14432
14433 if (index & 0x8000)
14434 {
14435
14436
14437 for (j = 0; j < gvar->axis_count; ++j)
14438 {
14439 if (tuple + 1 >= end)
14440 goto fail1;
14441
14442 memcpy (&coords[j], tuple, sizeof *coords);
14443 tuple += sizeof *coords;
14444 sfnt_swap16 (&coords[j]);
14445 }
14446 }
14447 else if ((index & 0xfff) > gvar->shared_coord_count)
14448
14449 goto fail1;
14450 else
14451
14452
14453 memcpy (coords, (gvar->global_coords
14454 + ((index & 0xfff) * gvar->axis_count)),
14455 gvar->axis_count * sizeof *coords);
14456
14457
14458 if (index & 0x4000)
14459 {
14460 for (j = 0; j < gvar->axis_count; ++j)
14461 {
14462 if (tuple + 1 >= end)
14463 goto fail1;
14464
14465 memcpy (&intermediate_start[j], tuple,
14466 sizeof *intermediate_start);
14467 tuple += sizeof *intermediate_start;
14468 sfnt_swap16 (&intermediate_start[j]);
14469 }
14470
14471 for (j = 0; j < gvar->axis_count; ++j)
14472 {
14473 if (tuple + 1 >= end)
14474 goto fail1;
14475
14476 memcpy (&intermediate_end[j], tuple,
14477 sizeof *intermediate_end);
14478 tuple += sizeof *intermediate_end;
14479 sfnt_swap16 (&intermediate_end[j]);
14480 }
14481 }
14482
14483
14484
14485
14486 scale = sfnt_compute_tuple_scale (blend, index & 0x4000,
14487 coords, intermediate_start,
14488 intermediate_end);
14489
14490 if (!scale)
14491 continue;
14492
14493 local_points = NULL;
14494
14495
14496
14497
14498
14499 if (index & 0x2000)
14500 {
14501 local_points = sfnt_read_packed_points (data, &n_local_points,
14502 end, &data);
14503 if (!local_points)
14504 goto fail1;
14505
14506 point_count = n_local_points;
14507 glyph_points = local_points;
14508 }
14509 else
14510 {
14511
14512
14513 point_count = npoints;
14514 glyph_points = points;
14515 }
14516
14517
14518
14519 dx = NULL;
14520 dy = NULL;
14521
14522 switch (point_count)
14523 {
14524 case UINT16_MAX:
14525
14526
14527
14528
14529 dx = sfnt_read_packed_deltas (data, end,
14530 glyph->simple->number_of_points + 4,
14531 &data);
14532 dy = sfnt_read_packed_deltas (data, end,
14533 glyph->simple->number_of_points + 4,
14534 &data);
14535
14536 if (!dx || !dy)
14537 goto fail3;
14538
14539
14540
14541 for (i = 0; i < glyph->simple->number_of_points; ++i)
14542 {
14543 fword = sfnt_mul_fixed_round (dx[i], scale);
14544 glyph->simple->x_coordinates[i] += fword;
14545 fword = sfnt_mul_fixed_round (dy[i], scale);
14546 glyph->simple->y_coordinates[i] += fword;
14547 }
14548
14549
14550 distortion->origin += sfnt_mul_fixed_round (dx[i++], scale);
14551 distortion->advance += sfnt_mul_fixed_round (dx[i], scale);
14552 break;
14553
14554 default:
14555 dx = sfnt_read_packed_deltas (data, end, point_count, &data);
14556 dy = sfnt_read_packed_deltas (data, end, point_count, &data);
14557
14558 if (!dx || !dy)
14559 goto fail3;
14560
14561
14562
14563 if (!original_x)
14564 {
14565 if ((glyph->simple->number_of_points
14566 * sizeof *touched) >= 1024 * 16)
14567 touched = xmalloc (sizeof *touched
14568 * glyph->simple->number_of_points);
14569 else
14570 touched = alloca (sizeof *touched
14571 * glyph->simple->number_of_points);
14572
14573 if ((sizeof *original_x * 2
14574 * glyph->simple->number_of_points) >= 1024 * 16)
14575 original_x = xmalloc (sizeof *original_x * 2
14576 * glyph->simple->number_of_points);
14577 else
14578 original_x = alloca (sizeof *original_x * 2
14579 * glyph->simple->number_of_points);
14580
14581 original_y = original_x + glyph->simple->number_of_points;
14582 memcpy (original_x, glyph->simple->x_coordinates,
14583 (sizeof *original_x
14584 * glyph->simple->number_of_points));
14585 memcpy (original_y, glyph->simple->y_coordinates,
14586 (sizeof *original_y
14587 * glyph->simple->number_of_points));
14588 }
14589
14590 memset (touched, 0, (sizeof *touched
14591 * glyph->simple->number_of_points));
14592
14593 for (i = 0; i < point_count; ++i)
14594 {
14595
14596
14597 if (glyph_points[i] == glyph->simple->number_of_points)
14598 {
14599 distortion->origin += sfnt_mul_fixed_round (dx[i], scale);
14600 continue;
14601 }
14602
14603 if (glyph_points[i] == glyph->simple->number_of_points + 1)
14604 {
14605 distortion->advance += sfnt_mul_fixed_round (dx[i], scale);
14606 continue;
14607 }
14608
14609
14610 if (glyph_points[i] >= glyph->simple->number_of_points)
14611 continue;
14612
14613 fword = sfnt_mul_fixed_round (dx[i], scale);
14614 glyph->simple->x_coordinates[glyph_points[i]] += fword;
14615 fword = sfnt_mul_fixed_round (dy[i], scale);
14616 glyph->simple->y_coordinates[glyph_points[i]] += fword;
14617 touched[glyph_points[i]] = true;
14618 }
14619
14620 sfnt_infer_deltas (glyph, touched, original_x,
14621 original_y);
14622 break;
14623 }
14624
14625 xfree (dx);
14626 xfree (dy);
14627
14628 if (local_points != (uint16_t *) -1)
14629 xfree (local_points);
14630 }
14631
14632
14633
14634 if ((glyph->simple->number_of_points
14635 * sizeof *touched) >= 1024 * 16)
14636 xfree (touched);
14637
14638 if (gvar->axis_count * sizeof *coords * 3 >= 1024 * 16)
14639 xfree (coords);
14640
14641 if ((sizeof *original_x * 2
14642 * glyph->simple->number_of_points) >= 1024 * 16)
14643 xfree (original_x);
14644
14645 if (points != (uint16_t *) -1)
14646 xfree (points);
14647
14648
14649 glyph->advance_distortion = distortion->advance;
14650 glyph->origin_distortion = distortion->origin;
14651
14652 return 0;
14653
14654 fail3:
14655 xfree (dx);
14656 xfree (dy);
14657 xfree (local_points);
14658 fail1:
14659
14660 if ((glyph->simple->number_of_points
14661 * sizeof *touched) >= 1024 * 16)
14662 xfree (touched);
14663
14664 if (gvar->axis_count * sizeof *coords * 3 >= 1024 * 16)
14665 xfree (coords);
14666
14667 if ((sizeof *original_x * 2
14668 * glyph->simple->number_of_points) >= 1024 * 16)
14669 xfree (original_x);
14670
14671 if (points != (uint16_t *) -1)
14672 xfree (points);
14673
14674 return 1;
14675 }
14676
14677
14678
14679
14680
14681
14682
14683
14684
14685 TEST_STATIC int
14686 sfnt_vary_compound_glyph (struct sfnt_blend *blend, sfnt_glyph id,
14687 struct sfnt_glyph *glyph,
14688 struct sfnt_metrics_distortion *distortion)
14689 {
14690 uint32_t offset;
14691 struct sfnt_gvar_glyph_header header;
14692 uint16_t *points, npoints;
14693 int i, ntuples, j, point_count;
14694 unsigned char *tuple, *end, *data;
14695 uint16_t data_size, index, *glyph_points;
14696 sfnt_f2dot14 *restrict coords;
14697 sfnt_f2dot14 *restrict intermediate_start;
14698 sfnt_f2dot14 *restrict intermediate_end;
14699 sfnt_fword *restrict dx, *restrict dy, fword, word;
14700 struct sfnt_gvar_table *gvar;
14701 uint16_t *local_points, n_local_points;
14702 sfnt_fixed scale;
14703 ptrdiff_t data_offset;
14704 struct sfnt_compound_glyph_component *component;
14705
14706 gvar = blend->gvar;
14707
14708 if (gvar->axis_count != blend->fvar->axis_count)
14709 return 1;
14710
14711 if (gvar->glyph_count <= id)
14712 return 1;
14713
14714 if (gvar->flags & 1)
14715 offset = gvar->u.offset_long[id];
14716 else
14717 offset = gvar->u.offset_word[id] * 2u;
14718
14719 if (offset >= gvar->data_size)
14720 return 1;
14721
14722 end = gvar->glyph_variation_data + gvar->data_size;
14723
14724
14725
14726 if (offset + sizeof header > gvar->data_size)
14727 return 1;
14728
14729
14730 distortion->origin = 0;
14731 distortion->advance = 0;
14732
14733 memcpy (&header, gvar->glyph_variation_data + offset,
14734 sizeof header);
14735
14736
14737 sfnt_swap16 (&header.tuple_count);
14738 sfnt_swap16 (&header.data_offset);
14739
14740
14741 ntuples = header.tuple_count & 0x0fff;
14742
14743
14744
14745 data_offset = header.data_offset;
14746
14747
14748
14749
14750 npoints = 0;
14751
14752 if (header.tuple_count & 0x8000)
14753 {
14754 data = gvar->glyph_variation_data + offset + data_offset;
14755 points = sfnt_read_packed_points (data, &npoints, end,
14756 &tuple);
14757
14758 if (!points)
14759 return 1;
14760
14761
14762
14763
14764
14765 data_offset += tuple - data;
14766 }
14767 else
14768 points = NULL;
14769
14770
14771 tuple = gvar->glyph_variation_data + offset + sizeof header;
14772
14773 if (gvar->axis_count * sizeof *coords * 3 >= 1024 * 16)
14774 coords = xmalloc (gvar->axis_count * sizeof *coords * 3);
14775 else
14776 coords = alloca (gvar->axis_count * sizeof *coords * 3);
14777
14778 intermediate_start = coords + gvar->axis_count;
14779 intermediate_end = coords + gvar->axis_count;
14780
14781 while (ntuples--)
14782 {
14783 data = gvar->glyph_variation_data + offset + data_offset;
14784
14785 if (tuple + 3 >= end)
14786 goto fail1;
14787
14788 memcpy (&data_size, tuple, sizeof data_size);
14789 tuple += sizeof data_size;
14790 memcpy (&index, tuple, sizeof index);
14791 tuple += sizeof index;
14792 sfnt_swap16 (&data_size);
14793 sfnt_swap16 (&index);
14794
14795
14796
14797 data_offset += data_size;
14798
14799 if (index & 0x8000)
14800 {
14801
14802
14803 for (j = 0; j < gvar->axis_count; ++j)
14804 {
14805 if (tuple + 1 >= end)
14806 goto fail1;
14807
14808 memcpy (&coords[j], tuple, sizeof *coords);
14809 tuple += sizeof *coords;
14810 sfnt_swap16 (&coords[j]);
14811 }
14812 }
14813 else if ((index & 0xfff) > gvar->shared_coord_count)
14814
14815 goto fail1;
14816 else
14817
14818
14819 memcpy (coords, (gvar->global_coords
14820 + ((index & 0xfff) * gvar->axis_count)),
14821 gvar->axis_count * sizeof *coords);
14822
14823
14824 if (index & 0x4000)
14825 {
14826 for (j = 0; j < gvar->axis_count; ++j)
14827 {
14828 if (tuple + 1 >= end)
14829 goto fail1;
14830
14831 memcpy (&intermediate_start[j], tuple,
14832 sizeof *intermediate_start);
14833 tuple += sizeof *intermediate_start;
14834 sfnt_swap16 (&intermediate_start[j]);
14835 }
14836
14837 for (j = 0; j < gvar->axis_count; ++j)
14838 {
14839 if (tuple + 1 >= end)
14840 goto fail1;
14841
14842 memcpy (&intermediate_end[j], tuple,
14843 sizeof *intermediate_end);
14844 tuple += sizeof *intermediate_end;
14845 sfnt_swap16 (&intermediate_end[j]);
14846 }
14847 }
14848
14849
14850
14851
14852 scale = sfnt_compute_tuple_scale (blend, index & 0x4000,
14853 coords, intermediate_start,
14854 intermediate_end);
14855
14856 if (!scale)
14857 continue;
14858
14859 local_points = NULL;
14860
14861
14862
14863
14864
14865 if (index & 0x2000)
14866 {
14867 local_points = sfnt_read_packed_points (data, &n_local_points,
14868 end, &data);
14869 if (!local_points)
14870 goto fail1;
14871
14872 point_count = n_local_points;
14873 glyph_points = local_points;
14874 }
14875 else
14876 {
14877
14878
14879 point_count = npoints;
14880 glyph_points = points;
14881 }
14882
14883
14884
14885 dx = NULL;
14886 dy = NULL;
14887
14888 switch (point_count)
14889 {
14890 case UINT16_MAX:
14891
14892
14893
14894 dx = sfnt_read_packed_deltas (data, end,
14895 glyph->compound->num_components + 4,
14896 &data);
14897 dy = sfnt_read_packed_deltas (data, end,
14898 glyph->compound->num_components + 4,
14899 &data);
14900
14901 if (!dx || !dy)
14902 goto fail3;
14903
14904
14905
14906 for (i = 0; i < glyph->compound->num_components; ++i)
14907 {
14908 component = &glyph->compound->components[i];
14909
14910
14911 if (!(component->flags & 02))
14912 continue;
14913
14914
14915
14916 if (!(component->flags & 01))
14917 word = component->argument1.b;
14918 else
14919 word = component->argument1.d;
14920
14921 fword = sfnt_mul_fixed_round (dx[i], scale);
14922 component->argument1.d = word + fword;
14923
14924
14925
14926 if (!(component->flags & 01))
14927 word = component->argument2.b;
14928 else
14929 word = component->argument2.d;
14930
14931 fword = sfnt_mul_fixed_round (dy[i], scale);
14932
14933
14934 component->flags |= 01;
14935 component->argument2.d = word + fword;
14936 }
14937
14938
14939 distortion->origin += sfnt_mul_fixed_round (dx[i++], scale);
14940 distortion->advance += sfnt_mul_fixed_round (dx[i], scale);
14941 break;
14942
14943 default:
14944 dx = sfnt_read_packed_deltas (data, end, point_count, &data);
14945 dy = sfnt_read_packed_deltas (data, end, point_count, &data);
14946
14947 if (!dx || !dy)
14948 goto fail3;
14949
14950
14951
14952 for (i = 0; i < point_count; ++i)
14953 {
14954
14955
14956 if (glyph_points[i] == glyph->compound->num_components)
14957 {
14958 distortion->origin += sfnt_mul_fixed_round (dx[i], scale);
14959 continue;
14960 }
14961
14962 if (glyph_points[i] == glyph->compound->num_components + 1)
14963 {
14964 distortion->advance += sfnt_mul_fixed_round (dx[i], scale);
14965 continue;
14966 }
14967
14968
14969 if (glyph_points[i] >= glyph->compound->num_components)
14970 continue;
14971
14972 component = &glyph->compound->components[glyph_points[i]];
14973
14974
14975 if (!(component->flags & 02))
14976 continue;
14977
14978
14979
14980 if (!(component->flags & 01))
14981 word = component->argument1.b;
14982 else
14983 word = component->argument1.d;
14984
14985 fword = sfnt_mul_fixed_round (dx[i], scale);
14986 component->argument1.d = word + fword;
14987
14988
14989
14990 if (!(component->flags & 01))
14991 word = component->argument2.b;
14992 else
14993 word = component->argument2.d;
14994
14995 fword = sfnt_mul_fixed_round (dy[i], scale);
14996
14997
14998 component->flags |= 01;
14999 component->argument2.d = word + fword;
15000 }
15001
15002 break;
15003 }
15004
15005 xfree (dx);
15006 xfree (dy);
15007
15008 if (local_points != (uint16_t *) -1)
15009 xfree (local_points);
15010 }
15011
15012
15013
15014 if (gvar->axis_count * sizeof *coords * 3 >= 1024 * 16)
15015 xfree (coords);
15016
15017 if (points != (uint16_t *) -1)
15018 xfree (points);
15019
15020
15021 glyph->advance_distortion = distortion->advance;
15022 glyph->origin_distortion = distortion->origin;
15023
15024 return 0;
15025
15026 fail3:
15027 xfree (dx);
15028 xfree (dy);
15029 xfree (local_points);
15030 fail1:
15031
15032 if (gvar->axis_count * sizeof *coords * 3 >= 1024 * 16)
15033 xfree (coords);
15034
15035 if (points != (uint16_t *) -1)
15036 xfree (points);
15037
15038 return 1;
15039 }
15040
15041
15042
15043
15044
15045
15046
15047
15048 TEST_STATIC void
15049 sfnt_vary_interpreter (struct sfnt_interpreter *interpreter,
15050 struct sfnt_blend *blend)
15051 {
15052 sfnt_fixed scale;
15053 int i;
15054 struct sfnt_tuple_variation *variation;
15055 size_t ndeltas, j, index;
15056 sfnt_f26dot6 delta;
15057
15058
15059 if (!blend->cvar)
15060 return;
15061
15062
15063 for (i = 0; i < (blend->cvar->tuple_count & 0x0fff); ++i)
15064 {
15065
15066 variation = &blend->cvar->variation[i];
15067 scale = sfnt_compute_tuple_scale (blend,
15068 variation->intermediate_start != NULL,
15069 variation->coordinates,
15070 variation->intermediate_start,
15071 variation->intermediate_end);
15072 if (!scale)
15073 continue;
15074
15075
15076
15077
15078
15079 ndeltas = (variation->points
15080 ? variation->num_points
15081 : interpreter->cvt_size);
15082
15083 for (j = 0; j < ndeltas; ++j)
15084 {
15085
15086 index = variation->points ? variation->points[j] : j;
15087
15088 if (index > interpreter->cvt_size)
15089 continue;
15090
15091
15092
15093 delta = sfnt_mul_f26dot6_fixed (variation->deltas[j] * 64,
15094 interpreter->scale);
15095 delta = sfnt_mul_fixed_round (delta, scale);
15096
15097
15098 interpreter->cvt[i] += delta;
15099 }
15100 }
15101
15102 interpreter->n_axis = blend->fvar->axis_count;
15103 interpreter->norm_coords = blend->norm_coords;
15104 }
15105
15106
15107
15108 #ifdef TEST
15109
15110 struct sfnt_test_dcontext
15111 {
15112
15113 struct sfnt_glyf_table *glyf;
15114 struct sfnt_loca_table_short *loca_short;
15115 struct sfnt_loca_table_long *loca_long;
15116 struct sfnt_blend *blend;
15117 };
15118
15119
15120 static sfnt_fixed sfnt_test_max;
15121
15122 static void
15123 sfnt_test_move_to (struct sfnt_point point, void *dcontext)
15124 {
15125 printf ("move_to: %g, %g\n", sfnt_coerce_fixed (point.x),
15126 sfnt_coerce_fixed (point.y));
15127 }
15128
15129 static void
15130 sfnt_test_line_to (struct sfnt_point point, void *dcontext)
15131 {
15132 printf ("line_to: %g, %g\n", sfnt_coerce_fixed (point.x),
15133 sfnt_coerce_fixed (point.y));
15134 }
15135
15136 static void
15137 sfnt_test_curve_to (struct sfnt_point control,
15138 struct sfnt_point endpoint,
15139 void *dcontext)
15140 {
15141 printf ("curve_to: %g, %g - %g, %g\n",
15142 sfnt_coerce_fixed (control.x),
15143 sfnt_coerce_fixed (control.y),
15144 sfnt_coerce_fixed (endpoint.x),
15145 sfnt_coerce_fixed (endpoint.y));
15146 }
15147
15148 static struct sfnt_glyph *
15149 sfnt_test_get_glyph (sfnt_glyph id, void *dcontext,
15150 bool *need_free)
15151 {
15152 struct sfnt_test_dcontext *tables;
15153 struct sfnt_glyph *glyph;
15154 struct sfnt_metrics_distortion distortion;
15155
15156 tables = dcontext;
15157 *need_free = true;
15158
15159 glyph = sfnt_read_glyph (id, tables->glyf,
15160 tables->loca_short,
15161 tables->loca_long);
15162
15163 if (tables->blend && glyph)
15164 {
15165 if (glyph->simple)
15166 sfnt_vary_simple_glyph (tables->blend, id, glyph,
15167 &distortion);
15168 else
15169 sfnt_vary_compound_glyph (tables->blend, id, glyph,
15170 &distortion);
15171 }
15172
15173 return glyph;
15174 }
15175
15176 static void
15177 sfnt_test_free_glyph (struct sfnt_glyph *glyph, void *dcontext)
15178 {
15179 sfnt_free_glyph (glyph);
15180 }
15181
15182 static void
15183 sfnt_test_span (struct sfnt_edge *edge, sfnt_fixed y,
15184 void *dcontext)
15185 {
15186 #if 1
15187 printf ("/* span at %g */\n", sfnt_coerce_fixed (y));
15188 for (; edge; edge = edge->next)
15189 {
15190 if (y >= edge->bottom && y < edge->top)
15191 printf ("ctx.fillRect (%g, %g, 1, 1); "
15192 "/* %g top: %g bot: %g stepx: %g winding: %d */\n",
15193 sfnt_coerce_fixed (edge->x),
15194 sfnt_coerce_fixed (sfnt_test_max - y),
15195 sfnt_coerce_fixed (y),
15196 sfnt_coerce_fixed (edge->top),
15197 sfnt_coerce_fixed (edge->bottom),
15198 sfnt_coerce_fixed (edge->step_x),
15199 edge->winding);
15200 else
15201 printf ("STRIPPED BAD SPAN!!! %g %g %"PRIi32
15202 " %"PRIi32" (winding: %d)\n",
15203 sfnt_coerce_fixed (edge->top),
15204 sfnt_coerce_fixed (edge->bottom),
15205 edge->top, y, edge->winding);
15206 }
15207 #elif 0
15208 int winding;
15209 short x, dx;
15210
15211 winding = 0;
15212 x = 0;
15213
15214 for (; edge; edge = edge->next)
15215 {
15216 dx = (edge->x >> 16) - x;
15217 x = edge->x >> 16;
15218
15219 for (; dx > 0; --dx)
15220 putc (winding ? '.' : ' ', stdout);
15221
15222 winding = !winding;
15223 }
15224
15225 putc ('\n', stdout);
15226 #elif 0
15227 for (; edge; edge = edge->next)
15228 printf ("%g-", sfnt_coerce_fixed (edge->x));
15229 puts ("");
15230 #endif
15231 }
15232
15233 static void
15234 sfnt_test_edge_ignore (struct sfnt_edge *edges, size_t num_edges,
15235 void *dcontext)
15236 {
15237
15238 }
15239
15240
15241 static void sfnt_setup_debugger (void);
15242
15243
15244 static Display *display;
15245
15246
15247 static Window window;
15248
15249
15250 static GC point_gc, background_gc;
15251
15252 static void
15253 sfnt_test_edges (struct sfnt_edge *edges, size_t num_edges)
15254 {
15255 static sfnt_fixed y;
15256 size_t i;
15257
15258 for (i = 0; i < num_edges; ++i)
15259 {
15260 if (y >= edges[i].bottom && y < edges[i].top)
15261 {
15262 XDrawPoint (display, window, point_gc,
15263 edges[i].x / 65536, 100 - (y / 65536));
15264 printf ("sfnt_test_edges: %d %d\n",
15265 edges[i].x / 65536, 100 - (y / 65536));
15266 }
15267 }
15268
15269 y += SFNT_POLY_STEP;
15270
15271 for (i = 0; i < num_edges; ++i)
15272 sfnt_step_edge (&edges[i]);
15273 }
15274
15275 static void
15276 sfnt_debug_edges (struct sfnt_edge *edges, size_t num_edges)
15277 {
15278 XEvent event;
15279
15280 sfnt_setup_debugger ();
15281
15282 while (true)
15283 {
15284 XNextEvent (display, &event);
15285
15286 switch (event.type)
15287 {
15288 case KeyPress:
15289 XDestroyWindow (display, window);
15290 XCloseDisplay (display);
15291 exit (0);
15292 break;
15293
15294 case Expose:
15295
15296 while (true)
15297 {
15298 sfnt_test_edges (edges, num_edges);
15299 XFlush (display);
15300 usleep (50000);
15301 }
15302
15303 break;
15304 }
15305 }
15306 }
15307
15308 static void
15309 sfnt_test_edge (struct sfnt_edge *edges, size_t num_edges,
15310 void *dcontext)
15311 {
15312 size_t i;
15313
15314 printf ("built %zu edges\n", num_edges);
15315
15316 for (i = 0; i < num_edges; ++i)
15317 {
15318 printf ("/* edge x, top, bot: %g, %g - %g. winding: %d */\n"
15319 "/* edge step_x: %g */\n",
15320 sfnt_coerce_fixed (edges[i].x),
15321 sfnt_coerce_fixed (edges[i].top),
15322 sfnt_coerce_fixed (edges[i].bottom),
15323 edges[i].winding,
15324 sfnt_coerce_fixed (edges[i].step_x));
15325 #ifdef TEST_VERTEX
15326 printf ("ctx.fillRect (%g, %g, 1, 1);\n",
15327 sfnt_coerce_fixed (edges[i].x),
15328 sfnt_coerce_fixed (sfnt_test_max
15329 - edges[i].y));
15330 #else
15331 printf ("ctx.fillRect (%g, %g, 1, 1);\n",
15332 sfnt_coerce_fixed (edges[i].x),
15333 sfnt_coerce_fixed (sfnt_test_max
15334 - edges[i].bottom));
15335 #endif
15336 }
15337
15338 if (getenv ("SFNT_DEBUG_STEP"))
15339 {
15340 if (!fork ())
15341 sfnt_debug_edges (edges, num_edges);
15342 }
15343
15344 printf ("==end of edges==\n");
15345
15346 sfnt_poly_edges (edges, num_edges, sfnt_test_span, NULL);
15347 }
15348
15349 static void
15350 sfnt_x_raster (struct sfnt_raster **rasters,
15351 int *advances,
15352 int nrasters,
15353 struct sfnt_hhea_table *hhea,
15354 sfnt_fixed scale)
15355 {
15356 Display *display;
15357 Window window;
15358 Pixmap *pixmaps;
15359 Picture *glyphs, drawable, solid;
15360 int event_base, error_base;
15361 int major, minor, *depths, count;
15362 XRenderPictFormat *format, *glyph_format;
15363 Visual *visual;
15364 XImage image;
15365 GC gc;
15366 XGCValues gcvalues;
15367 XEvent event;
15368 XRenderColor white, black;
15369 int i, ascent, origin, x, y;
15370 Font font;
15371
15372 if (!nrasters)
15373 exit (0);
15374
15375 display = XOpenDisplay (NULL);
15376
15377 if (!display)
15378 exit (0);
15379
15380 if (!XRenderQueryExtension (display, &event_base, &error_base)
15381 || !XRenderQueryVersion (display, &major, &minor))
15382 exit (0);
15383
15384 if (major == 0 && minor < 10)
15385 exit (0);
15386
15387 window = XCreateSimpleWindow (display, DefaultRootWindow (display),
15388 0, 0, 100, 150, 0, 0,
15389 WhitePixel (display,
15390 DefaultScreen (display)));
15391 XSelectInput (display, window, ExposureMask);
15392 XMapWindow (display, window);
15393
15394 visual = DefaultVisual (display, DefaultScreen (display));
15395 format = XRenderFindVisualFormat (display, visual);
15396
15397 if (!format)
15398 exit (0);
15399
15400 glyph_format = XRenderFindStandardFormat (display, PictStandardA8);
15401 depths = XListDepths (display, DefaultScreen (display), &count);
15402
15403 for (i = 0; i < count; ++i)
15404 {
15405 if (depths[i] == 8)
15406 goto depth_found;
15407 }
15408
15409 exit (0);
15410
15411 depth_found:
15412
15413 XFree (depths);
15414 pixmaps = alloca (sizeof *pixmaps * nrasters);
15415 glyphs = alloca (sizeof *glyphs * nrasters);
15416 gc = None;
15417
15418 for (i = 0; i < nrasters; ++i)
15419 {
15420 pixmaps[i] = XCreatePixmap (display, DefaultRootWindow (display),
15421 rasters[i]->width, rasters[i]->height, 8);
15422 if (!gc)
15423 gc = XCreateGC (display, pixmaps[i], 0, &gcvalues);
15424
15425
15426 image.width = rasters[i]->width;
15427 image.height = rasters[i]->height;
15428 image.xoffset = 0;
15429 image.format = ZPixmap;
15430 image.data = (char *) rasters[i]->cells;
15431 image.byte_order = MSBFirst;
15432 image.bitmap_unit = 8;
15433 image.bitmap_bit_order = LSBFirst;
15434 image.bitmap_pad = SFNT_POLY_ALIGNMENT * 8;
15435 image.depth = 8;
15436 image.bytes_per_line = rasters[i]->stride;
15437 image.bits_per_pixel = 8;
15438 image.red_mask = 0;
15439 image.green_mask = 0;
15440 image.blue_mask = 0;
15441
15442 if (!XInitImage (&image))
15443 abort ();
15444
15445 XPutImage (display, pixmaps[i], gc, &image,
15446 0, 0, 0, 0, image.width, image.height);
15447
15448 glyphs[i] = XRenderCreatePicture (display, pixmaps[i],
15449 glyph_format, 0, NULL);
15450 }
15451
15452 XFreeGC (display, gc);
15453
15454 font = XLoadFont (display, "6x13");
15455
15456 if (!font)
15457 exit (1);
15458
15459 gcvalues.font = font;
15460 gcvalues.foreground = BlackPixel (display, DefaultScreen (display));
15461 gc = XCreateGC (display, window, GCForeground | GCFont, &gcvalues);
15462
15463 drawable = XRenderCreatePicture (display, window, format,
15464 0, NULL);
15465 memset (&black, 0, sizeof black);
15466 black.alpha = 65535;
15467
15468 solid = XRenderCreateSolidFill (display, &black);
15469
15470 while (true)
15471 {
15472 XNextEvent (display, &event);
15473
15474 if (event.type == Expose)
15475 {
15476 white.red = 65535;
15477 white.green = 65535;
15478 white.blue = 65535;
15479 white.alpha = 65535;
15480
15481
15482 XRenderFillRectangle (display, PictOpSrc, drawable,
15483 &white, 0, 0, 65535, 65535);
15484
15485
15486 ascent = sfnt_mul_fixed (hhea->ascent * 65536,
15487 scale) / 65536;
15488
15489 origin = 0;
15490
15491 for (i = 0; i < nrasters; ++i)
15492 {
15493
15494 x = origin + rasters[i]->offx;
15495 y = ascent - rasters[i]->height - rasters[i]->offy;
15496
15497
15498 XRenderComposite (display, PictOpOver, solid, glyphs[i],
15499 drawable, 0, 0, 0, 0, x, y,
15500 rasters[i]->width, rasters[i]->height);
15501
15502 origin += advances[i];
15503 }
15504 }
15505 }
15506 }
15507
15508 static void
15509 sfnt_test_raster (struct sfnt_raster *raster,
15510 struct sfnt_hhea_table *hhea,
15511 sfnt_fixed scale)
15512 {
15513 int x, y, i;
15514
15515 for (y = 0; y < raster->height; ++y)
15516 {
15517 for (x = 0; x < raster->width; ++x)
15518 printf ("%3d ", (int) raster->cells[y * raster->stride + x]);
15519 puts ("");
15520 }
15521
15522 if (hhea && getenv ("SFNT_X"))
15523 {
15524 i = 0;
15525
15526 if (!fork ())
15527 sfnt_x_raster (&raster, &i, 1, hhea, scale);
15528 }
15529 }
15530
15531
15532
15533
15534
15535 static struct sfnt_maxp_table test_interpreter_profile =
15536 {
15537 0x00010000,
15538 650,
15539 100,
15540 100,
15541 100,
15542 100,
15543 2,
15544 100,
15545 255,
15546 12,
15547 12,
15548 100,
15549 5000,
15550 100,
15551 1,
15552 };
15553
15554 static sfnt_fword test_cvt_values[] =
15555 {
15556 100, 100, -100, -100, 50, 50, 50, 50, 0, 0,
15557 };
15558
15559 static struct sfnt_cvt_table test_interpreter_cvt =
15560 {
15561 10,
15562 test_cvt_values,
15563 };
15564
15565 static struct sfnt_head_table test_interpreter_head =
15566 {
15567 0x00010000,
15568 0x00010000,
15569 0,
15570 0x5f0f3cf5,
15571 0,
15572 800,
15573 0,
15574 0,
15575 0,
15576 0,
15577 -312,
15578 -555,
15579 1315,
15580 2163,
15581 0,
15582 12,
15583 0,
15584 0,
15585 0,
15586 };
15587
15588 static struct sfnt_interpreter *
15589 sfnt_make_test_interpreter (void)
15590 {
15591 return sfnt_make_interpreter (&test_interpreter_profile,
15592 &test_interpreter_cvt,
15593 &test_interpreter_head,
15594 NULL, 17, 17);
15595 }
15596
15597 struct sfnt_interpreter_test
15598 {
15599 const char *name;
15600 unsigned char *instructions;
15601 int num_instructions;
15602 void *arg;
15603 void (*check) (struct sfnt_interpreter *, void *, bool);
15604 };
15605
15606 static void
15607 sfnt_run_interpreter_test (struct sfnt_interpreter_test *test,
15608 struct sfnt_interpreter *interpreter)
15609 {
15610 fprintf (stderr, "Testing %s: ", test->name);
15611
15612 if (setjmp (interpreter->trap))
15613 test->check (interpreter, test->arg, true);
15614 else
15615 {
15616 interpreter->IP = 0;
15617 interpreter->SP = interpreter->stack;
15618 interpreter->instructions = test->instructions;
15619 interpreter->num_instructions = test->num_instructions;
15620
15621 sfnt_interpret_run (interpreter, SFNT_RUN_CONTEXT_TEST);
15622 test->check (interpreter, test->arg, false);
15623 }
15624 }
15625
15626 struct sfnt_generic_test_args
15627 {
15628 uint32_t *expected_stack;
15629 int expected_stack_elements;
15630 bool expected_trap;
15631 int expected_IP;
15632 };
15633
15634 static void
15635 sfnt_generic_check (struct sfnt_interpreter *interpreter,
15636 void *arg, bool trap)
15637 {
15638 struct sfnt_generic_test_args *args;
15639 int i;
15640
15641 args = arg;
15642
15643 if (((interpreter->SP - interpreter->stack)
15644 != args->expected_stack_elements))
15645 {
15646 fprintf (stderr,
15647 "failed at IP %d:%d (expected %d stack elements,"
15648 " got %td); last trap string: %s\n",
15649 interpreter->call_depth, interpreter->IP,
15650 args->expected_stack_elements,
15651 interpreter->SP - interpreter->stack,
15652 ((trap && interpreter->trap_reason)
15653 ? interpreter->trap_reason
15654 : "NULL"));
15655
15656 for (i = 0; i < interpreter->SP - interpreter->stack; ++i)
15657 fprintf (stderr, "%8d ", (int) interpreter->stack[i]);
15658 fprintf (stderr, "\n");
15659 return;
15660 }
15661
15662 if (memcmp (interpreter->stack, args->expected_stack,
15663 ((char *) interpreter->SP
15664 - (char *) interpreter->stack)))
15665 {
15666 fprintf (stderr, "failed (inconsistent stack elements)\n"
15667 "machine stack ------------------------->\n");
15668
15669 for (i = 0; i < args->expected_stack_elements; ++i)
15670 fprintf (stderr, "%8d ", (int) interpreter->stack[i]);
15671
15672 fprintf (stderr,
15673 "\nexpected stack ------------------------>\n");
15674
15675 for (i = 0; i < args->expected_stack_elements; ++i)
15676 fprintf (stderr, "%8d ", (int) args->expected_stack[i]);
15677
15678 fprintf (stderr, "\n");
15679 return;
15680 }
15681
15682 if (args->expected_IP != -1
15683 && interpreter->IP != args->expected_IP)
15684 {
15685 fprintf (stderr, "failed (IP is %d, not %d)\n",
15686 interpreter->IP, args->expected_IP);
15687 return;
15688 }
15689
15690 if (trap)
15691 {
15692 if (args->expected_trap)
15693 fprintf (stderr, "passed (with trap %s)\n",
15694 interpreter->trap_reason);
15695 else
15696 fprintf (stderr, "failed (unexpected trap %s)\n",
15697 interpreter->trap_reason);
15698
15699 return;
15700 }
15701
15702 if (args->expected_trap)
15703 fprintf (stderr, "failed, trap not encountered\n");
15704 else
15705 fprintf (stderr, "passed\n");
15706
15707 return;
15708 }
15709
15710 static void
15711 sfnt_check_srp0 (struct sfnt_interpreter *interpreter,
15712 void *arg, bool trap)
15713 {
15714 if (trap)
15715 {
15716 fprintf (stderr, "failed (unexpected trap %s)\n",
15717 interpreter->trap_reason);
15718 return;
15719 }
15720
15721 if (interpreter->state.rp0 != 0)
15722 {
15723 fprintf (stderr, "failed, rp0 is not 0, but %d\n",
15724 interpreter->state.rp0);
15725 return;
15726 }
15727
15728 if (interpreter->state.rp1 != 1)
15729 {
15730 fprintf (stderr, "failed, rp1 is not 1, but %d\n",
15731 interpreter->state.rp1);
15732 return;
15733 }
15734
15735 if (interpreter->state.rp2 != 2)
15736 {
15737 fprintf (stderr, "failed, rp2 is not 2, but %d\n",
15738 interpreter->state.rp2);
15739 return;
15740 }
15741
15742 if (interpreter->SP != interpreter->stack)
15743 {
15744 fprintf (stderr, "failed, stack not empty\n");
15745 return;
15746 }
15747
15748 fprintf (stderr, "passed\n");
15749 return;
15750 }
15751
15752 static void
15753 sfnt_check_szp0 (struct sfnt_interpreter *interpreter,
15754 void *arg, bool trap)
15755 {
15756 if (!trap)
15757 {
15758 fprintf (stderr, "failed, expected trap\n");
15759 return;
15760 }
15761
15762 if (interpreter->state.zp0 != 1
15763 || interpreter->state.zp1 != 1
15764 || interpreter->state.zp2 != 0)
15765 {
15766 fprintf (stderr,
15767 "failed, unexpected values of zone pointers: %d %d %d\n",
15768 interpreter->state.zp0, interpreter->state.zp1,
15769 interpreter->state.zp2);
15770 return;
15771 }
15772
15773 if (interpreter->SP != interpreter->stack)
15774 {
15775 fprintf (stderr, "failed, stack not empty\n");
15776 return;
15777 }
15778
15779 fprintf (stderr, "passed with expected trap %s\n",
15780 interpreter->trap_reason);
15781 return;
15782 }
15783
15784 static void
15785 sfnt_check_sloop (struct sfnt_interpreter *interpreter,
15786 void *arg, bool trap)
15787 {
15788 if (interpreter->state.loop != 1)
15789 {
15790
15791 fprintf (stderr, "failed, GS->loop should be 1, not %d\n",
15792 interpreter->state.loop);
15793 return;
15794 }
15795
15796 if (!trap)
15797 {
15798 fprintf (stderr, "failed, expected trap\n");
15799 return;
15800 }
15801
15802 if (interpreter->SP != interpreter->stack)
15803 {
15804 fprintf (stderr, "failed, stack not empty\n");
15805 return;
15806 }
15807
15808 fprintf (stderr, "passed with expected trap %s\n",
15809 interpreter->trap_reason);
15810 return;
15811 }
15812
15813 struct sfnt_rounding_test_args
15814 {
15815 sfnt_f26dot6 value;
15816 };
15817
15818 static void
15819 sfnt_check_rounding (struct sfnt_interpreter *interpreter,
15820 void *arg, bool trap)
15821 {
15822 sfnt_f26dot6 value;
15823 struct sfnt_rounding_test_args *args;
15824
15825 if (trap)
15826 {
15827 fprintf (stderr, "failed, unexpected trap: %s\n",
15828 interpreter->trap_reason);
15829 return;
15830 }
15831
15832 if (interpreter->SP == interpreter->stack)
15833 {
15834 fprintf (stderr, "failed, empty stack\n");
15835 return;
15836 }
15837
15838 value = *(interpreter->SP - 1);
15839 args = arg;
15840
15841 if (value != args->value)
15842 {
15843 fprintf (stderr, "failed. value is: %d %d, but wanted: %d %d\n",
15844 value >> 6, value & 63, args->value >> 6,
15845 args->value & 63);
15846 return;
15847 }
15848
15849 fprintf (stderr, "passed, expected value %d\n", value);
15850 return;
15851 }
15852
15853 static void
15854 sfnt_check_smd (struct sfnt_interpreter *interpreter,
15855 void *arg, bool trap)
15856 {
15857 if (trap)
15858 {
15859 fprintf (stderr, "failed, unexpected trap\n");
15860 return;
15861 }
15862
15863 if (interpreter->state.minimum_distance != 32)
15864 {
15865 fprintf (stderr, "failed, expected minimum distance"
15866 " of 32, got %d\n",
15867 interpreter->state.minimum_distance);
15868 return;
15869 }
15870
15871 fprintf (stderr, "passed\n");
15872 return;
15873 }
15874
15875 static void
15876 sfnt_check_scvtci (struct sfnt_interpreter *interpreter,
15877 void *arg, bool trap)
15878 {
15879 if (trap)
15880 {
15881 fprintf (stderr, "failed, unexpected trap\n");
15882 return;
15883 }
15884
15885 if (interpreter->state.cvt_cut_in != 128)
15886 {
15887 fprintf (stderr, "failed, expected 128, got %d\n",
15888 interpreter->state.cvt_cut_in);
15889 return;
15890 }
15891
15892 fprintf (stderr, "passed\n");
15893 return;
15894 }
15895
15896 static void
15897 sfnt_check_sswci (struct sfnt_interpreter *interpreter,
15898 void *arg, bool trap)
15899 {
15900 if (trap)
15901 {
15902 fprintf (stderr, "failed, unexpected trap\n");
15903 return;
15904 }
15905
15906 if (interpreter->state.sw_cut_in != 512)
15907 {
15908 fprintf (stderr, "failed, expected 512, got %d\n",
15909 interpreter->state.sw_cut_in);
15910 return;
15911 }
15912
15913 fprintf (stderr, "passed\n");
15914 return;
15915 }
15916
15917 static void
15918 sfnt_check_ssw (struct sfnt_interpreter *interpreter,
15919 void *arg, bool trap)
15920 {
15921 if (trap)
15922 {
15923 fprintf (stderr, "failed, unexpected trap\n");
15924 return;
15925 }
15926
15927 if (interpreter->state.single_width_value
15928 != sfnt_mul_f26dot6_fixed (-64, interpreter->scale))
15929 {
15930 fprintf (stderr, "failed, got %d at scale %d,"
15931 " expected %d\n",
15932 interpreter->state.single_width_value,
15933 interpreter->scale,
15934 sfnt_mul_f26dot6_fixed (-64, interpreter->scale));
15935 return;
15936 }
15937
15938 fprintf (stderr, "passed\n");
15939 return;
15940 }
15941
15942 static void
15943 sfnt_check_flipon (struct sfnt_interpreter *interpreter,
15944 void *arg, bool trap)
15945 {
15946 if (trap)
15947 {
15948 fprintf (stderr, "failed, unexpected trap\n");
15949 return;
15950 }
15951
15952 if (!interpreter->state.auto_flip)
15953 fprintf (stderr, "failed, auto flip not enabled\n");
15954 else
15955 fprintf (stderr, "pass\n");
15956
15957 return;
15958 }
15959
15960 static void
15961 sfnt_check_flipoff (struct sfnt_interpreter *interpreter,
15962 void *arg, bool trap)
15963 {
15964 if (trap)
15965 {
15966 fprintf (stderr, "failed, unexpected trap\n");
15967 return;
15968 }
15969
15970 if (interpreter->state.auto_flip)
15971 fprintf (stderr, "failed, auto flip not disabled\n");
15972 else
15973 fprintf (stderr, "pass\n");
15974
15975 return;
15976 }
15977
15978 static void
15979 sfnt_check_sdb (struct sfnt_interpreter *interpreter,
15980 void *arg, bool trap)
15981 {
15982 if (trap)
15983 {
15984 fprintf (stderr, "failed, unexpected trap %s\n",
15985 interpreter->trap_reason);
15986 return;
15987 }
15988
15989 if (interpreter->state.delta_base != 8)
15990 fprintf (stderr, "failed, delta base is %d, not 8\n",
15991 interpreter->state.delta_base);
15992 else
15993 fprintf (stderr, "pass\n");
15994
15995 return;
15996 }
15997
15998 static void
15999 sfnt_check_sds (struct sfnt_interpreter *interpreter,
16000 void *arg, bool trap)
16001 {
16002 if (trap)
16003 {
16004 fprintf (stderr, "failed, unexpected trap %s\n",
16005 interpreter->trap_reason);
16006 return;
16007 }
16008
16009 if (interpreter->state.delta_shift != 1)
16010 fprintf (stderr, "failed, delta shift is %d, not 1\n",
16011 interpreter->state.delta_shift);
16012 else
16013 fprintf (stderr, "pass\n");
16014
16015 return;
16016 }
16017
16018 static void
16019 sfnt_check_scanctrl (struct sfnt_interpreter *interpreter,
16020 void *arg, bool trap)
16021 {
16022 if (trap)
16023 {
16024 fprintf (stderr, "failed, unexpected trap %s\n",
16025 interpreter->trap_reason);
16026 return;
16027 }
16028
16029 if (interpreter->SP != interpreter->stack)
16030 {
16031 fprintf (stderr, "failed, expected empty stack\n");
16032 return;
16033 }
16034
16035 if (interpreter->state.scan_control != 1)
16036 fprintf (stderr, "failed, scan control is %d, not 1\n",
16037 interpreter->state.scan_control);
16038 else
16039 fprintf (stderr, "pass\n");
16040
16041 return;
16042 }
16043
16044 static void
16045 sfnt_check_instctrl (struct sfnt_interpreter *interpreter,
16046 void *arg, bool trap)
16047 {
16048 if (trap)
16049 {
16050 fprintf (stderr, "failed, unexpected trap %s\n",
16051 interpreter->trap_reason);
16052 return;
16053 }
16054
16055 if (interpreter->SP != interpreter->stack)
16056 {
16057 fprintf (stderr, "failed, expected empty stack\n");
16058 return;
16059 }
16060
16061 if (interpreter->state.instruct_control != 2)
16062 fprintf (stderr, "failed, inst control is %d, not 2\n",
16063 interpreter->state.instruct_control);
16064 else
16065 fprintf (stderr, "pass\n");
16066
16067 return;
16068 }
16069
16070 static struct sfnt_generic_test_args npushb_test_args =
16071 {
16072 (uint32_t []) { 1U, 2U, 3U, 4U, },
16073 4,
16074 true,
16075 6,
16076 };
16077
16078 static struct sfnt_generic_test_args npushw_test_args =
16079 {
16080 (uint32_t []) { 0x101U, 0x202U, 0x303U, 0x404U, },
16081 4,
16082 true,
16083 10,
16084 };
16085
16086 static struct sfnt_generic_test_args pushb_test_args =
16087 {
16088 (uint32_t []) { 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U,
16089 1U, },
16090 9,
16091 true,
16092 11,
16093 };
16094
16095 static struct sfnt_generic_test_args pushw_test_args =
16096 {
16097 (uint32_t []) { 0x203U, 0x204U, 0x205U, 0x206U, 0x207U, 0x208U,
16098 0x909U, 0x909U, (uint32_t) -1, },
16099 9,
16100 true,
16101 20,
16102 };
16103
16104 static struct sfnt_generic_test_args stack_overflow_test_args =
16105 {
16106 (uint32_t[]) { },
16107 0,
16108 true,
16109 0,
16110 };
16111
16112 static struct sfnt_generic_test_args stack_underflow_test_args =
16113 {
16114
16115 (uint32_t []) { },
16116 0,
16117 true,
16118 4,
16119 };
16120
16121 static struct sfnt_rounding_test_args rtg_test_args =
16122 {
16123 64,
16124 };
16125
16126 static struct sfnt_rounding_test_args rtg_symmetric_test_args =
16127 {
16128 -64,
16129 };
16130
16131 static struct sfnt_rounding_test_args rtg_1_test_args =
16132 {
16133 0,
16134 };
16135
16136 static struct sfnt_rounding_test_args rtg_1_symmetric_test_args =
16137 {
16138 0,
16139 };
16140
16141 static struct sfnt_rounding_test_args rthg_test_args =
16142 {
16143 32,
16144 };
16145
16146 static struct sfnt_rounding_test_args rthg_1_test_args =
16147 {
16148 96,
16149 };
16150
16151 static struct sfnt_rounding_test_args rtdg_test_args =
16152 {
16153 32,
16154 };
16155
16156 static struct sfnt_rounding_test_args rtdg_1_test_args =
16157 {
16158 0,
16159 };
16160
16161 static struct sfnt_rounding_test_args rtdg_2_test_args =
16162 {
16163 32,
16164 };
16165
16166 static struct sfnt_rounding_test_args rtdg_3_test_args =
16167 {
16168 64,
16169 };
16170
16171 static struct sfnt_generic_test_args else_test_args =
16172 {
16173 (uint32_t []) { 77U, 90U, 83U, },
16174 3,
16175 false,
16176 40,
16177 };
16178
16179 static struct sfnt_generic_test_args jmpr_test_args =
16180 {
16181
16182
16183
16184
16185
16186
16187
16188
16189
16190
16191
16192
16193
16194
16195
16196
16197
16198
16199
16200
16201
16202
16203
16204
16205
16206
16207
16208
16209
16210
16211
16212
16213
16214
16215
16216
16217
16218
16219
16220
16221
16222
16223
16224
16225
16226
16227
16228
16229
16230
16231
16232
16233
16234 (uint32_t []) { 0, 0xb2, 255, 253, 0x1c, },
16235 5,
16236 true,
16237 17,
16238 };
16239
16240 static struct sfnt_generic_test_args dup_test_args =
16241 {
16242 (uint32_t []) { },
16243 0,
16244 true,
16245 5,
16246 };
16247
16248 static struct sfnt_generic_test_args pop_test_args =
16249 {
16250 (uint32_t []) { 70, 70, },
16251 2,
16252 false,
16253 5,
16254 };
16255
16256 static struct sfnt_generic_test_args clear_test_args =
16257 {
16258 (uint32_t []) { },
16259 0,
16260 false,
16261 10,
16262 };
16263
16264 static struct sfnt_generic_test_args swap_test_args =
16265 {
16266 (uint32_t []) { 2, 1, },
16267 2,
16268 false,
16269 4,
16270 };
16271
16272 static struct sfnt_generic_test_args depth_test_args =
16273 {
16274 (uint32_t []) { 3, 3, 3, 3, },
16275 4,
16276 false,
16277 5,
16278 };
16279
16280 static struct sfnt_generic_test_args cindex_test_args =
16281 {
16282 (uint32_t []) { 0, 3, 3, 4, 0, },
16283 5,
16284 true,
16285 10,
16286 };
16287
16288 static struct sfnt_generic_test_args mindex_test_args =
16289 {
16290 (uint32_t []) { 0, 3, 7, 4, 4, },
16291 5,
16292 false,
16293 10,
16294 };
16295
16296 static struct sfnt_generic_test_args raw_test_args =
16297 {
16298 (uint32_t []) { },
16299 0,
16300 true,
16301 0,
16302 };
16303
16304 static struct sfnt_generic_test_args loopcall_test_args =
16305 {
16306 (uint32_t []) { 10, },
16307 1,
16308 false,
16309 12,
16310 };
16311
16312 static struct sfnt_generic_test_args call_test_args =
16313 {
16314 (uint32_t []) { 11, },
16315 1,
16316 true,
16317 2,
16318 };
16319
16320 static struct sfnt_generic_test_args fdef_test_args =
16321 {
16322 (uint32_t []) { },
16323 0,
16324 true,
16325 4,
16326 };
16327
16328 static struct sfnt_generic_test_args fdef_1_test_args =
16329 {
16330 (uint32_t []) { },
16331 0,
16332 true,
16333 9,
16334 };
16335
16336 static struct sfnt_generic_test_args endf_test_args =
16337 {
16338 (uint32_t []) { },
16339 0,
16340 true,
16341 0,
16342 };
16343
16344 static struct sfnt_generic_test_args ws_test_args =
16345 {
16346 (uint32_t []) { 40, },
16347 1,
16348 true,
16349 10,
16350 };
16351
16352 static struct sfnt_generic_test_args rs_test_args =
16353 {
16354 (uint32_t []) { },
16355 0,
16356 true,
16357 2,
16358 };
16359
16360 static struct sfnt_generic_test_args wcvtp_test_args =
16361 {
16362 (uint32_t []) { 32, },
16363 1,
16364 true,
16365 10,
16366 };
16367
16368 static struct sfnt_generic_test_args rcvt_test_args =
16369 {
16370 (uint32_t []) { 136, },
16371 1,
16372 true,
16373 5,
16374 };
16375
16376 static struct sfnt_generic_test_args mppem_test_args =
16377 {
16378 (uint32_t []) { 17, },
16379 1,
16380 false,
16381 1,
16382 };
16383
16384 static struct sfnt_generic_test_args mps_test_args =
16385 {
16386 (uint32_t []) { 17, },
16387 1,
16388 false,
16389 1,
16390 };
16391
16392 static struct sfnt_generic_test_args debug_test_args =
16393 {
16394 (uint32_t []) { },
16395 0,
16396 false,
16397 3,
16398 };
16399
16400 static struct sfnt_generic_test_args lt_test_args =
16401 {
16402 (uint32_t []) { 1, 0, 0, },
16403 3,
16404 false,
16405 12,
16406 };
16407
16408 static struct sfnt_generic_test_args lteq_test_args =
16409 {
16410 (uint32_t []) { 1, 0, 1, },
16411 3,
16412 false,
16413 12,
16414 };
16415
16416 static struct sfnt_generic_test_args gt_test_args =
16417 {
16418 (uint32_t []) { 0, 1, 0, },
16419 3,
16420 false,
16421 12,
16422 };
16423
16424 static struct sfnt_generic_test_args gteq_test_args =
16425 {
16426 (uint32_t []) { 0, 1, 1, },
16427 3,
16428 false,
16429 12,
16430 };
16431
16432 static struct sfnt_generic_test_args eq_test_args =
16433 {
16434 (uint32_t []) { 0, 1, 0, },
16435 3,
16436 false,
16437 18,
16438 };
16439
16440 static struct sfnt_generic_test_args neq_test_args =
16441 {
16442 (uint32_t []) { 1, 0, 1, },
16443 3,
16444 false,
16445 18,
16446 };
16447
16448 static struct sfnt_generic_test_args odd_test_args =
16449 {
16450 (uint32_t []) { 1, 0, },
16451 2,
16452 false,
16453 9,
16454 };
16455
16456 static struct sfnt_generic_test_args even_test_args =
16457 {
16458 (uint32_t []) { 0, 1, },
16459 2,
16460 false,
16461 9,
16462 };
16463
16464 static struct sfnt_generic_test_args if_test_args =
16465 {
16466 (uint32_t []) { 17, 24, 1, 2, 3, 4, 5, -1, -1,
16467 88, 1, 3, },
16468 12,
16469 false,
16470 185,
16471 };
16472
16473 static struct sfnt_generic_test_args eif_test_args =
16474 {
16475 (uint32_t []) { },
16476 0,
16477 false,
16478 3,
16479 };
16480
16481 static struct sfnt_generic_test_args and_test_args =
16482 {
16483 (uint32_t []) { 0, 0, 1, 0, },
16484 4,
16485 false,
16486 16,
16487 };
16488
16489 static struct sfnt_generic_test_args or_test_args =
16490 {
16491 (uint32_t []) { 1, 1, 1, 0, },
16492 4,
16493 false,
16494 16,
16495 };
16496
16497 static struct sfnt_generic_test_args not_test_args =
16498 {
16499 (uint32_t []) { 0, 1, },
16500 2,
16501 false,
16502 6,
16503 };
16504
16505 static struct sfnt_generic_test_args sds_test_args =
16506 {
16507 (uint32_t []) { },
16508 0,
16509 true,
16510 5,
16511 };
16512
16513 static struct sfnt_generic_test_args add_test_args =
16514 {
16515 (uint32_t []) { 96, -1, },
16516 2,
16517 false,
16518 10,
16519 };
16520
16521 static struct sfnt_generic_test_args sub_test_args =
16522 {
16523 (uint32_t []) { 64, -64, 431, },
16524 3,
16525 false,
16526 14,
16527 };
16528
16529 static struct sfnt_generic_test_args div_test_args =
16530 {
16531 (uint32_t []) { 32, -64, },
16532 2,
16533 true,
16534 15,
16535 };
16536
16537 static struct sfnt_generic_test_args mul_test_args =
16538 {
16539 (uint32_t []) { 255, -255, 255, },
16540 3,
16541 false,
16542 16,
16543 };
16544
16545 static struct sfnt_generic_test_args abs_test_args =
16546 {
16547 (uint32_t []) { 1, 1, },
16548 2,
16549 false,
16550 7,
16551 };
16552
16553 static struct sfnt_generic_test_args neg_test_args =
16554 {
16555 (uint32_t []) { 1, -1, },
16556 2,
16557 false,
16558 7,
16559 };
16560
16561 static struct sfnt_generic_test_args floor_test_args =
16562 {
16563 (uint32_t []) { -128, -64, 0, 64, 128, },
16564 5,
16565 false,
16566 17,
16567 };
16568
16569 static struct sfnt_generic_test_args ceiling_test_args =
16570 {
16571 (uint32_t []) { -128, -128, -64, 0, 64, 128, 128, },
16572 7,
16573 false,
16574 25,
16575 };
16576
16577 static struct sfnt_generic_test_args round_test_args =
16578 {
16579 (uint32_t []) { },
16580 0,
16581 true,
16582 0,
16583 };
16584
16585 static struct sfnt_generic_test_args nround_test_args =
16586 {
16587 (uint32_t []) { 63, },
16588 1,
16589 false,
16590 3,
16591 };
16592
16593 static struct sfnt_generic_test_args wcvtf_test_args =
16594 {
16595 (uint32_t []) { (63 * 17 * 65535 / 800) >> 10, },
16596 1,
16597 false,
16598 7,
16599 };
16600
16601 static struct sfnt_generic_test_args jrot_test_args =
16602 {
16603 (uint32_t []) { 40, 40, },
16604 2,
16605 false,
16606 13,
16607 };
16608
16609 static struct sfnt_generic_test_args jrof_test_args =
16610 {
16611 (uint32_t []) { 4, },
16612 1,
16613 false,
16614 13,
16615 };
16616
16617 static struct sfnt_generic_test_args deltac1_test_args =
16618 {
16619 (uint32_t []) { ((((50 * 17 * 65535) + 32767) / 800) >> 10) + 8,
16620 ((((50 * 17 * 65535) + 32767) / 800) >> 10) + 8, },
16621 2,
16622 false,
16623 22,
16624 };
16625
16626 static struct sfnt_generic_test_args deltac2_test_args =
16627 {
16628 (uint32_t []) { ((((50 * 17 * 65535) + 32767) / 800) >> 10) + 8,
16629 ((((50 * 17 * 65535) + 32767) / 800) >> 10) + 8, },
16630 2,
16631 false,
16632 22,
16633 };
16634
16635 static struct sfnt_generic_test_args deltac3_test_args =
16636 {
16637 (uint32_t []) { ((((50 * 17 * 65535) + 32767) / 800) >> 10) + 8,
16638 ((((50 * 17 * 65535) + 32767) / 800) >> 10) + 8, },
16639 2,
16640 false,
16641 22,
16642 };
16643
16644
16645
16646
16647
16648 #define SFNT_ROUNDING_OPERAND(period, phase, threshold) \
16649 0xb0, (((unsigned char) period << 6) \
16650 | ((unsigned char) phase & 3) << 4 \
16651 | ((unsigned char) threshold & 15)), 0x76
16652
16653
16654
16655 #define SFNT_ROUNDING_OPERAND_45(period, phase, threshold) \
16656 0xb0, (((unsigned char) period << 6) \
16657 | ((unsigned char) phase & 3) << 4 \
16658 | ((unsigned char) threshold & 15)), 0x77
16659
16660
16661
16662 #define SFNT_ROUND_VALUE(value) 0xb0, value, 0x68
16663
16664 static unsigned char sfnt_sround_instructions[] =
16665 {
16666 SFNT_ROUNDING_OPERAND (0, 0, 8),
16667 SFNT_ROUND_VALUE (15),
16668 SFNT_ROUND_VALUE (17),
16669 SFNT_ROUNDING_OPERAND (1, 0, 8),
16670 SFNT_ROUND_VALUE (32),
16671 SFNT_ROUND_VALUE (16),
16672 SFNT_ROUNDING_OPERAND (2, 0, 8),
16673 SFNT_ROUND_VALUE (64),
16674 SFNT_ROUND_VALUE (63),
16675 SFNT_ROUNDING_OPERAND (0, 1, 8),
16676 SFNT_ROUND_VALUE (16),
16677 SFNT_ROUND_VALUE (24),
16678 SFNT_ROUNDING_OPERAND (0, 2, 8),
16679 SFNT_ROUND_VALUE (20),
16680 SFNT_ROUND_VALUE (48),
16681 SFNT_ROUNDING_OPERAND (0, 3, 8),
16682 SFNT_ROUND_VALUE (7),
16683 SFNT_ROUND_VALUE (70),
16684 };
16685
16686 static uint32_t sfnt_sround_values[] =
16687 {
16688
16689
16690 0, 32,
16691
16692 64, 0,
16693
16694
16695 128, 0,
16696
16697
16698 8, 40,
16699
16700
16701 16, 48,
16702
16703
16704 16, 80,
16705 };
16706
16707 static struct sfnt_generic_test_args sround_test_args =
16708 {
16709 sfnt_sround_values,
16710 ARRAYELTS (sfnt_sround_values),
16711 false,
16712 ARRAYELTS (sfnt_sround_instructions),
16713 };
16714
16715 static unsigned char sfnt_s45round_instructions[] =
16716 {
16717 SFNT_ROUNDING_OPERAND_45 (0, 0, 0),
16718 SFNT_ROUND_VALUE (1),
16719 SFNT_ROUND_VALUE (45),
16720 };
16721
16722 static uint32_t sfnt_s45round_values[] =
16723 {
16724
16725
16726 45, 90,
16727 };
16728
16729 static struct sfnt_generic_test_args s45round_test_args =
16730 {
16731 sfnt_s45round_values,
16732 ARRAYELTS (sfnt_s45round_values),
16733 false,
16734 ARRAYELTS (sfnt_s45round_instructions),
16735 };
16736
16737 static struct sfnt_generic_test_args rutg_test_args =
16738 {
16739 (uint32_t []) { 64, 64, 0, },
16740 3,
16741 false,
16742 10,
16743 };
16744
16745 static struct sfnt_generic_test_args rdtg_test_args =
16746 {
16747 (uint32_t []) { 0, 0, 64, },
16748 3,
16749 false,
16750 10,
16751 };
16752
16753 static struct sfnt_generic_test_args sangw_test_args =
16754 {
16755 (uint32_t []) { },
16756 0,
16757 false,
16758 3,
16759 };
16760
16761 static struct sfnt_generic_test_args aa_test_args =
16762 {
16763 (uint32_t []) { },
16764 0,
16765 false,
16766 3,
16767 };
16768
16769 static struct sfnt_generic_test_args getinfo_test_args =
16770 {
16771
16772
16773
16774
16775 (uint32_t []) { 2, 0, },
16776 2,
16777 false,
16778 6,
16779 };
16780
16781 static struct sfnt_generic_test_args idef_test_args =
16782 {
16783 (uint32_t []) { 1, 2, 3, },
16784 3,
16785 false,
16786 11,
16787 };
16788
16789 static struct sfnt_generic_test_args roll_test_args =
16790 {
16791 (uint32_t []) { 1, 2, 4, 5, 3, },
16792 5,
16793 false,
16794 7,
16795 };
16796
16797 static struct sfnt_generic_test_args roll_1_test_args =
16798 {
16799 (uint32_t []) { 1, 2, },
16800 2,
16801 true,
16802 3,
16803 };
16804
16805 static struct sfnt_generic_test_args max_test_args =
16806 {
16807 (uint32_t []) { 70, },
16808 1,
16809 false,
16810 6,
16811 };
16812
16813 static struct sfnt_generic_test_args min_test_args =
16814 {
16815 (uint32_t []) { -70, },
16816 1,
16817 false,
16818 6,
16819 };
16820
16821 static struct sfnt_generic_test_args scantype_test_args =
16822 {
16823 (uint32_t []) { },
16824 0,
16825 false,
16826 3,
16827 };
16828
16829 static struct sfnt_interpreter_test all_tests[] =
16830 {
16831 {
16832 "NPUSHB",
16833
16834
16835 (unsigned char []) { 0x40, 4, 1, 2, 3, 4,
16836 0x40, 5, 1, 2, 3, 4, },
16837 10,
16838 &npushb_test_args,
16839 sfnt_generic_check,
16840 },
16841 {
16842 "NPUSHW",
16843
16844
16845 (unsigned char []) { 0x41, 4, 1, 1, 2, 2, 3, 3, 4, 4,
16846 0x41, 4, 1, 1, 2, 2, 3, 3, 4, },
16847 19,
16848 &npushw_test_args,
16849 sfnt_generic_check,
16850 },
16851 {
16852 "PUSHB",
16853
16854
16855
16856 (unsigned char []) { 0xb7, 1, 2, 3, 4, 5, 6, 7, 8,
16857 0xb0, 1,
16858 0xb5, 1, 2, 3, 4, 5, },
16859 17,
16860 &pushb_test_args,
16861 sfnt_generic_check,
16862 },
16863 {
16864 "PUSHW",
16865
16866
16867
16868 (unsigned char []) { 0xbf, 2, 3, 2, 4, 2, 5, 2, 6, 2, 7, 2, 8, 9, 9, 9, 9,
16869 0xb8, 255, 255,
16870 0xbc, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, },
16871 28,
16872 &pushw_test_args,
16873 sfnt_generic_check,
16874 },
16875 {
16876 "that stack overflow is handled correctly",
16877
16878 (unsigned char [103]) { 0x40, 101, },
16879 103,
16880 &stack_overflow_test_args,
16881 sfnt_generic_check,
16882 },
16883 {
16884 "that stack underflow is handled correctly",
16885
16886
16887
16888 (unsigned char []) { 0xb8, 100, 100,
16889 0x21,
16890 0x21, },
16891 5,
16892 &stack_underflow_test_args,
16893 sfnt_generic_check,
16894 },
16895 {
16896 "SRP0, SRP1, SRP2",
16897
16898
16899
16900
16901
16902
16903 (unsigned char []) { 0xb0, 0,
16904 0x10,
16905 0xb0, 1,
16906 0x11,
16907 0xb0, 2,
16908 0x12, },
16909 9,
16910 NULL,
16911 sfnt_check_srp0,
16912 },
16913 {
16914 "SZP0, SZP1, SZP2, SZPS",
16915
16916
16917
16918
16919
16920
16921
16922
16923 (unsigned char []) { 0xb0, 1,
16924 0x13,
16925 0xb0, 1,
16926 0x14,
16927 0xb0, 0,
16928 0x15,
16929 0xb0, 5,
16930 0x16, },
16931 12,
16932 NULL,
16933 sfnt_check_szp0,
16934 },
16935 {
16936 "SLOOP",
16937
16938
16939
16940
16941 (unsigned char []) { 0xb0, 2,
16942 0x17,
16943 0xb0, 0,
16944 0x17, },
16945 6,
16946 NULL,
16947 sfnt_check_sloop,
16948 },
16949 {
16950 "RTG",
16951
16952
16953
16954 (unsigned char []) { 0x18,
16955 0xb0, 32,
16956 0x68, },
16957 4,
16958 &rtg_test_args,
16959 sfnt_check_rounding,
16960 },
16961 {
16962 "rounding symmetry",
16963
16964
16965
16966 (unsigned char []) { 0x18,
16967 0xb8, 255, - (signed char) 32,
16968 0x68, },
16969 5,
16970 &rtg_symmetric_test_args,
16971 sfnt_check_rounding,
16972 },
16973 {
16974 "RTG to 0",
16975
16976
16977
16978 (unsigned char []) { 0x18,
16979 0xb0, 31,
16980 0x68, },
16981 4,
16982 &rtg_1_test_args,
16983 sfnt_check_rounding,
16984 },
16985 {
16986 "rounding symmetry to 0",
16987
16988
16989
16990 (unsigned char []) { 0x18,
16991 0xb8, 255, - (signed char) 31,
16992 0x68, },
16993 5,
16994 &rtg_1_symmetric_test_args,
16995 sfnt_check_rounding,
16996 },
16997 {
16998 "RTHG",
16999
17000
17001
17002 (unsigned char []) { 0x19,
17003 0xb0, 0,
17004 0x68, },
17005 4,
17006 &rthg_test_args,
17007 sfnt_check_rounding,
17008 },
17009 {
17010 "RTHG to 96",
17011
17012
17013
17014 (unsigned char []) { 0x19,
17015 0xb0, 64,
17016 0x68, },
17017 4,
17018 &rthg_1_test_args,
17019 sfnt_check_rounding,
17020 },
17021 {
17022 "SMD",
17023
17024
17025 (unsigned char []) { 0xb0, 32,
17026 0x1a, },
17027 3,
17028 NULL,
17029 sfnt_check_smd,
17030 },
17031 {
17032 "ELSE",
17033
17034
17035
17036
17037
17038
17039
17040
17041
17042
17043
17044
17045
17046
17047
17048
17049
17050
17051 (unsigned char []) { 0x1b,
17052 0x41, 3, 11, 22, 33, 44, 55, 66,
17053 0x40, 1, 3,
17054 0xba, 1, 1, 2, 2, 3, 3,
17055 0xb2, 1, 2, 3,
17056 0xb8, 1, 1,
17057 0x58,
17058 0xb8, 1, 1,
17059 0x1b,
17060 0xb8, 1, 1,
17061 0x59,
17062 0x59,
17063 0xb2, 77, 90, 83, },
17064 40,
17065 &else_test_args,
17066 sfnt_generic_check,
17067 },
17068 {
17069 "JMPR",
17070
17071
17072
17073
17074
17075
17076 (unsigned char []) { 0xba, 00, 00, 00, 0xb2, 255, 253, 0x1c,
17077 0xb0, 4,
17078 0x1c,
17079 255, 255, 255,
17080 0xb8, 255, -30,
17081 0x1c, },
17082 18,
17083 &jmpr_test_args,
17084 sfnt_generic_check,
17085 },
17086 {
17087 "SCVTCI",
17088
17089
17090 (unsigned char []) { 0xb0, 128,
17091 0x1d, },
17092 3,
17093 NULL,
17094 sfnt_check_scvtci,
17095 },
17096 {
17097 "SSWCI",
17098
17099
17100 (unsigned char []) { 0xb8, 2, 0,
17101 0x1e, },
17102 4,
17103 NULL,
17104 sfnt_check_sswci,
17105 },
17106 {
17107 "SSW",
17108
17109
17110 (unsigned char []) { 0xb8, 255, 255,
17111 0x1f, },
17112 4,
17113 NULL,
17114 sfnt_check_ssw,
17115 },
17116 {
17117 "DUP",
17118
17119
17120
17121
17122
17123 (unsigned char []) { 0xb0, 70,
17124 0x20,
17125 0x21,
17126 0x21,
17127 0x70, },
17128 6,
17129 &dup_test_args,
17130 sfnt_generic_check,
17131 },
17132 {
17133 "POP",
17134
17135
17136
17137
17138 (unsigned char []) { 0xb0, 70,
17139 0x20,
17140 0x20,
17141 0x21, },
17142 5,
17143 &pop_test_args,
17144 sfnt_generic_check,
17145 },
17146 {
17147 "CLEAR",
17148
17149
17150 (unsigned char []) { 0xb7, 1, 2, 3, 4, 5, 6, 7, 8,
17151 0x22, },
17152 10,
17153 &clear_test_args,
17154 sfnt_generic_check,
17155 },
17156 {
17157 "SWAP",
17158
17159
17160 (unsigned char []) { 0xb1, 1, 2,
17161 0x23, },
17162 4,
17163 &swap_test_args,
17164 sfnt_generic_check,
17165 },
17166 {
17167 "DEPTH",
17168
17169
17170 (unsigned char []) { 0xb2, 3, 3, 3,
17171 0x24, },
17172 5,
17173 &depth_test_args,
17174 sfnt_generic_check,
17175 },
17176 {
17177 "CINDEX",
17178
17179
17180
17181
17182
17183 (unsigned char []) { 0xb4, 0, 3, 3, 4, 1,
17184 0x25,
17185 0x25,
17186 0xb0, 6,
17187 0x25, },
17188 11,
17189 &cindex_test_args,
17190 sfnt_generic_check,
17191 },
17192 {
17193 "MINDEX",
17194
17195
17196
17197 (unsigned char []) { 0xb6, 0, 3, 4, 7, 3, 4, 2,
17198 0x26,
17199 0x26, },
17200 10,
17201 &mindex_test_args,
17202 sfnt_generic_check,
17203 },
17204 {
17205 "RAW",
17206
17207 (unsigned char []) { 0x28, },
17208 1,
17209 &raw_test_args,
17210 sfnt_generic_check,
17211 },
17212 {
17213 "LOOPCALL",
17214
17215
17216
17217
17218
17219
17220
17221 (unsigned char []) { 0xb1, 0, 2,
17222 0x2c,
17223 0xb0, 1,
17224 0x60,
17225 0x2d,
17226 0xb1, 10, 2,
17227 0x2a, },
17228 12,
17229 &loopcall_test_args,
17230 sfnt_generic_check,
17231 },
17232 {
17233 "CALL",
17234
17235
17236
17237
17238
17239
17240
17241
17242
17243
17244
17245
17246
17247
17248
17249
17250
17251 (unsigned char []) { 0xb1, 7, 2,
17252 0x2c,
17253 0xb0, 1,
17254 0x60,
17255 0x2d,
17256 0xb0, 2,
17257 0x2b,
17258 0xb0, 3,
17259 0x60,
17260 0xb0, 3,
17261 0x2c,
17262 0xb0, 3,
17263 0x2b,
17264 0x2d,
17265 0xb0, 3,
17266 0x2b, },
17267 24,
17268 &call_test_args,
17269 sfnt_generic_check,
17270 },
17271 {
17272 "that FDEF traps inside nested definitions",
17273
17274
17275
17276
17277
17278 (unsigned char []) { 0xb0, 1,
17279 0x2c,
17280 0x2c,
17281 0x2d,
17282 0x2d, },
17283 6,
17284 &fdef_test_args,
17285 sfnt_generic_check,
17286 },
17287 {
17288 "that FDEF traps upon missing ENDF",
17289
17290
17291
17292
17293 (unsigned char []) { 0xb0, 1,
17294 0x2c,
17295 0xb3, 1, 2, 3, 4,
17296 0x21, },
17297 9,
17298 &fdef_1_test_args,
17299 sfnt_generic_check,
17300 },
17301 {
17302 "ENDF",
17303
17304 (unsigned char []) { 0x2d, },
17305 1,
17306 &endf_test_args,
17307 sfnt_generic_check,
17308 },
17309 {
17310 "RTDG",
17311
17312
17313
17314 (unsigned char []) { 0x3d,
17315 0xb0, 16,
17316 0x68, },
17317 4,
17318 &rtdg_test_args,
17319 sfnt_check_rounding,
17320 },
17321 {
17322 "RTDG down to 0",
17323
17324
17325
17326 (unsigned char []) { 0x3d,
17327 0xb0, 15,
17328 0x68, },
17329 4,
17330 &rtdg_1_test_args,
17331 sfnt_check_rounding,
17332 },
17333 {
17334 "RTDG down to 32",
17335
17336
17337
17338 (unsigned char []) { 0x3d,
17339 0xb0, 47,
17340 0x68, },
17341 4,
17342 &rtdg_2_test_args,
17343 sfnt_check_rounding,
17344 },
17345 {
17346 "RTDG up to 64",
17347
17348
17349
17350 (unsigned char []) { 0x3d,
17351 0xb0, 48,
17352 0x68, },
17353 4,
17354 &rtdg_3_test_args,
17355 sfnt_check_rounding,
17356 },
17357 {
17358 "WS",
17359
17360
17361
17362
17363
17364
17365 (unsigned char []) { 0xb1, 240, 40,
17366 0x42,
17367 0xb0, 240,
17368 0x43,
17369 0xb1, 255, 40,
17370 0x42, },
17371 11,
17372 &ws_test_args,
17373 sfnt_generic_check,
17374 },
17375 {
17376 "RS",
17377
17378
17379 (unsigned char []) { 0xb0, 255,
17380 0x43, },
17381 3,
17382 &rs_test_args,
17383 sfnt_generic_check,
17384 },
17385 {
17386 "WCVTP",
17387
17388
17389
17390
17391
17392
17393 (unsigned char []) { 0xb1, 9, 32,
17394 0x44,
17395 0xb0, 9,
17396 0x45,
17397 0xb1, 10, 10,
17398 0x44, },
17399 11,
17400 &wcvtp_test_args,
17401 sfnt_generic_check,
17402 },
17403 {
17404 "RCVT",
17405
17406
17407
17408
17409 (unsigned char []) { 0xb0, 1,
17410 0x45,
17411 0xb0, 10,
17412 0x45, },
17413 6,
17414 &rcvt_test_args,
17415 sfnt_generic_check,
17416 },
17417 {
17418 "MPPEM",
17419
17420 (unsigned char []) { 0x4b, },
17421 1,
17422 &mppem_test_args,
17423 sfnt_generic_check,
17424 },
17425 {
17426 "MPS",
17427
17428 (unsigned char []) { 0x4c, },
17429 1,
17430 &mps_test_args,
17431 sfnt_generic_check,
17432 },
17433 {
17434 "FLIPON",
17435
17436 (unsigned char []) { 0x4d, },
17437 1,
17438 NULL,
17439 sfnt_check_flipon,
17440 },
17441 {
17442 "FLIPOFF",
17443
17444 (unsigned char []) { 0x4e, },
17445 1,
17446 NULL,
17447 sfnt_check_flipoff,
17448 },
17449 {
17450 "DEBUG",
17451
17452
17453 (unsigned char []) { 0xb0, 1,
17454 0x4f, },
17455 3,
17456 &debug_test_args,
17457 sfnt_generic_check,
17458 },
17459 {
17460 "LT",
17461
17462
17463
17464
17465
17466
17467 (unsigned char []) { 0xb1, 47, 48,
17468 0x50,
17469 0xb1, 48, 47,
17470 0x50,
17471 0xb1, 47, 47,
17472 0x50, },
17473 12,
17474 <_test_args,
17475 sfnt_generic_check,
17476 },
17477 {
17478 "LTEQ",
17479
17480
17481
17482
17483
17484
17485 (unsigned char []) { 0xb1, 47, 48,
17486 0x51,
17487 0xb1, 48, 47,
17488 0x51,
17489 0xb1, 47, 47,
17490 0x51, },
17491 12,
17492 <eq_test_args,
17493 sfnt_generic_check,
17494 },
17495 {
17496 "GT",
17497
17498
17499
17500
17501
17502
17503 (unsigned char []) { 0xb1, 47, 48,
17504 0x52,
17505 0xb1, 48, 47,
17506 0x52,
17507 0xb1, 47, 47,
17508 0x52, },
17509 12,
17510 >_test_args,
17511 sfnt_generic_check,
17512 },
17513 {
17514 "GTEQ",
17515
17516
17517
17518
17519
17520
17521 (unsigned char []) { 0xb1, 47, 48,
17522 0x53,
17523 0xb1, 48, 47,
17524 0x53,
17525 0xb1, 47, 47,
17526 0x53, },
17527 12,
17528 >eq_test_args,
17529 sfnt_generic_check,
17530 },
17531 {
17532 "EQ",
17533
17534
17535
17536
17537
17538
17539
17540 (unsigned char []) { 0xb9, 255, 253, 255, 255,
17541 0x54,
17542 0xb9, 27, 27, 27, 27,
17543 0x54,
17544 0xb0, 3,
17545 0xb8, 255, 254,
17546 0x54, },
17547 18,
17548 &eq_test_args,
17549 sfnt_generic_check,
17550 },
17551 {
17552 "NEQ",
17553
17554
17555
17556
17557
17558
17559
17560 (unsigned char []) { 0xb9, 255, 253, 255, 255,
17561 0x55,
17562 0xb9, 27, 27, 27, 27,
17563 0x55,
17564 0xb0, 3,
17565 0xb8, 255, 254,
17566 0x55, },
17567 18,
17568 &neq_test_args,
17569 sfnt_generic_check,
17570 },
17571 {
17572 "ODD",
17573
17574
17575
17576
17577
17578 (unsigned char []) { 0x18,
17579 0xb8, 255, 224,
17580 0x56,
17581 0xb8, 255, 159,
17582 0x56, },
17583 9,
17584 &odd_test_args,
17585 sfnt_generic_check,
17586 },
17587 {
17588 "EVEN",
17589
17590
17591
17592
17593
17594 (unsigned char []) { 0x18,
17595 0xb8, 255, 224,
17596 0x57,
17597 0xb8, 255, 159,
17598 0x57, },
17599 9,
17600 &even_test_args,
17601 sfnt_generic_check,
17602 },
17603 {
17604 "IF",
17605
17606
17607
17608
17609
17610
17611
17612
17613
17614
17615
17616
17617
17618
17619
17620
17621
17622
17623
17624
17625
17626
17627
17628
17629
17630
17631
17632
17633
17634
17635
17636
17637
17638
17639
17640
17641
17642
17643
17644
17645
17646
17647 (unsigned char []) { 0x40, 1, 0,
17648 0x58,
17649 0xb8, 1, 1,
17650 0xb9, 1, 1, 2, 2,
17651 0xba, 1, 1, 2, 2, 3, 3,
17652 0xbb, 1, 1, 2, 2, 3, 3, 4, 4,
17653 0xbc, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5,
17654 0xbd, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
17655 0xbe, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7,
17656 0xbf, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8,
17657 0xb0, 1,
17658 0xb1, 2, 1,
17659 0xb2, 3, 2, 1,
17660 0xb3, 4, 3, 2, 1,
17661 0xb4, 5, 4, 3, 2, 1,
17662 0xb5, 6, 5, 4, 3, 2, 1,
17663 0xb6, 7, 6, 5, 4, 3, 2, 1,
17664 0xb7, 8, 7, 6, 5, 4, 3, 2, 1,
17665 0x4f,
17666 0x58,
17667 0xb7, 12, 12, 12, 12, 12, 12, 12, 12,
17668 0x1b,
17669 0x59,
17670 0x1b,
17671 0xb1, 17, 24,
17672 0x40, 5, 1, 2, 3, 4, 5,
17673 0x41, 2, 255, 255, 255, 255,
17674 0x59,
17675 0xb0, 1,
17676 0x58,
17677 0x40, 2, 43, 43,
17678 0x58,
17679 0xb0, 45,
17680 0x1b,
17681 0xb0, 14,
17682 0x59,
17683 0x60,
17684 0x1b,
17685 0x40, 4, 3, 2, 1, 0,
17686 0x59,
17687 0xb1, 1, 3, },
17688 185,
17689 &if_test_args,
17690 sfnt_generic_check,
17691 },
17692 {
17693 "EIF",
17694
17695
17696
17697 (unsigned char []) { 0xb0, 1,
17698 0x58,
17699 0x59, },
17700 3,
17701 &eif_test_args,
17702 sfnt_generic_check,
17703 },
17704 {
17705 "AND",
17706
17707
17708
17709
17710
17711
17712
17713
17714 (unsigned char []) { 0xb1, 0, 1,
17715 0x5a,
17716 0xb1, 37, 0,
17717 0x5a,
17718 0xb1, 40, 1,
17719 0x5a,
17720 0xb1, 0, 0,
17721 0x5a, },
17722 16,
17723 &and_test_args,
17724 sfnt_generic_check,
17725 },
17726 {
17727 "OR",
17728
17729
17730
17731
17732
17733
17734
17735
17736 (unsigned char []) { 0xb1, 0, 1,
17737 0x5b,
17738 0xb1, 37, 0,
17739 0x5b,
17740 0xb1, 40, 1,
17741 0x5b,
17742 0xb1, 0, 0,
17743 0x5b, },
17744 16,
17745 &or_test_args,
17746 sfnt_generic_check,
17747 },
17748 {
17749 "NOT",
17750
17751
17752
17753
17754 (unsigned char []) { 0xb0, 1,
17755 0x5c,
17756 0xb0, 0,
17757 0x5c, },
17758 6,
17759 ¬_test_args,
17760 sfnt_generic_check,
17761 },
17762 {
17763 "SDB",
17764
17765
17766 (unsigned char []) { 0xb0, 8,
17767 0x5e, },
17768 3,
17769 NULL,
17770 sfnt_check_sdb,
17771 },
17772 {
17773 "SDS",
17774
17775
17776 (unsigned char []) { 0xb0, 1,
17777 0x5f, },
17778 3,
17779 NULL,
17780 sfnt_check_sds,
17781 },
17782 {
17783 "that SDS rejects invalid values",
17784
17785
17786
17787
17788 (unsigned char []) { 0xb0, 1,
17789 0x5f,
17790 0xb0, 7,
17791 0x5f, },
17792 6,
17793 &sds_test_args,
17794 sfnt_generic_check,
17795 },
17796 {
17797 "ADD",
17798
17799
17800
17801
17802 (unsigned char []) { 0xb1, 64, 32,
17803 0x60,
17804 0xb9, 255, 40, 0, 215,
17805 0x60, },
17806 10,
17807 &add_test_args,
17808 sfnt_generic_check,
17809 },
17810 {
17811 "SUB",
17812
17813
17814
17815
17816
17817
17818 (unsigned char []) { 0xb1, 96, 32,
17819 0x61,
17820 0xb1, 32, 96,
17821 0x61,
17822 0xb9, 0, 215, 255, 40,
17823 0x61, },
17824 14,
17825 &sub_test_args,
17826 sfnt_generic_check,
17827 },
17828 {
17829 "DIV",
17830
17831
17832
17833
17834
17835
17836 (unsigned char []) { 0xb1, 64, 128,
17837 0x62,
17838 0xb9, 0, 32, 255, 224,
17839 0x62,
17840 0xb9, 255, 255, 0, 0,
17841 0x62, },
17842 16,
17843 &div_test_args,
17844 sfnt_generic_check,
17845 },
17846 {
17847 "MUL",
17848
17849
17850
17851
17852
17853
17854 (unsigned char []) { 0xb1, 255, 64,
17855 0x63,
17856 0xb9, 0, 255, 255, 192,
17857 0x63,
17858 0xb9, 255, 1, 255, 192,
17859 0x63, },
17860 16,
17861 &mul_test_args,
17862 sfnt_generic_check,
17863 },
17864 {
17865 "ABS",
17866
17867
17868
17869
17870 (unsigned char []) { 0xb8, 255, 255,
17871 0x64,
17872 0xb0, 1,
17873 0x64, },
17874 7,
17875 &abs_test_args,
17876 sfnt_generic_check,
17877 },
17878 {
17879 "NEG",
17880
17881
17882
17883
17884 (unsigned char []) { 0xb8, 255, 255,
17885 0x65,
17886 0xb0, 1,
17887 0x65, },
17888 7,
17889 &neg_test_args,
17890 sfnt_generic_check,
17891 },
17892 {
17893 "FLOOR",
17894
17895
17896
17897
17898
17899
17900
17901
17902
17903
17904 (unsigned char []) { 0xb8, 255, 129,
17905 0x66,
17906 0xb8, 255, 193,
17907 0x66,
17908 0xb0, 63,
17909 0x66,
17910 0xb0, 127,
17911 0x66,
17912 0xb0, 191,
17913 0x66, },
17914 17,
17915 &floor_test_args,
17916 sfnt_generic_check,
17917 },
17918 {
17919 "CEILING",
17920
17921
17922
17923
17924
17925
17926
17927
17928
17929
17930
17931
17932
17933
17934 (unsigned char []) { 0xb8, 255, 128,
17935 0x67,
17936 0xb8, 255, 127,
17937 0x67,
17938 0xb8, 255, 191,
17939 0x67,
17940 0xb8, 255, 255,
17941 0x67,
17942 0xb0, 63,
17943 0x67,
17944 0xb0, 65,
17945 0x67,
17946 0xb0, 128,
17947 0x67, },
17948 25,
17949 &ceiling_test_args,
17950 sfnt_generic_check,
17951 },
17952 {
17953 "ROUND",
17954
17955 (unsigned char []) { 0x68, },
17956 1,
17957 &round_test_args,
17958 sfnt_generic_check,
17959 },
17960 {
17961 "NROUND",
17962
17963
17964 (unsigned char []) { 0xb0, 63,
17965 0x6c, },
17966 3,
17967 &nround_test_args,
17968 sfnt_generic_check,
17969 },
17970 {
17971 "WCVTF",
17972
17973
17974
17975
17976 (unsigned char []) { 0xb1, 1, 63,
17977 0x70,
17978 0xb0, 1,
17979 0x45, },
17980 7,
17981 &wcvtf_test_args,
17982 sfnt_generic_check,
17983 },
17984 {
17985 "JROT",
17986
17987
17988
17989
17990
17991
17992 (unsigned char []) { 0xb1, 4, 0,
17993 0x78,
17994 0xb1, 40, 40,
17995 0xb1, 3, 1,
17996 0x78,
17997 0xb0, 4, },
17998 13,
17999 &jrot_test_args,
18000 sfnt_generic_check,
18001 },
18002 {
18003 "JROF",
18004
18005
18006
18007
18008
18009
18010 (unsigned char []) { 0xb1, 4, 0,
18011 0x79,
18012 0xb1, 40, 40,
18013 0xb1, 3, 1,
18014 0x79,
18015 0xb0, 4, },
18016 13,
18017 &jrof_test_args,
18018 sfnt_generic_check,
18019 },
18020 {
18021 "DELTAC1",
18022
18023
18024
18025
18026
18027
18028
18029
18030
18031
18032
18033
18034
18035 (unsigned char []) { 0xb0, 2,
18036 0x5e,
18037 0xb0, 6,
18038 0x5f,
18039 0xb2, 255, 5, 1,
18040 0x73,
18041 0xb0, 5,
18042 0x45,
18043 0xb2, 239, 5, 1,
18044 0x73,
18045 0xb0, 5,
18046 0x45, },
18047 22,
18048 &deltac1_test_args,
18049 sfnt_generic_check,
18050 },
18051 {
18052 "DELTAC2",
18053
18054
18055
18056
18057
18058
18059
18060
18061
18062
18063
18064
18065
18066 (unsigned char []) { 0xb0, 2,
18067 0x5e,
18068 0xb0, 6,
18069 0x5f,
18070 0xb2, 255, 5, 1,
18071 0x74,
18072 0xb0, 5,
18073 0x45,
18074 0xb2, 239, 5, 1,
18075 0x74,
18076 0xb0, 5,
18077 0x45, },
18078 22,
18079 &deltac2_test_args,
18080 sfnt_generic_check,
18081 },
18082 {
18083 "DELTAC3",
18084
18085
18086
18087
18088
18089
18090
18091
18092
18093
18094
18095
18096
18097 (unsigned char []) { 0xb0, 2,
18098 0x5e,
18099 0xb0, 6,
18100 0x5f,
18101 0xb2, 255, 5, 1,
18102 0x75,
18103 0xb0, 5,
18104 0x45,
18105 0xb2, 239, 5, 1,
18106 0x75,
18107 0xb0, 5,
18108 0x45, },
18109 22,
18110 &deltac3_test_args,
18111 sfnt_generic_check,
18112 },
18113 {
18114 "SROUND",
18115 sfnt_sround_instructions,
18116 ARRAYELTS (sfnt_sround_instructions),
18117 &sround_test_args,
18118 sfnt_generic_check,
18119 },
18120 {
18121 "S45ROUND",
18122 sfnt_s45round_instructions,
18123 ARRAYELTS (sfnt_s45round_instructions),
18124 &s45round_test_args,
18125 sfnt_generic_check,
18126 },
18127 {
18128 "RUTG",
18129
18130
18131
18132
18133
18134
18135
18136 (unsigned char []) { 0x7c,
18137 0xb0, 1,
18138 0x68,
18139 0xb0, 64,
18140 0x68,
18141 0xb0, 0,
18142 0x68, },
18143 10,
18144 &rutg_test_args,
18145 sfnt_generic_check,
18146 },
18147 {
18148 "RDTG",
18149
18150
18151
18152
18153
18154
18155
18156 (unsigned char []) { 0x7d,
18157 0xb0, 1,
18158 0x68,
18159 0xb0, 63,
18160 0x68,
18161 0xb0, 64,
18162 0x68, },
18163 10,
18164 &rdtg_test_args,
18165 sfnt_generic_check,
18166 },
18167 {
18168 "SANGW",
18169
18170
18171 (unsigned char []) { 0xb0, 3,
18172 0x7e, },
18173 3,
18174 &sangw_test_args,
18175 sfnt_generic_check,
18176 },
18177 {
18178 "AA",
18179
18180
18181 (unsigned char []) { 0xb0, 3,
18182 0x7f, },
18183 3,
18184 &aa_test_args,
18185 sfnt_generic_check,
18186 },
18187 {
18188 "SCANCTRL",
18189
18190
18191 (unsigned char []) { 0xb0, 1,
18192 0x85, },
18193 3,
18194 NULL,
18195 sfnt_check_scanctrl,
18196 },
18197 {
18198 "GETINFO",
18199
18200
18201
18202
18203 (unsigned char []) { 0xb0, 1,
18204 0x88,
18205 0xb0, 6,
18206 0x88, },
18207 6,
18208 &getinfo_test_args,
18209 sfnt_generic_check,
18210 },
18211 {
18212 "IDEF",
18213
18214
18215
18216
18217
18218
18219 (unsigned char []) { 0xb0, 0x83,
18220 0x89,
18221 0xb3, 1, 2, 3, 4,
18222 0x21,
18223 0x2d,
18224 0x83, },
18225 11,
18226 &idef_test_args,
18227 sfnt_generic_check,
18228 },
18229 {
18230 "ROLL",
18231
18232
18233 (unsigned char []) { 0xb4, 1, 2, 3, 4, 5,
18234 0x8a, },
18235 7,
18236 &roll_test_args,
18237 sfnt_generic_check,
18238 },
18239 {
18240 "that ROLL correctly handles underflow",
18241
18242
18243 (unsigned char []) { 0xb1, 1, 2,
18244 0x8a, },
18245 4,
18246 &roll_1_test_args,
18247 sfnt_generic_check,
18248 },
18249 {
18250 "MAX",
18251
18252
18253 (unsigned char []) { 0xb9, 0, 70, 255, 186,
18254 0x8b, },
18255 6,
18256 &max_test_args,
18257 sfnt_generic_check,
18258 },
18259 {
18260 "MIN",
18261
18262
18263 (unsigned char []) { 0xb9, 0, 70, 255, 186,
18264 0x8c, },
18265 6,
18266 &min_test_args,
18267 sfnt_generic_check,
18268 },
18269 {
18270 "SCANTYPE",
18271
18272
18273 (unsigned char []) { 0xb0, 0,
18274 0x8d, },
18275 3,
18276 &scantype_test_args,
18277 sfnt_generic_check,
18278 },
18279 {
18280 "INSTCTRL",
18281
18282
18283
18284
18285
18286
18287 (unsigned char []) { 0xb1, 1, 1,
18288 0x8e,
18289 0xb1, 2, 1,
18290 0x8e,
18291 0xb1, 2, 0,
18292 0x8e, },
18293 12,
18294 NULL,
18295 sfnt_check_instctrl,
18296 },
18297 };
18298
18299
18300
18301
18302
18303 static void
18304 sfnt_setup_debugger (void)
18305 {
18306 XGCValues gcv;
18307 Font font;
18308
18309 display = XOpenDisplay (NULL);
18310
18311 if (!display)
18312 exit (1);
18313
18314 window = XCreateSimpleWindow (display, DefaultRootWindow (display),
18315 0, 0, 200, 200, 0, 0,
18316 WhitePixel (display,
18317 DefaultScreen (display)));
18318 XMapWindow (display, window);
18319
18320
18321 XSelectInput (display, window, KeyPressMask | ExposureMask);
18322
18323
18324 font = XLoadFont (display, "6x13");
18325
18326 if (!font)
18327 exit (1);
18328
18329
18330
18331
18332 gcv.foreground = BlackPixel (display, DefaultScreen (display));
18333 gcv.font = font;
18334 point_gc = XCreateGC (display, window, GCForeground | GCFont,
18335 &gcv);
18336 gcv.foreground = WhitePixel (display, DefaultScreen (display));
18337 background_gc = XCreateGC (display, window, GCForeground, &gcv);
18338 }
18339
18340 static const char *
18341 sfnt_name_instruction (unsigned char opcode)
18342 {
18343 static const char *const opcode_names[256] = {
18344 "7 SVTCA y",
18345 "7 SVTCA x",
18346 "8 SPvTCA y",
18347 "8 SPvTCA x",
18348 "8 SFvTCA y",
18349 "8 SFvTCA x",
18350 "8 SPvTL ||",
18351 "7 SPvTL +",
18352 "8 SFvTL ||",
18353 "7 SFvTL +",
18354 "5 SPvFS",
18355 "5 SFvFS",
18356 "3 GPv",
18357 "3 GFv",
18358 "6 SFvTPv",
18359 "5 ISECT",
18360
18361 "4 SRP0",
18362 "4 SRP1",
18363 "4 SRP2",
18364 "4 SZP0",
18365 "4 SZP1",
18366 "4 SZP2",
18367 "4 SZPS",
18368 "5 SLOOP",
18369 "3 RTG",
18370 "4 RTHG",
18371 "3 SMD",
18372 "4 ELSE",
18373 "4 JMPR",
18374 "6 SCvTCi",
18375 "5 SSwCi",
18376 "3 SSW",
18377
18378 "3 DUP",
18379 "3 POP",
18380 "5 CLEAR",
18381 "4 SWAP",
18382 "5 DEPTH",
18383 "6 CINDEX",
18384 "6 MINDEX",
18385 "8 AlignPTS",
18386 "7 INS_$28",
18387 "3 UTP",
18388 "8 LOOPCALL",
18389 "4 CALL",
18390 "4 FDEF",
18391 "4 ENDF",
18392 "7 MDAP[0]",
18393 "7 MDAP[1]",
18394
18395 "6 IUP[0]",
18396 "6 IUP[1]",
18397 "6 SHP[0]",
18398 "6 SHP[1]",
18399 "6 SHC[0]",
18400 "6 SHC[1]",
18401 "6 SHZ[0]",
18402 "6 SHZ[1]",
18403 "5 SHPIX",
18404 "2 IP",
18405 "8 MSIRP[0]",
18406 "8 MSIRP[1]",
18407 "7 AlignRP",
18408 "4 RTDG",
18409 "7 MIAP[0]",
18410 "7 MIAP[1]",
18411
18412 "6 NPushB",
18413 "6 NPushW",
18414 "2 WS",
18415 "2 RS",
18416 "5 WCvtP",
18417 "4 RCvt",
18418 "5 GC[0]",
18419 "5 GC[1]",
18420 "4 SCFS",
18421 "5 MD[0]",
18422 "5 MD[1]",
18423 "5 MPPEM",
18424 "3 MPS",
18425 "6 FlipON",
18426 "7 FlipOFF",
18427 "5 DEBUG",
18428
18429 "2 LT",
18430 "4 LTEQ",
18431 "2 GT",
18432 "4 GTEQ",
18433 "2 EQ",
18434 "3 NEQ",
18435 "3 ODD",
18436 "4 EVEN",
18437 "2 IF",
18438 "3 EIF",
18439 "3 AND",
18440 "2 OR",
18441 "3 NOT",
18442 "7 DeltaP1",
18443 "3 SDB",
18444 "3 SDS",
18445
18446 "3 ADD",
18447 "3 SUB",
18448 "3 DIV",
18449 "3 MUL",
18450 "3 ABS",
18451 "3 NEG",
18452 "5 FLOOR",
18453 "7 CEILING",
18454 "8 ROUND[0]",
18455 "8 ROUND[1]",
18456 "8 ROUND[2]",
18457 "8 ROUND[3]",
18458 "9 NROUND[0]",
18459 "9 NROUND[1]",
18460 "9 NROUND[2]",
18461 "9 NROUND[3]",
18462
18463 "5 WCvtF",
18464 "7 DeltaP2",
18465 "7 DeltaP3",
18466 "A DeltaCn[0]",
18467 "A DeltaCn[1]",
18468 "A DeltaCn[2]",
18469 "6 SROUND",
18470 "8 S45Round",
18471 "4 JROT",
18472 "4 JROF",
18473 "4 ROFF",
18474 "7 INS_$7B",
18475 "4 RUTG",
18476 "4 RDTG",
18477 "5 SANGW",
18478 "2 AA",
18479
18480 "6 FlipPT",
18481 "8 FlipRgON",
18482 "9 FlipRgOFF",
18483 "7 INS_$83",
18484 "7 INS_$84",
18485 "8 ScanCTRL",
18486 "9 SDPvTL[0]",
18487 "9 SDPvTL[1]",
18488 "7 GetINFO",
18489 "4 IDEF",
18490 "4 ROLL",
18491 "3 MAX",
18492 "3 MIN",
18493 "8 ScanTYPE",
18494 "8 InstCTRL",
18495 "7 INS_$8F",
18496
18497 "7 INS_$90",
18498 "7 GXAXIS",
18499 "7 INS_$92",
18500 "7 INS_$93",
18501 "7 INS_$94",
18502 "7 INS_$95",
18503 "7 INS_$96",
18504 "7 INS_$97",
18505 "7 INS_$98",
18506 "7 INS_$99",
18507 "7 INS_$9A",
18508 "7 INS_$9B",
18509 "7 INS_$9C",
18510 "7 INS_$9D",
18511 "7 INS_$9E",
18512 "7 INS_$9F",
18513
18514 "7 INS_$A0",
18515 "7 INS_$A1",
18516 "7 INS_$A2",
18517 "7 INS_$A3",
18518 "7 INS_$A4",
18519 "7 INS_$A5",
18520 "7 INS_$A6",
18521 "7 INS_$A7",
18522 "7 INS_$A8",
18523 "7 INS_$A9",
18524 "7 INS_$AA",
18525 "7 INS_$AB",
18526 "7 INS_$AC",
18527 "7 INS_$AD",
18528 "7 INS_$AE",
18529 "7 INS_$AF",
18530
18531 "8 PushB[0]",
18532 "8 PushB[1]",
18533 "8 PushB[2]",
18534 "8 PushB[3]",
18535 "8 PushB[4]",
18536 "8 PushB[5]",
18537 "8 PushB[6]",
18538 "8 PushB[7]",
18539 "8 PushW[0]",
18540 "8 PushW[1]",
18541 "8 PushW[2]",
18542 "8 PushW[3]",
18543 "8 PushW[4]",
18544 "8 PushW[5]",
18545 "8 PushW[6]",
18546 "8 PushW[7]",
18547
18548 "7 MDRP[G]",
18549 "7 MDRP[B]",
18550 "7 MDRP[W]",
18551 "7 MDRP[?]",
18552 "8 MDRP[rG]",
18553 "8 MDRP[rB]",
18554 "8 MDRP[rW]",
18555 "8 MDRP[r?]",
18556 "8 MDRP[mG]",
18557 "8 MDRP[mB]",
18558 "8 MDRP[mW]",
18559 "8 MDRP[m?]",
18560 "9 MDRP[mrG]",
18561 "9 MDRP[mrB]",
18562 "9 MDRP[mrW]",
18563 "9 MDRP[mr?]",
18564
18565 "8 MDRP[pG]",
18566 "8 MDRP[pB]",
18567 "8 MDRP[pW]",
18568 "8 MDRP[p?]",
18569 "9 MDRP[prG]",
18570 "9 MDRP[prB]",
18571 "9 MDRP[prW]",
18572 "9 MDRP[pr?]",
18573 "9 MDRP[pmG]",
18574 "9 MDRP[pmB]",
18575 "9 MDRP[pmW]",
18576 "9 MDRP[pm?]",
18577 "A MDRP[pmrG]",
18578 "A MDRP[pmrB]",
18579 "A MDRP[pmrW]",
18580 "A MDRP[pmr?]",
18581
18582 "7 MIRP[G]",
18583 "7 MIRP[B]",
18584 "7 MIRP[W]",
18585 "7 MIRP[?]",
18586 "8 MIRP[rG]",
18587 "8 MIRP[rB]",
18588 "8 MIRP[rW]",
18589 "8 MIRP[r?]",
18590 "8 MIRP[mG]",
18591 "8 MIRP[mB]",
18592 "8 MIRP[mW]",
18593 "8 MIRP[m?]",
18594 "9 MIRP[mrG]",
18595 "9 MIRP[mrB]",
18596 "9 MIRP[mrW]",
18597 "9 MIRP[mr?]",
18598
18599 "8 MIRP[pG]",
18600 "8 MIRP[pB]",
18601 "8 MIRP[pW]",
18602 "8 MIRP[p?]",
18603 "9 MIRP[prG]",
18604 "9 MIRP[prB]",
18605 "9 MIRP[prW]",
18606 "9 MIRP[pr?]",
18607 "9 MIRP[pmG]",
18608 "9 MIRP[pmB]",
18609 "9 MIRP[pmW]",
18610 "9 MIRP[pm?]",
18611 "A MIRP[pmrG]",
18612 "A MIRP[pmrB]",
18613 "A MIRP[pmrW]",
18614 "A MIRP[pmr?]"
18615 };
18616
18617 return opcode_names[opcode];
18618 }
18619
18620 static void
18621 sfnt_draw_debugger (struct sfnt_interpreter *interpreter)
18622 {
18623 int x, y, i;
18624 char buffer[80];
18625 const char *name;
18626 int opcode;
18627
18628 sprintf (buffer, "opcode:IP:depth: 0x%x:%d:%d",
18629 interpreter->instructions[interpreter->IP],
18630 interpreter->IP,
18631 interpreter->call_depth);
18632
18633
18634 XFillRectangle (display, window, background_gc,
18635 0, 0, 65535, 65535);
18636
18637
18638 XDrawString (display, window, point_gc, 0, 13, buffer,
18639 strlen (buffer));
18640
18641 opcode = interpreter->instructions[interpreter->IP];
18642
18643 sprintf (buffer, "opcode: %s",
18644 sfnt_name_instruction (opcode));
18645
18646 XDrawString (display, window, point_gc, 14, 27, buffer,
18647 strlen (buffer));
18648
18649 if (interpreter->state.project
18650 == sfnt_project_onto_x_axis_vector)
18651 name = "X axis";
18652 else if (interpreter->state.project
18653 == sfnt_project_onto_y_axis_vector)
18654 name = "Y axis";
18655 else
18656 name = "Any";
18657
18658 sprintf (buffer, "projection function: %s", name);
18659
18660 XDrawString (display, window, point_gc, 28, 42, buffer,
18661 strlen (buffer));
18662
18663
18664 for (i = 0; i < interpreter->glyph_zone->num_points; ++i)
18665 {
18666 x = interpreter->glyph_zone->x_current[i] / 16;
18667 y = (200 - interpreter->glyph_zone->y_current[i] / 16);
18668
18669 XFillRectangle (display, window, point_gc, x, y, 4, 4);
18670 }
18671 }
18672
18673 static void
18674 sfnt_run_hook (struct sfnt_interpreter *interpreter)
18675 {
18676 pid_t pid;
18677 XEvent event;
18678
18679 #ifdef TEST_BREAK_AFTER
18680 static unsigned int instructions;
18681
18682 if (++instructions < TEST_BREAK_AFTER)
18683 return;
18684 #endif
18685
18686 pid = fork ();
18687
18688 if (pid == 0)
18689 {
18690 sfnt_setup_debugger ();
18691
18692 while (true)
18693 {
18694 XNextEvent (display, &event);
18695
18696 switch (event.type)
18697 {
18698 case KeyPress:
18699 XDestroyWindow (display, window);
18700 XCloseDisplay (display);
18701 exit (0);
18702 break;
18703
18704 case Expose:
18705 sfnt_draw_debugger (interpreter);
18706 break;
18707 }
18708 }
18709 }
18710 else
18711 {
18712 while (waitpid (pid, NULL, 0) != pid && errno == EINTR)
18713 ;
18714 }
18715 }
18716
18717 static struct sfnt_prep_table *exec_prep;
18718 static struct sfnt_fpgm_table *exec_fpgm;
18719
18720 static const char *
18721 sfnt_identify_instruction (struct sfnt_interpreter *interpreter)
18722 {
18723 static char buffer[256];
18724 unsigned char *where;
18725
18726 where = interpreter->instructions + interpreter->IP;
18727
18728 if (exec_prep
18729 && where >= exec_prep->instructions
18730 && where < (exec_prep->instructions
18731 + exec_prep->num_instructions))
18732 {
18733 sprintf (buffer, "prep+%td",
18734 where - exec_prep->instructions);
18735 return buffer;
18736 }
18737
18738 if (exec_fpgm->instructions
18739 && where >= exec_fpgm->instructions
18740 && where < (exec_fpgm->instructions
18741 + exec_fpgm->num_instructions))
18742 {
18743 sprintf (buffer, "fpgm+%td",
18744 where - exec_fpgm->instructions);
18745 return buffer;
18746 }
18747
18748 sprintf (buffer, "IP+%td", where - interpreter->instructions);
18749 return buffer;
18750 }
18751
18752 static void
18753 sfnt_verbose (struct sfnt_interpreter *interpreter)
18754 {
18755 struct sfnt_instructed_outline temp;
18756 struct sfnt_glyph_outline *outline;
18757 struct sfnt_raster *raster;
18758 unsigned char opcode;
18759 const char *name;
18760 static unsigned int instructions;
18761
18762
18763
18764
18765 if (interpreter->glyph_zone)
18766 {
18767 temp.num_points = interpreter->glyph_zone->num_points;
18768 temp.num_contours = interpreter->glyph_zone->num_contours;
18769 temp.contour_end_points = interpreter->glyph_zone->contour_end_points;
18770 temp.x_points = interpreter->glyph_zone->x_current;
18771 temp.y_points = interpreter->glyph_zone->y_current;
18772 temp.flags = interpreter->glyph_zone->flags;
18773
18774 outline = sfnt_build_instructed_outline (&temp);
18775
18776 if (!outline)
18777 return;
18778
18779 printf ("outline bounds: %g %g, %g %g\n",
18780 sfnt_coerce_fixed (outline->xmin),
18781 sfnt_coerce_fixed (outline->ymin),
18782 sfnt_coerce_fixed (outline->xmax),
18783 sfnt_coerce_fixed (outline->ymax));
18784
18785 raster = sfnt_raster_glyph_outline (outline);
18786
18787 if (raster)
18788 sfnt_test_raster (raster, NULL, 0);
18789
18790 xfree (outline);
18791 xfree (raster);
18792 }
18793
18794 opcode = interpreter->instructions[interpreter->IP];
18795 printf ("opcode, number of instructions: %s %u\n",
18796 sfnt_name_instruction (opcode), instructions++);
18797 printf ("instruction: %s\n",
18798 sfnt_identify_instruction (interpreter));
18799
18800 if (interpreter->state.project
18801 == sfnt_project_onto_x_axis_vector)
18802 name = "X axis";
18803 else if (interpreter->state.project
18804 == sfnt_project_onto_y_axis_vector)
18805 name = "Y axis";
18806 else
18807 name = "Any";
18808
18809 printf ("projection function: %s\n", name);
18810
18811 printf ("proj and free vecs: %d %d %d %d\n",
18812 interpreter->state.projection_vector.x,
18813 interpreter->state.projection_vector.y,
18814 interpreter->state.freedom_vector.x,
18815 interpreter->state.freedom_vector.y);
18816 }
18817
18818 static void
18819 sfnt_push_hook (struct sfnt_interpreter *interpreter,
18820 uint32_t value)
18821 {
18822 int32_t alternate;
18823
18824 alternate = value;
18825
18826 fprintf (stderr, "--> %"PRIi32"\n", alternate);
18827 }
18828
18829 static void
18830 sfnt_pop_hook (struct sfnt_interpreter *interpreter,
18831 uint32_t value)
18832 {
18833 int32_t alternate;
18834
18835 alternate = value;
18836
18837 fprintf (stderr, "<<- %"PRIi32"\n", alternate);
18838 }
18839
18840
18841
18842 static void
18843 sfnt_test_uvs (int fd, struct sfnt_cmap_format_14 *format14)
18844 {
18845 struct sfnt_uvs_context *context;
18846 size_t i, j;
18847 sfnt_glyph glyph;
18848 sfnt_char c;
18849 struct sfnt_nondefault_uvs_table *uvs;
18850
18851 context = sfnt_create_uvs_context (format14, fd);
18852
18853
18854
18855 if (!context)
18856 fprintf (stderr, "failed to read uvs data\n");
18857 else
18858 {
18859 fprintf (stderr, "UVS context with %zu records and %zu tables\n",
18860 context->num_records, context->nmemb);
18861
18862 for (i = 0; i < context->num_records; ++i)
18863 {
18864 if (!context->records[i].nondefault_uvs)
18865 continue;
18866
18867 uvs = context->records[i].nondefault_uvs;
18868
18869 for (j = 0; j < uvs->num_uvs_mappings; ++j)
18870 {
18871 c = uvs->mappings[j].unicode_value;
18872 glyph = sfnt_variation_glyph_for_char (uvs, c);
18873
18874 if (glyph != uvs->mappings[j].base_character_value)
18875 abort ();
18876
18877 fprintf (stderr, " UVS: %"PRIx32" (%"PRIx32") -> %"PRIu32"\n",
18878 c, context->records[i].selector, glyph);
18879 }
18880 }
18881
18882 sfnt_free_uvs_context (context);
18883 }
18884 }
18885
18886
18887
18888
18889
18890
18891
18892
18893
18894
18895
18896
18897
18898
18899
18900
18901
18902
18903
18904
18905
18906
18907
18908
18909
18910
18911
18912
18913
18914
18915
18916
18917 int
18918 main (int argc, char **argv)
18919 {
18920 struct sfnt_offset_subtable *font;
18921 struct sfnt_cmap_encoding_subtable *subtables;
18922 struct sfnt_cmap_encoding_subtable_data **data;
18923 struct sfnt_cmap_table *table;
18924 int fd, i, j;
18925 sfnt_char character;
18926 struct sfnt_head_table *head;
18927 struct sfnt_hhea_table *hhea;
18928 struct sfnt_loca_table_short *loca_short;
18929 struct sfnt_loca_table_long *loca_long;
18930 struct sfnt_glyf_table *glyf;
18931 struct sfnt_glyph *glyph;
18932 sfnt_glyph code;
18933 struct sfnt_test_dcontext dcontext;
18934 struct sfnt_glyph_outline *outline;
18935 struct timespec start, end, sub, sub1, sub2, sub3;
18936 static struct sfnt_maxp_table *maxp;
18937 struct sfnt_raster *raster;
18938 struct sfnt_hmtx_table *hmtx;
18939 struct sfnt_glyph_metrics metrics;
18940 struct sfnt_name_table *name;
18941 unsigned char *string;
18942 struct sfnt_name_record record;
18943 struct sfnt_meta_table *meta;
18944 struct sfnt_ttc_header *ttc;
18945 struct sfnt_interpreter *interpreter;
18946 struct sfnt_cvt_table *cvt;
18947 struct sfnt_fpgm_table *fpgm;
18948 const char *trap;
18949 struct sfnt_prep_table *prep;
18950 struct sfnt_graphics_state state;
18951 struct sfnt_instructed_outline *value;
18952 struct sfnt_fvar_table *fvar;
18953 struct sfnt_gvar_table *gvar;
18954 struct sfnt_avar_table *avar;
18955 struct sfnt_cvar_table *cvar;
18956 sfnt_fixed scale;
18957 char *fancy;
18958 int *advances;
18959 struct sfnt_raster **rasters;
18960 size_t length;
18961 char *axis_name;
18962 struct sfnt_instance *instance;
18963 struct sfnt_blend blend;
18964 struct sfnt_metrics_distortion distortion;
18965
18966 if (argc < 2)
18967 return 1;
18968
18969 instance = NULL;
18970
18971 if (!strcmp (argv[1], "--check-interpreter"))
18972 {
18973 interpreter = sfnt_make_test_interpreter ();
18974
18975 if (!interpreter)
18976 abort ();
18977
18978 for (i = 0; i < ARRAYELTS (all_tests); ++i)
18979 sfnt_run_interpreter_test (&all_tests[i], interpreter);
18980
18981 exit (0);
18982 }
18983
18984 fd = open (argv[1], O_RDONLY);
18985
18986 if (fd < 1)
18987 return 1;
18988
18989 ttc = NULL;
18990
18991 font = sfnt_read_table_directory (fd);
18992
18993 if (font == (struct sfnt_offset_subtable *) -1)
18994 {
18995 if (lseek (fd, 0, SEEK_SET) != 0)
18996 return 1;
18997
18998 ttc = sfnt_read_ttc_header (fd);
18999
19000 if (!ttc)
19001 return 1;
19002
19003 fprintf (stderr, "TrueType collection: %"PRIu32" fonts installed\n",
19004 ttc->num_fonts);
19005 fflush (stderr);
19006
19007 printf ("Which font? ");
19008 if (scanf ("%d", &i) == EOF)
19009 return 1;
19010
19011 if (i >= ttc->num_fonts || i < 0)
19012 {
19013 printf ("out of range\n");
19014 return 1;
19015 }
19016
19017 if (lseek (fd, ttc->offset_table[i], SEEK_SET)
19018 != ttc->offset_table[i])
19019 return 1;
19020
19021 font = sfnt_read_table_directory (fd);
19022 }
19023
19024 if (!font || font == (struct sfnt_offset_subtable *) -1)
19025 {
19026 close (fd);
19027 return 1;
19028 }
19029
19030 for (i = 0; i < font->num_tables; ++i)
19031 fprintf (stderr, "Found new subtable with tag %"PRIx32
19032 " at offset %"PRIu32"\n",
19033 font->subtables[i].tag,
19034 font->subtables[i].offset);
19035
19036 table = sfnt_read_cmap_table (fd, font, &subtables, &data);
19037
19038 if (!table)
19039 {
19040 close (fd);
19041 xfree (font);
19042 return 1;
19043 }
19044
19045 fprintf (stderr, "number of subtables: %"PRIu16"\n",
19046 table->num_subtables);
19047
19048 for (i = 0; i < table->num_subtables; ++i)
19049 {
19050 fprintf (stderr, "Found cmap table %"PRIu32": %p\n",
19051 subtables[i].offset, (void *) data[i]);
19052
19053 if (data[i])
19054 fprintf (stderr, " format: %"PRIu16"\n",
19055 data[i]->format);
19056 }
19057
19058 if (argc >= 3 && !strcmp (argv[2], "--check-variation-selectors"))
19059 {
19060
19061
19062 for (i = 0; i < table->num_subtables; ++i)
19063 {
19064 if (data[i]->format == 14)
19065 {
19066 fprintf (stderr, "format 14 subtable found\n");
19067 sfnt_test_uvs (fd, (struct sfnt_cmap_format_14 *) data[i]);
19068 return 0;
19069 }
19070 }
19071
19072 return 1;
19073 }
19074
19075 #define FANCY_PPEM 12
19076 #define EASY_PPEM 12
19077
19078 interpreter = NULL;
19079 head = sfnt_read_head_table (fd, font);
19080 hhea = sfnt_read_hhea_table (fd, font);
19081 glyf = sfnt_read_glyf_table (fd, font);
19082 maxp = sfnt_read_maxp_table (fd, font);
19083 name = sfnt_read_name_table (fd, font);
19084 meta = sfnt_read_meta_table (fd, font);
19085 cvt = sfnt_read_cvt_table (fd, font);
19086 fpgm = sfnt_read_fpgm_table (fd, font);
19087 prep = sfnt_read_prep_table (fd, font);
19088 fvar = sfnt_read_fvar_table (fd, font);
19089 gvar = sfnt_read_gvar_table (fd, font);
19090 avar = sfnt_read_avar_table (fd, font);
19091 cvar = NULL;
19092 hmtx = NULL;
19093
19094 if (fvar && cvt)
19095 cvar = sfnt_read_cvar_table (fd, font, fvar, cvt);
19096
19097 if (cvar)
19098 fprintf (stderr, "cvar table found\n");
19099
19100 exec_prep = prep;
19101 exec_fpgm = fpgm;
19102 fancy = getenv ("SFNT_FANCY_TEST");
19103
19104 loca_long = NULL;
19105 loca_short = NULL;
19106
19107 if (fvar)
19108 {
19109 fprintf (stderr, "FVAR table found!\n"
19110 "version: %"PRIu16".%"PRIu16"\n"
19111 "axis_count: %"PRIu16"\n"
19112 "axis_size: %"PRIu16"\n"
19113 "instance_count: %"PRIu16"\n"
19114 "instance_size: %"PRIu16"\n",
19115 fvar->major_version,
19116 fvar->minor_version,
19117 fvar->axis_count,
19118 fvar->axis_size,
19119 fvar->instance_count,
19120 fvar->instance_size);
19121
19122 for (i = 0; i < fvar->axis_count; ++i)
19123 {
19124 if (name)
19125 {
19126 axis_name
19127 = (char *) sfnt_find_name (name, fvar->axis[i].name_id,
19128 &record);
19129
19130 if (axis_name)
19131 fprintf (stderr, "axis no: %d; name: %.*s\n",
19132 i, record.length, axis_name);
19133 }
19134
19135 fprintf (stderr, " axis: %"PRIx32" %g %g %g\n",
19136 fvar->axis[i].axis_tag,
19137 sfnt_coerce_fixed (fvar->axis[i].min_value),
19138 sfnt_coerce_fixed (fvar->axis[i].default_value),
19139 sfnt_coerce_fixed (fvar->axis[i].max_value));
19140 }
19141
19142 for (i = 0; i < fvar->instance_count; ++i)
19143 {
19144 if (name)
19145 {
19146 axis_name
19147 = (char *) sfnt_find_name (name, fvar->instance[i].name_id,
19148 &record);
19149
19150 if (axis_name)
19151 fprintf (stderr, "instance no: %d; name: %.*s\n",
19152 i, record.length, axis_name);
19153 }
19154 }
19155
19156 if (fvar->instance_count > 1)
19157 {
19158 printf ("instance? ");
19159
19160 if (scanf ("%d", &i) == EOF)
19161 goto free_lab;
19162
19163 if (i >= fvar->instance_count)
19164 goto free_lab;
19165
19166 if (i >= 0)
19167 instance = &fvar->instance[i];
19168 }
19169 }
19170
19171 if (gvar)
19172 fprintf (stderr, "gvar table found\n");
19173
19174 if (avar)
19175 {
19176 fprintf (stderr, "avar table found\n");
19177
19178 for (i = 0; i < avar->axis_count; ++i)
19179 {
19180 fprintf (stderr, "axis: %d, %"PRIu16" pairs\n",
19181 i, avar->segments[i].pair_count);
19182
19183 for (j = 0; j < avar->segments[i].pair_count; ++j)
19184 fprintf (stderr, "pair: %g, %g\n",
19185 (avar->segments[i].correspondence[j].from_coord
19186 / 16384.0),
19187 (avar->segments[i].correspondence[j].to_coord
19188 / 16384.0));
19189 }
19190 }
19191
19192 memset (&blend, 0, sizeof blend);
19193
19194 if (instance && gvar)
19195 {
19196 sfnt_init_blend (&blend, fvar, gvar, avar,
19197 cvar);
19198
19199 for (i = 0; i < fvar->axis_count; ++i)
19200 blend.coords[i] = instance->coords[i];
19201
19202 sfnt_normalize_blend (&blend);
19203 }
19204
19205 if (fancy)
19206 {
19207 length = strlen (fancy);
19208 scale = sfnt_div_fixed (FANCY_PPEM, head->units_per_em);
19209
19210 if (hhea && maxp)
19211 hmtx = sfnt_read_hmtx_table (fd, font, hhea, maxp);
19212
19213 if (!maxp || !head || !prep || !hmtx || !hhea
19214 || table->num_subtables < 1)
19215 exit (1);
19216
19217 if (head->index_to_loc_format)
19218 {
19219 loca_long = sfnt_read_loca_table_long (fd, font);
19220 if (!loca_long)
19221 return 1;
19222
19223 fprintf (stderr, "long loca table has %zu glyphs\n",
19224 loca_long->num_offsets);
19225 }
19226 else
19227 {
19228 loca_short = sfnt_read_loca_table_short (fd, font);
19229 if (!loca_short)
19230 return 1;
19231
19232 fprintf (stderr, "short loca table has %zu glyphs\n",
19233 loca_short->num_offsets);
19234 }
19235
19236 interpreter = sfnt_make_interpreter (maxp, cvt, head, fvar,
19237 FANCY_PPEM, FANCY_PPEM);
19238 if (instance && gvar)
19239 sfnt_vary_interpreter (interpreter, &blend);
19240
19241 if (!interpreter)
19242 exit (1);
19243
19244 if (fpgm)
19245 {
19246 fprintf (stderr, "interpreting the font program, with"
19247 " %zu instructions\n", fpgm->num_instructions);
19248 trap = sfnt_interpret_font_program (interpreter, fpgm);
19249
19250 if (trap)
19251 fprintf (stderr, "**TRAP**: %s\n", trap);
19252 }
19253
19254 if (prep)
19255 {
19256 fprintf (stderr, "interpreting the control value program, with"
19257 " %zu instructions\n", prep->num_instructions);
19258 trap = sfnt_interpret_control_value_program (interpreter, prep,
19259 &state);
19260
19261 if (trap)
19262 fprintf (stderr, "**TRAP**: %s\n", trap);
19263 }
19264
19265 state = interpreter->state;
19266
19267 advances = alloca (sizeof *advances * length);
19268 rasters = alloca (sizeof *rasters * length);
19269
19270 for (i = 0; i < length; ++i)
19271 {
19272 code = sfnt_lookup_glyph (fancy[i], data[0]);
19273
19274 if (!code)
19275 exit (2);
19276
19277 glyph = sfnt_read_glyph (code, glyf, loca_short,
19278 loca_long);
19279
19280 if (!glyph || !glyph->simple)
19281 exit (3);
19282
19283 if (instance && gvar)
19284 sfnt_vary_simple_glyph (&blend, code, glyph,
19285 &distortion);
19286
19287 if (sfnt_lookup_glyph_metrics (code, -1,
19288 &metrics,
19289 hmtx, hhea,
19290 head, maxp))
19291 exit (4);
19292
19293 interpreter->state = state;
19294 trap = sfnt_interpret_simple_glyph (glyph, interpreter,
19295 &metrics, &value);
19296
19297 if (trap)
19298 {
19299 fprintf (stderr, "*TRAP*: %s\n", trap);
19300 exit (5);
19301 }
19302
19303 outline = sfnt_build_instructed_outline (value);
19304
19305 if (!outline)
19306 exit (6);
19307
19308 xfree (value);
19309
19310 raster = sfnt_raster_glyph_outline (outline);
19311
19312 if (!raster)
19313 exit (7);
19314
19315 xfree (outline);
19316
19317 rasters[i] = raster;
19318 advances[i] = (sfnt_mul_fixed (metrics.advance, scale)
19319 + sfnt_mul_fixed (distortion.advance, scale));
19320 }
19321
19322 sfnt_x_raster (rasters, advances, length, hhea, scale);
19323 exit (0);
19324 }
19325
19326 if (hhea && maxp)
19327 hmtx = sfnt_read_hmtx_table (fd, font, hhea, maxp);
19328
19329 if (maxp)
19330 fprintf (stderr, "maxp says num glyphs is %"PRIu16"\n",
19331 maxp->num_glyphs);
19332
19333 if (name)
19334 {
19335 fprintf (stderr, "name table of format: %"PRIu16" count: %"
19336 PRIu16"\n", name->format, name->count);
19337
19338 string = sfnt_find_name (name, SFNT_NAME_FONT_FAMILY,
19339 &record);
19340
19341 if (string)
19342 fprintf (stderr, "FONT_FAMILY: %"PRIu16", %"PRIu16"\n",
19343 record.platform_id, record.length);
19344 }
19345
19346 if (meta)
19347 {
19348 fprintf (stderr, "meta table with count: %"PRIu32"\n",
19349 meta->num_data_maps);
19350
19351 for (i = 0; i < meta->num_data_maps; ++i)
19352 fprintf (stderr, " meta tag: %"PRIx32"\n",
19353 meta->data_maps[i].tag);
19354 }
19355
19356 loca_long = NULL;
19357 loca_short = NULL;
19358
19359 if (head)
19360 {
19361 fprintf (stderr, "HEAD table:\n"
19362 "version: \t\t\t%g\n"
19363 "revision: \t\t\t%g\n"
19364 "checksum_adjustment: \t\t%"PRIu32"\n"
19365 "magic: \t\t\t\t%"PRIx32"\n"
19366 "flags: \t\t\t\t%"PRIx16"\n"
19367 "units_per_em: \t\t\t%"PRIu16"\n"
19368 "xmin, ymin, xmax, ymax: \t%d, %d, %d, %d\n"
19369 "mac_style: \t\t\t%"PRIx16"\n"
19370 "lowest_rec_ppem: \t\t%"PRIu16"\n"
19371 "font_direction_hint: \t\t%"PRIi16"\n"
19372 "index_to_loc_format: \t\t%"PRIi16"\n"
19373 "glyph_data_format: \t\t%"PRIi16"\n",
19374 sfnt_coerce_fixed (head->version),
19375 sfnt_coerce_fixed (head->revision),
19376 head->checksum_adjustment,
19377 head->magic,
19378 head->flags,
19379 head->units_per_em,
19380 (int) head->xmin,
19381 (int) head->ymin,
19382 (int) head->xmax,
19383 (int) head->ymax,
19384 head->mac_style,
19385 head->lowest_rec_ppem,
19386 head->font_direction_hint,
19387 head->index_to_loc_format,
19388 head->glyph_data_format);
19389
19390 if (head->index_to_loc_format)
19391 {
19392 loca_long = sfnt_read_loca_table_long (fd, font);
19393 if (!loca_long)
19394 return 1;
19395
19396 fprintf (stderr, "long loca table has %zu glyphs\n",
19397 loca_long->num_offsets);
19398 }
19399 else
19400 {
19401 loca_short = sfnt_read_loca_table_short (fd, font);
19402 if (!loca_short)
19403 return 1;
19404
19405 fprintf (stderr, "short loca table has %zu glyphs\n",
19406 loca_short->num_offsets);
19407 }
19408 }
19409
19410 if (hhea)
19411 fprintf (stderr, "HHEA table:\n"
19412 "version: \t\t\t%g\n"
19413 "ascent, descent: \t\t%d %d\n"
19414 "line_gap: \t\t\t%d\n"
19415 "advance_width_max: \t\t%u\n"
19416 "min_lsb: \t\t\t%d\n"
19417 "min_rsb: \t\t\t%d\n"
19418 "caret_srise: \t\t\t%d\n"
19419 "caret_srun: \t\t\t%d\n",
19420 sfnt_coerce_fixed (hhea->version),
19421 (int) hhea->ascent,
19422 (int) hhea->descent,
19423 (int) hhea->line_gap,
19424 (unsigned int) hhea->advance_width_max,
19425 (int) hhea->min_left_side_bearing,
19426 (int) hhea->min_right_side_bearing,
19427 (int) hhea->caret_slope_rise,
19428 (int) hhea->caret_slope_run);
19429
19430 if (head && maxp && maxp->version >= 0x00010000)
19431 {
19432 fprintf (stderr, "creating interpreter\n"
19433 "the size of the stack is %"PRIu16"\n"
19434 "the size of the twilight zone is %"PRIu16"\n"
19435 "the size of the storage area is %"PRIu16"\n"
19436 "there are at most %"PRIu16" idefs\n"
19437 "there are at most %"PRIu16" fdefs\n"
19438 "the cvt is %zu fwords in length\n",
19439 maxp->max_stack_elements,
19440 maxp->max_twilight_points,
19441 maxp->max_storage,
19442 maxp->max_instruction_defs,
19443 maxp->max_function_defs,
19444 cvt ? cvt->num_elements : 0ul);
19445
19446 interpreter = sfnt_make_interpreter (maxp, cvt, head,
19447 fvar, FANCY_PPEM,
19448 FANCY_PPEM);
19449 state = interpreter->state;
19450
19451 if (instance && gvar)
19452 sfnt_vary_interpreter (interpreter, &blend);
19453
19454 if (fpgm)
19455 {
19456 fprintf (stderr, "interpreting the font program, with"
19457 " %zu instructions\n", fpgm->num_instructions);
19458
19459 trap = sfnt_interpret_font_program (interpreter, fpgm);
19460
19461 if (trap)
19462 fprintf (stderr, "**TRAP**: %s\n", trap);
19463 }
19464
19465 if (prep)
19466 {
19467 fprintf (stderr, "interpreting the control value program, with"
19468 " %zu instructions\n", prep->num_instructions);
19469
19470 trap = sfnt_interpret_control_value_program (interpreter, prep,
19471 &state);
19472
19473 if (trap)
19474 fprintf (stderr, "**TRAP**: %s\n", trap);
19475 }
19476 }
19477
19478 while (true)
19479 {
19480 printf ("table, character? ");
19481
19482 if (scanf ("%d %"SCNu32"", &i, &character) == EOF)
19483 break;
19484
19485 if (i < 0 || i >= table->num_subtables)
19486 {
19487 printf ("table out of range\n");
19488 continue;
19489 }
19490
19491 if (!data[i])
19492 {
19493 printf ("table not present\n");
19494 continue;
19495 }
19496
19497 code = sfnt_lookup_glyph (character, data[i]);
19498 printf ("glyph is %"PRIu32"\n", code);
19499
19500 if ((loca_long || loca_short) && glyf)
19501 {
19502 scale = sfnt_div_fixed (EASY_PPEM, head->units_per_em);
19503 glyph = sfnt_read_glyph (code, glyf, loca_short,
19504 loca_long);
19505
19506 if (glyph)
19507 {
19508 printf ("glyph is: %s\n",
19509 glyph->simple ? "simple" : "compound");
19510
19511 dcontext.glyf = glyf;
19512 dcontext.loca_short = loca_short;
19513 dcontext.loca_long = loca_long;
19514
19515 if (instance && gvar)
19516 dcontext.blend = &blend;
19517 else
19518 dcontext.blend = NULL;
19519
19520 if (glyph->simple && instance && gvar)
19521 {
19522 printf ("applying variations to simple glyph...\n");
19523
19524 clock_gettime (CLOCK_THREAD_CPUTIME_ID, &start);
19525 if (sfnt_vary_simple_glyph (&blend, code, glyph,
19526 &distortion))
19527 printf ("variation failed!\n");
19528 clock_gettime (CLOCK_THREAD_CPUTIME_ID, &end);
19529 sub = timespec_sub (end, start);
19530
19531 printf ("time spent varying: %lld sec %ld nsec\n",
19532 (long long) sub.tv_sec, sub.tv_nsec);
19533 printf ("distortions: %"PRIi16", %"PRIi16"\n",
19534 distortion.origin, distortion.advance);
19535 }
19536 else if (instance && gvar)
19537 {
19538 printf ("applying variations to compound glyph...\n");
19539
19540 if (sfnt_vary_compound_glyph (&blend, code, glyph,
19541 &distortion))
19542 printf ("variation failed!\n");
19543 }
19544
19545 if (sfnt_decompose_glyph (glyph, sfnt_test_move_to,
19546 sfnt_test_line_to,
19547 sfnt_test_curve_to,
19548 sfnt_test_get_glyph,
19549 sfnt_test_free_glyph,
19550 &dcontext))
19551 printf ("decomposition failure\n");
19552
19553 if (sfnt_lookup_glyph_metrics (code, -1,
19554 &metrics,
19555 hmtx, hhea,
19556 head, maxp))
19557 {
19558 printf ("metrics lookup failure");
19559 memset (&metrics, 0, sizeof metrics);
19560 }
19561
19562
19563 clock_gettime (CLOCK_THREAD_CPUTIME_ID, &start);
19564 outline = sfnt_build_glyph_outline (glyph, scale,
19565 &metrics,
19566 sfnt_test_get_glyph,
19567 sfnt_test_free_glyph,
19568 &dcontext);
19569
19570 clock_gettime (CLOCK_THREAD_CPUTIME_ID, &end);
19571 sub = timespec_sub (end, start);
19572 memset (&sub1, 0, sizeof sub1);
19573
19574 if (outline)
19575 {
19576 fprintf (stderr, "outline origin, rbearing: %"
19577 PRIi32" %"PRIi32"\n",
19578 outline->origin,
19579 outline->ymax - outline->origin);
19580 sfnt_test_max = outline->ymax - outline->ymin;
19581
19582 for (i = 0; i < outline->outline_used; i++)
19583 printf ("ctx.%s (%g, %g) /* %g, %g */\n",
19584 ((outline->outline[i].flags
19585 & SFNT_GLYPH_OUTLINE_LINETO)
19586 ? "lineTo" : "moveTo"),
19587 sfnt_coerce_fixed (outline->outline[i].x
19588 - outline->xmin),
19589 sfnt_coerce_fixed (sfnt_test_max
19590 - (outline->outline[i].y
19591 - outline->ymin)),
19592 sfnt_coerce_fixed (outline->outline[i].x
19593 - outline->xmin),
19594 sfnt_coerce_fixed (outline->outline[i].y
19595 - outline->ymin));
19596
19597 clock_gettime (CLOCK_THREAD_CPUTIME_ID, &start);
19598 sfnt_build_outline_edges (outline, sfnt_test_edge_ignore,
19599 NULL);
19600 clock_gettime (CLOCK_THREAD_CPUTIME_ID, &end);
19601 sub1 = timespec_sub (end, start);
19602
19603 sfnt_build_outline_edges (outline, sfnt_test_edge,
19604 NULL);
19605
19606 raster = NULL;
19607
19608 clock_gettime (CLOCK_THREAD_CPUTIME_ID, &start);
19609
19610 for (i = 0; i < 120; ++i)
19611 {
19612 xfree (raster);
19613 raster = sfnt_raster_glyph_outline (outline);
19614 }
19615
19616 clock_gettime (CLOCK_THREAD_CPUTIME_ID, &end);
19617 sub2 = timespec_sub (end, start);
19618
19619
19620 sfnt_test_raster (raster, hhea, scale);
19621 printf ("raster offsets: %d, %d\n",
19622 raster->offx, raster->offy);
19623
19624 xfree (raster);
19625
19626 printf ("outline bounds: %g %g, %g %g\n",
19627 sfnt_coerce_fixed (outline->xmin),
19628 sfnt_coerce_fixed (outline->ymin),
19629 sfnt_coerce_fixed (outline->xmax),
19630 sfnt_coerce_fixed (outline->ymax));
19631 }
19632
19633 if (hmtx && head)
19634 {
19635 if (!sfnt_lookup_glyph_metrics (code, EASY_PPEM,
19636 &metrics,
19637 hmtx, hhea,
19638 head, maxp))
19639 printf ("lbearing, advance: %g, %g\n",
19640 sfnt_coerce_fixed (metrics.lbearing),
19641 sfnt_coerce_fixed (metrics.advance));
19642
19643 if (interpreter)
19644 {
19645 if (getenv ("SFNT_DEBUG"))
19646 interpreter->run_hook = sfnt_run_hook;
19647 else if (getenv ("SFNT_VERBOSE"))
19648 {
19649 interpreter->run_hook = sfnt_verbose;
19650 interpreter->push_hook = sfnt_push_hook;
19651 interpreter->pop_hook = sfnt_pop_hook;
19652 }
19653
19654 if (!sfnt_lookup_glyph_metrics (code, -1,
19655 &metrics,
19656 hmtx, hhea,
19657 head, maxp))
19658 {
19659 printf ("interpreting glyph\n");
19660 interpreter->state = state;
19661 clock_gettime (CLOCK_THREAD_CPUTIME_ID, &start);
19662 if (glyph->simple)
19663 trap
19664 = sfnt_interpret_simple_glyph (glyph,
19665 interpreter,
19666 &metrics,
19667 &value);
19668 else
19669 #define GG sfnt_test_get_glyph
19670 #define FG sfnt_test_free_glyph
19671 trap
19672 = sfnt_interpret_compound_glyph (glyph,
19673 interpreter,
19674 &state,
19675 GG, FG,
19676 hmtx, hhea,
19677 maxp,
19678 &metrics,
19679 &dcontext,
19680 &value);
19681 #undef GG
19682 #undef FG
19683 clock_gettime (CLOCK_THREAD_CPUTIME_ID, &end);
19684 sub3 = timespec_sub (end, start);
19685
19686 if (trap)
19687 printf ("**TRAP**: %s\n", trap);
19688 else
19689 {
19690 printf ("rasterizing instructed outline\n");
19691 if (outline)
19692 xfree (outline);
19693 outline = sfnt_build_instructed_outline (value);
19694 xfree (value);
19695
19696 if (outline)
19697 {
19698 raster = sfnt_raster_glyph_outline (outline);
19699
19700 if (raster)
19701 {
19702 sfnt_test_raster (raster, hhea, scale);
19703 printf ("raster offsets: %d, %d\n",
19704 raster->offx, raster->offy);
19705 xfree (raster);
19706 }
19707 }
19708 }
19709
19710 fprintf (stderr, "execution time: %lld sec %ld nse"
19711 "c\n",
19712 (long long) sub3.tv_sec, sub3.tv_nsec);
19713 }
19714
19715 interpreter->run_hook = NULL;
19716 }
19717 }
19718
19719 printf ("time spent outlining: %lld sec %ld nsec\n",
19720 (long long) sub.tv_sec, sub.tv_nsec);
19721 printf ("time spent building edges: %lld sec %ld nsec\n",
19722 (long long) sub1.tv_sec, sub1.tv_nsec);
19723 printf ("time spent rasterizing: %lld sec %ld nsec\n",
19724 (long long) sub2.tv_sec / 120, sub2.tv_nsec / 120);
19725
19726 xfree (outline);
19727 }
19728
19729 sfnt_free_glyph (glyph);
19730 }
19731 }
19732
19733 free_lab:
19734
19735 xfree (font);
19736
19737 for (i = 0; i < table->num_subtables; ++i)
19738 xfree (data[i]);
19739
19740 if (instance && gvar)
19741 sfnt_free_blend (&blend);
19742
19743 xfree (table);
19744 xfree (data);
19745 xfree (subtables);
19746 xfree (head);
19747 xfree (hhea);
19748 xfree (loca_long);
19749 xfree (loca_short);
19750 xfree (glyf);
19751 xfree (maxp);
19752 xfree (hmtx);
19753 xfree (name);
19754 xfree (meta);
19755 xfree (ttc);
19756 xfree (cvt);
19757 xfree (fpgm);
19758 xfree (interpreter);
19759 xfree (prep);
19760 xfree (fvar);
19761 xfree (gvar);
19762 xfree (avar);
19763 xfree (cvar);
19764
19765 return 0;
19766 }
19767
19768 #endif