aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPo Lu2023-01-07 20:27:30 +0800
committerPo Lu2023-01-07 20:27:30 +0800
commitdd8078ed113bc6c7ad8aa8c877e8ac7d09c52a38 (patch)
tree40e3ee750249141a849ce58558b0e183ad338425 /src
parent6d823d1077e979b3266e85cbdc476646b7bdb36b (diff)
downloademacs-dd8078ed113bc6c7ad8aa8c877e8ac7d09c52a38.tar.gz
emacs-dd8078ed113bc6c7ad8aa8c877e8ac7d09c52a38.zip
Check in new file sfnt.c
* src/sfnt.c (xmalloc, xrealloc, xfree, eassert, MIN) (sfnt_table_names, SFNT_ENDOF, struct sfnt_table_directory) (enum sfnt_scaler_type, sfnt_coerce_fixed, struct sfnt_hhea_table) (struct sfnt_cmap_table, enum sfnt_platform_id) (enum sfnt_unicode_platform_specific_id) (enum sfnt_macintosh_platform_specific_id) (enum sfnt_microsoft_platform_specific_id) (struct sfnt_cmap_encoding_subtable) (struct sfnt_cmap_encoding_subtable_data) (struct sfnt_cmap_format_0, struct sfnt_cmap_format_2_subheader) (struct sfnt_cmap_format_2, struct sfnt_cmap_format_4) (struct sfnt_cmap_format_6, struct sfnt_cmap_format_8_or_12_group) (struct sfnt_cmap_format_8, struct sfnt_cmap_format_12) (struct sfnt_maxp_table, struct sfnt_loca_table_short) (struct sfnt_loca_table_long, struct sfnt_glyf_table) (struct sfnt_simple_glyph, struct sfnt_compound_glyph_component) (struct sfnt_compound_glyph, struct sfnt_glyph, _sfnt_swap16) (_sfnt_swap32, sfnt_swap16, 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_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, sfnt_lookup_glyph_6, sfnt_lookup_glyph_8) (sfnt_lookup_glyph_12, sfnt_lookup_glyph, sfnt_read_head_table) (sfnt_read_hhea_table, sfnt_read_loca_table_short) (sfnt_read_loca_table_long, sfnt_read_maxp_table) (sfnt_read_glyf_table, sfnt_read_simple_glyph) (sfnt_read_compound_glyph, sfnt_read_glyph, sfnt_free_glyph) (struct sfnt_point, sfnt_transform_coordinates) (struct sfnt_compound_glyph_context) (sfnt_expand_compound_glyph_context, sfnt_round_fixed) (sfnt_decompose_compound_glyph, sfnt_lerp_half) (sfnt_decompose_glyph, struct sfnt_glyph_outline) (enum sfnt_glyph_outline_flags) (struct sfnt_build_glyph_outline_context, sfnt_build_append) (sfnt_move_to_and_build, sfnt_line_to_and_build, sfnt_mul_fixed) (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) (struct sfnt_raster, struct sfnt_edge, sfnt_poly_coverage) (sfnt_poly_grid_ceil, sfnt_prepare_raster, sfnt_step_edge_by) (sfnt_build_outline_edges, sfnt_compare_edges, sfnt_poly_edges) (sfnt_saturate_short, sfnt_fill_span, sfnt_poly_span) (sfnt_raster_span, sfnt_raster_edge, sfnt_raster_glyph_outline) (struct sfnt_long_hor_metric, struct sfnt_hmtx_table) (struct sfnt_glyph_metrics, sfnt_read_hmtx_table) (sfnt_lookup_glyph_metrics, struct sfnt_test_dcontext) (sfnt_test_move_to, sfnt_test_line_to, sfnt_test_curve_to) (sfnt_test_get_glyph, sfnt_test_free_glyph, sfnt_test_span) (sfnt_test_edge, sfnt_test_raster, main): Check in 5000-line-long file written by me for reading TrueType and OpenType fonts with TrueType outlines.
Diffstat (limited to 'src')
-rw-r--r--src/sfnt.c4868
1 files changed, 4868 insertions, 0 deletions
diff --git a/src/sfnt.c b/src/sfnt.c
new file mode 100644
index 00000000000..9ac023ddba9
--- /dev/null
+++ b/src/sfnt.c
@@ -0,0 +1,4868 @@
1/* sfnt format font support for GNU Emacs.
2
3Copyright (C) 2023 Free Software Foundation, Inc.
4
5This file is part of GNU Emacs.
6
7GNU Emacs is free software: you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation, either version 3 of the License, or (at
10your option) any later version.
11
12GNU Emacs is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU Emacs. If not, write to the Free Software Foundation,
19Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20
21#include <config.h>
22
23#include <assert.h>
24#include <byteswap.h>
25#include <fcntl.h>
26#include <intprops.h>
27#include <inttypes.h>
28#include <stdint.h>
29#include <stdio.h>
30#include <stdlib.h>
31#include <string.h>
32#include <unistd.h>
33
34#ifdef TEST
35
36#include <time.h>
37#include <timespec.h>
38
39static void *
40xmalloc (size_t size)
41{
42 return malloc (size);
43}
44
45static void *
46xrealloc (void *ptr, size_t size)
47{
48 return realloc (ptr, size);
49}
50
51static void
52xfree (void *ptr)
53{
54 return free (ptr);
55}
56
57static void
58eassert (bool condition)
59{
60 if (!condition)
61 abort ();
62}
63
64#else
65#include "lisp.h"
66#endif
67
68#define MIN(a, b) ((a) < (b) ? (a) : (b))
69#define MAX(a, b) ((a) > (b) ? (a) : (b))
70
71/* This file provides generic support for reading most TrueType fonts,
72 and some OpenType fonts with TrueType outlines, along with glyph
73 lookup, outline decomposition, and alpha mask generation from those
74 glyphs. It is intended to be used on any platform where proper
75 libraries such as FreeType are not easily available, and the native
76 font library is too limited for Emacs to support properly.
77
78 Unlike most popular libraries for handling fonts, no "font" or
79 "face" type is provided. Instead, routines and structure
80 definitions for accessing and making use of individual tables in a
81 font file are exported, which allows for flexibility in the rest of
82 Emacs. */
83
84
85
86/* The sfnt container format is organized into different tables, such
87 as ``cmap'' or ``glyf''. Each of these tables has a specific
88 format and use. These are all the tables known to Emacs. */
89
90enum sfnt_table
91 {
92 SFNT_TABLE_CMAP,
93 SFNT_TABLE_GLYF,
94 SFNT_TABLE_HEAD,
95 SFNT_TABLE_HHEA,
96 SFNT_TABLE_HMTX,
97 SFNT_TABLE_LOCA,
98 SFNT_TABLE_MAXP,
99 SFNT_TABLE_NAME,
100 };
101
102/* Mapping between sfnt table names and their identifiers. */
103
104uint32_t sfnt_table_names[] =
105 {
106 [SFNT_TABLE_CMAP] = 0x636d6170,
107 [SFNT_TABLE_GLYF] = 0x676c7966,
108 [SFNT_TABLE_HEAD] = 0x68656164,
109 [SFNT_TABLE_HHEA] = 0x68686561,
110 [SFNT_TABLE_HMTX] = 0x686d7478,
111 [SFNT_TABLE_LOCA] = 0x6c6f6361,
112 [SFNT_TABLE_MAXP] = 0x6d617870,
113 [SFNT_TABLE_NAME] = 0x6e616d65,
114 };
115
116#define SFNT_ENDOF(type, field, type1) \
117 ((size_t) offsetof (type, field) + sizeof (type1))
118
119/* Each of these structures must be aligned so that no compiler will
120 ever generate padding bytes on platforms where the alignment
121 requirements for uint32_t and uint16_t are no larger than 4 and 2
122 bytes respectively. */
123
124struct sfnt_offset_subtable
125{
126 /* The scaler type. */
127 uint32_t scaler_type;
128
129 /* The number of tables. */
130 uint16_t num_tables;
131
132 /* (Maximum power of 2 <= numTables) * 16. */
133 uint16_t search_range;
134
135 /* log2 (maximum power of 2 <= numTables) */
136 uint16_t entry_selector;
137
138 /* numTables * 16 - searchRange. */
139 uint16_t range_shift;
140
141 /* Variable length data. */
142 struct sfnt_table_directory *subtables;
143};
144
145/* The table directory. Follows the offset subtable, with one for
146 each table. */
147
148struct sfnt_table_directory
149{
150 /* 4-byte identifier for each table. See sfnt_table_names. */
151 uint32_t tag;
152
153 /* Table checksum. */
154 uint32_t checksum;
155
156 /* Offset from the start of the file. */
157 uint32_t offset;
158
159 /* Length of the table in bytes, not subject to padding. */
160 uint32_t length;
161};
162
163enum sfnt_scaler_type
164 {
165 SFNT_SCALER_TRUE = 0x74727565,
166 SFNT_SCALER_VER1 = 0x00010000,
167 SFNT_SCALER_TYP1 = 0x74797031,
168 SFNT_SCALER_OTTO = 0x4F54544F,
169 };
170
171typedef int32_t sfnt_fixed;
172typedef int16_t sfnt_fword;
173typedef uint16_t sfnt_ufword;
174
175#define sfnt_coerce_fixed(fixed) ((sfnt_fixed) (fixed) / 65535.0)
176
177typedef unsigned int sfnt_glyph;
178typedef unsigned int sfnt_char;
179
180struct sfnt_head_table
181{
182 /* The version. This is a 16.16 fixed point number. */
183 sfnt_fixed version;
184
185 /* The revision. */
186 sfnt_fixed revision;
187
188 /* Checksum adjustment. */
189 uint32_t checksum_adjustment;
190
191 /* Magic number, should be 0x5F0F3CF5. */
192 uint32_t magic;
193
194 /* Flags for the font. */
195 uint16_t flags;
196
197 /* Units per em. */
198 uint16_t units_per_em;
199
200 /* Time of creation. */
201 uint32_t created_high, created_low;
202
203 /* Time of modification. */
204 uint32_t modified_high, modified_low;
205
206 /* Minimum bounds. */
207 sfnt_fword xmin, ymin, xmax, ymax;
208
209 /* Mac specific stuff. */
210 uint16_t mac_style;
211
212 /* Smallest readable size in pixels. */
213 uint16_t lowest_rec_ppem;
214
215 /* Font direction hint. */
216 int16_t font_direction_hint;
217
218 /* Index to loc format. 0 for short offsets, 1 for long. */
219 int16_t index_to_loc_format;
220
221 /* Unused. */
222 int16_t glyph_data_format;
223};
224
225struct sfnt_hhea_table
226{
227 /* The version. This is a 16.16 fixed point number. */
228 sfnt_fixed version;
229
230 /* The maximum ascent and descent values for this font. */
231 sfnt_fword ascent, descent;
232
233 /* The typographic line gap. */
234 sfnt_fword line_gap;
235
236 /* The maximum advance width. */
237 sfnt_ufword advance_width_max;
238
239 /* The minimum bearings on either side. */
240 sfnt_fword min_left_side_bearing, min_right_side_bearing;
241
242 /* The maximum extent. */
243 sfnt_fword x_max_extent;
244
245 /* Caret slope. */
246 int16_t caret_slope_rise, caret_slope_run;
247
248 /* Caret offset for non slanted fonts. */
249 sfnt_fword caret_offset;
250
251 /* Reserved values. */
252 int16_t reserved1, reserved2, reserved3, reserved4;
253
254 /* Should always be zero. */
255 int16_t metric_data_format;
256
257 /* Number of advanced widths in metrics table. */
258 uint16_t num_of_long_hor_metrics;
259};
260
261struct sfnt_cmap_table
262{
263 /* Should be zero. */
264 uint16_t version;
265
266 /* Number of subtables. */
267 uint16_t num_subtables;
268};
269
270enum sfnt_platform_id
271 {
272 SFNT_PLATFORM_UNICODE = 0,
273 SFNT_PLATFORM_MACINTOSH = 1,
274 SFNT_PLATFORM_RESERVED = 2,
275 SFNT_PLATFORM_MICROSOFT = 3,
276 };
277
278enum sfnt_unicode_platform_specific_id
279 {
280 SFNT_UNICODE_1_0 = 0,
281 SFNT_UNICODE_1_1 = 1,
282 SFNT_UNICODE_ISO_10646_1993 = 2,
283 SFNT_UNICODE_2_0_BMP = 3,
284 SFNT_UNICODE_2_0 = 4,
285 SFNT_UNICODE_VARIATION_SEQUENCES = 5,
286 SFNT_UNICODE_LAST_RESORT = 6,
287 };
288
289enum sfnt_macintosh_platform_specific_id
290 {
291 SFNT_MACINTOSH_ROMAN = 0,
292 SFNT_MACINTOSH_JAPANESE = 1,
293 SFNT_MACINTOSH_TRADITIONAL_CHINESE = 2,
294 SFNT_MACINTOSH_KOREAN = 3,
295 SFNT_MACINTOSH_ARABIC = 4,
296 SFNT_MACINTOSH_HEBREW = 5,
297 SFNT_MACINTOSH_GREEK = 6,
298 SFNT_MACINTOSH_RUSSIAN = 7,
299 SFNT_MACINTOSH_RSYMBOL = 8,
300 SFNT_MACINTOSH_DEVANGARI = 9,
301 SFNT_MACINTOSH_GURMUKHI = 10,
302 SFNT_MACINTOSH_GUJARATI = 11,
303 SFNT_MACINTOSH_ORIYA = 12,
304 SFNT_MACINTOSH_BENGALI = 13,
305 SFNT_MACINTOSH_TAMIL = 14,
306 SFNT_MACINTOSH_TELUGU = 15,
307 SFNT_MACINTOSH_KANNADA = 16,
308 SFNT_MACINTOSH_MALAYALAM = 17,
309 SFNT_MACINTOSH_SINHALESE = 18,
310 SFNT_MACINTOSH_BURMESE = 19,
311 SFNT_MACINTOSH_KHMER = 20,
312 SFNT_MACINTOSH_THAI = 21,
313 SFNT_MACINTOSH_LAOTIAN = 22,
314 SFNT_MACINTOSH_GEORGIAN = 23,
315 SFNT_MACINTOSH_ARMENIAN = 24,
316 SFNT_MACINTOSH_SIMPLIFIED_CHINESE = 25,
317 SFNT_MACINTOSH_TIBETIAN = 26,
318 SFNT_MACINTOSH_MONGOLIAN = 27,
319 SFNT_MACINTOSH_GEEZ = 28,
320 SFNT_MACINTOSH_SLAVIC = 29,
321 SFNT_MACINTOSH_VIETNAMESE = 30,
322 SFNT_MACINTOSH_SINDHI = 31,
323 SFNT_MACINTOSH_UNINTERPRETED = 32,
324 };
325
326enum sfnt_microsoft_platform_specific_id
327 {
328 SFNT_MICROSOFT_SYMBOL = 0,
329 SFNT_MICROSOFT_UNICODE_BMP = 1,
330 SFNT_MICROSOFT_SHIFT_JIS = 2,
331 SFNT_MICROSOFT_PRC = 3,
332 SFNT_MICROSOFT_BIG_FIVE = 4,
333 SFNT_MICROSOFT_JOHAB = 5,
334 SFNT_MICROSOFT_UNICODE_UCS_4 = 6,
335 };
336
337struct sfnt_cmap_encoding_subtable
338{
339 /* The platform ID. */
340 uint16_t platform_id;
341
342 /* Platform specific ID. */
343 uint16_t platform_specific_id;
344
345 /* Mapping table offset. */
346 uint32_t offset;
347};
348
349struct sfnt_cmap_encoding_subtable_data
350{
351 /* Format and possibly the length in bytes. */
352 uint16_t format, length;
353};
354
355struct sfnt_cmap_format_0
356{
357 /* Format, set to 0. */
358 uint16_t format;
359
360 /* Length in bytes. Should be 262. */
361 uint16_t length;
362
363 /* Language code. */
364 uint16_t language;
365
366 /* Character code to glyph index map. */
367 uint8_t glyph_index_array[256];
368};
369
370struct sfnt_cmap_format_2_subheader
371{
372 uint16_t first_code;
373 uint16_t entry_count;
374 int16_t id_delta;
375 uint16_t id_range_offset;
376};
377
378struct sfnt_cmap_format_2
379{
380 /* Format, set to 2. */
381 uint16_t format;
382
383 /* Length in bytes. */
384 uint16_t length;
385
386 /* Language code. */
387 uint16_t language;
388
389 /* Array mapping high bytes to subheaders. */
390 uint16_t sub_header_keys[256];
391
392 /* Variable length data. */
393 struct sfnt_cmap_format_2_subheader *subheaders;
394 uint16_t *glyph_index_array;
395 uint16_t num_glyphs;
396};
397
398struct sfnt_cmap_format_4
399{
400 /* Format, set to 4. */
401 uint16_t format;
402
403 /* Length in bytes. */
404 uint16_t length;
405
406 /* Language code. */
407 uint16_t language;
408
409 /* 2 * seg_count. */
410 uint16_t seg_count_x2;
411
412 /* 2 * (2**FLOOR(log2(segCount))) */
413 uint16_t search_range;
414
415 /* log2(searchRange/2) */
416 uint16_t entry_selector;
417
418 /* Variable-length data. */
419 uint16_t *end_code;
420 uint16_t *reserved_pad;
421 uint16_t *start_code;
422 int16_t *id_delta;
423 int16_t *id_range_offset;
424 uint16_t *glyph_index_array;
425
426 /* The number of elements in glyph_index_array. */
427 size_t glyph_index_size;
428};
429
430struct sfnt_cmap_format_6
431{
432 /* Format, set to 6. */
433 uint16_t format;
434
435 /* Length in bytes. */
436 uint16_t length;
437
438 /* Language code. */
439 uint16_t language;
440
441 /* First character code in subrange. */
442 uint16_t first_code;
443
444 /* Number of character codes. */
445 uint16_t entry_count;
446
447 /* Variable-length data. */
448 uint16_t *glyph_index_array;
449};
450
451struct sfnt_cmap_format_8_or_12_group
452{
453 uint32_t start_char_code;
454 uint32_t end_char_code;
455 uint32_t start_glyph_code;
456};
457
458struct sfnt_cmap_format_8
459{
460 /* Format, set to 8. */
461 uint16_t format;
462
463 /* Reserved. */
464 uint16_t reserved;
465
466 /* Length in bytes. */
467 uint32_t length;
468
469 /* Language code. */
470 uint32_t language;
471
472 /* Tightly packed array of bits (8K bytes total) indicating whether
473 the particular 16-bit (index) value is the start of a 32-bit
474 character code. */
475 uint8_t is32[65536];
476
477 /* Number of groups. */
478 uint32_t num_groups;
479
480 /* Variable length data. */
481 struct sfnt_cmap_format_8_or_12_group *groups;
482};
483
484/* cmap formats 10, 13 and 14 unsupported. */
485
486struct sfnt_cmap_format_12
487{
488 /* Format, set to 12. */
489 uint16_t format;
490
491 /* Reserved. */
492 uint16_t reserved;
493
494 /* Length in bytes. */
495 uint32_t length;
496
497 /* Language code. */
498 uint32_t language;
499
500 /* Number of groups. */
501 uint32_t num_groups;
502
503 /* Variable length data. */
504 struct sfnt_cmap_format_8_or_12_group *groups;
505};
506
507struct sfnt_maxp_table
508{
509 /* Table version. */
510 sfnt_fixed version;
511
512 /* The number of glyphs in this font - 1. Set at version 0.5 or
513 later. */
514 uint16_t num_glyphs;
515
516 /* These fields are only set in version 1.0 or later. Maximum
517 points in a non-composite glyph. */
518 uint16_t max_points;
519
520 /* Maximum contours in a non-composite glyph. */
521 uint16_t max_contours;
522
523 /* Maximum points in a composite glyph. */
524 uint16_t max_composite_points;
525
526 /* Maximum contours in a composite glyph. */
527 uint16_t max_composite_contours;
528
529 /* 1 if instructions do not use the twilight zone (Z0), or 2 if
530 instructions do use Z0; should be set to 2 in most cases. */
531 uint16_t max_zones;
532
533 /* Maximum points used in Z0. */
534 uint16_t max_twilight_points;
535
536 /* Number of Storage Area locations. */
537 uint16_t max_storage;
538
539 /* Number of FDEFs, equal to the highest function number + 1. */
540 uint16_t max_function_defs;
541
542 /* Number of IDEFs. */
543 uint16_t max_instruction_defs;
544
545 /* Maximum stack depth across Font Program ('fpgm' table), CVT
546 Program ('prep' table) and all glyph instructions (in the 'glyf'
547 table). */
548 uint16_t max_stack_elements;
549
550 /* Maximum byte count for glyph instructions. */
551 uint16_t max_size_of_instructions;
552
553 /* Maximum number of components referenced at ``top level'' for any
554 composite glyph. */
555 uint16_t max_component_elements;
556
557 /* Maximum levels of recursion; 1 for simple components. */
558 uint16_t max_component_depth;
559};
560
561struct sfnt_loca_table_short
562{
563 /* Offsets to glyph data divided by two. */
564 uint16_t *offsets;
565
566 /* Size of the offsets list. */
567 size_t num_offsets;
568};
569
570struct sfnt_loca_table_long
571{
572 /* Offsets to glyph data. */
573 uint32_t *offsets;
574
575 /* Size of the offsets list. */
576 size_t num_offsets;
577};
578
579struct sfnt_glyf_table
580{
581 /* Size of the glyph data. */
582 size_t size;
583
584 /* Pointer to possibly unaligned glyph data. */
585 unsigned char *glyphs;
586};
587
588struct sfnt_simple_glyph
589{
590 /* The total number of points in this glyph. */
591 size_t number_of_points;
592
593 /* Array containing the last points of each contour. */
594 uint16_t *end_pts_of_contours;
595
596 /* Total number of bytes needed for instructions. */
597 uint16_t instruction_length;
598
599 /* Instruction data. */
600 uint8_t *instructions;
601
602 /* Array of flags. */
603 uint8_t *flags;
604
605 /* Array of X coordinates. */
606 int16_t *x_coordinates;
607
608 /* Array of Y coordinates. */
609 int16_t *y_coordinates;
610
611 /* Pointer to the end of that array. */
612 int16_t *y_coordinates_end;
613};
614
615struct sfnt_compound_glyph_component
616{
617 /* Compound glyph flags. */
618 uint16_t flags;
619
620 /* Component glyph index. */
621 uint16_t glyph_index;
622
623 /* X-offset for component or point number; type depends on bits 0
624 and 1 in component flags. */
625 union {
626 uint8_t a;
627 int8_t b;
628 uint16_t c;
629 int16_t d;
630 } argument1;
631
632 /* Y-offset for component or point number; type depends on bits 0
633 and 1 in component flags. */
634 union {
635 uint8_t a;
636 int8_t b;
637 uint16_t c;
638 int16_t d;
639 } argument2;
640
641 /* Various scale formats. */
642 union {
643 uint16_t scale;
644 struct {
645 uint16_t xscale;
646 uint16_t yscale;
647 } a;
648 struct {
649 uint16_t xscale;
650 uint16_t scale01;
651 uint16_t scale10;
652 uint16_t yscale;
653 } b;
654 } u;
655};
656
657struct sfnt_compound_glyph
658{
659 /* Pointer to array of components. */
660 struct sfnt_compound_glyph_component *components;
661
662 /* Number of elements in that array. */
663 size_t num_components;
664
665 /* Instruction data. */
666 uint8_t *instructions;
667
668 /* Length of instructions. */
669 uint16_t instruction_length;
670};
671
672struct sfnt_glyph
673{
674 /* Number of contours in this glyph. */
675 int16_t number_of_contours;
676
677 /* Coordinate bounds. */
678 sfnt_fword xmin, ymin, xmax, ymax;
679
680 /* Either a simple glyph or a compound glyph, depending on which is
681 set. */
682 struct sfnt_simple_glyph *simple;
683 struct sfnt_compound_glyph *compound;
684};
685
686
687
688/* Swap values from TrueType to system byte order. */
689
690static void
691_sfnt_swap16 (uint16_t *value)
692{
693#ifndef WORDS_BIGENDIAN
694 *value = bswap_16 (*value);
695#endif
696}
697
698static void
699_sfnt_swap32 (uint32_t *value)
700{
701#ifndef WORDS_BIGENDIAN
702 *value = bswap_32 (*value);
703#endif
704}
705
706#define sfnt_swap16(what) (_sfnt_swap16 ((uint16_t *) (what)))
707#define sfnt_swap32(what) (_sfnt_swap32 ((uint32_t *) (what)))
708
709/* Read the table directory from the file FD. FD must currently be at
710 the start of the file, and must be seekable. Return the table
711 directory upon success, else NULL. */
712
713static struct sfnt_offset_subtable *
714sfnt_read_table_directory (int fd)
715{
716 struct sfnt_offset_subtable *subtable;
717 ssize_t rc;
718 size_t offset, subtable_size;
719 int i;
720
721 subtable = xmalloc (sizeof *subtable);
722 offset = SFNT_ENDOF (struct sfnt_offset_subtable,
723 range_shift, uint16_t);
724 rc = read (fd, subtable, offset);
725
726 if (rc < offset)
727 {
728 xfree (subtable);
729 return NULL;
730 }
731
732 sfnt_swap32 (&subtable->scaler_type);
733 sfnt_swap16 (&subtable->num_tables);
734 sfnt_swap16 (&subtable->search_range);
735 sfnt_swap16 (&subtable->entry_selector);
736 sfnt_swap16 (&subtable->range_shift);
737
738 /* Figure out how many more tables have to be read, and read each
739 one of them. */
740 subtable_size = (subtable->num_tables
741 * sizeof (struct sfnt_table_directory));
742 subtable = xrealloc (subtable, sizeof *subtable + subtable_size);
743 subtable->subtables
744 = (struct sfnt_table_directory *) (subtable + 1);
745
746 rc = read (fd, subtable->subtables, subtable_size);
747
748 if (rc < offset)
749 {
750 xfree (subtable);
751 return NULL;
752 }
753
754 /* Swap each of the subtables. */
755
756 for (i = 0; i < subtable->num_tables; ++i)
757 {
758 sfnt_swap32 (&subtable->subtables[i].tag);
759 sfnt_swap32 (&subtable->subtables[i].checksum);
760 sfnt_swap32 (&subtable->subtables[i].offset);
761 sfnt_swap32 (&subtable->subtables[i].length);
762 }
763
764 return subtable;
765}
766
767/* Return a pointer to the table directory entry for TABLE in
768 SUBTABLE, or NULL if it was not found. */
769
770static struct sfnt_table_directory *
771sfnt_find_table (struct sfnt_offset_subtable *subtable,
772 enum sfnt_table table)
773{
774 int i;
775
776 for (i = 0; i < subtable->num_tables; ++i)
777 {
778 if (subtable->subtables[i].tag == sfnt_table_names[table])
779 return &subtable->subtables[i];
780 }
781
782 return NULL;
783}
784
785
786
787/* Character mapping routines. */
788
789/* Read a format 0 cmap subtable from FD. HEADER has already been
790 read. */
791
792static struct sfnt_cmap_format_0 *
793sfnt_read_cmap_format_0 (int fd,
794 struct sfnt_cmap_encoding_subtable_data *header)
795{
796 struct sfnt_cmap_format_0 *format0;
797 ssize_t rc;
798 size_t wanted_size;
799
800 format0 = xmalloc (sizeof *format0);
801
802 /* Fill in fields that have already been read. */
803 format0->format = header->format;
804 format0->length = header->length;
805
806#pragma GCC diagnostic push
807#pragma GCC diagnostic ignored "-Wstringop-overflow"
808
809 /* Read the rest. */
810 wanted_size = (sizeof *format0
811 - offsetof (struct sfnt_cmap_format_0,
812 language));
813 rc = read (fd, &format0->language, wanted_size);
814
815#pragma GCC diagnostic pop
816
817 if (rc < wanted_size)
818 {
819 xfree (format0);
820 return (struct sfnt_cmap_format_0 *) -1;
821 }
822
823 /* Swap fields and return. */
824 sfnt_swap16 (&format0->language);
825 return format0;
826}
827
828/* Read a format 2 cmap subtable from FD. HEADER has already been
829 read. */
830
831static struct sfnt_cmap_format_2 *
832sfnt_read_cmap_format_2 (int fd,
833 struct sfnt_cmap_encoding_subtable_data *header)
834{
835 struct sfnt_cmap_format_2 *format2;
836 ssize_t rc;
837 size_t min_bytes;
838 int i, nsub;
839
840 /* Reject contents that are too small. */
841 min_bytes = SFNT_ENDOF (struct sfnt_cmap_format_2,
842 sub_header_keys, uint16_t[256]);
843 if (header->length < min_bytes)
844 return NULL;
845
846 /* Add enough bytes at the end to fit the two variable length
847 pointers. */
848 format2 = xmalloc (header->length + sizeof *format2);
849 format2->format = header->format;
850 format2->length = header->length;
851
852#pragma GCC diagnostic push
853#pragma GCC diagnostic ignored "-Wstringop-overflow"
854
855 /* Read the part before the variable length data. */
856 min_bytes -= offsetof (struct sfnt_cmap_format_2, language);
857 rc = read (fd, &format2->language, min_bytes);
858 if (rc < min_bytes)
859 {
860 xfree (format2);
861 return (struct sfnt_cmap_format_2 *) -1;
862 }
863
864 /* Swap the fields now. */
865
866 sfnt_swap16 (&format2->language);
867
868 /* At the same time, look for the largest value in sub_header_keys.
869 That will be the number of subheaders and elements in the glyph
870 index array. */
871
872 nsub = 0;
873
874 for (i = 0; i < 256; ++i)
875 {
876 sfnt_swap16 (&format2->sub_header_keys[i]);
877
878 if (format2->sub_header_keys[i] > nsub)
879 nsub = format2->sub_header_keys[i];
880 }
881
882 if (!nsub)
883 /* If there are no subheaders, then things are finished. */
884 return format2;
885
886 /* Otherwise, read the rest of the variable length data to the end
887 of format2. */
888 min_bytes = (format2->length
889 - SFNT_ENDOF (struct sfnt_cmap_format_2,
890 sub_header_keys, uint16_t[256]));
891 rc = read (fd, format2 + 1, min_bytes);
892 if (rc < min_bytes)
893 {
894 xfree (format2);
895 return (struct sfnt_cmap_format_2 *) -1;
896 }
897
898#pragma GCC diagnostic pop
899
900 /* Check whether or not the data is of the correct size. */
901 if (min_bytes < nsub * sizeof *format2->subheaders)
902 {
903 xfree (format2);
904 return (struct sfnt_cmap_format_2 *) -1;
905 }
906
907 /* Point the data pointers to the right location, swap everything,
908 and return. */
909
910 format2->subheaders
911 = (struct sfnt_cmap_format_2_subheader *) (format2 + 1);
912 format2->glyph_index_array
913 = (uint16_t *) (format2->subheaders + nsub);
914
915 for (i = 0; i < nsub; ++i)
916 {
917 sfnt_swap16 (&format2->subheaders[i].first_code);
918 sfnt_swap16 (&format2->subheaders[i].entry_count);
919 sfnt_swap16 (&format2->subheaders[i].id_delta);
920 sfnt_swap16 (&format2->subheaders[i].id_range_offset);
921 }
922
923 /* Figure out how big the glyph index array is, and swap everything
924 there. */
925 format2->num_glyphs
926 = (min_bytes - nsub * sizeof *format2->subheaders) / 2;
927
928 for (i = 0; i < format2->num_glyphs; ++i)
929 sfnt_swap16 (&format2->glyph_index_array[i]);
930
931 return format2;
932}
933
934/* Read a format 4 cmap subtable from FD. HEADER has already been
935 read. */
936
937static struct sfnt_cmap_format_4 *
938sfnt_read_cmap_format_4 (int fd,
939 struct sfnt_cmap_encoding_subtable_data *header)
940{
941 struct sfnt_cmap_format_4 *format4;
942 size_t min_bytes, variable_size;
943 ssize_t rc;
944 size_t bytes_minus_format4;
945 int seg_count, i;
946
947 min_bytes = SFNT_ENDOF (struct sfnt_cmap_format_4,
948 entry_selector, uint16_t);
949
950 /* Check that the length is at least min_bytes. */
951 if (header->length < min_bytes)
952 return NULL;
953
954 /* Allocate the format4 buffer, making it the size of the buffer
955 itself plus that of the data. */
956 format4 = xmalloc (header->length + sizeof *format4);
957
958 /* Copy over fields that have already been read. */
959 format4->format = header->format;
960 format4->length = header->length;
961
962#pragma GCC diagnostic push
963#pragma GCC diagnostic ignored "-Wstringop-overflow"
964
965 /* Read the initial data. */
966 min_bytes -= offsetof (struct sfnt_cmap_format_4, language);
967 rc = read (fd, &format4->language, min_bytes);
968 if (rc < min_bytes)
969 {
970 xfree (format4);
971 return (struct sfnt_cmap_format_4 *) -1;
972 }
973
974 /* Swap fields that have been read. */
975 sfnt_swap16 (&format4->language);
976 sfnt_swap16 (&format4->seg_count_x2);
977 sfnt_swap16 (&format4->search_range);
978 sfnt_swap16 (&format4->entry_selector);
979
980 /* Get the number of segments to read. */
981 seg_count = format4->seg_count_x2 / 2;
982
983 /* Now calculate whether or not the size is sufficiently large. */
984 bytes_minus_format4
985 = format4->length - SFNT_ENDOF (struct sfnt_cmap_format_4,
986 entry_selector, uint16_t);
987 variable_size = (seg_count * sizeof *format4->end_code
988 + sizeof *format4->reserved_pad
989 + seg_count * sizeof *format4->start_code
990 + seg_count * sizeof *format4->id_delta
991 + seg_count * sizeof *format4->id_range_offset);
992
993 if (bytes_minus_format4 < variable_size)
994 {
995 /* Not enough bytes to fit the entire implied table
996 contents. */
997 xfree (format4);
998 return NULL;
999 }
1000
1001 /* Read the rest of the bytes to the end of format4. */
1002 rc = read (fd, format4 + 1, bytes_minus_format4);
1003 if (rc < bytes_minus_format4)
1004 {
1005 xfree (format4);
1006 return (struct sfnt_cmap_format_4 *) -1;
1007 }
1008
1009 /* Set data pointers to the right locations. */
1010 format4->end_code = (uint16_t *) (format4 + 1);
1011 format4->reserved_pad = format4->end_code + seg_count;
1012 format4->start_code = format4->reserved_pad + 1;
1013 format4->id_delta = (int16_t *) (format4->start_code + seg_count);
1014 format4->id_range_offset = format4->id_delta + seg_count;
1015 format4->glyph_index_array = (uint16_t *) (format4->id_range_offset
1016 + seg_count);
1017
1018 /* N.B. that the number of elements in glyph_index_array is
1019 (bytes_minus_format4 - variable_size) / 2. Swap all the
1020 data. */
1021
1022 sfnt_swap16 (format4->reserved_pad);
1023
1024 for (i = 0; i < seg_count; ++i)
1025 {
1026 sfnt_swap16 (&format4->end_code[i]);
1027 sfnt_swap16 (&format4->start_code[i]);
1028 sfnt_swap16 (&format4->id_delta[i]);
1029 sfnt_swap16 (&format4->id_range_offset[i]);
1030 }
1031
1032 format4->glyph_index_size
1033 = (bytes_minus_format4 - variable_size) / 2;
1034
1035 for (i = 0; i < format4->glyph_index_size; ++i)
1036 sfnt_swap16 (&format4->glyph_index_array[i]);
1037
1038#pragma GCC diagnostic pop
1039
1040 /* Done. Return the format 4 character map. */
1041 return format4;
1042}
1043
1044/* Read a format 6 cmap subtable from FD. HEADER has already been
1045 read. */
1046
1047static struct sfnt_cmap_format_6 *
1048sfnt_read_cmap_format_6 (int fd,
1049 struct sfnt_cmap_encoding_subtable_data *header)
1050{
1051 struct sfnt_cmap_format_6 *format6;
1052 size_t min_size;
1053 ssize_t rc;
1054 uint16_t i;
1055
1056 min_size = SFNT_ENDOF (struct sfnt_cmap_format_6, entry_count,
1057 uint16_t);
1058
1059 /* See if header->length is big enough. */
1060 if (header->length < min_size)
1061 return NULL;
1062
1063 /* Allocate the buffer to hold header->size and enough for at least
1064 the glyph index array pointer. */
1065 format6 = xmalloc (header->length + sizeof *format6);
1066
1067 /* Fill in data that has already been read. */
1068 format6->format = header->format;
1069 format6->length = header->length;
1070
1071#pragma GCC diagnostic push
1072#pragma GCC diagnostic ignored "-Wstringop-overflow"
1073
1074 /* Read the fixed size data. */
1075 min_size -= offsetof (struct sfnt_cmap_format_6, language);
1076 rc = read (fd, &format6->language, min_size);
1077 if (rc < min_size)
1078 {
1079 xfree (format6);
1080 return (struct sfnt_cmap_format_6 *) -1;
1081 }
1082
1083 /* Swap what was read. */
1084 sfnt_swap16 (&format6->language);
1085 sfnt_swap16 (&format6->first_code);
1086 sfnt_swap16 (&format6->entry_count);
1087
1088 /* Figure out whether or not header->length is sufficient to hold
1089 the variable length data. */
1090 if (header->length
1091 < format6->entry_count * sizeof *format6->glyph_index_array)
1092 {
1093 xfree (format6);
1094 return NULL;
1095 }
1096
1097 /* Read the variable length data. */
1098 rc = read (fd, format6 + 1,
1099 (format6->entry_count
1100 * sizeof *format6->glyph_index_array));
1101 if (rc < format6->entry_count * sizeof *format6->glyph_index_array)
1102 {
1103 xfree (format6);
1104 return (struct sfnt_cmap_format_6 *) -1;
1105 }
1106
1107#pragma GCC diagnostic pop
1108
1109 /* Set the data pointer and swap everything. */
1110 format6->glyph_index_array = (uint16_t *) (format6 + 1);
1111 for (i = 0; i < format6->entry_count; ++i)
1112 sfnt_swap16 (&format6->glyph_index_array[i]);
1113
1114 /* All done! */
1115 return format6;
1116}
1117
1118/* Read a format 8 cmap subtable from FD. HEADER has already been
1119 read. */
1120
1121static struct sfnt_cmap_format_8 *
1122sfnt_read_cmap_format_8 (int fd,
1123 struct sfnt_cmap_encoding_subtable_data *header)
1124{
1125 struct sfnt_cmap_format_8 *format8;
1126 size_t min_size, temp;
1127 ssize_t rc;
1128 uint32_t length, i;
1129
1130 /* Read the 32-bit lenth field. */
1131 if (read (fd, &length, sizeof (length)) < sizeof (length))
1132 return (struct sfnt_cmap_format_8 *) -1;
1133
1134 /* Swap the 32-bit length field. */
1135 sfnt_swap32 (&length);
1136
1137 min_size = SFNT_ENDOF (struct sfnt_cmap_format_8, num_groups,
1138 uint32_t);
1139
1140 /* Make sure the header is at least as large as min_size. */
1141 if (length < min_size)
1142 return NULL;
1143
1144 /* Allocate a buffer of sufficient size. */
1145 format8 = xmalloc (length + sizeof *format8);
1146 format8->format = header->format;
1147 format8->reserved = header->length;
1148 format8->length = length;
1149
1150#pragma GCC diagnostic push
1151#pragma GCC diagnostic ignored "-Wstringop-overflow"
1152
1153 /* Read the fixed length data. */
1154 min_size -= offsetof (struct sfnt_cmap_format_8, language);
1155 rc = read (fd, &format8->language, min_size);
1156 if (rc < min_size)
1157 {
1158 xfree (format8);
1159 return (struct sfnt_cmap_format_8 *) -1;
1160 }
1161
1162 /* Swap what was read. */
1163 sfnt_swap32 (&format8->language);
1164 sfnt_swap32 (&format8->num_groups);
1165
1166 /* See if the size is sufficient to read the variable length
1167 data. */
1168 min_size = SFNT_ENDOF (struct sfnt_cmap_format_8, num_groups,
1169 uint32_t);
1170
1171 if (INT_MULTIPLY_WRAPV (format8->num_groups, sizeof *format8->groups,
1172 &temp))
1173 {
1174 xfree (format8);
1175 return NULL;
1176 }
1177
1178 if (INT_ADD_WRAPV (min_size, temp, &min_size))
1179 {
1180 xfree (format8);
1181 return NULL;
1182 }
1183
1184 if (length < min_size)
1185 {
1186 xfree (format8);
1187 return NULL;
1188 }
1189
1190 /* Now read the variable length data. */
1191 rc = read (fd, format8 + 1, temp);
1192 if (rc < temp)
1193 {
1194 xfree (format8);
1195 return (struct sfnt_cmap_format_8 *) -1;
1196 }
1197
1198#pragma GCC diagnostic pop
1199
1200 /* Set the pointer to the variable length data. */
1201 format8->groups
1202 = (struct sfnt_cmap_format_8_or_12_group *) (format8 + 1);
1203
1204 for (i = 0; i < format8->num_groups; ++i)
1205 {
1206 sfnt_swap32 (&format8->groups[i].start_char_code);
1207 sfnt_swap32 (&format8->groups[i].end_char_code);
1208 sfnt_swap32 (&format8->groups[i].start_glyph_code);
1209 }
1210
1211 /* All done. */
1212 return format8;
1213}
1214
1215/* Read a format 12 cmap subtable from FD. HEADER has already been
1216 read. */
1217
1218static struct sfnt_cmap_format_12 *
1219sfnt_read_cmap_format_12 (int fd,
1220 struct sfnt_cmap_encoding_subtable_data *header)
1221{
1222 struct sfnt_cmap_format_12 *format12;
1223 size_t min_size, temp;
1224 ssize_t rc;
1225 uint32_t length, i;
1226
1227 /* Read the 32-bit lenth field. */
1228 if (read (fd, &length, sizeof (length)) < sizeof (length))
1229 return (struct sfnt_cmap_format_12 *) -1;
1230
1231 /* Swap the 32-bit length field. */
1232 sfnt_swap32 (&length);
1233
1234 min_size = SFNT_ENDOF (struct sfnt_cmap_format_12, num_groups,
1235 uint32_t);
1236
1237 /* Make sure the header is at least as large as min_size. */
1238 if (length < min_size)
1239 return NULL;
1240
1241 /* Allocate a buffer of sufficient size. */
1242 format12 = xmalloc (length + sizeof *format12);
1243 format12->format = header->format;
1244 format12->reserved = header->length;
1245 format12->length = length;
1246
1247#pragma GCC diagnostic push
1248#pragma GCC diagnostic ignored "-Wstringop-overflow"
1249
1250 /* Read the fixed length data. */
1251 min_size -= offsetof (struct sfnt_cmap_format_12, language);
1252 rc = read (fd, &format12->language, min_size);
1253 if (rc < min_size)
1254 {
1255 xfree (format12);
1256 return (struct sfnt_cmap_format_12 *) -1;
1257 }
1258
1259#pragma GCC diagnostic pop
1260
1261 /* Swap what was read. */
1262 sfnt_swap32 (&format12->language);
1263 sfnt_swap32 (&format12->num_groups);
1264
1265 /* See if the size is sufficient to read the variable length
1266 data. */
1267 min_size = SFNT_ENDOF (struct sfnt_cmap_format_12, num_groups,
1268 uint32_t);
1269
1270 if (INT_MULTIPLY_WRAPV (format12->num_groups, sizeof *format12->groups,
1271 &temp))
1272 {
1273 xfree (format12);
1274 return NULL;
1275 }
1276
1277 if (INT_ADD_WRAPV (min_size, temp, &min_size))
1278 {
1279 xfree (format12);
1280 return NULL;
1281 }
1282
1283 if (length < min_size)
1284 {
1285 xfree (format12);
1286 return NULL;
1287 }
1288
1289 /* Now read the variable length data. */
1290 rc = read (fd, format12 + 1, temp);
1291 if (rc < temp)
1292 {
1293 xfree (format12);
1294 return (struct sfnt_cmap_format_12 *) -1;
1295 }
1296
1297 /* Set the pointer to the variable length data. */
1298 format12->groups
1299 = (struct sfnt_cmap_format_8_or_12_group *) (format12 + 1);
1300
1301 for (i = 0; i < format12->num_groups; ++i)
1302 {
1303 sfnt_swap32 (&format12->groups[i].start_char_code);
1304 sfnt_swap32 (&format12->groups[i].end_char_code);
1305 sfnt_swap32 (&format12->groups[i].start_glyph_code);
1306 }
1307
1308 /* All done. */
1309 return format12;
1310}
1311
1312/* Read the CMAP subtable data from a given file FD at TABLE_OFFSET
1313 bytes from DIRECTORY_OFFSET. Return the subtable data if it is
1314 supported. Else, value is NULL if the format is unsupported, or -1
1315 upon an IO error. */
1316
1317static struct sfnt_cmap_encoding_subtable_data *
1318sfnt_read_cmap_table_1 (int fd, uint32_t directory_offset,
1319 uint32_t table_offset)
1320{
1321 off_t offset;
1322 struct sfnt_cmap_encoding_subtable_data header;
1323
1324 if (INT_ADD_WRAPV (directory_offset, table_offset, &offset))
1325 return (struct sfnt_cmap_encoding_subtable_data *) -1;
1326
1327 if (lseek (fd, offset, SEEK_SET) == (off_t) -1)
1328 return (struct sfnt_cmap_encoding_subtable_data *) -1;
1329
1330 if (read (fd, &header, sizeof header) < sizeof header)
1331 return (struct sfnt_cmap_encoding_subtable_data *) -1;
1332
1333 sfnt_swap16 (&header.format);
1334 sfnt_swap16 (&header.length);
1335
1336 switch (header.format)
1337 {
1338 case 0:
1339 /* If the length changes, then something has changed to the
1340 format. */
1341 if (header.length != 262)
1342 return NULL;
1343
1344 return ((struct sfnt_cmap_encoding_subtable_data *)
1345 sfnt_read_cmap_format_0 (fd, &header));
1346
1347 case 2:
1348 return ((struct sfnt_cmap_encoding_subtable_data *)
1349 sfnt_read_cmap_format_2 (fd, &header));
1350
1351 case 4:
1352 return ((struct sfnt_cmap_encoding_subtable_data *)
1353 sfnt_read_cmap_format_4 (fd, &header));
1354
1355 case 6:
1356 return ((struct sfnt_cmap_encoding_subtable_data *)
1357 sfnt_read_cmap_format_6 (fd, &header));
1358
1359 case 8:
1360 return ((struct sfnt_cmap_encoding_subtable_data *)
1361 sfnt_read_cmap_format_8 (fd, &header));
1362
1363 case 12:
1364 return ((struct sfnt_cmap_encoding_subtable_data *)
1365 sfnt_read_cmap_format_12 (fd, &header));
1366
1367 default:
1368 return NULL;
1369 }
1370}
1371
1372/* Read the CMAP table of a given font from the file FD. Use the
1373 table directory specified in SUBTABLE.
1374
1375 Return the CMAP table and a list of encoding subtables in
1376 *SUBTABLES and *DATA upon success, else NULL. */
1377
1378static struct sfnt_cmap_table *
1379sfnt_read_cmap_table (int fd, struct sfnt_offset_subtable *subtable,
1380 struct sfnt_cmap_encoding_subtable **subtables,
1381 struct sfnt_cmap_encoding_subtable_data ***data)
1382{
1383 struct sfnt_table_directory *directory;
1384 struct sfnt_cmap_table *cmap;
1385 ssize_t rc;
1386 int i, j;
1387
1388 /* Find the CMAP table in the table directory. */
1389 directory = sfnt_find_table (subtable, SFNT_TABLE_CMAP);
1390
1391 if (!directory)
1392 return NULL;
1393
1394 /* Seek to the start of the CMAP table. */
1395 if (lseek (fd, directory->offset, SEEK_SET) == (off_t) -1)
1396 return NULL;
1397
1398 /* Read the table header. */
1399 cmap = xmalloc (sizeof *cmap);
1400 rc = read (fd, cmap, sizeof *cmap);
1401
1402 if (rc < sizeof *cmap)
1403 {
1404 xfree (cmap);
1405 return NULL;
1406 }
1407
1408 /* Swap the header data. */
1409 sfnt_swap16 (&cmap->version);
1410 sfnt_swap16 (&cmap->num_subtables);
1411
1412 if (cmap->version != 0)
1413 {
1414 xfree (cmap);
1415 return NULL;
1416 }
1417
1418 *subtables = xmalloc (cmap->num_subtables
1419 * sizeof **subtables);
1420
1421
1422 /* First, read the common parts of each encoding subtable. */
1423
1424 for (i = 0; i < cmap->num_subtables; ++i)
1425 {
1426 /* Read the common part of the new subtable. */
1427 rc = read (fd, &(*subtables)[i], sizeof (*subtables)[i]);
1428
1429 if (rc < sizeof (*subtables))
1430 {
1431 xfree (cmap);
1432 xfree (*subtables);
1433 return NULL;
1434 }
1435
1436 sfnt_swap16 (&(*subtables)[i].platform_id);
1437 sfnt_swap16 (&(*subtables)[i].platform_specific_id);
1438 sfnt_swap32 (&(*subtables)[i].offset);
1439 }
1440
1441 /* Second, read each encoding subtable itself. */
1442 *data = xmalloc (cmap->num_subtables
1443 * sizeof **subtables);
1444
1445 for (i = 0; i < cmap->num_subtables; ++i)
1446 {
1447 (*data)[i] = sfnt_read_cmap_table_1 (fd, directory->offset,
1448 (*subtables)[i].offset);
1449
1450 if ((*data)[i] == (void *) -1)
1451 {
1452 /* An IO error occurred (as opposed to the subtable format
1453 being unsupported.) Return now. */
1454
1455 for (j = 0; j < i; ++j)
1456 xfree (data[i]);
1457 xfree (*data);
1458 xfree (*subtables);
1459 xfree (cmap);
1460 return NULL;
1461 }
1462 }
1463
1464 return cmap;
1465}
1466
1467/* Look up the glyph corresponding to CHARACTER in the format 0 cmap
1468 FORMAT0. Return 0 if no glyph was found. */
1469
1470static sfnt_glyph
1471sfnt_lookup_glyph_0 (sfnt_char character,
1472 struct sfnt_cmap_format_0 *format0)
1473{
1474 if (character >= 256)
1475 return 0;
1476
1477 return format0->glyph_index_array[character];
1478}
1479
1480/* Look up the glyph corresponding to CHARACTER in the format 2 cmap
1481 FORMAT2. Return 0 if no glyph was found. */
1482
1483static sfnt_glyph
1484sfnt_lookup_glyph_2 (sfnt_char character,
1485 struct sfnt_cmap_format_2 *format2)
1486{
1487 unsigned char i, k, j;
1488 struct sfnt_cmap_format_2_subheader *subheader;
1489 unsigned char *slice;
1490 uint16_t glyph;
1491
1492 if (character > 65335)
1493 return 0;
1494
1495 i = character >> 16;
1496 j = character & 0xff;
1497 k = format2->sub_header_keys[i] / 8;
1498
1499 if (k)
1500 {
1501 subheader = &format2->subheaders[k];
1502
1503 if (subheader->first_code <= j
1504 && j <= ((int) subheader->first_code
1505 + (int) subheader->entry_count))
1506 {
1507 /* id_range_offset is actually the number of bytes past
1508 itself containing the uint16_t ``slice''. It is possibly
1509 unaligned. */
1510 slice = (unsigned char *) &subheader->id_range_offset;
1511 slice += subheader->id_range_offset;
1512 slice += (j - subheader->first_code) * sizeof (uint16_t);
1513
1514 if (slice < (unsigned char *) format2->glyph_index_array
1515 || (slice + 1
1516 > (unsigned char *) (format2->glyph_index_array
1517 + format2->num_glyphs)))
1518 /* The character is out of bounds. */
1519 return 0;
1520
1521 memcpy (&glyph, slice, sizeof glyph);
1522 return (glyph + subheader->id_delta) % 65536;
1523 }
1524 else
1525 return 0;
1526 }
1527
1528 /* k is 0, so glyph_index_array[i] is the glyph. */
1529 return (i < format2->num_glyphs
1530 ? format2->glyph_index_array[i]
1531 : 0);
1532}
1533
1534/* Like `bsearch'. However, return the highest element above KEY if
1535 it could not be found. */
1536
1537static void *
1538sfnt_bsearch_above (const void *key, const void *base,
1539 size_t nmemb, size_t size,
1540 int (*compar) (const void *,
1541 const void *))
1542{
1543 const unsigned char *bytes, *sample;
1544 size_t low, high, mid;
1545
1546 bytes = base;
1547 low = 0;
1548 high = nmemb - 1;
1549
1550 if (!nmemb)
1551 return NULL;
1552
1553 while (low != high)
1554 {
1555 mid = low + (high - low) / 2;
1556 sample = bytes + mid * size;
1557
1558 if (compar (key, sample) > 0)
1559 low = mid + 1;
1560 else
1561 high = mid;
1562 }
1563
1564 return (unsigned char *) bytes + low * size;
1565}
1566
1567/* Compare two uint16_t's. Used to bisect through a format 4
1568 table. */
1569
1570static int
1571sfnt_compare_uint16 (const void *a, const void *b)
1572{
1573 return ((int) *((uint16_t *) a)) - ((int) *((uint16_t *) b));
1574}
1575
1576/* Look up the glyph corresponding to CHARACTER in the format 4 cmap
1577 FORMAT4. Return 0 if no glyph was found. */
1578
1579static sfnt_glyph
1580sfnt_lookup_glyph_4 (sfnt_char character,
1581 struct sfnt_cmap_format_4 *format4)
1582{
1583 uint16_t *segment_address, *index;
1584 uint16_t code, segment;
1585
1586 if (character > 65535)
1587 return 0;
1588
1589 code = character;
1590
1591 /* Find the segment above CHARACTER. */
1592 segment_address = sfnt_bsearch_above (&code, format4->end_code,
1593 format4->seg_count_x2 / 2,
1594 sizeof code,
1595 sfnt_compare_uint16);
1596 segment = segment_address - format4->end_code;
1597
1598 /* If the segment starts too late, return 0. */
1599 if (!segment_address || format4->start_code[segment] > character)
1600 return 0;
1601
1602 if (format4->id_range_offset[segment])
1603 {
1604 /* id_range_offset is not 0, so the glyph mapping depends on
1605 it. */
1606 index = (uint16_t *) (&format4->id_range_offset[segment]
1607 + format4->id_range_offset[segment] / 2
1608 + (code - format4->start_code[segment]));
1609
1610 /* Check that index is not out of bounds. */
1611 if (index >= (format4->glyph_index_array
1612 + format4->glyph_index_size)
1613 || index < format4->glyph_index_array)
1614 return 0;
1615
1616 /* Return what is in index. */
1617 return (*index ? (format4->id_delta[segment]
1618 + *index) % 65536 : 0);
1619 }
1620
1621 /* Otherwise, just add id_delta. */
1622 return (format4->id_delta[segment] + code) % 65536;
1623}
1624
1625/* Look up the glyph corresponding to CHARACTER in the format 6 cmap
1626 FORMAT6. Return 0 if no glyph was found. */
1627
1628static sfnt_glyph
1629sfnt_lookup_glyph_6 (sfnt_char character,
1630 struct sfnt_cmap_format_6 *format6)
1631{
1632 if (character < format6->first_code
1633 || character >= (format6->first_code
1634 + (int) format6->entry_count))
1635 return 0;
1636
1637 return format6->glyph_index_array[character - format6->first_code];
1638}
1639
1640/* Look up the glyph corresponding to CHARACTER in the format 8 cmap
1641 FORMAT8. Return 0 if no glyph was found. */
1642
1643static sfnt_glyph
1644sfnt_lookup_glyph_8 (sfnt_char character,
1645 struct sfnt_cmap_format_8 *format8)
1646{
1647 uint32_t i;
1648
1649 if (character > 0xffffffff)
1650 return 0;
1651
1652 for (i = 0; i < format8->num_groups; ++i)
1653 {
1654 if (format8->groups[i].start_char_code <= character
1655 && format8->groups[i].end_char_code >= character)
1656 return (format8->groups[i].start_glyph_code
1657 + (character
1658 - format8->groups[i].start_char_code));
1659 }
1660
1661 return 0;
1662}
1663
1664/* Look up the glyph corresponding to CHARACTER in the format 12 cmap
1665 FORMAT12. Return 0 if no glyph was found. */
1666
1667static sfnt_glyph
1668sfnt_lookup_glyph_12 (sfnt_char character,
1669 struct sfnt_cmap_format_12 *format12)
1670{
1671 uint32_t i;
1672
1673 if (character > 0xffffffff)
1674 return 0;
1675
1676 for (i = 0; i < format12->num_groups; ++i)
1677 {
1678 if (format12->groups[i].start_char_code <= character
1679 && format12->groups[i].end_char_code >= character)
1680 return (format12->groups[i].start_glyph_code
1681 + (character
1682 - format12->groups[i].start_char_code));
1683 }
1684
1685 return 0;
1686}
1687
1688/* Look up the glyph index corresponding to the character CHARACTER,
1689 which must be in the correct encoding for the cmap table pointed to
1690 by DATA. */
1691
1692static sfnt_glyph
1693sfnt_lookup_glyph (sfnt_char character,
1694 struct sfnt_cmap_encoding_subtable_data *data)
1695{
1696 switch (data->format)
1697 {
1698 case 0:
1699 return sfnt_lookup_glyph_0 (character,
1700 (struct sfnt_cmap_format_0 *) data);
1701
1702 case 2:
1703 return sfnt_lookup_glyph_2 (character,
1704 (struct sfnt_cmap_format_2 *) data);
1705
1706 case 4:
1707 return sfnt_lookup_glyph_4 (character,
1708 (struct sfnt_cmap_format_4 *) data);
1709
1710 case 6:
1711 return sfnt_lookup_glyph_6 (character,
1712 (struct sfnt_cmap_format_6 *) data);
1713
1714 case 8:
1715 return sfnt_lookup_glyph_8 (character,
1716 (struct sfnt_cmap_format_8 *) data);
1717
1718 case 12:
1719 return sfnt_lookup_glyph_12 (character,
1720 (struct sfnt_cmap_format_12 *) data);
1721 }
1722
1723 return 0;
1724}
1725
1726
1727
1728/* Header reading routines. */
1729
1730/* Read the head table of a given font FD. Use the table directory
1731 specified in SUBTABLE.
1732
1733 Return the head table upon success, else NULL. */
1734
1735static struct sfnt_head_table *
1736sfnt_read_head_table (int fd, struct sfnt_offset_subtable *subtable)
1737{
1738 struct sfnt_table_directory *directory;
1739 struct sfnt_head_table *head;
1740 ssize_t rc;
1741
1742 /* Find the table in the directory. */
1743
1744 directory = sfnt_find_table (subtable, SFNT_TABLE_HEAD);
1745
1746 if (!directory)
1747 return NULL;
1748
1749 /* Seek to the location given in the directory. */
1750 if (lseek (fd, directory->offset, SEEK_SET) == (off_t) -1)
1751 return NULL;
1752
1753 /* Read the entire table. */
1754 head = xmalloc (sizeof *head);
1755 rc = read (fd, head, sizeof *head);
1756
1757 if (rc < sizeof *head)
1758 {
1759 xfree (head);
1760 return NULL;
1761 }
1762
1763 /* Swap the header data. */
1764 sfnt_swap32 (&head->version);
1765 sfnt_swap32 (&head->revision);
1766
1767 if (head->version != 0x00010000)
1768 {
1769 xfree (head);
1770 return NULL;
1771 }
1772
1773 /* Swap the rest of the data. */
1774 sfnt_swap32 (&head->checksum_adjustment);
1775 sfnt_swap32 (&head->magic);
1776
1777 if (head->magic != 0x5f0f3cf5)
1778 {
1779 xfree (head);
1780 return NULL;
1781 }
1782
1783 sfnt_swap16 (&head->flags);
1784 sfnt_swap16 (&head->units_per_em);
1785 sfnt_swap32 (&head->created_high);
1786 sfnt_swap32 (&head->created_low);
1787 sfnt_swap32 (&head->modified_high);
1788 sfnt_swap32 (&head->modified_low);
1789 sfnt_swap16 (&head->xmin);
1790 sfnt_swap16 (&head->xmax);
1791 sfnt_swap16 (&head->ymin);
1792 sfnt_swap16 (&head->ymax);
1793 sfnt_swap16 (&head->mac_style);
1794 sfnt_swap16 (&head->lowest_rec_ppem);
1795 sfnt_swap16 (&head->font_direction_hint);
1796 sfnt_swap16 (&head->index_to_loc_format);
1797 sfnt_swap16 (&head->glyph_data_format);
1798
1799 return head;
1800}
1801
1802/* Read the hhea table of a given font FD. Use the table directory
1803 specified in SUBTABLE.
1804
1805 Return the head table upon success, else NULL. */
1806
1807static struct sfnt_hhea_table *
1808sfnt_read_hhea_table (int fd, struct sfnt_offset_subtable *subtable)
1809{
1810 struct sfnt_table_directory *directory;
1811 struct sfnt_hhea_table *hhea;
1812 ssize_t rc;
1813
1814 /* Find the table in the directory. */
1815
1816 directory = sfnt_find_table (subtable, SFNT_TABLE_HHEA);
1817
1818 if (!directory)
1819 return NULL;
1820
1821 /* Check the length is right. */
1822 if (directory->length != sizeof *hhea)
1823 return NULL;
1824
1825 /* Seek to the location given in the directory. */
1826 if (lseek (fd, directory->offset, SEEK_SET) == (off_t) -1)
1827 return NULL;
1828
1829 /* Read the entire table. */
1830 hhea = xmalloc (sizeof *hhea);
1831 rc = read (fd, hhea, sizeof *hhea);
1832
1833 if (rc < sizeof *hhea)
1834 {
1835 xfree (hhea);
1836 return NULL;
1837 }
1838
1839 /* Swap the header data. */
1840 sfnt_swap32 (&hhea->version);
1841
1842 if (hhea->version != 0x00010000)
1843 {
1844 xfree (hhea);
1845 return NULL;
1846 }
1847
1848 /* Swap the rest of the data. */
1849 sfnt_swap16 (&hhea->ascent);
1850 sfnt_swap16 (&hhea->descent);
1851 sfnt_swap16 (&hhea->line_gap);
1852 sfnt_swap16 (&hhea->advance_width_max);
1853 sfnt_swap16 (&hhea->min_left_side_bearing);
1854 sfnt_swap16 (&hhea->min_right_side_bearing);
1855 sfnt_swap16 (&hhea->x_max_extent);
1856 sfnt_swap16 (&hhea->caret_slope_rise);
1857 sfnt_swap16 (&hhea->caret_slope_run);
1858 sfnt_swap16 (&hhea->reserved1);
1859 sfnt_swap16 (&hhea->reserved2);
1860 sfnt_swap16 (&hhea->reserved3);
1861 sfnt_swap16 (&hhea->reserved4);
1862 sfnt_swap16 (&hhea->metric_data_format);
1863 sfnt_swap16 (&hhea->num_of_long_hor_metrics);
1864
1865 return hhea;
1866}
1867
1868/* Read a short loca table from the given font FD. Use the table
1869 directory specified in SUBTABLE.
1870
1871 Return the short table upon success, else NULL. */
1872
1873static struct sfnt_loca_table_short *
1874sfnt_read_loca_table_short (int fd, struct sfnt_offset_subtable *subtable)
1875{
1876 struct sfnt_table_directory *directory;
1877 struct sfnt_loca_table_short *loca;
1878 ssize_t rc;
1879 int i;
1880
1881 /* Find the table in the directory. */
1882
1883 directory = sfnt_find_table (subtable, SFNT_TABLE_LOCA);
1884
1885 if (!directory)
1886 return NULL;
1887
1888 /* Seek to the location given in the directory. */
1889 if (lseek (fd, directory->offset, SEEK_SET) == (off_t) -1)
1890 return NULL;
1891
1892 /* Figure out how many glyphs there are based on the length. */
1893 loca = xmalloc (sizeof *loca + directory->length);
1894 loca->offsets = (uint16_t *) (loca + 1);
1895 loca->num_offsets = directory->length / 2;
1896
1897 /* Read the variable-length table data. */
1898 rc = read (fd, loca->offsets, directory->length);
1899 if (rc < directory->length)
1900 {
1901 xfree (loca);
1902 return NULL;
1903 }
1904
1905 /* Swap each of the offsets. */
1906 for (i = 0; i < loca->num_offsets; ++i)
1907 sfnt_swap16 (&loca->offsets[i]);
1908
1909 /* Return the table. */
1910 return loca;
1911}
1912
1913/* Read a long loca table from the given font FD. Use the table
1914 directory specified in SUBTABLE.
1915
1916 Return the long table upon success, else NULL. */
1917
1918static struct sfnt_loca_table_long *
1919sfnt_read_loca_table_long (int fd, struct sfnt_offset_subtable *subtable)
1920{
1921 struct sfnt_table_directory *directory;
1922 struct sfnt_loca_table_long *loca;
1923 ssize_t rc;
1924 int i;
1925
1926 /* Find the table in the directory. */
1927
1928 directory = sfnt_find_table (subtable, SFNT_TABLE_LOCA);
1929
1930 if (!directory)
1931 return NULL;
1932
1933 /* Seek to the location given in the directory. */
1934 if (lseek (fd, directory->offset, SEEK_SET) == (off_t) -1)
1935 return NULL;
1936
1937 /* Figure out how many glyphs there are based on the length. */
1938 loca = xmalloc (sizeof *loca + directory->length);
1939 loca->offsets = (uint32_t *) (loca + 1);
1940 loca->num_offsets = directory->length / 4;
1941
1942 /* Read the variable-length table data. */
1943 rc = read (fd, loca->offsets, directory->length);
1944 if (rc < directory->length)
1945 {
1946 xfree (loca);
1947 return NULL;
1948 }
1949
1950 /* Swap each of the offsets. */
1951 for (i = 0; i < loca->num_offsets; ++i)
1952 sfnt_swap32 (&loca->offsets[i]);
1953
1954 /* Return the table. */
1955 return loca;
1956}
1957
1958/* Read the maxp table from the given font FD. Use the table
1959 directory specified in SUBTABLE.
1960
1961 Return the maxp table upon success, else NULL. If the version is
1962 0.5, fields past num_glyphs will not be populated. */
1963
1964static struct sfnt_maxp_table *
1965sfnt_read_maxp_table (int fd, struct sfnt_offset_subtable *subtable)
1966{
1967 struct sfnt_table_directory *directory;
1968 struct sfnt_maxp_table *maxp;
1969 size_t size;
1970 ssize_t rc;
1971
1972 /* Find the table in the directory. */
1973
1974 directory = sfnt_find_table (subtable, SFNT_TABLE_MAXP);
1975
1976 if (!directory)
1977 return NULL;
1978
1979 /* Seek to the location given in the directory. */
1980 if (lseek (fd, directory->offset, SEEK_SET) == (off_t) -1)
1981 return NULL;
1982
1983 /* If directory->length is not big enough for version 0.5, punt. */
1984 if (directory->length < SFNT_ENDOF (struct sfnt_maxp_table,
1985 num_glyphs, uint16_t))
1986 return NULL;
1987
1988 /* Allocate the buffer to hold the data. Then, read
1989 directory->length or sizeof *maxp bytes into it, whichever is
1990 smaller. */
1991
1992 maxp = malloc (sizeof *maxp);
1993 size = MIN (directory->length, sizeof *maxp);
1994 rc = read (fd, maxp, size);
1995
1996 if (rc < size)
1997 {
1998 xfree (maxp);
1999 return NULL;
2000 }
2001
2002 /* Now, swap version and num_glyphs. */
2003 sfnt_swap32 (&maxp->version);
2004 sfnt_swap16 (&maxp->num_glyphs);
2005
2006 /* Reject version 1.0 tables that are too small. */
2007 if (maxp->version > 0x00005000 && size < sizeof *maxp)
2008 {
2009 xfree (maxp);
2010 return NULL;
2011 }
2012
2013 /* If the table is version 0.5, then this function is done. */
2014 if (maxp->version == 0x00005000)
2015 return maxp;
2016 else if (maxp->version != 0x00010000)
2017 {
2018 /* Reject invalid versions. */
2019 xfree (maxp);
2020 return NULL;
2021 }
2022
2023 /* Otherwise, swap the rest of the fields. */
2024 sfnt_swap16 (&maxp->max_points);
2025 sfnt_swap16 (&maxp->max_contours);
2026 sfnt_swap16 (&maxp->max_composite_points);
2027 sfnt_swap16 (&maxp->max_composite_contours);
2028 sfnt_swap16 (&maxp->max_zones);
2029 sfnt_swap16 (&maxp->max_twilight_points);
2030 sfnt_swap16 (&maxp->max_storage);
2031 sfnt_swap16 (&maxp->max_function_defs);
2032 sfnt_swap16 (&maxp->max_instruction_defs);
2033 sfnt_swap16 (&maxp->max_stack_elements);
2034 sfnt_swap16 (&maxp->max_size_of_instructions);
2035 sfnt_swap16 (&maxp->max_component_elements);
2036 sfnt_swap16 (&maxp->max_component_depth);
2037
2038 /* All done. */
2039 return maxp;
2040}
2041
2042
2043
2044/* Glyph outlining generation. */
2045
2046/* Read a glyf table from the given font FD. Use the table directory
2047 specified in SUBTABLE. The glyph data is not swapped.
2048
2049 Return the glyf table upon success, else NULL. */
2050
2051static struct sfnt_glyf_table *
2052sfnt_read_glyf_table (int fd, struct sfnt_offset_subtable *subtable)
2053{
2054 struct sfnt_table_directory *directory;
2055 struct sfnt_glyf_table *glyf;
2056 ssize_t rc;
2057
2058 /* Find the table in the directory. */
2059
2060 directory = sfnt_find_table (subtable, SFNT_TABLE_GLYF);
2061
2062 if (!directory)
2063 return NULL;
2064
2065 /* Seek to the location given in the directory. */
2066 if (lseek (fd, directory->offset, SEEK_SET) == (off_t) -1)
2067 return NULL;
2068
2069 /* Allocate enough to hold everything. */
2070 glyf = xmalloc (sizeof *glyf + directory->length);
2071 glyf->size = directory->length;
2072 glyf->glyphs = (unsigned char *) (glyf + 1);
2073
2074 /* Read the glyph data. */
2075 rc = read (fd, glyf->glyphs, glyf->size);
2076 if (rc < glyf->size)
2077 {
2078 xfree (glyf);
2079 return NULL;
2080 }
2081
2082 /* Return the table. */
2083 return glyf;
2084}
2085
2086/* Read the simple glyph outline from the glyph GLYPH from the
2087 specified glyf table at the given offset. Set GLYPH->simple to a
2088 non-NULL value upon success, else set it to NULL. */
2089
2090static void
2091sfnt_read_simple_glyph (struct sfnt_glyph *glyph,
2092 struct sfnt_glyf_table *glyf,
2093 ptrdiff_t offset)
2094{
2095 struct sfnt_simple_glyph *simple;
2096 ssize_t min_size, min_size_2;
2097 int i, number_of_points, repeat_count;
2098 unsigned char *instructions_start;
2099 unsigned char *flags_start, *flags_end;
2100 unsigned char *vec_start;
2101 int16_t delta, x, y;
2102
2103 /* Calculate the minimum size of the glyph data. This is the size
2104 of the instruction length field followed by
2105 glyf->number_of_contours * sizeof (uint16_t). */
2106
2107 min_size = (glyph->number_of_contours * sizeof (uint16_t)
2108 + sizeof (uint16_t));
2109
2110 /* Check that the size is big enough. */
2111 if (glyf->size < offset + min_size)
2112 {
2113 glyph->simple = NULL;
2114 return;
2115 }
2116
2117 /* Allocate enough to read at least that. */
2118 simple = xmalloc (sizeof *simple + min_size);
2119 simple->end_pts_of_contours = (uint16_t *) (simple + 1);
2120 memcpy (simple->end_pts_of_contours, glyf->glyphs + offset,
2121 min_size);
2122
2123 /* This is not really an index into simple->end_pts_of_contours.
2124 Rather, it is reading the first word past it. */
2125 simple->instruction_length
2126 = simple->end_pts_of_contours[glyph->number_of_contours];
2127
2128 /* Swap the contour end point indices and the instruction
2129 length. */
2130
2131 for (i = 0; i < glyph->number_of_contours; ++i)
2132 sfnt_swap16 (&simple->end_pts_of_contours[i]);
2133
2134 sfnt_swap16 (&simple->instruction_length);
2135
2136 /* Based on those values, calculate the maximum size of the
2137 following data. This is the instruction length + the last
2138 contour point + the last contour point * uint16_t * 2. */
2139
2140 if (glyph->number_of_contours)
2141 number_of_points
2142 = simple->end_pts_of_contours[glyph->number_of_contours - 1] + 1;
2143 else
2144 number_of_points = 0;
2145
2146 min_size_2 = (simple->instruction_length
2147 + number_of_points
2148 + (number_of_points
2149 * sizeof (uint16_t) * 2));
2150
2151 /* Set simple->number_of_points. */
2152 simple->number_of_points = number_of_points;
2153
2154 /* Make simple big enough. */
2155 simple = xrealloc (simple, sizeof *simple + min_size + min_size_2);
2156 simple->end_pts_of_contours = (uint16_t *) (simple + 1);
2157
2158 /* Set the instruction data pointer and other pointers.
2159 simple->instructions comes one word past number_of_contours,
2160 because end_pts_of_contours also contains the instruction
2161 length. */
2162 simple->instructions = (uint8_t *) (simple->end_pts_of_contours
2163 + glyph->number_of_contours + 1);
2164 simple->flags = simple->instructions + simple->instruction_length;
2165
2166 /* Read instructions into the glyph. */
2167 instructions_start = glyf->glyphs + offset + min_size;
2168
2169 if (instructions_start >= glyf->glyphs + glyf->size
2170 || (instructions_start + simple->instruction_length
2171 >= glyf->glyphs + glyf->size))
2172 {
2173 glyph->simple = NULL;
2174 xfree (simple);
2175 return;
2176 }
2177
2178 memcpy (simple->instructions, instructions_start,
2179 simple->instruction_length);
2180
2181 /* Start reading flags. */
2182 flags_start = (glyf->glyphs + offset
2183 + min_size + simple->instruction_length);
2184 flags_end = flags_start + number_of_points;
2185
2186 if (flags_start >= glyf->glyphs + glyf->size)
2187 {
2188 glyph->simple = NULL;
2189 xfree (simple);
2190 return;
2191 }
2192
2193 i = 0;
2194
2195 while (flags_start < flags_end)
2196 {
2197 if (i == number_of_points)
2198 break;
2199
2200 if (flags_start >= glyf->glyphs + glyf->size)
2201 break;
2202
2203 simple->flags[i++] = *flags_start;
2204
2205 if (*flags_start & 010) /* REPEAT_FLAG */
2206 {
2207 /* The next byte specifies how many times this byte is to be
2208 repeated. Check that it is in range. */
2209
2210 if (flags_start + 1 >= glyf->glyphs + glyf->size)
2211 {
2212 glyph->simple = NULL;
2213 xfree (simple);
2214 }
2215
2216 /* Repeat the current flag until
2217 glyph->number_of_points. */
2218
2219 repeat_count = *(flags_start + 1);
2220
2221 while (i < number_of_points && repeat_count)
2222 {
2223 simple->flags[i++] = *flags_start;
2224 repeat_count--;
2225 }
2226
2227 /* Skip one byte in flags_start. */
2228 flags_start++;
2229 }
2230
2231 flags_start++;
2232 }
2233
2234 /* If an insufficient number of flags have been read, then the
2235 outline is invalid. */
2236
2237 if (i != number_of_points)
2238 {
2239 glyph->simple = NULL;
2240 xfree (simple);
2241 return;
2242 }
2243
2244 /* Now that the flags have been decoded, start decoding the
2245 vectors. */
2246 simple->x_coordinates = (int16_t *) (simple->flags + number_of_points);
2247 vec_start = flags_start;
2248 i = 0;
2249 x = 0;
2250
2251 /* flags_start is now repurposed to act as a pointer to the flags
2252 for the current vector! */
2253 flags_start = simple->flags;
2254
2255 while (i < number_of_points)
2256 {
2257 delta = 0;
2258
2259 if ((*flags_start) & 02) /* X_SHORT_VECTOR */
2260 {
2261 /* The next byte is a delta to apply to the previous
2262 value. Make sure it is in bounds. */
2263
2264 if (vec_start + 1 >= glyf->glyphs + glyf->size)
2265 {
2266 glyph->simple = NULL;
2267 xfree (simple);
2268 return;
2269 }
2270
2271 delta = *vec_start++;
2272
2273 if (!(*flags_start & 020)) /* SAME_X */
2274 delta = -delta;
2275 }
2276 else if (!(*flags_start & 020)) /* SAME_X */
2277 {
2278 /* The next word is a delta to apply to the previous value.
2279 Make sure it is in bounds. */
2280
2281 if (vec_start + 2 >= glyf->glyphs + glyf->size)
2282 {
2283 glyph->simple = NULL;
2284 xfree (simple);
2285 return;
2286 }
2287
2288 /* Read the unaligned word and swap it. */
2289 memcpy (&delta, vec_start, sizeof delta);
2290 sfnt_swap16 (&delta);
2291 vec_start += 2;
2292 }
2293
2294 /* Apply the delta and set the X value. */
2295 x += delta;
2296 simple->x_coordinates[i++] = x;
2297 flags_start++;
2298 }
2299
2300 /* Decode the Y vector. flags_start is again repurposed to act as a
2301 pointer to the flags for the current vector. */
2302 flags_start = simple->flags;
2303 y = 0;
2304 simple->y_coordinates = simple->x_coordinates + i;
2305 i = 0;
2306
2307 while (i < number_of_points)
2308 {
2309 delta = 0;
2310
2311 if (*flags_start & 04) /* Y_SHORT_VECTOR */
2312 {
2313 /* The next byte is a delta to apply to the previous
2314 value. Make sure it is in bounds. */
2315
2316 if (vec_start + 1 >= glyf->glyphs + glyf->size)
2317 {
2318 glyph->simple = NULL;
2319 xfree (simple);
2320 return;
2321 }
2322
2323 delta = *vec_start++;
2324
2325 if (!(*flags_start & 040)) /* SAME_Y */
2326 delta = -delta;
2327 }
2328 else if (!(*flags_start & 040)) /* SAME_Y */
2329 {
2330 /* The next word is a delta to apply to the previous value.
2331 Make sure it is in bounds. */
2332
2333 if (vec_start + 2 >= glyf->glyphs + glyf->size)
2334 {
2335 glyph->simple = NULL;
2336 xfree (simple);
2337 return;
2338 }
2339
2340 /* Read the unaligned word and swap it. */
2341 memcpy (&delta, vec_start, sizeof delta);
2342 sfnt_swap16 (&delta);
2343 vec_start += 2;
2344 }
2345
2346 /* Apply the delta and set the X value. */
2347 y += delta;
2348 simple->y_coordinates[i++] = y;
2349 flags_start++;
2350 }
2351
2352 /* All done. */
2353 simple->y_coordinates_end = simple->y_coordinates + i;
2354 glyph->simple = simple;
2355 return;
2356}
2357
2358/* Read the compound glyph outline from the glyph GLYPH from the
2359 specified glyf table at the given offset. Set GLYPH->compound to a
2360 non-NULL value upon success, else set it to NULL. */
2361
2362static void
2363sfnt_read_compound_glyph (struct sfnt_glyph *glyph,
2364 struct sfnt_glyf_table *glyf,
2365 ptrdiff_t offset)
2366{
2367 uint16_t flags, instruction_length, words[2], words4[4];
2368 size_t required_bytes, num_components, i;
2369 unsigned char *data, *instruction_base;
2370
2371 /* Assume failure for now. Figure out how many bytes have to be
2372 allocated by reading the compound data. */
2373 glyph->compound = NULL;
2374 required_bytes = 0;
2375 num_components = 0;
2376 data = glyf->glyphs + offset;
2377
2378 /* Offset could be unaligned. */
2379 do
2380 {
2381 if (data + 2 > glyf->glyphs + glyf->size)
2382 return;
2383
2384 memcpy (&flags, data, sizeof flags);
2385 sfnt_swap16 (&flags);
2386 data += sizeof flags;
2387
2388 /* Require at least one structure to hold this data. */
2389 required_bytes += sizeof (struct sfnt_compound_glyph_component);
2390 num_components++;
2391
2392 /* Skip past unused data. */
2393 data += 2;
2394
2395 if (flags & 01) /* ARG_1_AND_2_ARE_WORDS */
2396 data += sizeof (int16_t) * 2;
2397 else
2398 data += sizeof (int8_t) * 2;
2399
2400 if (flags & 010) /* WE_HAVE_A_SCALE */
2401 data += sizeof (uint16_t);
2402 else if (flags & 0100) /* WE_HAVE_AN_X_AND_Y_SCALE */
2403 data += sizeof (uint16_t) * 2;
2404 else if (flags & 0200) /* WE_HAVE_A_TWO_BY_TWO */
2405 data += sizeof (uint16_t) * 4;
2406 }
2407 while (flags & 040); /* MORE_COMPONENTS */
2408
2409 if (flags & 0400) /* WE_HAVE_INSTRUCTIONS */
2410 {
2411 /* Figure out the instruction length. */
2412 if (data + 2 > glyf->glyphs + glyf->size)
2413 return;
2414
2415 /* Now see how much is required to hold the instruction
2416 data. */
2417 memcpy (&instruction_length, data,
2418 sizeof instruction_length);
2419 sfnt_swap16 (&instruction_length);
2420 required_bytes += instruction_length;
2421 data += sizeof data + instruction_length;
2422 }
2423
2424 /* Now allocate the buffer to hold all the glyph data. */
2425 glyph->compound = xmalloc (sizeof *glyph->compound
2426 + required_bytes);
2427 glyph->compound->components
2428 = (struct sfnt_compound_glyph_component *) (glyph->compound + 1);
2429 glyph->compound->num_components = num_components;
2430
2431 /* Figure out where instruction data starts. It comes after
2432 glyph->compound->components ends. */
2433 instruction_base
2434 = (unsigned char *) (glyph->compound->components
2435 + glyph->compound->num_components);
2436
2437 /* Start reading. */
2438 i = 0;
2439 data = glyf->glyphs + offset;
2440 do
2441 {
2442 if (data + 4 > glyf->glyphs + glyf->size)
2443 {
2444 xfree (glyph->compound);
2445 glyph->compound = NULL;
2446 return;
2447 }
2448
2449 memcpy (&flags, data, sizeof flags);
2450 sfnt_swap16 (&flags);
2451 data += sizeof flags;
2452 glyph->compound->components[i].flags = flags;
2453
2454 memcpy (&glyph->compound->components[i].glyph_index,
2455 data, sizeof glyph->compound->components[i].glyph_index);
2456 sfnt_swap16 (&glyph->compound->components[i].glyph_index);
2457 data += sizeof glyph->compound->components[i].glyph_index;
2458
2459 if (flags & 01) /* ARG_1_AND_2_ARE_WORDS. */
2460 {
2461 if (data + 4 > glyf->glyphs + glyf->size)
2462 {
2463 xfree (glyph->compound);
2464 glyph->compound = NULL;
2465 return;
2466 }
2467
2468 /* Read two words into arg1 and arg2. */
2469 memcpy (words, data, sizeof words);
2470 sfnt_swap16 (&words[0]);
2471 sfnt_swap16 (&words[1]);
2472
2473 glyph->compound->components[i].argument1.c = words[0];
2474 glyph->compound->components[i].argument2.c = words[1];
2475 data += sizeof words;
2476 }
2477 else
2478 {
2479 if (data + 2 > glyf->glyphs + glyf->size)
2480 {
2481 xfree (glyph->compound);
2482 glyph->compound = NULL;
2483 return;
2484 }
2485
2486 /* Read two bytes into arg1 and arg2. */
2487 glyph->compound->components[i].argument1.a = data[0];
2488 glyph->compound->components[i].argument2.a = data[1];
2489 data += 2;
2490 }
2491
2492 if (flags & 010) /* WE_HAVE_A_SCALE */
2493 {
2494 if (data + 2 > glyf->glyphs + glyf->size)
2495 {
2496 xfree (glyph->compound);
2497 glyph->compound = NULL;
2498 return;
2499 }
2500
2501 /* Read one word into scale. */
2502 memcpy (&glyph->compound->components[i].u.scale, data,
2503 sizeof glyph->compound->components[i].u.scale);
2504 sfnt_swap16 (&glyph->compound->components[i].u.scale);
2505 data += sizeof glyph->compound->components[i].u.scale;
2506 }
2507 else if (flags & 0100) /* WE_HAVE_AN_X_AND_Y_SCALE. */
2508 {
2509 if (data + 4 > glyf->glyphs + glyf->size)
2510 {
2511 xfree (glyph->compound);
2512 glyph->compound = NULL;
2513 return;
2514 }
2515
2516 /* Read two words into xscale and yscale. */
2517 memcpy (words, data, sizeof words);
2518 sfnt_swap16 (&words[0]);
2519 sfnt_swap16 (&words[1]);
2520
2521 glyph->compound->components[i].u.a.xscale = words[0];
2522 glyph->compound->components[i].u.a.yscale = words[1];
2523 data += sizeof words;
2524 }
2525 else if (flags & 0200) /* WE_HAVE_A_TWO_BY_TWO */
2526 {
2527 if (data + 8 > glyf->glyphs + glyf->size)
2528 {
2529 xfree (glyph->compound);
2530 glyph->compound = NULL;
2531 return;
2532 }
2533
2534 /* Read 4 words into the transformation matrix. */
2535 memcpy (words4, data, sizeof words4);
2536 sfnt_swap16 (&words4[0]);
2537 sfnt_swap16 (&words4[1]);
2538 sfnt_swap16 (&words4[2]);
2539 sfnt_swap16 (&words4[3]);
2540
2541 glyph->compound->components[i].u.b.xscale = words4[0];
2542 glyph->compound->components[i].u.b.scale01 = words4[1];
2543 glyph->compound->components[i].u.b.scale10 = words4[2];
2544 glyph->compound->components[i].u.b.yscale = words4[3];
2545 data += sizeof words4;
2546 }
2547
2548 i++;
2549 }
2550 while (flags & 040); /* MORE_COMPONENTS */
2551
2552 if (flags & 0400) /* WE_HAVE_INSTR */
2553 {
2554 /* Figure out the instruction length. */
2555 if (data + 2 > glyf->glyphs + glyf->size)
2556 {
2557 xfree (glyph->compound);
2558 glyph->compound = NULL;
2559 return;
2560 }
2561
2562 /* Now see how much is required to hold the instruction
2563 data. */
2564 memcpy (&glyph->compound->instruction_length,
2565 data,
2566 sizeof glyph->compound->instruction_length);
2567 sfnt_swap16 (&glyph->compound->instruction_length);
2568 data += 2;
2569
2570 /* Read the instructions. */
2571 glyph->compound->instructions = instruction_base;
2572
2573 if (data + glyph->compound->instruction_length
2574 > glyf->glyphs + glyf->size)
2575 {
2576 xfree (glyph->compound);
2577 glyph->compound = NULL;
2578 return;
2579 }
2580
2581 memcpy (instruction_base, data,
2582 glyph->compound->instruction_length);
2583 }
2584 else
2585 {
2586 glyph->compound->instructions = NULL;
2587 glyph->compound->instruction_length = 0;
2588 }
2589
2590 /* Data read successfully. */
2591 return;
2592}
2593
2594/* Read the description of the glyph GLYPH_CODE from the specified
2595 glyf table, using the offsets of LOCA_SHORT or LOCA_LONG, depending
2596 on which is non-NULL. */
2597
2598static struct sfnt_glyph *
2599sfnt_read_glyph (sfnt_glyph glyph_code,
2600 struct sfnt_glyf_table *glyf,
2601 struct sfnt_loca_table_short *loca_short,
2602 struct sfnt_loca_table_long *loca_long)
2603{
2604 struct sfnt_glyph glyph, *memory;
2605 ptrdiff_t offset;
2606
2607 if (loca_short)
2608 {
2609 /* Check that the glyph is within bounds. */
2610 if (glyph_code > loca_short->num_offsets)
2611 return NULL;
2612
2613 offset = loca_short->offsets[glyph_code] * 2;
2614 }
2615 else if (loca_long)
2616 {
2617 if (glyph_code > loca_long->num_offsets)
2618 return NULL;
2619
2620 offset = loca_long->offsets[glyph_code];
2621 }
2622 else
2623 abort ();
2624
2625 /* Verify that GLYF is big enough to hold a glyph at OFFSET. */
2626 if (glyf->size < offset + SFNT_ENDOF (struct sfnt_glyph,
2627 ymax, sfnt_fword))
2628 return NULL;
2629
2630 /* Copy over the glyph data. */
2631 memcpy (&glyph, glyf->glyphs + offset,
2632 SFNT_ENDOF (struct sfnt_glyph,
2633 ymax, sfnt_fword));
2634
2635 /* Swap the glyph data. */
2636 sfnt_swap16 (&glyph.number_of_contours);
2637 sfnt_swap16 (&glyph.xmin);
2638 sfnt_swap16 (&glyph.ymin);
2639 sfnt_swap16 (&glyph.xmax);
2640 sfnt_swap16 (&glyph.ymax);
2641
2642 /* Figure out what needs to be read based on
2643 glyph.number_of_contours. */
2644 if (glyph.number_of_contours >= 0)
2645 {
2646 /* Read the simple glyph. */
2647
2648 glyph.compound = NULL;
2649 sfnt_read_simple_glyph (&glyph, glyf,
2650 offset + SFNT_ENDOF (struct sfnt_glyph,
2651 ymax, sfnt_fword));
2652
2653 if (glyph.simple)
2654 {
2655 memory = xmalloc (sizeof glyph);
2656 *memory = glyph;
2657
2658 return memory;
2659 }
2660 }
2661 else
2662 {
2663 /* Read the compound glyph. */
2664
2665 glyph.simple = NULL;
2666 sfnt_read_compound_glyph (&glyph, glyf,
2667 offset + SFNT_ENDOF (struct sfnt_glyph,
2668 ymax, sfnt_fword));
2669
2670 if (glyph.compound)
2671 {
2672 memory = xmalloc (sizeof glyph);
2673 *memory = glyph;
2674
2675 return memory;
2676 }
2677 }
2678
2679 return NULL;
2680}
2681
2682/* Free a glyph returned from sfnt_read_glyph. GLYPH may be NULL. */
2683
2684static void
2685sfnt_free_glyph (struct sfnt_glyph *glyph)
2686{
2687 if (!glyph)
2688 return;
2689
2690 xfree (glyph->simple);
2691 xfree (glyph->compound);
2692 xfree (glyph);
2693}
2694
2695
2696
2697/* Glyph outline decomposition. */
2698
2699struct sfnt_point
2700{
2701 /* X and Y in em space. */
2702 sfnt_fixed x, y;
2703};
2704
2705typedef void (*sfnt_move_to_proc) (struct sfnt_point, void *);
2706typedef void (*sfnt_line_to_proc) (struct sfnt_point, void *);
2707typedef void (*sfnt_curve_to_proc) (struct sfnt_point,
2708 struct sfnt_point,
2709 void *);
2710
2711typedef struct sfnt_glyph *(*sfnt_get_glyph_proc) (sfnt_glyph, void *,
2712 bool *);
2713typedef void (*sfnt_free_glyph_proc) (struct sfnt_glyph *, void *);
2714
2715/* Apply the transform in the compound glyph component COMPONENT to
2716 the array of points of length NUM_COORDINATES given as X and Y. */
2717
2718static void
2719sfnt_transform_coordinates (struct sfnt_compound_glyph_component *component,
2720 sfnt_fixed *x, sfnt_fixed *y,
2721 size_t num_coordinates)
2722{
2723 double m1, m2, m3;
2724 double m4, m5, m6;
2725 size_t i;
2726
2727 if (component->flags & 010) /* WE_HAVE_A_SCALE */
2728 {
2729 for (i = 0; i < num_coordinates; ++i)
2730 {
2731 x[i] *= component->u.scale / 16384.0;
2732 y[i] *= component->u.scale / 16384.0;
2733 }
2734 }
2735 else if (component->flags & 0100) /* WE_HAVE_AN_X_AND_Y_SCALE */
2736 {
2737 for (i = 0; i < num_coordinates; ++i)
2738 {
2739 x[i] *= component->u.a.xscale / 16384.0;
2740 y[i] *= component->u.a.yscale / 16384.0;
2741 }
2742 }
2743 else if (component->flags & 0200) /* WE_HAVE_A_TWO_BY_TWO */
2744 {
2745 /* Apply the specified affine transformation.
2746 A transform looks like:
2747
2748 M1 M2 M3 X
2749 M4 M5 M6 * Y
2750
2751 =
2752
2753 M1*X + M2*Y + M3*1 = X1
2754 M4*X + M5*Y + M6*1 = Y1
2755
2756 (In most transforms, there is another row at the bottom for
2757 mathematical reasons. Since Z1 is always 1.0, the row is
2758 simply implied to be 0 0 1, because 0 * x + 0 * y + 1 * 1 =
2759 1.0. See the definition of matrix3x3 in image.c for some
2760 more explanations about this.) */
2761 m1 = component->u.b.xscale / 16384.0;
2762 m2 = component->u.b.scale01 / 16384.0;
2763 m3 = 0;
2764 m4 = component->u.b.scale10 / 16384.0;
2765 m5 = component->u.b.yscale / 16384.0;
2766 m6 = 0;
2767
2768 for (i = 0; i < num_coordinates; ++i)
2769 {
2770 x[i] = m1 * x[i] + m2 * y[i] + m3 * 1;
2771 y[i] = m4 * x[i] + m5 * y[i] + m6 * 1;
2772 }
2773 }
2774}
2775
2776struct sfnt_compound_glyph_context
2777{
2778 /* Array of points. */
2779 sfnt_fixed *x_coordinates, *y_coordinates;
2780
2781 /* Array of flags for the points. */
2782 unsigned char *flags;
2783
2784 /* Number of points in that array, and the size of that array. */
2785 size_t num_points, points_size;
2786
2787 /* Array of contour end points. */
2788 ptrdiff_t *contour_end_points;
2789
2790 /* Number of elements in and the size of that array. */
2791 size_t num_end_points, end_points_size;
2792};
2793
2794/* Extend the arrays inside the compound glyph decomposition context
2795 CONTEXT. NUMBER_OF_CONTOURS is the number of contours to add.
2796 NUMBER_OF_POINTS is the number of points to add.
2797
2798 Return pointers to the beginning of the extension in *X_BASE,
2799 *Y_BASE, *FLAGS_BASE and *CONTOUR_BASE. Value zero upon success,
2800 and something else on failure. */
2801
2802static int
2803sfnt_expand_compound_glyph_context (struct sfnt_compound_glyph_context *context,
2804 size_t number_of_contours,
2805 size_t number_of_points,
2806 sfnt_fixed **x_base, sfnt_fixed **y_base,
2807 unsigned char **flags_base,
2808 ptrdiff_t **contour_base)
2809{
2810 size_t size_bytes;
2811
2812 /* Add each field while checking for overflow. */
2813 if (INT_ADD_WRAPV (number_of_contours, context->num_end_points,
2814 &context->num_end_points))
2815 return 1;
2816
2817 if (INT_ADD_WRAPV (number_of_points, context->num_points,
2818 &context->num_points))
2819 return 1;
2820
2821 /* Reallocate each array to the new size if necessary. */
2822 if (context->points_size < context->num_points)
2823 {
2824 if (INT_MULTIPLY_WRAPV (context->num_points, 2,
2825 &context->points_size))
2826 context->points_size = context->num_points;
2827
2828 if (INT_MULTIPLY_WRAPV (context->points_size,
2829 sizeof *context->x_coordinates,
2830 &size_bytes))
2831 return 1;
2832
2833 context->x_coordinates = xrealloc (context->x_coordinates,
2834 size_bytes);
2835 context->y_coordinates = xrealloc (context->y_coordinates,
2836 size_bytes);
2837 context->flags = xrealloc (context->flags, context->num_points);
2838 }
2839
2840 /* Set x_base and y_base. */
2841 *x_base = (context->x_coordinates
2842 + context->num_points
2843 - number_of_points);
2844 *y_base = (context->y_coordinates
2845 + context->num_points
2846 - number_of_points);
2847 *flags_base = (context->flags
2848 + context->num_points
2849 - number_of_points);
2850
2851 if (context->end_points_size < context->num_end_points)
2852 {
2853 if (INT_MULTIPLY_WRAPV (context->num_end_points, 2,
2854 &context->end_points_size))
2855 context->end_points_size = context->num_end_points;
2856
2857 if (INT_MULTIPLY_WRAPV (context->end_points_size,
2858 sizeof *context->contour_end_points,
2859 &size_bytes))
2860 return 1;
2861
2862 context->contour_end_points
2863 = xrealloc (context->contour_end_points,
2864 size_bytes);
2865 }
2866
2867 /* Set contour_base. */
2868 *contour_base = (context->contour_end_points
2869 + context->num_end_points
2870 - number_of_contours);
2871 return 0;
2872}
2873
2874/* Round the 16.16 fixed point number NUMBER to the nearest integral
2875 value. */
2876
2877static int32_t
2878sfnt_round_fixed (int32_t number)
2879{
2880 /* Add 0.5... */
2881 number += (1 << 15);
2882
2883 /* Remove the fractional. */
2884 return number & ~0xffff;
2885}
2886
2887/* Decompose GLYPH, a compound glyph, into an array of points and
2888 contours. CONTEXT should be zeroed and put on the stack. OFF_X
2889 and OFF_Y should be zero, as should RECURSION_COUNT. GET_GLYPH and
2890 FREE_GLYPH, along with DCONTEXT, mean the same as in
2891 sfnt_decompose_glyph. */
2892
2893static int
2894sfnt_decompose_compound_glyph (struct sfnt_glyph *glyph,
2895 struct sfnt_compound_glyph_context *context,
2896 sfnt_get_glyph_proc get_glyph,
2897 sfnt_free_glyph_proc free_glyph,
2898 sfnt_fixed off_x, sfnt_fixed off_y,
2899 int recursion_count,
2900 void *dcontext)
2901{
2902 struct sfnt_glyph *subglyph;
2903 int i, rc;
2904 bool need_free;
2905 struct sfnt_compound_glyph_component *component;
2906 sfnt_fixed x, y, xtemp, ytemp;
2907 ptrdiff_t point, point2, index;
2908 uint16_t last_point, number_of_contours;
2909 sfnt_fixed *x_base, *y_base;
2910 ptrdiff_t *contour_base;
2911 unsigned char *flags_base;
2912 ptrdiff_t base_index, contour_start;
2913
2914 /* Prevent infinite loops. */
2915 if (recursion_count > 12)
2916 return 1;
2917
2918 /* Set up the base index. */
2919 base_index = context->num_points;
2920
2921 for (i = 0; i < glyph->compound->num_components; ++i)
2922 {
2923 /* Look up the associated subglyph. */
2924 component = &glyph->compound->components[i];
2925 subglyph = get_glyph (component->glyph_index,
2926 dcontext, &need_free);
2927
2928 if (!subglyph)
2929 return -1;
2930
2931 /* Compute the offset for the component. */
2932 if (component->flags & 02) /* ARGS_ARE_XY_VALUES */
2933 {
2934 /* Component offsets are X/Y values as opposed to points
2935 GLYPH. */
2936
2937 if (!(component->flags & 01)) /* ARG_1_AND_2_ARE_WORDS */
2938 {
2939 /* X and Y are signed bytes. */
2940 x = component->argument1.b << 16;
2941 y = component->argument2.b << 16;
2942 }
2943 else
2944 {
2945 /* X and Y are signed words. */
2946 x = component->argument1.d << 16;
2947 y = component->argument1.d << 16;
2948 }
2949
2950 /* If there is some kind of scale and component offsets are
2951 scaled, then apply the transform to the offset. */
2952 if (component->flags & 04000) /* SCALED_COMPONENT_OFFSET */
2953 sfnt_transform_coordinates (component, &x, &y, 1);
2954
2955 if (component->flags & 04) /* ROUND_XY_TO_GRID */
2956 {
2957 x = sfnt_round_fixed (x);
2958 y = sfnt_round_fixed (y);
2959 }
2960 }
2961 else
2962 {
2963 /* The offset is determined by matching a point location in
2964 a preceeding component with a point location in the
2965 current component. The index of the point in the
2966 previous component can be determined by adding
2967 component->argument1.a or component->argument1.c to
2968 point. argument2 contains the index of the point in the
2969 current component. */
2970
2971 if (!(component->flags & 01)) /* ARG_1_AND_2_ARE_WORDS */
2972 {
2973 point = base_index + component->argument1.a;
2974 point2 = component->argument2.a;
2975 }
2976 else
2977 {
2978 point = base_index + component->argument1.c;
2979 point2 = component->argument2.c;
2980 }
2981
2982 /* If subglyph is itself a compound glyph, how is Emacs
2983 supposed to compute the offset of its children correctly,
2984 when said offset depends on itself? */
2985
2986 if (subglyph->compound)
2987 {
2988 if (need_free)
2989 free_glyph (subglyph, dcontext);
2990
2991 return 1;
2992 }
2993
2994 /* Check that POINT and POINT2 are valid. */
2995 if (point >= context->num_points
2996 || (subglyph->simple->y_coordinates + point2
2997 >= subglyph->simple->y_coordinates_end))
2998 {
2999 if (need_free)
3000 free_glyph (subglyph, dcontext);
3001
3002 return 1;
3003 }
3004
3005 /* Get the points and use them to compute the offsets. */
3006 xtemp = context->x_coordinates[point];
3007 ytemp = context->y_coordinates[point];
3008 x = (xtemp - subglyph->simple->x_coordinates[point2]) << 16;
3009 y = (ytemp - subglyph->simple->y_coordinates[point2]) << 16;
3010 }
3011
3012 /* Record the size of the point array before expansion. This
3013 will be the base to apply to all points coming from this
3014 subglyph. */
3015 contour_start = context->num_points;
3016
3017 if (subglyph->simple)
3018 {
3019 /* Simple subglyph. Copy over the points and contours, and
3020 transform them. */
3021 if (subglyph->number_of_contours)
3022 {
3023 index = subglyph->number_of_contours - 1;
3024 last_point
3025 = subglyph->simple->end_pts_of_contours[index];
3026 number_of_contours = subglyph->number_of_contours;
3027
3028
3029 /* Grow various arrays. */
3030 rc = sfnt_expand_compound_glyph_context (context,
3031 /* Number of
3032 new contours
3033 required. */
3034 number_of_contours,
3035 /* Number of new
3036 points
3037 required. */
3038 last_point + 1,
3039 &x_base,
3040 &y_base,
3041 &flags_base,
3042 &contour_base);
3043 if (rc)
3044 {
3045 if (need_free)
3046 free_glyph (subglyph, dcontext);
3047
3048 return 1;
3049 }
3050
3051 for (i = 0; i <= last_point; ++i)
3052 {
3053 x_base[i] = ((subglyph->simple->x_coordinates[i] << 16)
3054 + off_x + x);
3055 y_base[i] = ((subglyph->simple->y_coordinates[i] << 16)
3056 + off_y + y);
3057 flags_base[i] = subglyph->simple->flags[i];
3058 }
3059
3060 /* Apply the transform to the points. */
3061 sfnt_transform_coordinates (component, x_base, y_base,
3062 last_point + 1);
3063
3064 /* Copy over the contours. */
3065 for (i = 0; i < number_of_contours; ++i)
3066 contour_base[i] = (contour_start
3067 + subglyph->simple->end_pts_of_contours[i]);
3068 }
3069 }
3070 else
3071 {
3072 /* Compound subglyph. Decompose the glyph recursively, and
3073 then apply the transform. */
3074 rc = sfnt_decompose_compound_glyph (subglyph,
3075 context,
3076 get_glyph,
3077 free_glyph,
3078 off_x + x,
3079 off_y + y,
3080 recursion_count + 1,
3081 dcontext);
3082
3083 if (rc)
3084 {
3085 if (need_free)
3086 free_glyph (subglyph, dcontext);
3087
3088 return 1;
3089 }
3090
3091 sfnt_transform_coordinates (component,
3092 context->x_coordinates + contour_start,
3093 context->y_coordinates + contour_start,
3094 contour_start - context->num_points);
3095 }
3096
3097 if (need_free)
3098 free_glyph (subglyph, dcontext);
3099 }
3100
3101 /* Decomposition is complete. CONTEXT now contains the adjusted
3102 outlines of the entire compound glyph. */
3103 return 0;
3104}
3105
3106/* Linear-interpolate to a point halfway between the points specified
3107 by CONTROL1 and CONTROL2. Put the result in RESULT. */
3108
3109static void
3110sfnt_lerp_half (struct sfnt_point *control1, struct sfnt_point *control2,
3111 struct sfnt_point *result)
3112{
3113 result->x = (control1->x + control2->x) / 2;
3114 result->y = (control1->y + control2->y) / 2;
3115}
3116
3117/* Decompose GLYPH into its individual components. Call MOVE_TO to
3118 move to a specific location. For each line encountered, call
3119 LINE_TO to draw a line to that location. For each spline
3120 encountered, call CURVE_TO to draw the curves comprising the
3121 spline.
3122
3123 If GLYPH is compound, use GET_GLYPH to obtain subglyphs. PROC must
3124 return whether or not FREE_PROC will be called with the glyph after
3125 sfnt_decompose_glyph is done with it.
3126
3127 Both functions will be called with DCONTEXT as an argument.
3128
3129 The winding rule used to fill the resulting lines is described in
3130 chapter 2 of the TrueType reference manual, under the heading
3131 "distinguishing the inside from the outside of a glyph."
3132
3133 Value is 0 upon success, or some non-zero value upon failure, which
3134 can happen if the glyph is invalid. */
3135
3136static int
3137sfnt_decompose_glyph (struct sfnt_glyph *glyph,
3138 sfnt_move_to_proc move_to,
3139 sfnt_line_to_proc line_to,
3140 sfnt_curve_to_proc curve_to,
3141 sfnt_get_glyph_proc get_glyph,
3142 sfnt_free_glyph_proc free_glyph,
3143 void *dcontext)
3144{
3145 size_t here, last;
3146 struct sfnt_point pen, control1, control2;
3147 struct sfnt_compound_glyph_context context;
3148 size_t n;
3149
3150 if (glyph->simple)
3151 {
3152 if (!glyph->number_of_contours)
3153 /* No contours. */
3154 return 1;
3155
3156 here = 0;
3157
3158 for (n = 0; n < glyph->number_of_contours; ++n)
3159 {
3160 /* here is the first index into the glyph's point arrays
3161 belonging to the contour in question. last is the index
3162 of the last point in the contour. */
3163 last = glyph->simple->end_pts_of_contours[n];
3164
3165 /* Move to the start. */
3166 pen.x = glyph->simple->x_coordinates[here] << 16U;
3167 pen.y = glyph->simple->y_coordinates[here] << 16U;
3168 move_to (pen, dcontext);
3169
3170 /* If there is only one point in a contour, draw a one pixel
3171 wide line. */
3172 if (last == here)
3173 {
3174 line_to (pen, dcontext);
3175 here++;
3176
3177 continue;
3178 }
3179
3180 if (here > last)
3181 /* Indices moved backwards. */
3182 return 1;
3183
3184 /* Now start reading points. If the next point is on the
3185 curve, then it is actually a line. */
3186 for (++here; here <= last; ++here)
3187 {
3188 /* Make sure here is within bounds. */
3189 if (here >= glyph->simple->number_of_points)
3190 return 1;
3191
3192 if (glyph->simple->flags[here] & 01) /* On Curve */
3193 {
3194 pen.x = glyph->simple->x_coordinates[here] << 16U;
3195 pen.y = glyph->simple->y_coordinates[here] << 16U;
3196
3197 /* See if the last point was on the curve. If it
3198 wasn't, then curve from there to here. */
3199 if (!(glyph->simple->flags[here - 1] & 01))
3200 {
3201 control1.x
3202 = glyph->simple->x_coordinates[here - 1] << 16U;
3203 control1.y
3204 = glyph->simple->y_coordinates[here - 1] << 16U;
3205 curve_to (control1, pen, dcontext);
3206 }
3207 else
3208 /* Otherwise, this is an ordinary line from there
3209 to here. */
3210 line_to (pen, dcontext);
3211
3212 continue;
3213 }
3214
3215 /* If the last point was on the curve, then there's
3216 nothing extraordinary to do yet. */
3217 if (glyph->simple->flags[here - 1] & 01)
3218 ;
3219 else
3220 {
3221 /* Otherwise, interpolate the point halfway between
3222 the last and current points and make that point
3223 the pen. */
3224 control1.x = glyph->simple->x_coordinates[here - 1] << 16U;
3225 control1.y = glyph->simple->y_coordinates[here - 1] << 16U;
3226 control2.x = glyph->simple->x_coordinates[here] << 16U;
3227 control2.y = glyph->simple->y_coordinates[here] << 16U;
3228 sfnt_lerp_half (&control1, &control2, &pen);
3229 curve_to (control1, pen, dcontext);
3230 }
3231 }
3232 }
3233
3234 return 0;
3235 }
3236
3237 /* Decompose the specified compound glyph. */
3238 memset (&context, 0, sizeof context);
3239
3240 if (sfnt_decompose_compound_glyph (glyph, &context,
3241 get_glyph, free_glyph,
3242 0, 0, 0, dcontext))
3243 {
3244 xfree (context.x_coordinates);
3245 xfree (context.y_coordinates);
3246 xfree (context.flags);
3247 xfree (context.contour_end_points);
3248
3249 return 1;
3250 }
3251
3252 /* Now, generate the outlines. */
3253
3254 if (!context.num_end_points)
3255 /* No contours. */
3256 goto fail;
3257
3258 here = 0;
3259
3260 for (n = 0; n < context.num_end_points; ++n)
3261 {
3262 /* here is the first index into the glyph's point arrays
3263 belonging to the contour in question. last is the index
3264 of the last point in the contour. */
3265 last = context.contour_end_points[n];
3266
3267 /* Move to the start. */
3268 pen.x = context.x_coordinates[here];
3269 pen.y = context.y_coordinates[here];
3270 move_to (pen, dcontext);
3271
3272 /* If there is only one point in a contour, draw a one pixel
3273 wide line. */
3274 if (last == here)
3275 {
3276 line_to (pen, dcontext);
3277 here++;
3278
3279 continue;
3280 }
3281
3282 if (here > last)
3283 /* Indices moved backwards. */
3284 goto fail;
3285
3286 /* Now start reading points. If the next point is on the
3287 curve, then it is actually a line. */
3288 for (++here; here <= last; ++here)
3289 {
3290 /* Make sure here is within bounds. */
3291 if (here >= context.num_points)
3292 return 1;
3293
3294 if (context.flags[here] & 01) /* On Curve */
3295 {
3296 pen.x = context.x_coordinates[here];
3297 pen.y = context.y_coordinates[here];
3298
3299 /* See if the last point was on the curve. If it
3300 wasn't, then curve from there to here. */
3301 if (!(context.flags[here - 1] & 01))
3302 {
3303 control1.x = context.x_coordinates[here - 1];
3304 control1.y = context.y_coordinates[here - 1];
3305 curve_to (control1, pen, dcontext);
3306 }
3307 else
3308 /* Otherwise, this is an ordinary line from there
3309 to here. */
3310 line_to (pen, dcontext);
3311
3312 continue;
3313 }
3314
3315 /* If the last point was on the curve, then there's
3316 nothing extraordinary to do yet. */
3317 if (context.flags[here - 1] & 01)
3318 ;
3319 else
3320 {
3321 /* Otherwise, interpolate the point halfway between
3322 the last and current points and make that point
3323 the pen. */
3324 control1.x = context.x_coordinates[here - 1];
3325 control1.y = context.y_coordinates[here - 1];
3326 control2.x = context.x_coordinates[here];
3327 control2.y = context.y_coordinates[here];
3328 sfnt_lerp_half (&control1, &control2, &pen);
3329 curve_to (control1, pen, dcontext);
3330 }
3331 }
3332 }
3333
3334 xfree (context.x_coordinates);
3335 xfree (context.y_coordinates);
3336 xfree (context.flags);
3337 xfree (context.contour_end_points);
3338 return 0;
3339
3340 fail:
3341 xfree (context.x_coordinates);
3342 xfree (context.y_coordinates);
3343 xfree (context.flags);
3344 xfree (context.contour_end_points);
3345 return 1;
3346}
3347
3348/* Structure describing a single recorded outline in fixed pixel
3349 space. */
3350
3351struct sfnt_glyph_outline
3352{
3353 /* Packed outline data. This is made of aligned, signed, 4 byte
3354 words. The first word is a number containing flags. The second
3355 and third words are a point in 16.16 fixed format. */
3356 int *outline;
3357
3358 /* Size of the outline data in word increments, and how much is
3359 full. */
3360 size_t outline_size, outline_used;
3361
3362 /* Rectangle defining bounds of the outline. Namely, the minimum
3363 and maximum X and Y positions. */
3364 sfnt_fixed xmin, ymin, xmax, ymax;
3365};
3366
3367enum sfnt_glyph_outline_flags
3368 {
3369 SFNT_GLYPH_OUTLINE_LINETO = (1 << 1),
3370 };
3371
3372struct sfnt_build_glyph_outline_context
3373{
3374 /* The outline being built. */
3375 struct sfnt_glyph_outline *outline;
3376
3377 /* The head table. */
3378 struct sfnt_head_table *head;
3379
3380 /* The pixel size being used, and any extra flags to apply to the
3381 outline at this point. */
3382 int pixel_size;
3383
3384 /* Factor to multiply positions by to get the pixel width. */
3385 double factor;
3386
3387 /* The position of the pen in 16.16 fixed point format. */
3388 sfnt_fixed x, y;
3389};
3390
3391/* Global state for sfnt_build_glyph_outline and related
3392 functions. */
3393static struct sfnt_build_glyph_outline_context build_outline_context;
3394
3395/* Append the given three words FLAGS, X, and Y to the outline
3396 currently being built. Value is the new pointer to outline
3397 memory. */
3398
3399static struct sfnt_glyph_outline *
3400sfnt_build_append (unsigned int flags, unsigned int x, unsigned int y)
3401{
3402 struct sfnt_glyph_outline *outline;
3403
3404 if (x == build_outline_context.x
3405 && y == build_outline_context.y)
3406 /* Ignore redundant motion. */
3407 return build_outline_context.outline;
3408
3409 outline = build_outline_context.outline;
3410 outline->outline_used += 3;
3411
3412 /* See if the outline has to be extended. Checking for overflow
3413 should not be necessary. */
3414
3415 if (outline->outline_used > outline->outline_size)
3416 {
3417 outline->outline_size = outline->outline_used * 2;
3418
3419 /* Extend the outline to some size past the new size. */
3420 outline = xrealloc (outline, (sizeof *outline
3421 + (outline->outline_size
3422 * sizeof *outline->outline)));
3423 outline->outline = (int *) (outline + 1);
3424 }
3425
3426 /* Write the outline data. */
3427 outline->outline[outline->outline_used - 3] = flags;
3428 outline->outline[outline->outline_used - 2] = x;
3429 outline->outline[outline->outline_used - 1] = y;
3430
3431 /* Extend outline bounding box. */
3432
3433 if (outline->outline_used == 3)
3434 {
3435 /* These are the first points in the outline. */
3436 outline->xmin = outline->xmax = x;
3437 outline->ymin = outline->ymax = y;
3438 }
3439 else
3440 {
3441 outline->xmin = MIN ((sfnt_fixed) x, outline->xmin);
3442 outline->ymin = MIN ((sfnt_fixed) y, outline->ymin);
3443 outline->xmax = MAX ((sfnt_fixed) x, outline->xmax);
3444 outline->ymax = MAX ((sfnt_fixed) y, outline->ymax);
3445 }
3446
3447 return outline;
3448}
3449
3450/* Set the pen size to the specified point and return. POINT will be
3451 scaled up to the pixel size. */
3452
3453static void
3454sfnt_move_to_and_build (struct sfnt_point point, void *dcontext)
3455{
3456 sfnt_fixed x, y;
3457
3458 x = build_outline_context.factor * point.x;
3459 y = build_outline_context.factor * point.y;
3460
3461 build_outline_context.outline = sfnt_build_append (0, x, y);
3462 build_outline_context.x = x;
3463 build_outline_context.y = y;
3464}
3465
3466/* Record a line to the specified point and return. POINT will be
3467 scaled up to the pixel size. */
3468
3469static void
3470sfnt_line_to_and_build (struct sfnt_point point, void *dcontext)
3471{
3472 sfnt_fixed x, y;
3473
3474 x = build_outline_context.factor * point.x;
3475 y = build_outline_context.factor * point.y;
3476
3477 build_outline_context.outline
3478 = sfnt_build_append (SFNT_GLYPH_OUTLINE_LINETO,
3479 x, y);
3480 build_outline_context.x = x;
3481 build_outline_context.y = y;
3482}
3483
3484/* Multiply the two 16.16 fixed point numbers X and Y. Return the
3485 result regardless of overflow. */
3486
3487static sfnt_fixed
3488sfnt_mul_fixed (sfnt_fixed x, sfnt_fixed y)
3489{
3490#ifdef INT64_MAX
3491 int64_t product;
3492
3493 product = (int64_t) x * (int64_t) y;
3494
3495 /* This can be done quickly with int64_t. */
3496 return product >> 16;
3497#else
3498 int a, b, c, d, product_high;
3499 unsigned int carry, product_low;
3500
3501 a = (x >> 16);
3502 c = (y >> 16);
3503 b = (x & 0xffff);
3504 d = (y & 0xffff);
3505
3506 product_high = a * c + ((a * d + c * b) >> 16);
3507 carry = (a * d + c * b) << 16;
3508 product_low = b * d + carry;
3509
3510 if (product_low < b * d)
3511 product_high++;
3512
3513 return (product_high << 16) | (product_low >> 16);
3514#endif
3515}
3516
3517/* Divide the two 16.16 fixed point numbers X and Y. Return the
3518 result regardless of overflow. */
3519
3520static sfnt_fixed
3521sfnt_div_fixed (sfnt_fixed x, sfnt_fixed y)
3522{
3523#ifdef INT64_MAX
3524 int64_t result;
3525
3526 result = ((int64_t) x << 16) / y;
3527
3528 return result;
3529#else
3530 unsigned int reciprocal;
3531 int product;
3532
3533 reciprocal = 1U << 31;
3534 reciprocal = reciprocal / y;
3535
3536 product = x * reciprocal;
3537
3538 /* This loses one bit at the end. Now to see if anyone runs across
3539 this... */
3540 return product << 1;
3541#endif
3542}
3543
3544/* Return the ceiling value of the specified fixed point number X. */
3545
3546static sfnt_fixed
3547sfnt_ceil_fixed (sfnt_fixed x)
3548{
3549 if (!(x & 0177777))
3550 return x;
3551
3552 return (x + 0200000) & 037777600000;
3553}
3554
3555/* Return the floor value of the specified fixed point number X. */
3556
3557static sfnt_fixed
3558sfnt_floor_fixed (sfnt_fixed x)
3559{
3560 return x & 037777600000;
3561}
3562
3563/* Given a curve consisting of three points CONTROL0, CONTROL1 and
3564 ENDPOINT, return whether or not the curve is sufficiently small to
3565 be approximated by a line between CONTROL0 and ENDPOINT. */
3566
3567static bool
3568sfnt_curve_is_flat (struct sfnt_point control0,
3569 struct sfnt_point control1,
3570 struct sfnt_point endpoint)
3571{
3572 struct sfnt_point g, h;
3573
3574 g.x = control1.x - control0.x;
3575 g.y = control1.y - control0.y;
3576 h.x = endpoint.x - control0.x;
3577 h.y = endpoint.y - control0.y;
3578
3579 /* 2.0 is a constant describing the area covered at which point the
3580 curve is considered "flat". */
3581 return (abs (sfnt_mul_fixed (g.x, h.x)
3582 - sfnt_mul_fixed (g.y, h.y))
3583 <= 0400000);
3584}
3585
3586/* Recursively split the splines in the bezier curve formed from
3587 CONTROL0, CONTROL1 and ENDPOINT until the area between the curve's
3588 two ends is small enough to be considered ``flat''. Then, turn
3589 those ``flat'' curves into lines. */
3590
3591static void
3592sfnt_curve_to_and_build_1 (struct sfnt_point control0,
3593 struct sfnt_point control1,
3594 struct sfnt_point endpoint)
3595{
3596 struct sfnt_point ab;
3597
3598 /* control0, control and endpoint make up the spline. Figure out
3599 its distance from a line. */
3600 if (sfnt_curve_is_flat (control0, control1, endpoint))
3601 {
3602 /* Draw a line to endpoint. */
3603 build_outline_context.outline
3604 = sfnt_build_append (SFNT_GLYPH_OUTLINE_LINETO,
3605 endpoint.x, endpoint.y);
3606 build_outline_context.x = endpoint.x;
3607 build_outline_context.y = endpoint.y;
3608 }
3609 else
3610 {
3611 /* Split the spline between control0 and control1.
3612 Maybe apply a recursion limit here? */
3613 sfnt_lerp_half (&control0, &control1, &ab);
3614
3615 /* Keep splitting until a flat enough spline results. */
3616 sfnt_curve_to_and_build_1 (control0, ab, control1);
3617
3618 /* Then go on with the spline between control1 and endpoint. */
3619 sfnt_curve_to_and_build_1 (ab, control1, endpoint);
3620 }
3621}
3622
3623/* Scale and decompose the specified bezier curve into individual
3624 lines. Then, record each of those lines into the outline being
3625 built. */
3626
3627static void
3628sfnt_curve_to_and_build (struct sfnt_point control,
3629 struct sfnt_point endpoint,
3630 void *dcontext)
3631{
3632 struct sfnt_point control0;
3633
3634 control0.x = build_outline_context.x;
3635 control0.y = build_outline_context.y;
3636 control.x *= build_outline_context.factor;
3637 control.y *= build_outline_context.factor;
3638 endpoint.x *= build_outline_context.factor;
3639 endpoint.y *= build_outline_context.factor;
3640
3641 sfnt_curve_to_and_build_1 (control0, control, endpoint);
3642}
3643
3644/* Non-reentrantly build the outline for the specified GLYPH at the
3645 given pixel size. Return the outline data upon success, or NULL
3646 upon failure.
3647
3648 Call GET_GLYPH and FREE_GLYPH with the specified DCONTEXT to obtain
3649 glyphs for compound glyph subcomponents.
3650
3651 HEAD should be the `head' table of the font. */
3652
3653static struct sfnt_glyph_outline *
3654sfnt_build_glyph_outline (struct sfnt_glyph *glyph,
3655 struct sfnt_head_table *head,
3656 int pixel_size,
3657 sfnt_get_glyph_proc get_glyph,
3658 sfnt_free_glyph_proc free_glyph,
3659 void *dcontext)
3660{
3661 struct sfnt_glyph_outline *outline;
3662 int rc;
3663
3664 /* Allocate the outline now with enough for 44 words at the end. */
3665 outline = xmalloc (sizeof *outline + 44 * sizeof (unsigned int));
3666 outline->outline_size = 44;
3667 outline->outline_used = 0;
3668 outline->outline = (int *) (outline + 1);
3669
3670 /* DCONTEXT will be passed to GET_GLYPH and FREE_GLYPH, so global
3671 variables must be used to communicate with the decomposition
3672 functions. */
3673 build_outline_context.outline = outline;
3674 build_outline_context.head = head;
3675 build_outline_context.pixel_size = pixel_size;
3676
3677 /* Clear outline bounding box. */
3678 outline->xmin = 0;
3679 outline->ymin = 0;
3680 outline->xmax = 0;
3681 outline->ymax = 0;
3682
3683 /* Figure out how to convert from font unit-space to pixel space.
3684 To turn one unit to its corresponding pixel size given a ppem of
3685 1, the unit must be divided by head->units_per_em. Then, it must
3686 be multipled by the ppem. So,
3687
3688 PIXEL = UNIT / UPEM * PPEM
3689
3690 which means:
3691
3692 PIXEL = UNIT * PPEM / UPEM
3693
3694 It would be nice to get rid of this floating point arithmetic at
3695 some point. */
3696 build_outline_context.factor
3697 = (double) pixel_size / head->units_per_em;
3698
3699 /* Decompose the outline. */
3700 rc = sfnt_decompose_glyph (glyph, sfnt_move_to_and_build,
3701 sfnt_line_to_and_build,
3702 sfnt_curve_to_and_build,
3703 get_glyph, free_glyph, dcontext);
3704
3705 /* Synchronize the outline object with what might have changed
3706 inside sfnt_decompose_glyph. */
3707 outline = build_outline_context.outline;
3708
3709 if (rc)
3710 {
3711 xfree (outline);
3712 return NULL;
3713 }
3714
3715 return outline;
3716}
3717
3718
3719
3720/* Glyph rasterization. The algorithm used here is fairly simple.
3721 Each contour is decomposed into lines, which turn into a polygon.
3722 Then, a bog standard edge filler is used to turn them into
3723 spans. */
3724
3725struct sfnt_raster
3726{
3727 /* Basic dimensions of the raster. */
3728 unsigned short width, height;
3729
3730 /* Integer offset to apply to positions in the raster. */
3731 unsigned short offx, offy;
3732
3733 /* Pointer to coverage data. */
3734 unsigned char *cells;
3735};
3736
3737struct sfnt_edge
3738{
3739 /* Next edge in this chain. */
3740 struct sfnt_edge *next;
3741
3742 /* Winding direction. 1 if clockwise, -1 if counterclockwise. */
3743 int winding;
3744
3745 /* inc_x is which direction (left or right) a vector from this edge
3746 to the edge on top goes. */
3747 int inc_x;
3748
3749 /* X position, top and bottom of edges. */
3750 sfnt_fixed x, top, bottom;
3751
3752 /* DX and DY are the total delta between this edge and the next edge
3753 on top. */
3754 sfnt_fixed dx, dy;
3755
3756 /* step_x is how many pixels to move for each increase in Y. */
3757 sfnt_fixed step_x;
3758};
3759
3760enum
3761 {
3762 SFNT_POLY_SHIFT = 2,
3763 SFNT_POLY_SAMPLE = (1 << SFNT_POLY_SHIFT),
3764 SFNT_POLY_MASK = (SFNT_POLY_SAMPLE - 1),
3765 SFNT_POLY_STEP = (0x10000 >> SFNT_POLY_SHIFT),
3766 SFNT_POLY_START = (SFNT_POLY_STEP >> 1),
3767 };
3768
3769/* Coverage table. This is a four dimensional array indiced by the Y,
3770 then X axis fractional, shifted down to 2 bits. */
3771
3772static unsigned char sfnt_poly_coverage[4][4] =
3773 {
3774 { 0x10, 0x10, 0x10, 0x10 },
3775 { 0x10, 0x10, 0x10, 0x10 },
3776 { 0x0f, 0x10, 0x10, 0x10 },
3777 { 0x10, 0x10, 0x10, 0x10 },
3778 };
3779
3780/* Return the nearest coordinate on the sample grid no less than
3781 F. */
3782
3783static sfnt_fixed
3784sfnt_poly_grid_ceil (sfnt_fixed f)
3785{
3786 return (((f + (SFNT_POLY_START - 1))
3787 & ~(SFNT_POLY_STEP - 1)) + SFNT_POLY_START);
3788}
3789
3790/* Initialize the specified RASTER in preparation for displaying spans
3791 for OUTLINE. The caller must then set RASTER->cells to a zeroed
3792 array of size RASTER->width * RASTER->height. */
3793
3794static void
3795sfnt_prepare_raster (struct sfnt_raster *raster,
3796 struct sfnt_glyph_outline *outline)
3797{
3798 raster->width
3799 = sfnt_ceil_fixed (outline->xmax - outline->xmin) >> 16;
3800 raster->height
3801 = sfnt_ceil_fixed (outline->ymax - outline->ymin) >> 16;
3802 raster->offx
3803 = sfnt_floor_fixed (outline->xmin);
3804 raster->offy
3805 = sfnt_floor_fixed (outline->xmax);
3806}
3807
3808typedef void (*sfnt_edge_proc) (struct sfnt_edge *, size_t,
3809 void *);
3810typedef void (*sfnt_span_proc) (struct sfnt_edge *, sfnt_fixed, void *);
3811
3812/* Move EDGE->x forward, assuming that the scanline has moved upwards
3813 by DY. */
3814
3815static void
3816sfnt_step_edge_by (struct sfnt_edge *edge, sfnt_fixed dy)
3817{
3818 /* Step edge. */
3819 edge->x += sfnt_mul_fixed (edge->step_x, dy);
3820}
3821
3822/* Build a list of edges for each contour in OUTLINE, applying
3823 OUTLINE->xmin and OUTLINE->ymin as the offset to each edge. Call
3824 EDGE_PROC with DCONTEXT and the resulting edges as arguments. It
3825 is OK to modify the edges given to EDGE_PROC. Align all edges to
3826 the sub-pixel grid. */
3827
3828static void
3829sfnt_build_outline_edges (struct sfnt_glyph_outline *outline,
3830 sfnt_edge_proc edge_proc, void *dcontext)
3831{
3832 struct sfnt_edge *edges;
3833 size_t i, edge, start, next_vertex, y;
3834
3835 eassert (!(outline->outline_used % 3));
3836
3837 /* outline->outline uses 3 words for each point. */
3838 edges = alloca (outline->outline_used / 3 * sizeof *edges);
3839 edge = 0;
3840
3841 /* First outline currently being processed. */
3842 start = 0;
3843
3844 for (i = 0; i < outline->outline_used; i += 3)
3845 {
3846 if (!(outline->outline[i] & SFNT_GLYPH_OUTLINE_LINETO))
3847 /* Flush the edge. */
3848 start = i;
3849
3850 /* Set NEXT_VERTEX to the next point (vertex) in this contour.
3851 If i + 3 is the end of the contour, then the next point is
3852 its start, so wrap it around to there. */
3853 next_vertex = i + 3;
3854 if (next_vertex == outline->outline_used
3855 || !(outline->outline[next_vertex]
3856 & SFNT_GLYPH_OUTLINE_LINETO))
3857 next_vertex = start;
3858
3859 /* Skip past horizontal vertices. */
3860 if (outline->outline[next_vertex + 2] /* next_vertex->y */
3861 == outline->outline[i + 2])
3862 continue;
3863
3864 /* Figure out the winding direction. */
3865 if (outline->outline[next_vertex + 2] /* next_vertex->y */
3866 < outline->outline[i + 2])
3867 /* Vector will cross imaginary ray from its bottom from the
3868 left of the ray. Winding is thus 1. */
3869 edges[edge].winding = 1;
3870 else
3871 /* Moving clockwise. Winding is thus -1. */
3872 edges[edge].winding = -1;
3873
3874 /* Figure out the top and bottom values of this edge. If the
3875 next edge is below, top is here and bot is the edge below.
3876 If the next edge is above, then top is there and this is the
3877 bottom. */
3878
3879 if (outline->outline[next_vertex + 2] < outline->outline[i + 2])
3880 {
3881 /* Next edge is below this one (keep in mind this is a
3882 cartesian coordinate system, so smaller values are below
3883 larger ones.) */
3884 edges[edge].top = (outline->outline[i + 2]
3885 - outline->ymin);
3886 edges[edge].bottom = (outline->outline[next_vertex + 2]
3887 - outline->ymin);
3888
3889 /* Record the edge. Rasterization happens from bottom to
3890 up, so record the X at the bottom. */
3891 edges[edge].x = (outline->outline[next_vertex + 1]
3892 - outline->xmin);
3893
3894 eassert (edges[edge].top >= edges[edge].bottom);
3895
3896 edges[edge].dx = (outline->outline[i + 1]
3897 - outline->outline[next_vertex + 1]);
3898 }
3899 else
3900 {
3901 /* Next edge is below this one. */
3902 edges[edge].bottom = (outline->outline[i + 2]
3903 - outline->ymin);
3904 edges[edge].top = (outline->outline[next_vertex + 2]
3905 - outline->ymin);
3906
3907 /* Record the edge. Rasterization happens from bottom to
3908 up, so record the X at the bottom. */
3909 edges[edge].x = (outline->outline[i + 1]
3910 - outline->xmin);
3911
3912 eassert (edges[edge].top >= edges[edge].bottom);
3913
3914 edges[edge].dx = (outline->outline[next_vertex + 1]
3915 - outline->outline[i + 1]);
3916 }
3917
3918 edges[edge].dy = abs (outline->outline[i + 2]
3919 - outline->outline[next_vertex + 2]);
3920
3921 /* Compute the increment. This is which direction X moves in
3922 for each increase in Y. */
3923
3924 if (edges[edge].dx >= 0)
3925 edges[edge].inc_x = 1;
3926 else
3927 {
3928 edges[edge].inc_x = -1;
3929 edges[edge].dx = -edges[edge].dx;
3930 }
3931
3932 /* Compute the step X. This is how much X changes for each
3933 increase in Y. */
3934 edges[edge].step_x = (edges[edge].inc_x
3935 * sfnt_div_fixed (edges[edge].dx,
3936 edges[edge].dy));
3937
3938 /* Step to first grid point. */
3939 y = sfnt_poly_grid_ceil (edges[edge].bottom);
3940 sfnt_step_edge_by (&edges[edge], edges[edge].bottom - y);
3941 edges[edge].bottom = y;
3942 edges[edge].next = NULL;
3943
3944 edge++;
3945 }
3946
3947 if (edge)
3948 edge_proc (edges, edge, dcontext);
3949}
3950
3951static int
3952sfnt_compare_edges (const void *a, const void *b)
3953{
3954 const struct sfnt_edge *first, *second;
3955
3956 first = a;
3957 second = b;
3958
3959 return (int) (first->bottom - second->bottom);
3960}
3961
3962/* Draw EDGES, an unsorted array of polygon edges of size SIZE. For
3963 each scanline, call SPAN_FUNC with a list of active edges and
3964 coverage information, and DCONTEXT.
3965
3966 Sort each edge in ascending order by the bottommost Y coordinate to
3967 which it applies. Start a loop on the Y coordinate, which starts
3968 out at that of the bottommost edge. For each iteration, add edges
3969 that now overlap with Y, keeping them sorted by X. Poly those
3970 edges through SPAN_FUNC. Then, move upwards by SFNT_POLY_STEP,
3971 remove edges that no longer apply, and interpolate the remaining
3972 edge's X coordinates. Repeat until all the edges have been polyed.
3973
3974 Or alternatively, think of this as such: each edge is actually a
3975 vector from its bottom position towards its top most position.
3976 Every time Y moves upwards, the position of each edge intersecting
3977 with Y is interpolated and added to a list of spans along with
3978 winding information that is then given to EDGE_FUNC.
3979
3980 Anti-aliasing is performed using a coverage map for fractional
3981 coordinates, and incrementing the Y axis by SFNT_POLY_STEP instead
3982 of 1. SFNT_POLY_STEP is chosen to always keep Y aligned to a grid
3983 placed such that there are always 1 << SFNT_POLY_SHIFT positions
3984 available for each integral pixel coordinate. */
3985
3986static void
3987sfnt_poly_edges (struct sfnt_edge *edges, size_t size,
3988 sfnt_span_proc span_func, void *dcontext)
3989{
3990 sfnt_fixed y;
3991 size_t e;
3992 struct sfnt_edge *active, **prev, *a, *n;
3993
3994 if (!size)
3995 return;
3996
3997 /* Sort edges to ascend by Y-order. Once again, remember: cartesian
3998 coordinates. */
3999 qsort (edges, size, sizeof *edges, sfnt_compare_edges);
4000
4001 /* Step down line by line. Find active edges. */
4002
4003 y = edges[0].bottom;
4004 active = 0;
4005 active = NULL;
4006 e = 0;
4007
4008 for (;;)
4009 {
4010 /* Add in new edges keeping them sorted. */
4011 for (; e < size && edges[e].bottom <= y; ++e)
4012 {
4013 /* Find where to place this edge. */
4014 for (prev = &active; (a = *prev); prev = &(a->next))
4015 {
4016 if (a->x > edges[e].x)
4017 break;
4018 }
4019
4020 edges[e].next = *prev;
4021 *prev = &edges[e];
4022 }
4023
4024 /* Draw this span at the current position. Y axis antialiasing
4025 is expected to be handled by SPAN_FUNC. */
4026 span_func (active, y, dcontext);
4027
4028 /* Compute the next Y position. */
4029 y += SFNT_POLY_STEP;
4030
4031 /* Strip out edges that no longer have effect. */
4032
4033 for (prev = &active; (a = *prev);)
4034 {
4035 if (a->top <= y)
4036 *prev = a->next;
4037 else
4038 prev = &a->next;
4039 }
4040
4041 /* Break if all is done. */
4042 if (!active && e == size)
4043 break;
4044
4045 /* Step all edges. */
4046 for (a = active; a; a = a->next)
4047 sfnt_step_edge_by (a, SFNT_POLY_STEP);
4048
4049 /* Resort on X axis. */
4050 for (prev = &active; (a = *prev) && (n = a->next);)
4051 {
4052 if (a->x > n->x)
4053 {
4054 a->next = n->next;
4055 n->next = a;
4056 *prev = n;
4057 prev = &active;
4058 }
4059 else
4060 prev = &a->next;
4061 }
4062 }
4063}
4064
4065/* Saturate-convert the given unsigned short value X to an unsigned
4066 char. */
4067
4068static unsigned char
4069sfnt_saturate_short (unsigned short x)
4070{
4071 return (unsigned char) ((x) | (0 - ((x) >> 8)));
4072}
4073
4074/* Fill a single span of pixels between X0 and X1 at Y, a raster
4075 coordinate, onto RASTER. */
4076
4077static void
4078sfnt_fill_span (struct sfnt_raster *raster, sfnt_fixed y,
4079 sfnt_fixed x0, sfnt_fixed x1)
4080{
4081 unsigned char *start;
4082 unsigned char *coverage;
4083 sfnt_fixed left, right;
4084 unsigned short w, a;
4085 int row, col;
4086
4087 /* Clip bounds to pixmap. */
4088 if (x0 < 0)
4089 x0 = 0;
4090
4091 if (x1 >= raster->width << 16)
4092 x1 = (raster->width - 1) << 16;
4093
4094 /* Check for empty bounds. */
4095 if (x1 <= x0)
4096 return;
4097
4098 /* Figure out coverage based on Y axis fractional. */
4099 coverage = sfnt_poly_coverage[(y >> (16 - SFNT_POLY_SHIFT))
4100 & SFNT_POLY_MASK];
4101 row = y >> 16;
4102
4103 /* Don't fill out of bounds rows. */
4104 if (row < 0 || row >= raster->height)
4105 return;
4106
4107 /* Set start, then start filling according to coverage. left and
4108 right are now 16.2. */
4109 left = sfnt_poly_grid_ceil (x0) >> (16 - SFNT_POLY_SHIFT);
4110 right = sfnt_poly_grid_ceil (x1) >> (16 - SFNT_POLY_SHIFT);
4111 start = raster->cells + row * raster->width;
4112 start += left >> SFNT_POLY_SHIFT;
4113
4114 /* Compute coverage for first pixel, then poly. */
4115 if (left & SFNT_POLY_MASK)
4116 {
4117 w = 0;
4118
4119 /* Note that col is an index into the columns of the coverage
4120 map, unlike row which indexes the raster. */
4121 col = 0;
4122
4123 while (left < right && (left & SFNT_POLY_MASK))
4124 left++, w += coverage[col++];
4125
4126 a = *start + w;
4127 *start++ = sfnt_saturate_short (a);
4128 }
4129
4130 /* Clear coverage info for first pixel. Compute coverage for center
4131 pixels. */
4132 w = 0;
4133 for (col = 0; col < SFNT_POLY_SAMPLE; ++col)
4134 w += coverage[col];
4135
4136 /* Fill pixels between left and right. */
4137 while (left + SFNT_POLY_MASK < right)
4138 {
4139 a = *start + w;
4140 *start++ = sfnt_saturate_short (a);
4141 left += SFNT_POLY_SAMPLE;
4142 }
4143
4144 /* Fill right pixel if necessary (because it has a fractional
4145 part.) */
4146 if (right & SFNT_POLY_MASK)
4147 {
4148 w = 0;
4149 col = 0;
4150 while (left < right)
4151 left++, w += coverage[col++];
4152 a = *start + w;
4153 *start = sfnt_saturate_short (a);
4154 }
4155
4156 /* All done. */
4157}
4158
4159/* Poly each span starting from START onto RASTER, at position Y. Y
4160 here is still a cartesian coordinate, where the bottom of the
4161 raster is 0. But that is no longer true by the time sfnt_span_fill
4162 is called. */
4163
4164static void
4165sfnt_poly_span (struct sfnt_edge *start, sfnt_fixed y,
4166 struct sfnt_raster *raster)
4167{
4168 struct sfnt_edge *edge;
4169 int winding;
4170 sfnt_fixed x0;
4171
4172 /* Generate the X axis coverage map. Then poly it onto RASTER.
4173 winding on each edge determines the winding direction: when it is
4174 positive, winding is 1. When it is negative, winding is -1. */
4175
4176 winding = 0;
4177
4178 for (edge = start; edge; edge = edge->next)
4179 {
4180 /* Skip out of bounds spans. This ought to go away. */
4181 if (!(y >= edge->bottom && y < edge->top))
4182 continue;
4183
4184 if (!winding)
4185 x0 = edge->x;
4186 else
4187 sfnt_fill_span (raster, (raster->height << 16) - y,
4188 x0, edge->x);
4189
4190 winding += edge->winding;
4191 }
4192}
4193
4194
4195
4196/* Main entry point for outline rasterization. */
4197
4198/* Raster the spans between START and its end to the raster specified
4199 as DCONTEXT. The span's position is Y. */
4200
4201static void
4202sfnt_raster_span (struct sfnt_edge *start, sfnt_fixed y,
4203 void *dcontext)
4204{
4205 sfnt_poly_span (start, y, dcontext);
4206}
4207
4208/* Generate and poly each span in EDGES onto the raster specified as
4209 DCONTEXT. */
4210
4211static void
4212sfnt_raster_edge (struct sfnt_edge *edges, size_t num_edges,
4213 void *dcontext)
4214{
4215 sfnt_poly_edges (edges, num_edges, sfnt_raster_span,
4216 dcontext);
4217}
4218
4219/* Generate an alpha mask for the glyph outline OUTLINE. Value is the
4220 alpha mask upon success, NULL upon failure. */
4221
4222static struct sfnt_raster *
4223sfnt_raster_glyph_outline (struct sfnt_glyph_outline *outline)
4224{
4225 struct sfnt_raster raster, *data;
4226
4227 /* Get the raster parameters. */
4228 sfnt_prepare_raster (&raster, outline);
4229
4230 /* Allocate the raster data. */
4231 data = xmalloc (sizeof *data + raster.width * raster.height);
4232 *data = raster;
4233 data->cells = (unsigned char *) (data + 1);
4234 memset (data->cells, 0, raster.width * raster.height);
4235
4236 /* Generate edges for the outline, polying each array of edges to
4237 the raster. */
4238 sfnt_build_outline_edges (outline, sfnt_raster_edge, data);
4239
4240 /* All done. */
4241 return data;
4242}
4243
4244
4245
4246/* Glyph metrics computation. */
4247
4248struct sfnt_long_hor_metric
4249{
4250 uint16_t advance_width;
4251 int16_t left_side_bearing;
4252};
4253
4254struct sfnt_hmtx_table
4255{
4256 /* Array of horizontal metrics for each glyph. */
4257 struct sfnt_long_hor_metric *h_metrics;
4258
4259 /* Lbearing for remaining glyphs. */
4260 int16_t *left_side_bearing;
4261};
4262
4263/* Structure describing the metrics of a single glyph. The fields
4264 mean the same as in XCharStruct, except they are 16.16 fixed point
4265 values, and are missing significant information. */
4266
4267struct sfnt_glyph_metrics
4268{
4269 /* Distance between origin and left edge of raster. Positive
4270 changes move rightwards. */
4271 sfnt_fixed lbearing;
4272
4273 /* Advance to next glyph's origin. */
4274 sfnt_fixed advance;
4275};
4276
4277/* Read an hmtx table from the font FD, using the table directory
4278 specified as SUBTABLE, the maxp table MAXP, and the hhea table
4279 HHEA.
4280
4281 Return NULL upon failure, and the hmtx table otherwise.
4282 HHEA->num_of_long_hor_metrics determines the number of horizontal
4283 metrics present, and MAXP->num_glyphs -
4284 HHEA->num_of_long_hor_metrics determines the number of left-side
4285 bearings present. */
4286
4287static struct sfnt_hmtx_table *
4288sfnt_read_hmtx_table (int fd, struct sfnt_offset_subtable *subtable,
4289 struct sfnt_hhea_table *hhea,
4290 struct sfnt_maxp_table *maxp)
4291{
4292 struct sfnt_table_directory *directory;
4293 struct sfnt_hmtx_table *hmtx;
4294 size_t size;
4295 ssize_t rc;
4296 int i;
4297
4298 /* Find the table in the directory. */
4299
4300 directory = sfnt_find_table (subtable, SFNT_TABLE_HMTX);
4301
4302 if (!directory)
4303 return NULL;
4304
4305 /* Figure out how many bytes are required. */
4306 size = ((hhea->num_of_long_hor_metrics
4307 * sizeof (struct sfnt_long_hor_metric))
4308 + (MAX (0, ((int) maxp->num_glyphs
4309 - hhea->num_of_long_hor_metrics))
4310 * sizeof (int16_t)));
4311
4312 /* Check the length matches exactly. */
4313 if (directory->length != size)
4314 return NULL;
4315
4316 /* Seek to the location given in the directory. */
4317 if (lseek (fd, directory->offset, SEEK_SET) == (off_t) -1)
4318 return NULL;
4319
4320 /* Now allocate enough to hold all of that along with the table
4321 directory structure. */
4322
4323 hmtx = xmalloc (sizeof *hmtx + size);
4324
4325 /* Read into hmtx + 1. */
4326 rc = read (fd, hmtx + 1, size);
4327 if (rc < size)
4328 {
4329 xfree (hmtx);
4330 return NULL;
4331 }
4332
4333 /* Set pointers to data. */
4334 hmtx->h_metrics = (struct sfnt_long_hor_metric *) (hmtx + 1);
4335 hmtx->left_side_bearing
4336 = (int16_t *) (hmtx->h_metrics
4337 + hhea->num_of_long_hor_metrics);
4338
4339 /* Swap what was read. */
4340
4341 for (i = 0; i < hhea->num_of_long_hor_metrics; ++i)
4342 {
4343 sfnt_swap16 (&hmtx->h_metrics[i].advance_width);
4344 sfnt_swap16 (&hmtx->h_metrics[i].left_side_bearing);
4345 }
4346
4347 for (; i <= maxp->num_glyphs; ++i)
4348 sfnt_swap16 (&hmtx->left_side_bearing[i]);
4349
4350 /* All done. */
4351 return hmtx;
4352}
4353
4354/* Obtain glyph metrics for the glyph indiced by GLYPH at the
4355 specified PIXEL_SIZE. Return 0 and the metrics in *METRICS if
4356 metrics could be found, else 1.
4357
4358 HMTX, HHEA, HEAD and MAXP should be the hmtx, hhea, head, and maxp
4359 tables of the font respectively. */
4360
4361static int
4362sfnt_lookup_glyph_metrics (sfnt_glyph glyph, int pixel_size,
4363 struct sfnt_glyph_metrics *metrics,
4364 struct sfnt_hmtx_table *hmtx,
4365 struct sfnt_hhea_table *hhea,
4366 struct sfnt_head_table *head,
4367 struct sfnt_maxp_table *maxp)
4368{
4369 short lbearing;
4370 unsigned short advance;
4371 sfnt_fixed factor;
4372
4373 if (glyph < hhea->num_of_long_hor_metrics)
4374 {
4375 /* There is a long entry in the hmtx table. */
4376 lbearing = hmtx->h_metrics[glyph].left_side_bearing;
4377 advance = hmtx->h_metrics[glyph].advance_width;
4378 }
4379 else if (hhea->num_of_long_hor_metrics
4380 && glyph <= maxp->num_glyphs)
4381 {
4382 /* There is a short entry in the hmtx table. */
4383 lbearing
4384 = hmtx->left_side_bearing[glyph
4385 - hhea->num_of_long_hor_metrics];
4386 advance
4387 = hmtx->h_metrics[hhea->num_of_long_hor_metrics - 1].advance_width;
4388 }
4389 else
4390 /* No entry corresponds to the glyph. */
4391 return 1;
4392
4393 /* Now scale lbearing and advance up to the pixel size. */
4394 factor = sfnt_div_fixed (pixel_size << 16,
4395 head->units_per_em << 16);
4396
4397 /* Save them. */
4398 metrics->lbearing = sfnt_mul_fixed (lbearing << 16, factor);
4399 metrics->advance = sfnt_mul_fixed (advance << 16, factor);
4400
4401 /* All done. */
4402 return 0;
4403}
4404
4405
4406
4407#ifdef TEST
4408
4409struct sfnt_test_dcontext
4410{
4411 /* Context for sfnt_test_get_glyph. */
4412 struct sfnt_glyf_table *glyf;
4413 struct sfnt_loca_table_short *loca_short;
4414 struct sfnt_loca_table_long *loca_long;
4415};
4416
4417/* Global context for test functions. Height of glyph. */
4418static sfnt_fixed sfnt_test_max;
4419
4420static void
4421sfnt_test_move_to (struct sfnt_point point, void *dcontext)
4422{
4423 printf ("move_to: %g, %g\n", sfnt_coerce_fixed (point.x),
4424 sfnt_coerce_fixed (point.y));
4425}
4426
4427static void
4428sfnt_test_line_to (struct sfnt_point point, void *dcontext)
4429{
4430 printf ("line_to: %g, %g\n", sfnt_coerce_fixed (point.x),
4431 sfnt_coerce_fixed (point.y));
4432}
4433
4434static void
4435sfnt_test_curve_to (struct sfnt_point control,
4436 struct sfnt_point endpoint,
4437 void *dcontext)
4438{
4439 printf ("curve_to: %g, %g - %g, %g\n",
4440 sfnt_coerce_fixed (control.x),
4441 sfnt_coerce_fixed (control.y),
4442 sfnt_coerce_fixed (endpoint.x),
4443 sfnt_coerce_fixed (endpoint.y));
4444}
4445
4446static struct sfnt_glyph *
4447sfnt_test_get_glyph (sfnt_glyph glyph, void *dcontext,
4448 bool *need_free)
4449{
4450 struct sfnt_test_dcontext *tables;
4451
4452 tables = dcontext;
4453 *need_free = true;
4454
4455 return sfnt_read_glyph (glyph, tables->glyf,
4456 tables->loca_short,
4457 tables->loca_long);
4458}
4459
4460static void
4461sfnt_test_free_glyph (struct sfnt_glyph *glyph, void *dcontext)
4462{
4463 sfnt_free_glyph (glyph);
4464}
4465
4466static void
4467sfnt_test_span (struct sfnt_edge *edge, sfnt_fixed y,
4468 void *dcontext)
4469{
4470#if 0
4471 printf ("/* span at %g */\n", sfnt_coerce_fixed (y));
4472 for (; edge; edge = edge->next)
4473 {
4474 if (y >= edge->bottom && y < edge->top)
4475 printf ("ctx.fillRect (%g, %g, 1, 1); "
4476 "/* %g top: %g bot: %g stepx: %g */\n",
4477 sfnt_coerce_fixed (edge->x),
4478 sfnt_coerce_fixed (sfnt_test_max - y),
4479 sfnt_coerce_fixed (y),
4480 sfnt_coerce_fixed (edge->bottom),
4481 sfnt_coerce_fixed (edge->top),
4482 sfnt_coerce_fixed (edge->step_x));
4483 }
4484#elif 0
4485 int winding;
4486 short x, dx;
4487
4488 winding = 0;
4489 x = 0;
4490
4491 for (; edge; edge = edge->next)
4492 {
4493 dx = (edge->x >> 16) - x;
4494 x = edge->x >> 16;
4495
4496 for (; dx > 0; --dx)
4497 putc (winding ? '.' : ' ', stdout);
4498
4499 winding = !winding;
4500 }
4501
4502 putc ('\n', stdout);
4503#elif 0
4504 for (; edge; edge = edge->next)
4505 printf ("%g-", sfnt_coerce_fixed (edge->x));
4506 puts ("");
4507#endif
4508}
4509
4510static void
4511sfnt_test_edge (struct sfnt_edge *edges, size_t num_edges,
4512 void *dcontext)
4513{
4514 size_t i;
4515
4516 printf ("built %zu edges\n", num_edges);
4517
4518 for (i = 0; i < num_edges; ++i)
4519 {
4520 printf ("/* edge x, top, bot: %g, %g - %g. winding: %d */\n",
4521 sfnt_coerce_fixed (edges[i].x),
4522 sfnt_coerce_fixed (edges[i].top),
4523 sfnt_coerce_fixed (edges[i].bottom),
4524 edges[i].winding);
4525#ifdef TEST_VERTEX
4526 printf ("ctx.fillRect (%g, %g, 1, 1);\n",
4527 sfnt_coerce_fixed (edges[i].x),
4528 sfnt_coerce_fixed (sfnt_test_max
4529 - edges[i].y));
4530#endif
4531 }
4532
4533 printf ("==end of edges==\n");
4534
4535 sfnt_poly_edges (edges, num_edges, sfnt_test_span, NULL);
4536}
4537
4538static void
4539sfnt_test_raster (struct sfnt_raster *raster)
4540{
4541 int x, y;
4542
4543 for (y = 0; y < raster->height; ++y)
4544 {
4545 for (x = 0; x < raster->width; ++x)
4546 printf ("%3d ", (int) raster->cells[y * raster->width + x]);
4547 puts ("");
4548 }
4549}
4550
4551/* Simple tests that were used while developing this file. By the
4552 time you are reading this, they probably no longer work.
4553
4554 Compile like so in this directory:
4555
4556 gcc -Demacs -I. -I. -I../lib -I../lib -MMD -MF deps/.d -MP
4557 -fno-common -Wall -Warith-conversion -Wdate-time
4558 -Wdisabled-optimization -Wdouble-promotion -Wduplicated-cond
4559 -Wextra -Wformat-signedness -Winit-self -Winvalid-pch -Wlogical-op
4560 -Wmissing-declarations -Wmissing-include-dirs -Wmissing-prototypes
4561 -Wnested-externs -Wnull-dereference -Wold-style-definition
4562 -Wopenmp-simd -Wpacked -Wpointer-arith -Wstrict-prototypes
4563 -Wsuggest-attribute=format -Wsuggest-final-methods
4564 -Wsuggest-final-types -Wtrampolines -Wuninitialized
4565 -Wunknown-pragmas -Wunused-macros -Wvariadic-macros
4566 -Wvector-operation-performance -Wwrite-strings -Warray-bounds=2
4567 -Wattribute-alias=2 -Wformat=2 -Wformat-truncation=2
4568 -Wimplicit-fallthrough=5 -Wshift-overflow=2 -Wuse-after-free=3
4569 -Wvla-larger-than=4031 -Wredundant-decls
4570 -Wno-missing-field-initializers -Wno-override-init
4571 -Wno-sign-compare -Wno-type-limits -Wno-unused-parameter
4572 -Wno-format-nonliteral -Wno-bidi-chars -g3 -O0 -DTEST sfnt.c -o
4573 sfnt ../lib/libgnu.a
4574
4575 after gnulib has been built. Then, run ./sfnt
4576 /path/to/font.ttf. */
4577
4578int
4579main (int argc, char **argv)
4580{
4581 struct sfnt_offset_subtable *font;
4582 struct sfnt_cmap_encoding_subtable *subtables;
4583 struct sfnt_cmap_encoding_subtable_data **data;
4584 struct sfnt_cmap_table *table;
4585 int fd, i;
4586 sfnt_char character;
4587 struct sfnt_head_table *head;
4588 struct sfnt_hhea_table *hhea;
4589 struct sfnt_loca_table_short *loca_short;
4590 struct sfnt_loca_table_long *loca_long;
4591 struct sfnt_glyf_table *glyf;
4592 struct sfnt_glyph *glyph;
4593 sfnt_glyph code;
4594 struct sfnt_test_dcontext dcontext;
4595 struct sfnt_glyph_outline *outline;
4596 struct timespec start, end, sub, sub1;
4597 static struct sfnt_maxp_table *maxp;
4598 struct sfnt_raster *raster;
4599 struct sfnt_hmtx_table *hmtx;
4600 struct sfnt_glyph_metrics metrics;
4601
4602 if (argc != 2)
4603 return 1;
4604
4605 fd = open (argv[1], O_RDONLY);
4606
4607 if (fd < 1)
4608 return 1;
4609
4610 font = sfnt_read_table_directory (fd);
4611
4612 if (!font)
4613 {
4614 close (fd);
4615 return 1;
4616 }
4617
4618 for (i = 0; i < font->num_tables; ++i)
4619 fprintf (stderr, "Found new subtable with tag %"PRIx32
4620 " at offset %"PRIu32"\n",
4621 font->subtables[i].tag,
4622 font->subtables[i].offset);
4623
4624 table = sfnt_read_cmap_table (fd, font, &subtables, &data);
4625
4626 if (!table)
4627 {
4628 close (fd);
4629 xfree (font);
4630 return 1;
4631 }
4632
4633 for (i = 0; i < table->num_subtables; ++i)
4634 {
4635 fprintf (stderr, "Found cmap table %"PRIu32": %p\n",
4636 subtables[i].offset, data);
4637
4638 if (data)
4639 fprintf (stderr, " format: %"PRIu16"\n",
4640 data[i]->format);
4641 }
4642
4643 head = sfnt_read_head_table (fd, font);
4644 hhea = sfnt_read_hhea_table (fd, font);
4645 glyf = sfnt_read_glyf_table (fd, font);
4646 maxp = sfnt_read_maxp_table (fd, font);
4647 hmtx = NULL;
4648
4649 if (hhea && maxp)
4650 hmtx = sfnt_read_hmtx_table (fd, font, hhea, maxp);
4651
4652 if (maxp)
4653 fprintf (stderr, "maxp says num glyphs is %"PRIu16"\n",
4654 maxp->num_glyphs);
4655
4656 loca_long = NULL;
4657 loca_short = NULL;
4658
4659 if (head)
4660 {
4661 fprintf (stderr, "HEAD table:\n"
4662 "version: \t\t\t%g\n"
4663 "revision: \t\t\t%g\n"
4664 "checksum_adjustment: \t\t%"PRIu32"\n"
4665 "magic: \t\t\t\t%"PRIx32"\n"
4666 "flags: \t\t\t\t%"PRIx16"\n"
4667 "units_per_em: \t\t\t%"PRIx16"\n"
4668 "xmin, ymin, xmax, ymax: \t%d, %d, %d, %d\n"
4669 "mac_style: \t\t\t%"PRIx16"\n"
4670 "lowest_rec_ppem: \t\t%"PRIu16"\n"
4671 "font_direction_hint: \t\t%"PRIi16"\n"
4672 "index_to_loc_format: \t\t%"PRIi16"\n"
4673 "glyph_data_format: \t\t%"PRIi16"\n",
4674 sfnt_coerce_fixed (head->version),
4675 sfnt_coerce_fixed (head->revision),
4676 head->checksum_adjustment,
4677 head->magic,
4678 head->flags,
4679 head->units_per_em,
4680 (int) head->xmin,
4681 (int) head->ymin,
4682 (int) head->xmax,
4683 (int) head->ymax,
4684 head->mac_style,
4685 head->lowest_rec_ppem,
4686 head->font_direction_hint,
4687 head->index_to_loc_format,
4688 head->glyph_data_format);
4689
4690 if (head->index_to_loc_format)
4691 {
4692 loca_long = sfnt_read_loca_table_long (fd, font);
4693 if (!loca_long)
4694 return 1;
4695
4696 fprintf (stderr, "long loca table has %zu glyphs\n",
4697 loca_long->num_offsets);
4698 }
4699 else
4700 {
4701 loca_short = sfnt_read_loca_table_short (fd, font);
4702 if (!loca_short)
4703 return 1;
4704
4705 fprintf (stderr, "short loca table has %zu glyphs\n",
4706 loca_short->num_offsets);
4707 }
4708 }
4709
4710 if (hhea)
4711 fprintf (stderr, "HHEA table:\n"
4712 "version: \t\t\t%g\n"
4713 "ascent, descent: \t\t%d %d\n"
4714 "line_gap: \t\t\t%d\n"
4715 "advance_width_max: \t\t%u\n"
4716 "min_lsb: \t\t\t%d\n"
4717 "min_rsb: \t\t\t%d\n"
4718 "caret_srise: \t\t\t%d\n"
4719 "caret_srun: \t\t\t%d\n",
4720 sfnt_coerce_fixed (hhea->version),
4721 (int) hhea->ascent,
4722 (int) hhea->descent,
4723 (int) hhea->line_gap,
4724 (unsigned int) hhea->advance_width_max,
4725 (int) hhea->min_left_side_bearing,
4726 (int) hhea->min_right_side_bearing,
4727 (int) hhea->caret_slope_rise,
4728 (int) hhea->caret_slope_run);
4729
4730 while (true)
4731 {
4732 printf ("table, character? ");
4733
4734 if (scanf ("%d %"SCNu32"", &i, &character) == EOF)
4735 break;
4736
4737 if (i >= table->num_subtables)
4738 {
4739 printf ("table out of range\n");
4740 continue;
4741 }
4742
4743 if (!data[i])
4744 {
4745 printf ("table not present\n");
4746 continue;
4747 }
4748
4749 code = sfnt_lookup_glyph (character, data[i]);
4750 printf ("glyph is %"PRIu32"\n", code);
4751
4752 if ((loca_long || loca_short) && glyf)
4753 {
4754 glyph = sfnt_read_glyph (code, glyf, loca_short,
4755 loca_long);
4756
4757 if (glyph)
4758 {
4759 printf ("glyph is: %s\n",
4760 glyph->simple ? "simple" : "compound");
4761
4762 dcontext.glyf = glyf;
4763 dcontext.loca_short = loca_short;
4764 dcontext.loca_long = loca_long;
4765
4766 if (sfnt_decompose_glyph (glyph, sfnt_test_move_to,
4767 sfnt_test_line_to,
4768 sfnt_test_curve_to,
4769 sfnt_test_get_glyph,
4770 sfnt_test_free_glyph,
4771 &dcontext))
4772 printf ("decomposition failure\n");
4773
4774 /* Time this important bit. */
4775 clock_gettime (CLOCK_THREAD_CPUTIME_ID, &start);
4776 outline = sfnt_build_glyph_outline (glyph, head,
4777 40,
4778 sfnt_test_get_glyph,
4779 sfnt_test_free_glyph,
4780 &dcontext);
4781
4782 clock_gettime (CLOCK_THREAD_CPUTIME_ID, &end);
4783 sub = timespec_sub (end, start);
4784 memset (&sub1, 0, sizeof sub1);
4785
4786 if (outline)
4787 {
4788 sfnt_test_max = outline->ymax - outline->ymin;
4789
4790 for (i = 0; i < outline->outline_used; i += 3)
4791 {
4792 printf ("ctx.%s (%g, %g) /* %g, %g */\n",
4793 (outline->outline[i] & SFNT_GLYPH_OUTLINE_LINETO
4794 ? "lineTo" : "moveTo"),
4795 sfnt_coerce_fixed (outline->outline[i + 1]
4796 - outline->xmin),
4797 sfnt_coerce_fixed (sfnt_test_max
4798 - (outline->outline[i + 2]
4799 - outline->ymin)),
4800 sfnt_coerce_fixed (outline->outline[i + 1]
4801 - outline->xmin),
4802 sfnt_coerce_fixed (outline->outline[i + 2]
4803 - outline->ymin));
4804 }
4805
4806 sfnt_build_outline_edges (outline, sfnt_test_edge,
4807 NULL);
4808
4809 clock_gettime (CLOCK_THREAD_CPUTIME_ID, &start);
4810 raster = sfnt_raster_glyph_outline (outline);
4811 clock_gettime (CLOCK_THREAD_CPUTIME_ID, &end);
4812 sub1 = timespec_sub (end, start);
4813
4814 /* Print out the raster. */
4815 sfnt_test_raster (raster);
4816
4817 xfree (raster);
4818
4819 printf ("outline bounds: %g %g, %g %g\n",
4820 sfnt_coerce_fixed (outline->xmin),
4821 sfnt_coerce_fixed (outline->ymin),
4822 sfnt_coerce_fixed (outline->xmax),
4823 sfnt_coerce_fixed (outline->ymax));
4824 }
4825
4826 if (hmtx && head)
4827 {
4828 if (!sfnt_lookup_glyph_metrics (code, 40,
4829 &metrics,
4830 hmtx, hhea,
4831 head, maxp))
4832 printf ("lbearing, advance: %g, %g\n",
4833 sfnt_coerce_fixed (metrics.lbearing),
4834 sfnt_coerce_fixed (metrics.advance));
4835 }
4836
4837 printf ("time spent outlining: %lld sec %ld nsec\n",
4838 (long long) sub.tv_sec, sub.tv_nsec);
4839 printf ("time spent rasterizing: %lld sec %ld nsec\n",
4840 (long long) sub1.tv_sec, sub1.tv_nsec);
4841
4842 xfree (outline);
4843 }
4844
4845 sfnt_free_glyph (glyph);
4846 }
4847 }
4848
4849 xfree (font);
4850
4851 for (i = 0; i < table->num_subtables; ++i)
4852 xfree (data[i]);
4853
4854 xfree (table);
4855 xfree (data);
4856 xfree (subtables);
4857 xfree (head);
4858 xfree (hhea);
4859 xfree (loca_long);
4860 xfree (loca_short);
4861 xfree (glyf);
4862 xfree (maxp);
4863 xfree (hmtx);
4864
4865 return 0;
4866}
4867
4868#endif