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