aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPo Lu2023-01-08 15:43:09 +0800
committerPo Lu2023-01-08 15:43:09 +0800
commitee256d1e25b8ab080a2715c5fc792fee516e83d1 (patch)
treec1df5a4864de6a6640cbbb1f33e52432c45048ea /src
parent1584a58efd63d6806dbff51adcbfec054533b316 (diff)
downloademacs-ee256d1e25b8ab080a2715c5fc792fee516e83d1.tar.gz
emacs-ee256d1e25b8ab080a2715c5fc792fee516e83d1.zip
Check in new files
* src/sfnt.h: * src/sfntfont-android.c: * src/sfntfont.c: * src/sfntfont.h: New files.
Diffstat (limited to 'src')
-rw-r--r--src/sfnt.h957
-rw-r--r--src/sfntfont-android.c36
-rw-r--r--src/sfntfont.c493
-rw-r--r--src/sfntfont.h26
4 files changed, 1512 insertions, 0 deletions
diff --git a/src/sfnt.h b/src/sfnt.h
new file mode 100644
index 00000000000..868d0f9b5a9
--- /dev/null
+++ b/src/sfnt.h
@@ -0,0 +1,957 @@
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#ifndef _SFNT_H_
22#define _SFNT_H_
23
24#include <stdint.h>
25#include <stddef.h>
26
27
28
29/* Container structure and enumerator definitions. */
30
31/* The sfnt container format is organized into different tables, such
32 as ``cmap'' or ``glyf''. Each of these tables has a specific
33 format and use. These are all the tables known to Emacs. */
34
35enum sfnt_table
36 {
37 SFNT_TABLE_CMAP,
38 SFNT_TABLE_GLYF,
39 SFNT_TABLE_HEAD,
40 SFNT_TABLE_HHEA,
41 SFNT_TABLE_HMTX,
42 SFNT_TABLE_LOCA,
43 SFNT_TABLE_MAXP,
44 SFNT_TABLE_NAME,
45 SFNT_TABLE_META,
46 };
47
48#define SFNT_ENDOF(type, field, type1) \
49 ((size_t) offsetof (type, field) + sizeof (type1))
50
51/* Each of these structures must be aligned so that no compiler will
52 ever generate padding bytes on platforms where the alignment
53 requirements for uint32_t and uint16_t are no larger than 4 and 2
54 bytes respectively. */
55
56struct sfnt_offset_subtable
57{
58 /* The scaler type. */
59 uint32_t scaler_type;
60
61 /* The number of tables. */
62 uint16_t num_tables;
63
64 /* (Maximum power of 2 <= numTables) * 16. */
65 uint16_t search_range;
66
67 /* log2 (maximum power of 2 <= numTables) */
68 uint16_t entry_selector;
69
70 /* numTables * 16 - searchRange. */
71 uint16_t range_shift;
72
73 /* Variable length data. */
74 struct sfnt_table_directory *subtables;
75};
76
77/* The table directory. Follows the offset subtable, with one for
78 each table. */
79
80struct sfnt_table_directory
81{
82 /* 4-byte identifier for each table. See sfnt_table_names. */
83 uint32_t tag;
84
85 /* Table checksum. */
86 uint32_t checksum;
87
88 /* Offset from the start of the file. */
89 uint32_t offset;
90
91 /* Length of the table in bytes, not subject to padding. */
92 uint32_t length;
93};
94
95enum sfnt_scaler_type
96 {
97 SFNT_SCALER_TRUE = 0x74727565,
98 SFNT_SCALER_VER1 = 0x00010000,
99 SFNT_SCALER_TYP1 = 0x74797031,
100 SFNT_SCALER_OTTO = 0x4F54544F,
101 };
102
103typedef int32_t sfnt_fixed;
104typedef int16_t sfnt_fword;
105typedef uint16_t sfnt_ufword;
106
107#define sfnt_coerce_fixed(fixed) ((sfnt_fixed) (fixed) / 65535.0)
108
109typedef unsigned int sfnt_glyph;
110typedef unsigned int sfnt_char;
111
112struct sfnt_head_table
113{
114 /* The version. This is a 16.16 fixed point number. */
115 sfnt_fixed version;
116
117 /* The revision. */
118 sfnt_fixed revision;
119
120 /* Checksum adjustment. */
121 uint32_t checksum_adjustment;
122
123 /* Magic number, should be 0x5F0F3CF5. */
124 uint32_t magic;
125
126 /* Flags for the font. */
127 uint16_t flags;
128
129 /* Units per em. */
130 uint16_t units_per_em;
131
132 /* Time of creation. */
133 uint32_t created_high, created_low;
134
135 /* Time of modification. */
136 uint32_t modified_high, modified_low;
137
138 /* Minimum bounds. */
139 sfnt_fword xmin, ymin, xmax, ymax;
140
141 /* Mac specific stuff. */
142 uint16_t mac_style;
143
144 /* Smallest readable size in pixels. */
145 uint16_t lowest_rec_ppem;
146
147 /* Font direction hint. */
148 int16_t font_direction_hint;
149
150 /* Index to loc format. 0 for short offsets, 1 for long. */
151 int16_t index_to_loc_format;
152
153 /* Unused. */
154 int16_t glyph_data_format;
155};
156
157struct sfnt_hhea_table
158{
159 /* The version. This is a 16.16 fixed point number. */
160 sfnt_fixed version;
161
162 /* The maximum ascent and descent values for this font. */
163 sfnt_fword ascent, descent;
164
165 /* The typographic line gap. */
166 sfnt_fword line_gap;
167
168 /* The maximum advance width. */
169 sfnt_ufword advance_width_max;
170
171 /* The minimum bearings on either side. */
172 sfnt_fword min_left_side_bearing, min_right_side_bearing;
173
174 /* The maximum extent. */
175 sfnt_fword x_max_extent;
176
177 /* Caret slope. */
178 int16_t caret_slope_rise, caret_slope_run;
179
180 /* Caret offset for non slanted fonts. */
181 sfnt_fword caret_offset;
182
183 /* Reserved values. */
184 int16_t reserved1, reserved2, reserved3, reserved4;
185
186 /* Should always be zero. */
187 int16_t metric_data_format;
188
189 /* Number of advanced widths in metrics table. */
190 uint16_t num_of_long_hor_metrics;
191};
192
193struct sfnt_cmap_table
194{
195 /* Should be zero. */
196 uint16_t version;
197
198 /* Number of subtables. */
199 uint16_t num_subtables;
200};
201
202enum sfnt_platform_id
203 {
204 SFNT_PLATFORM_UNICODE = 0,
205 SFNT_PLATFORM_MACINTOSH = 1,
206 SFNT_PLATFORM_RESERVED = 2,
207 SFNT_PLATFORM_MICROSOFT = 3,
208 };
209
210enum sfnt_unicode_platform_specific_id
211 {
212 SFNT_UNICODE_1_0 = 0,
213 SFNT_UNICODE_1_1 = 1,
214 SFNT_UNICODE_ISO_10646_1993 = 2,
215 SFNT_UNICODE_2_0_BMP = 3,
216 SFNT_UNICODE_2_0 = 4,
217 SFNT_UNICODE_VARIATION_SEQUENCES = 5,
218 SFNT_UNICODE_LAST_RESORT = 6,
219 };
220
221enum sfnt_macintosh_platform_specific_id
222 {
223 SFNT_MACINTOSH_ROMAN = 0,
224 SFNT_MACINTOSH_JAPANESE = 1,
225 SFNT_MACINTOSH_TRADITIONAL_CHINESE = 2,
226 SFNT_MACINTOSH_KOREAN = 3,
227 SFNT_MACINTOSH_ARABIC = 4,
228 SFNT_MACINTOSH_HEBREW = 5,
229 SFNT_MACINTOSH_GREEK = 6,
230 SFNT_MACINTOSH_RUSSIAN = 7,
231 SFNT_MACINTOSH_RSYMBOL = 8,
232 SFNT_MACINTOSH_DEVANGARI = 9,
233 SFNT_MACINTOSH_GURMUKHI = 10,
234 SFNT_MACINTOSH_GUJARATI = 11,
235 SFNT_MACINTOSH_ORIYA = 12,
236 SFNT_MACINTOSH_BENGALI = 13,
237 SFNT_MACINTOSH_TAMIL = 14,
238 SFNT_MACINTOSH_TELUGU = 15,
239 SFNT_MACINTOSH_KANNADA = 16,
240 SFNT_MACINTOSH_MALAYALAM = 17,
241 SFNT_MACINTOSH_SINHALESE = 18,
242 SFNT_MACINTOSH_BURMESE = 19,
243 SFNT_MACINTOSH_KHMER = 20,
244 SFNT_MACINTOSH_THAI = 21,
245 SFNT_MACINTOSH_LAOTIAN = 22,
246 SFNT_MACINTOSH_GEORGIAN = 23,
247 SFNT_MACINTOSH_ARMENIAN = 24,
248 SFNT_MACINTOSH_SIMPLIFIED_CHINESE = 25,
249 SFNT_MACINTOSH_TIBETIAN = 26,
250 SFNT_MACINTOSH_MONGOLIAN = 27,
251 SFNT_MACINTOSH_GEEZ = 28,
252 SFNT_MACINTOSH_SLAVIC = 29,
253 SFNT_MACINTOSH_VIETNAMESE = 30,
254 SFNT_MACINTOSH_SINDHI = 31,
255 SFNT_MACINTOSH_UNINTERPRETED = 32,
256 };
257
258enum sfnt_microsoft_platform_specific_id
259 {
260 SFNT_MICROSOFT_SYMBOL = 0,
261 SFNT_MICROSOFT_UNICODE_BMP = 1,
262 SFNT_MICROSOFT_SHIFT_JIS = 2,
263 SFNT_MICROSOFT_PRC = 3,
264 SFNT_MICROSOFT_BIG_FIVE = 4,
265 SFNT_MICROSOFT_WANSUNG = 5,
266 SFNT_MICROSOFT_JOHAB = 6,
267 SFNT_MICROSOFT_UNICODE_UCS_4 = 10,
268 };
269
270struct sfnt_cmap_encoding_subtable
271{
272 /* The platform ID. */
273 uint16_t platform_id;
274
275 /* Platform specific ID. */
276 uint16_t platform_specific_id;
277
278 /* Mapping table offset. */
279 uint32_t offset;
280};
281
282struct sfnt_cmap_encoding_subtable_data
283{
284 /* Format and possibly the length in bytes. */
285 uint16_t format, length;
286};
287
288struct sfnt_cmap_format_0
289{
290 /* Format, set to 0. */
291 uint16_t format;
292
293 /* Length in bytes. Should be 262. */
294 uint16_t length;
295
296 /* Language code. */
297 uint16_t language;
298
299 /* Character code to glyph index map. */
300 uint8_t glyph_index_array[256];
301};
302
303struct sfnt_cmap_format_2_subheader
304{
305 uint16_t first_code;
306 uint16_t entry_count;
307 int16_t id_delta;
308 uint16_t id_range_offset;
309};
310
311struct sfnt_cmap_format_2
312{
313 /* Format, set to 2. */
314 uint16_t format;
315
316 /* Length in bytes. */
317 uint16_t length;
318
319 /* Language code. */
320 uint16_t language;
321
322 /* Array mapping high bytes to subheaders. */
323 uint16_t sub_header_keys[256];
324
325 /* Variable length data. */
326 struct sfnt_cmap_format_2_subheader *subheaders;
327 uint16_t *glyph_index_array;
328 uint16_t num_glyphs;
329};
330
331struct sfnt_cmap_format_4
332{
333 /* Format, set to 4. */
334 uint16_t format;
335
336 /* Length in bytes. */
337 uint16_t length;
338
339 /* Language code. */
340 uint16_t language;
341
342 /* 2 * seg_count. */
343 uint16_t seg_count_x2;
344
345 /* 2 * (2**FLOOR(log2(segCount))) */
346 uint16_t search_range;
347
348 /* log2(searchRange/2) */
349 uint16_t entry_selector;
350
351 /* Variable-length data. */
352 uint16_t *end_code;
353 uint16_t *reserved_pad;
354 uint16_t *start_code;
355 int16_t *id_delta;
356 int16_t *id_range_offset;
357 uint16_t *glyph_index_array;
358
359 /* The number of elements in glyph_index_array. */
360 size_t glyph_index_size;
361};
362
363struct sfnt_cmap_format_6
364{
365 /* Format, set to 6. */
366 uint16_t format;
367
368 /* Length in bytes. */
369 uint16_t length;
370
371 /* Language code. */
372 uint16_t language;
373
374 /* First character code in subrange. */
375 uint16_t first_code;
376
377 /* Number of character codes. */
378 uint16_t entry_count;
379
380 /* Variable-length data. */
381 uint16_t *glyph_index_array;
382};
383
384struct sfnt_cmap_format_8_or_12_group
385{
386 uint32_t start_char_code;
387 uint32_t end_char_code;
388 uint32_t start_glyph_code;
389};
390
391struct sfnt_cmap_format_8
392{
393 /* Format, set to 8. */
394 uint16_t format;
395
396 /* Reserved. */
397 uint16_t reserved;
398
399 /* Length in bytes. */
400 uint32_t length;
401
402 /* Language code. */
403 uint32_t language;
404
405 /* Tightly packed array of bits (8K bytes total) indicating whether
406 the particular 16-bit (index) value is the start of a 32-bit
407 character code. */
408 uint8_t is32[65536];
409
410 /* Number of groups. */
411 uint32_t num_groups;
412
413 /* Variable length data. */
414 struct sfnt_cmap_format_8_or_12_group *groups;
415};
416
417/* cmap formats 10, 13 and 14 unsupported. */
418
419struct sfnt_cmap_format_12
420{
421 /* Format, set to 12. */
422 uint16_t format;
423
424 /* Reserved. */
425 uint16_t reserved;
426
427 /* Length in bytes. */
428 uint32_t length;
429
430 /* Language code. */
431 uint32_t language;
432
433 /* Number of groups. */
434 uint32_t num_groups;
435
436 /* Variable length data. */
437 struct sfnt_cmap_format_8_or_12_group *groups;
438};
439
440struct sfnt_maxp_table
441{
442 /* Table version. */
443 sfnt_fixed version;
444
445 /* The number of glyphs in this font - 1. Set at version 0.5 or
446 later. */
447 uint16_t num_glyphs;
448
449 /* These fields are only set in version 1.0 or later. Maximum
450 points in a non-composite glyph. */
451 uint16_t max_points;
452
453 /* Maximum contours in a non-composite glyph. */
454 uint16_t max_contours;
455
456 /* Maximum points in a composite glyph. */
457 uint16_t max_composite_points;
458
459 /* Maximum contours in a composite glyph. */
460 uint16_t max_composite_contours;
461
462 /* 1 if instructions do not use the twilight zone (Z0), or 2 if
463 instructions do use Z0; should be set to 2 in most cases. */
464 uint16_t max_zones;
465
466 /* Maximum points used in Z0. */
467 uint16_t max_twilight_points;
468
469 /* Number of Storage Area locations. */
470 uint16_t max_storage;
471
472 /* Number of FDEFs, equal to the highest function number + 1. */
473 uint16_t max_function_defs;
474
475 /* Number of IDEFs. */
476 uint16_t max_instruction_defs;
477
478 /* Maximum stack depth across Font Program ('fpgm' table), CVT
479 Program ('prep' table) and all glyph instructions (in the 'glyf'
480 table). */
481 uint16_t max_stack_elements;
482
483 /* Maximum byte count for glyph instructions. */
484 uint16_t max_size_of_instructions;
485
486 /* Maximum number of components referenced at ``top level'' for any
487 composite glyph. */
488 uint16_t max_component_elements;
489
490 /* Maximum levels of recursion; 1 for simple components. */
491 uint16_t max_component_depth;
492};
493
494struct sfnt_loca_table_short
495{
496 /* Offsets to glyph data divided by two. */
497 uint16_t *offsets;
498
499 /* Size of the offsets list. */
500 size_t num_offsets;
501};
502
503struct sfnt_loca_table_long
504{
505 /* Offsets to glyph data. */
506 uint32_t *offsets;
507
508 /* Size of the offsets list. */
509 size_t num_offsets;
510};
511
512struct sfnt_glyf_table
513{
514 /* Size of the glyph data. */
515 size_t size;
516
517 /* Pointer to possibly unaligned glyph data. */
518 unsigned char *glyphs;
519};
520
521struct sfnt_simple_glyph
522{
523 /* The total number of points in this glyph. */
524 size_t number_of_points;
525
526 /* Array containing the last points of each contour. */
527 uint16_t *end_pts_of_contours;
528
529 /* Total number of bytes needed for instructions. */
530 uint16_t instruction_length;
531
532 /* Instruction data. */
533 uint8_t *instructions;
534
535 /* Array of flags. */
536 uint8_t *flags;
537
538 /* Array of X coordinates. */
539 int16_t *x_coordinates;
540
541 /* Array of Y coordinates. */
542 int16_t *y_coordinates;
543
544 /* Pointer to the end of that array. */
545 int16_t *y_coordinates_end;
546};
547
548struct sfnt_compound_glyph_component
549{
550 /* Compound glyph flags. */
551 uint16_t flags;
552
553 /* Component glyph index. */
554 uint16_t glyph_index;
555
556 /* X-offset for component or point number; type depends on bits 0
557 and 1 in component flags. */
558 union {
559 uint8_t a;
560 int8_t b;
561 uint16_t c;
562 int16_t d;
563 } argument1;
564
565 /* Y-offset for component or point number; type depends on bits 0
566 and 1 in component flags. */
567 union {
568 uint8_t a;
569 int8_t b;
570 uint16_t c;
571 int16_t d;
572 } argument2;
573
574 /* Various scale formats. */
575 union {
576 uint16_t scale;
577 struct {
578 uint16_t xscale;
579 uint16_t yscale;
580 } a;
581 struct {
582 uint16_t xscale;
583 uint16_t scale01;
584 uint16_t scale10;
585 uint16_t yscale;
586 } b;
587 } u;
588};
589
590struct sfnt_compound_glyph
591{
592 /* Pointer to array of components. */
593 struct sfnt_compound_glyph_component *components;
594
595 /* Number of elements in that array. */
596 size_t num_components;
597
598 /* Instruction data. */
599 uint8_t *instructions;
600
601 /* Length of instructions. */
602 uint16_t instruction_length;
603};
604
605struct sfnt_glyph
606{
607 /* Number of contours in this glyph. */
608 int16_t number_of_contours;
609
610 /* Coordinate bounds. */
611 sfnt_fword xmin, ymin, xmax, ymax;
612
613 /* Either a simple glyph or a compound glyph, depending on which is
614 set. */
615 struct sfnt_simple_glyph *simple;
616 struct sfnt_compound_glyph *compound;
617};
618
619
620
621/* Glyph outline decomposition. */
622
623struct sfnt_point
624{
625 /* X and Y in em space. */
626 sfnt_fixed x, y;
627};
628
629typedef void (*sfnt_move_to_proc) (struct sfnt_point, void *);
630typedef void (*sfnt_line_to_proc) (struct sfnt_point, void *);
631typedef void (*sfnt_curve_to_proc) (struct sfnt_point,
632 struct sfnt_point,
633 void *);
634
635typedef struct sfnt_glyph *(*sfnt_get_glyph_proc) (sfnt_glyph, void *,
636 bool *);
637typedef void (*sfnt_free_glyph_proc) (struct sfnt_glyph *, void *);
638
639
640
641/* Decomposed glyph outline. */
642
643struct sfnt_glyph_outline_command
644{
645 /* Flags for this outline command. */
646 int flags;
647
648 /* X and Y position of this command. */
649 sfnt_fixed x, y;
650};
651
652/* Structure describing a single recorded outline in fixed pixel
653 space. */
654
655struct sfnt_glyph_outline
656{
657 /* Array of outlines elements. */
658 struct sfnt_glyph_outline_command *outline;
659
660 /* Size of the outline data, and how much is full. */
661 size_t outline_size, outline_used;
662
663 /* Rectangle defining bounds of the outline. Namely, the minimum
664 and maximum X and Y positions. */
665 sfnt_fixed xmin, ymin, xmax, ymax;
666};
667
668enum sfnt_glyph_outline_flags
669 {
670 SFNT_GLYPH_OUTLINE_LINETO = (1 << 1),
671 };
672
673struct sfnt_build_glyph_outline_context
674{
675 /* The outline being built. */
676 struct sfnt_glyph_outline *outline;
677
678 /* The head table. */
679 struct sfnt_head_table *head;
680
681 /* The pixel size being used, and any extra flags to apply to the
682 outline at this point. */
683 int pixel_size;
684
685 /* Factor to multiply positions by to get the pixel width. */
686 double factor;
687
688 /* The position of the pen in 16.16 fixed point format. */
689 sfnt_fixed x, y;
690};
691
692
693
694/* Glyph rasterization. */
695
696struct sfnt_raster
697{
698 /* Basic dimensions of the raster. */
699 unsigned short width, height;
700
701 /* Integer offset to apply to positions in the raster. */
702 unsigned short offx, offy;
703
704 /* Pointer to coverage data. */
705 unsigned char *cells;
706};
707
708struct sfnt_edge
709{
710 /* Next edge in this chain. */
711 struct sfnt_edge *next;
712
713 /* Winding direction. 1 if clockwise, -1 if counterclockwise. */
714 int winding;
715
716 /* X position, top and bottom of edges. */
717 sfnt_fixed x, top, bottom;
718
719 /* step_x is how many pixels to move for each increase in Y. */
720 sfnt_fixed step_x;
721};
722
723
724
725/* Polygon rasterization constants. */
726
727enum
728 {
729 SFNT_POLY_SHIFT = 2,
730 SFNT_POLY_SAMPLE = (1 << SFNT_POLY_SHIFT),
731 SFNT_POLY_MASK = (SFNT_POLY_SAMPLE - 1),
732 SFNT_POLY_STEP = (0x10000 >> SFNT_POLY_SHIFT),
733 SFNT_POLY_START = (SFNT_POLY_STEP >> 1),
734 };
735
736
737
738/* Glyph metrics computation. */
739
740struct sfnt_long_hor_metric
741{
742 uint16_t advance_width;
743 int16_t left_side_bearing;
744};
745
746struct sfnt_hmtx_table
747{
748 /* Array of horizontal metrics for each glyph. */
749 struct sfnt_long_hor_metric *h_metrics;
750
751 /* Lbearing for remaining glyphs. */
752 int16_t *left_side_bearing;
753};
754
755/* Structure describing the metrics of a single glyph. The fields
756 mean the same as in XCharStruct, except they are 16.16 fixed point
757 values, and are missing significant information. */
758
759struct sfnt_glyph_metrics
760{
761 /* Distance between origin and left edge of raster. Positive
762 changes move rightwards. */
763 sfnt_fixed lbearing;
764
765 /* Advance to next glyph's origin. */
766 sfnt_fixed advance;
767};
768
769
770
771/* Font style parsing. */
772
773struct sfnt_name_record
774{
775 /* Platform identifier code. */
776 uint16_t platform_id;
777
778 /* Platform specific ID. */
779 uint16_t platform_specific_id;
780
781 /* Language identifier. */
782 uint16_t language_id;
783
784 /* Name identifier. */
785 uint16_t name_id;
786
787 /* String length in bytes. */
788 uint16_t length;
789
790 /* Offset from start of storage area. */
791 uint16_t offset;
792};
793
794struct sfnt_name_table
795{
796 /* Format selector of name table. */
797 uint16_t format;
798
799 /* Number of name records. */
800 uint16_t count;
801
802 /* Offset to start of string data. */
803 uint16_t string_offset;
804
805 /* Variable length data. */
806 struct sfnt_name_record *name_records;
807
808 /* Start of string data. */
809 unsigned char *data;
810};
811
812/* Name identifier codes. These are Apple's codes, not
813 Microsoft's. */
814
815enum sfnt_name_identifier_code
816 {
817 SFNT_NAME_COPYRIGHT_NOTICE = 0,
818 SFNT_NAME_FONT_FAMILY = 1,
819 SFNT_NAME_FONT_SUBFAMILY = 2,
820 SFNT_NAME_UNIQUE_SUBFAMILY_IDENTIFICATION = 3,
821 SFNT_NAME_FULL_NAME = 4,
822 SFNT_NAME_NAME_TABLE_VERSION = 5,
823 SFNT_NAME_POSTSCRIPT_NAME = 6,
824 SFNT_NAME_TRADEMARK_NOTICE = 7,
825 SFNT_NAME_MANUFACTURER_NAME = 8,
826 SFNT_NAME_DESIGNER = 9,
827 SFNT_NAME_DESCRIPTION = 10,
828 SFNT_NAME_FONT_VENDOR_URL = 11,
829 SFNT_NAME_FONT_DESIGNER_URL = 12,
830 SFNT_NAME_LICENSE_DESCRIPTION = 13,
831 SFNT_NAME_LICENSE_INFORMATION_URL = 14,
832 SFNT_NAME_PREFERRED_FAMILY = 16,
833 SFNT_NAME_PREFERRED_SUBFAMILY = 17,
834 SFNT_NAME_COMPATIBLE_FULL = 18,
835 SFNT_NAME_SAMPLE_TEXT = 19,
836 SFNT_NAME_VARIATIONS_POSTSCRIPT_NAME_PREFIX = 25,
837 };
838
839struct sfnt_meta_data_map
840{
841 /* Identifier for the tag. */
842 uint32_t tag;
843
844 /* Offset from start of table to data. */
845 uint32_t data_offset;
846
847 /* Length of the data. */
848 uint32_t data_length;
849};
850
851struct sfnt_meta_table
852{
853 /* Version of the table. Currently set to 1. */
854 uint32_t version;
855
856 /* Flags. Currently 0. */
857 uint32_t flags;
858
859 /* Offset from start of table to beginning of variable length
860 data. */
861 uint32_t data_offset;
862
863 /* Number of data maps in the table. */
864 uint32_t num_data_maps;
865
866 /* Beginning of variable length data. */
867 struct sfnt_meta_data_map *data_maps;
868
869 /* The whole table contents. */
870 unsigned char *data;
871};
872
873enum sfnt_meta_data_tag
874 {
875 SFNT_META_DATA_TAG_DLNG = 0x646c6e67,
876 SFNT_META_DATA_TAG_SLNG = 0x736c6e67,
877 };
878
879
880
881/* Function declarations. Keep these sorted by the order in which
882 they appear in sfnt.c. Keep each line no longer than 80
883 columns. */
884
885#ifndef TEST
886
887extern struct sfnt_offset_subtable *sfnt_read_table_directory (int);
888
889#define PROTOTYPE \
890 int, struct sfnt_offset_subtable *, \
891 struct sfnt_cmap_encoding_subtable **, \
892 struct sfnt_cmap_encoding_subtable_data ***
893static struct sfnt_cmap_table *sfnt_read_cmap_table (PROTOTYPE);
894#undef PROTOTYPE
895
896#define PROTOTYPE int, struct sfnt_offset_subtable *
897extern struct sfnt_head_table *sfnt_read_head_table (PROTOTYPE);
898extern struct sfnt_hhea_table *sfnt_read_hhea_table (PROTOTYPE);
899extern struct sfnt_loca_table_short *sfnt_read_loca_table_short (PROTOTYPE);
900extern struct sfnt_loca_table_long *sfnt_read_loca_table_long (PROTOTYPE);
901extern struct sfnt_maxp_table *sfnt_read_maxp_table (PROTOTYPE);
902extern struct sfnt_glyf_table *sfnt_read_glyf_table (PROTOTYPE);
903#undef PROTOTYPE
904
905extern struct sfnt_glyph *sfnt_read_glyph (sfnt_glyph, struct sfnt_glyf_table *,
906 struct sfnt_loca_table_short *,
907 struct sfnt_loca_table_long *);
908
909#define PROTOTYPE \
910 struct sfnt_glyph *, \
911 struct sfnt_head_table *, \
912 int, sfnt_get_glyph_proc, \
913 sfnt_free_glyph_proc, \
914 void *
915extern struct sfnt_glyph_outline *sfnt_build_glyph_outline (PROTOTYPE);
916#undef PROTOTYPE
917
918extern void sfnt_prepare_raster (struct sfnt_raster *,
919 struct sfnt_glyph_outline *);
920
921#define PROTOTYPE struct sfnt_glyph_outline *
922extern struct sfnt_raster *sfnt_raster_glyph_outline (PROTOTYPE);
923#undef PROTOTYPE
924
925#define PROTOTYPE \
926 int, \
927 struct sfnt_offset_subtable *, \
928 struct sfnt_hhea_table *, \
929 struct sfnt_maxp_table *
930extern struct sfnt_hmtx_table *sfnt_read_hmtx_table (PROTOTYPE);
931#undef PROTOTYPE
932
933extern int sfnt_lookup_glyph_metrics (sfnt_glyph, int,
934 struct sfnt_glyph_metrics *,
935 struct sfnt_hmtx_table *,
936 struct sfnt_hhea_table *,
937 struct sfnt_head_table *,
938 struct sfnt_maxp_table *);
939
940#define PROTOTYPE int, struct sfnt_offset_subtable *
941extern struct sfnt_name_table *sfnt_read_name_table (PROTOTYPE);
942#undef PROTOTYPE
943
944extern unsigned char *sfnt_find_name (struct sfnt_name_table *,
945 enum sfnt_name_identifier_code,
946 struct sfnt_name_record *);
947
948#define PROTOTYPE int, struct sfnt_offset_subtable *
949extern struct sfnt_meta_table *sfnt_read_meta_table (PROTOTYPE);
950#undef PROTOTYPE
951
952extern char *sfnt_find_metadata (struct sfnt_meta_table *,
953 enum sfnt_meta_data_tag,
954 struct sfnt_meta_data_map *);
955
956#endif /* TEST */
957#endif /* _SFNT_H_ */
diff --git a/src/sfntfont-android.c b/src/sfntfont-android.c
new file mode 100644
index 00000000000..d3c05fa4ac7
--- /dev/null
+++ b/src/sfntfont-android.c
@@ -0,0 +1,36 @@
1/* sfnt format font driver for Android.
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 "androidterm.h"
24#include "sfntfont.h"
25
26void
27init_sfntfont_android (void)
28{
29
30}
31
32void
33syms_of_sfntfont_android (void)
34{
35
36}
diff --git a/src/sfntfont.c b/src/sfntfont.c
new file mode 100644
index 00000000000..a9cc6d11b45
--- /dev/null
+++ b/src/sfntfont.c
@@ -0,0 +1,493 @@
1/* sfnt format font driver 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 "lisp.h"
24#include "sfnt.h"
25#include "coding.h"
26
27/* Generic font driver for sfnt-based fonts (currently TrueType, but
28 it would be easy to add CFF support in the future.)
29
30 This is not a complete font driver. Hooks must be supplied by the
31 platform implementer to draw glyphs. */
32
33
34
35/* Description of a font that hasn't been opened. */
36
37struct sfnt_font_desc
38{
39 /* Next font in this list. */
40 struct sfnt_font_desc *next;
41
42 /* Family name of the font. */
43 Lisp_Object family;
44
45 /* Style name of the font. */
46 Lisp_Object style;
47
48 /* Numeric width, weight, slant and spacing. */
49 int width, weight, slant, spacing;
50
51 /* Path to the font file. */
52 char *path;
53};
54
55/* List of fonts. */
56
57static struct sfnt_font_desc *system_fonts;
58
59/* Font enumeration and matching. The sfnt driver assumes it can read
60 data from each font at startup. It then reads the head, meta and
61 name tables to determine font data, and records the font in a list
62 of system fonts that is then matched against. */
63
64/* Set up the coding system CODING to decode string data from the
65 given platform id ID and platform specific id PLATFORM_SPECIFIC_ID.
66 Value is 0 upon success, 1 upon failure. */
67
68static int
69sfnt_setup_coding_system (enum sfnt_platform_id id, int platform_specific_id,
70 struct coding_system *coding)
71{
72 Lisp_Object system;
73
74 system = Qnil;
75
76 /* Figure out what coding system to use. */
77
78 switch (id)
79 {
80 case SFNT_PLATFORM_UNICODE:
81 system = Qutf_16be;
82 break;
83
84 case SFNT_PLATFORM_MACINTOSH:
85
86 if (platform_specific_id == SFNT_MACINTOSH_ROMAN)
87 system = Qmac_roman;
88 else
89 /* MULE doesn't support the rest... */
90 system = Qnil;
91
92 break;
93
94 case SFNT_PLATFORM_MICROSOFT:
95 system = Qutf_16be;
96
97 /* FIXME will someone look at the MS spec and see if this
98 right. */
99 if (platform_specific_id
100 == SFNT_MICROSOFT_BIG_FIVE)
101 system = Qchinese_big5;
102
103 break;
104 }
105
106 if (NILP (system))
107 return 1;
108
109 setup_coding_system (system, coding);
110}
111
112/* Globals used to communicate inside the condition-case wrapper. */
113static struct coding_system *sfnt_font_coding;
114
115/* The src_object being encoded from. This should be on the stack as
116 well, or it will get garbage collected. */
117static Lisp_Object sfnt_font_src_object;
118
119/* From-position. */
120static ptrdiff_t sfnt_font_from, sfnt_font_from_byte;
121
122/* To-position. */
123static ptrdiff_t sfnt_font_to, sfnt_font_to_byte;
124
125/* Destination object. Once again, this should also be on the
126 stack. */
127static Lisp_Object sfnt_font_dst_object;
128
129/* Error flag. Set to true if a signal was caught. */
130static bool sfnt_font_signal;
131
132static Lisp_Object
133sfnt_safe_encode_coding_object_1 (void)
134{
135 encode_coding_object (sfnt_font_coding,
136 sfnt_font_src_object,
137 sfnt_font_from,
138 sfnt_font_from_byte,
139 sfnt_font_to,
140 sfnt_font_to_byte,
141 sfnt_font_dst_object);
142 return Qnil;
143}
144
145static Lisp_Object
146sfnt_safe_encode_coding_object_2 (void)
147{
148 sfnt_font_signal = true;
149
150 return Qnil;
151}
152
153/* Like encode_coding_object, but return 1 if a signal happens. Value
154 is otherwise 0. */
155
156static int
157sfnt_safe_encode_coding_object (struct coding_system *coding,
158 Lisp_Object src_object,
159 ptrdiff_t from, ptrdiff_t from_byte,
160 ptrdiff_t to, ptrdiff_t to_byte,
161 Lisp_Object dst_object)
162{
163 sfnt_font_coding = coding;
164 sfnt_font_src_object = src_object;
165 sfnt_font_from = from;
166 sfnt_font_from_byte = from_byte;
167 sfnt_font_to = to;
168 sfnt_font_to_byte = to_byte;
169 sfnt_font_dst_object = dst_object;
170 sfnt_font_signal = false;
171
172 internal_condition_case (sfnt_safe_encode_coding_object_1,
173 Qt,
174 sfnt_safe_encode_coding_object_2);
175
176 return (int) sfnt_font_signal;
177}
178
179/* Decode the specified string DATA. The encoding is determined based
180 on PLATFORM_ID, PLATFORM_SPECIFIC_ID and LANGUAGE_ID. Consult
181 sfnt.h and the TrueType Reference Manual for more details. LENGTH
182 is the length of DATA in bytes.
183
184 Value is nil upon failure, else the decoded string. */
185
186static Lisp_Object
187sfnt_decode_font_string (unsigned char *data, enum sfnt_platform_id id,
188 int platform_specific_id, int language_id,
189 size_t length)
190{
191 struct coding_system coding;
192
193 memset (&coding, 0, sizeof coding);
194 sfnt_setup_coding_system (id, platform_specific_id, &coding);
195 coding.mode |= CODING_MODE_SAFE_ENCODING;
196 coding.mode |= CODING_MODE_LAST_BLOCK;
197 /* Suppress producing escape sequences for composition. */
198 coding.common_flags &= ~CODING_ANNOTATION_MASK;
199 coding.source = data;
200
201 if (sfnt_safe_encode_coding_object (&coding, Qnil, 0, 0,
202 0, 0, length, length,
203 Qnil))
204 return Qnil;
205
206 return coding.dst_object;
207}
208
209/* Decode the family and style names from the name table NAME. Return
210 0 and the family and style names upon success, else 1. */
211
212static int
213sfnt_decode_family_style (struct sfnt_name_table *name,
214 Lisp_Object *family, Lisp_Object *style)
215{
216 struct sfnt_name_record family_rec, style_rec;
217 unsigned char *family_data, *style_data;
218
219 family_data = sfnt_find_name (name, SFNT_NAME_FONT_FAMILY,
220 &family_rec);
221 style_data = sfnt_find_name (name, SFNT_NAME_FONT_SUBFAMILY,
222 &style_rec);
223
224 if (!family_data || !style_data)
225 return 1;
226
227 /* Now decode the data. */
228 *family = sfnt_decode_font_string (family_data,
229 family_rec.platform_id,
230 family_rec.platform_specific_id,
231 family_rec.language_id,
232 family_rec.length);
233 *style = sfnt_decode_font_string (style_data,
234 style_rec.platform_id,
235 style_rec.platform_specific_id,
236 style_rec.language_id,
237 style_rec.length);
238
239 /* Return whether or not it was successful. */
240 return (!NILP (*family) && !NILP (*style)) ? 0 : 1;
241}
242
243struct sfnt_style_desc
244{
245 /* The C string to match against. */
246 const char *c_string;
247
248 /* The value of the style field. */
249 int value;
250};
251
252/* Array of style descriptions describing weight. */
253static struct sfnt_style_desc sfnt_weight_descriptions =
254 {
255 { "thin", 0, },
256 { "extralight", 40, },
257 { "ultralight", 40, },
258 { "demilight", 55, },
259 { "semilight", 55, },
260 { "book", 75, },
261 { "medium", 100, },
262 { "demibold", 180, },
263 { "semibold", 180, },
264 { "bold", 200, },
265 { "extrabold", 205, },
266 { "ultrabold", 205, },
267 { "black", 210, },
268 { "heavy", 210, },
269 { "extrablack", 215, },
270 { "ultrablack", 215, },
271 };
272
273/* Array of style descriptions describing slant. */
274static struct sfnt_style_desc sfnt_slant_descriptions =
275 {
276 { "italic", 100, },
277 { "oblique", 110, },
278 };
279
280/* Array of style descriptions describing width. */
281static struct sfnt_width_desc sfnt_width_descriptions =
282 {
283 { "ultracondensed", 50, },
284 { "extracondensed", 63, },
285 { "condensed", 75, },
286 { "semicondensed", 87, },
287 { "semiexpanded", 113, },
288 { "expanded", 125, },
289 { "extraexpanded", 150, },
290 { "ultraexpanded", 200, },
291 };
292
293/* Figure out DESC->width, DESC->weight, DESC->slant and DESC->spacing
294 based on the style name passed as STYLE. */
295
296static void
297sfnt_parse_style (Lisp_Object style, struct sfnt_font_desc *desc)
298{
299 char *style, single, *saveptr;
300 int i;
301
302 /* Fill in default values. */
303 desc->weight = 80;
304 desc->slant = 0;
305 desc->width = 100;
306
307 /* Split the style into spaces. As long as no weight, slant, or
308 width is encountered, look in the corresponding descriptions
309 array. GC must not happen inside this block. */
310 style = SSDATA (Fdowncase (style));
311 saveptr = NULL;
312
313 while ((single = strtok_r (style, " ", &saveptr)))
314 {
315 style = NULL;
316
317 if (desc->weight == 80)
318 {
319 /* Weight hasn't been found yet. Scan through the weight
320 table. */
321 for (i = 0; i < ARRAYELTS (sfnt_weight_descriptions); ++i)
322 {
323 if (!strcmp (sfnt_weight_descriptions[i].c_string,
324 single))
325 {
326 /* Weight found. Continue on reading the slant and
327 width. */
328 desc->weight = sfnt_weight_descriptions[i].value;
329 goto next;
330 }
331 }
332 }
333
334 if (!desc->slant)
335 {
336 /* Slant hasn't been found yet. Scan through the slant
337 table. */
338 for (i = 0; i < ARRAYELTS (sfnt_slant_descriptions); ++i)
339 {
340 if (!strcmp (sfnt_weight_descriptions[i].c_string,
341 single))
342 {
343 /* Slant found. Continue on reading the weight and
344 width. */
345 desc->slant = sfnt_weight_descriptions[i].value;
346 goto next;
347 }
348 }
349 }
350
351 if (desc->width == 100)
352 {
353 /* Width hasn't been found yet. Scan through the width
354 table. */
355 for (i = 0; i < ARRAYELTS (sfnt_width_descriptions); ++i)
356 {
357 if (!strcmp (sfnt_width_descriptions[i].c_string,
358 single))
359 {
360 /* Width found. Continue on reading the slant and
361 weight. */
362 desc->slant = sfnt_width_descriptions[i].value;
363 goto next;
364 }
365 }
366 }
367
368 next:
369
370 /* Break early if everything has been found. */
371 if (desc->slant && desc->width != 100 && desc->weight != 80)
372 break;
373
374 continue;
375 }
376}
377
378/* Enumerate the font FILE into the list of system fonts. Return 1 if
379 it could not be enumerated, 0 otherwise. */
380
381int
382sfnt_enum_font (const char *file)
383{
384 struct sfnt_font_desc *desc;
385 int fd;
386 struct sfnt_offset_subtable *subtables;
387 struct sfnt_head_table *head;
388 struct sfnt_name_table *name;
389 struct sfnt_meta_table *meta;
390 Lisp_Object family, style;
391
392 /* Create the font desc and copy in the file name. */
393 desc = xzalloc (sizeof *desc + strlen (file) + 1);
394 desc->path = (char *) (desc + 1);
395 memcpy (desc->path, file, strlen (file) + 1);
396
397 /* Now open the font for reading. */
398 fd = emacs_open (file, O_RDWR);
399
400 /* Read the table directory. */
401 subtables = sfnt_read_table_directory (fd);
402
403 if (!subtables)
404 goto bail0;
405
406 /* Check that this is a TrueType font. */
407 if (subtables->scaler_type != SFNT_SCALER_TRUE
408 && subtables->scaler_type != SFNT_SCALER_VER1)
409 goto bail1;
410
411 /* Read required tables. */
412 head = sfnt_read_head_table (fd, subtables);
413 if (!head)
414 goto bail1;
415
416 name = sfnt_read_name_table (fd, subtables);
417 if (!name)
418 goto bail2;
419
420 /* meta is not required, nor present on many non-Apple fonts. */
421 meta = sfnt_read_meta_table (fd, subtables);
422
423 /* Decode the family and style from the name table. */
424 if (sfnt_decode_family_style (name, &family, &style))
425 goto bail3;
426
427 /* Set the family. */
428 desc->family = family;
429
430 /* Parse the style. */
431 sfnt_parse_style (style, desc);
432
433 /* Figure out the spacing. Some fancy test like what Fontconfig
434 does is probably in order but not really necessary. */
435 if (!NILP (Fstring_search (Fdowncase (family),
436 build_string ("mono"),
437 Qnil)))
438 desc->spacing = 100; /* FC_MONO */
439
440 /* Finally add mac-style flags. Allow them to override styles that
441 have not been found. */
442
443 if (head->mac_style & 01 && desc->weight == 80) /* Bold */
444 desc->weight = 200;
445
446 if (head->mac_style & 02 && desc->slant == 0) /* Italic */
447 desc->slant = 100;
448
449 /* Set the style, link the desc onto system_fonts and return. */
450 desc->style = style;
451 desc->next = system_fonts;
452 system_fonts = desc;
453
454 xfree (meta);
455 xfree (name);
456 xfree (head);
457 xfree (subtables);
458 emacs_close (fd);
459 return 0;
460
461 bail3:
462 xfree (meta);
463 xfree (name);
464 bail2:
465 xfree (head);
466 bail1:
467 xfree (subtables);
468 bail0:
469 emacs_close (fd);
470 return 1;
471}
472
473
474
475void
476syms_of_sfntfont (void)
477{
478 DEFSYM (Qutf_16be, "utf-16be");
479 DEFSYM (Qmac_roman, "mac-roman");
480}
481
482void
483mark_sfntfont (void)
484{
485 struct sfnt_font_desc *desc;
486
487 /* Mark each font desc. */
488 for (desc = system_fonts; ++desc; desc = desc->next)
489 {
490 mark_object (desc->family);
491 mark_object (desc->style);
492 }
493}
diff --git a/src/sfntfont.h b/src/sfntfont.h
new file mode 100644
index 00000000000..3ce60f83984
--- /dev/null
+++ b/src/sfntfont.h
@@ -0,0 +1,26 @@
1/* sfnt format font driver 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#ifndef _SFNTFONT_H_
22#define _SFNTFONT_H_
23
24extern int sfnt_enum_font (const char *);
25
26#endif /* _SFNTFONT_H_ */