diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/sfnt.h | 957 | ||||
| -rw-r--r-- | src/sfntfont-android.c | 36 | ||||
| -rw-r--r-- | src/sfntfont.c | 493 | ||||
| -rw-r--r-- | src/sfntfont.h | 26 |
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 | |||
| 3 | Copyright (C) 2023 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | This file is part of GNU Emacs. | ||
| 6 | |||
| 7 | GNU Emacs is free software: you can redistribute it and/or modify | ||
| 8 | it under the terms of the GNU General Public License as published by | ||
| 9 | the Free Software Foundation, either version 3 of the License, or (at | ||
| 10 | your option) any later version. | ||
| 11 | |||
| 12 | GNU Emacs is distributed in the hope that it will be useful, | ||
| 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | GNU General Public License for more details. | ||
| 16 | |||
| 17 | You should have received a copy of the GNU General Public License | ||
| 18 | along with GNU Emacs. If not, write to the Free Software Foundation, | ||
| 19 | Inc., 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 | |||
| 35 | enum 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 | |||
| 56 | struct 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 | |||
| 80 | struct 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 | |||
| 95 | enum 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 | |||
| 103 | typedef int32_t sfnt_fixed; | ||
| 104 | typedef int16_t sfnt_fword; | ||
| 105 | typedef uint16_t sfnt_ufword; | ||
| 106 | |||
| 107 | #define sfnt_coerce_fixed(fixed) ((sfnt_fixed) (fixed) / 65535.0) | ||
| 108 | |||
| 109 | typedef unsigned int sfnt_glyph; | ||
| 110 | typedef unsigned int sfnt_char; | ||
| 111 | |||
| 112 | struct 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 | |||
| 157 | struct 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 | |||
| 193 | struct sfnt_cmap_table | ||
| 194 | { | ||
| 195 | /* Should be zero. */ | ||
| 196 | uint16_t version; | ||
| 197 | |||
| 198 | /* Number of subtables. */ | ||
| 199 | uint16_t num_subtables; | ||
| 200 | }; | ||
| 201 | |||
| 202 | enum 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 | |||
| 210 | enum 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 | |||
| 221 | enum 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 | |||
| 258 | enum 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 | |||
| 270 | struct 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 | |||
| 282 | struct sfnt_cmap_encoding_subtable_data | ||
| 283 | { | ||
| 284 | /* Format and possibly the length in bytes. */ | ||
| 285 | uint16_t format, length; | ||
| 286 | }; | ||
| 287 | |||
| 288 | struct 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 | |||
| 303 | struct 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 | |||
| 311 | struct 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 | |||
| 331 | struct 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 | |||
| 363 | struct 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 | |||
| 384 | struct 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 | |||
| 391 | struct 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 | |||
| 419 | struct 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 | |||
| 440 | struct 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 | |||
| 494 | struct 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 | |||
| 503 | struct 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 | |||
| 512 | struct 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 | |||
| 521 | struct 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 | |||
| 548 | struct 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 | |||
| 590 | struct 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 | |||
| 605 | struct 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 | |||
| 623 | struct sfnt_point | ||
| 624 | { | ||
| 625 | /* X and Y in em space. */ | ||
| 626 | sfnt_fixed x, y; | ||
| 627 | }; | ||
| 628 | |||
| 629 | typedef void (*sfnt_move_to_proc) (struct sfnt_point, void *); | ||
| 630 | typedef void (*sfnt_line_to_proc) (struct sfnt_point, void *); | ||
| 631 | typedef void (*sfnt_curve_to_proc) (struct sfnt_point, | ||
| 632 | struct sfnt_point, | ||
| 633 | void *); | ||
| 634 | |||
| 635 | typedef struct sfnt_glyph *(*sfnt_get_glyph_proc) (sfnt_glyph, void *, | ||
| 636 | bool *); | ||
| 637 | typedef void (*sfnt_free_glyph_proc) (struct sfnt_glyph *, void *); | ||
| 638 | |||
| 639 | |||
| 640 | |||
| 641 | /* Decomposed glyph outline. */ | ||
| 642 | |||
| 643 | struct 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 | |||
| 655 | struct 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 | |||
| 668 | enum sfnt_glyph_outline_flags | ||
| 669 | { | ||
| 670 | SFNT_GLYPH_OUTLINE_LINETO = (1 << 1), | ||
| 671 | }; | ||
| 672 | |||
| 673 | struct 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 | |||
| 696 | struct 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 | |||
| 708 | struct 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 | |||
| 727 | enum | ||
| 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 | |||
| 740 | struct sfnt_long_hor_metric | ||
| 741 | { | ||
| 742 | uint16_t advance_width; | ||
| 743 | int16_t left_side_bearing; | ||
| 744 | }; | ||
| 745 | |||
| 746 | struct 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 | |||
| 759 | struct 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 | |||
| 773 | struct 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 | |||
| 794 | struct 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 | |||
| 815 | enum 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 | |||
| 839 | struct 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 | |||
| 851 | struct 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 | |||
| 873 | enum 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 | |||
| 887 | extern 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 *** | ||
| 893 | static struct sfnt_cmap_table *sfnt_read_cmap_table (PROTOTYPE); | ||
| 894 | #undef PROTOTYPE | ||
| 895 | |||
| 896 | #define PROTOTYPE int, struct sfnt_offset_subtable * | ||
| 897 | extern struct sfnt_head_table *sfnt_read_head_table (PROTOTYPE); | ||
| 898 | extern struct sfnt_hhea_table *sfnt_read_hhea_table (PROTOTYPE); | ||
| 899 | extern struct sfnt_loca_table_short *sfnt_read_loca_table_short (PROTOTYPE); | ||
| 900 | extern struct sfnt_loca_table_long *sfnt_read_loca_table_long (PROTOTYPE); | ||
| 901 | extern struct sfnt_maxp_table *sfnt_read_maxp_table (PROTOTYPE); | ||
| 902 | extern struct sfnt_glyf_table *sfnt_read_glyf_table (PROTOTYPE); | ||
| 903 | #undef PROTOTYPE | ||
| 904 | |||
| 905 | extern 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 * | ||
| 915 | extern struct sfnt_glyph_outline *sfnt_build_glyph_outline (PROTOTYPE); | ||
| 916 | #undef PROTOTYPE | ||
| 917 | |||
| 918 | extern void sfnt_prepare_raster (struct sfnt_raster *, | ||
| 919 | struct sfnt_glyph_outline *); | ||
| 920 | |||
| 921 | #define PROTOTYPE struct sfnt_glyph_outline * | ||
| 922 | extern 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 * | ||
| 930 | extern struct sfnt_hmtx_table *sfnt_read_hmtx_table (PROTOTYPE); | ||
| 931 | #undef PROTOTYPE | ||
| 932 | |||
| 933 | extern 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 * | ||
| 941 | extern struct sfnt_name_table *sfnt_read_name_table (PROTOTYPE); | ||
| 942 | #undef PROTOTYPE | ||
| 943 | |||
| 944 | extern 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 * | ||
| 949 | extern struct sfnt_meta_table *sfnt_read_meta_table (PROTOTYPE); | ||
| 950 | #undef PROTOTYPE | ||
| 951 | |||
| 952 | extern 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 | |||
| 3 | Copyright (C) 2023 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | This file is part of GNU Emacs. | ||
| 6 | |||
| 7 | GNU Emacs is free software: you can redistribute it and/or modify | ||
| 8 | it under the terms of the GNU General Public License as published by | ||
| 9 | the Free Software Foundation, either version 3 of the License, or (at | ||
| 10 | your option) any later version. | ||
| 11 | |||
| 12 | GNU Emacs is distributed in the hope that it will be useful, | ||
| 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | GNU General Public License for more details. | ||
| 16 | |||
| 17 | You should have received a copy of the GNU General Public License | ||
| 18 | along with GNU Emacs. If not, write to the Free Software Foundation, | ||
| 19 | Inc., 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 | |||
| 26 | void | ||
| 27 | init_sfntfont_android (void) | ||
| 28 | { | ||
| 29 | |||
| 30 | } | ||
| 31 | |||
| 32 | void | ||
| 33 | syms_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 | |||
| 3 | Copyright (C) 2023 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | This file is part of GNU Emacs. | ||
| 6 | |||
| 7 | GNU Emacs is free software: you can redistribute it and/or modify | ||
| 8 | it under the terms of the GNU General Public License as published by | ||
| 9 | the Free Software Foundation, either version 3 of the License, or (at | ||
| 10 | your option) any later version. | ||
| 11 | |||
| 12 | GNU Emacs is distributed in the hope that it will be useful, | ||
| 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | GNU General Public License for more details. | ||
| 16 | |||
| 17 | You should have received a copy of the GNU General Public License | ||
| 18 | along with GNU Emacs. If not, write to the Free Software Foundation, | ||
| 19 | Inc., 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 | |||
| 37 | struct 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 | |||
| 57 | static 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 | |||
| 68 | static int | ||
| 69 | sfnt_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. */ | ||
| 113 | static 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. */ | ||
| 117 | static Lisp_Object sfnt_font_src_object; | ||
| 118 | |||
| 119 | /* From-position. */ | ||
| 120 | static ptrdiff_t sfnt_font_from, sfnt_font_from_byte; | ||
| 121 | |||
| 122 | /* To-position. */ | ||
| 123 | static ptrdiff_t sfnt_font_to, sfnt_font_to_byte; | ||
| 124 | |||
| 125 | /* Destination object. Once again, this should also be on the | ||
| 126 | stack. */ | ||
| 127 | static Lisp_Object sfnt_font_dst_object; | ||
| 128 | |||
| 129 | /* Error flag. Set to true if a signal was caught. */ | ||
| 130 | static bool sfnt_font_signal; | ||
| 131 | |||
| 132 | static Lisp_Object | ||
| 133 | sfnt_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 | |||
| 145 | static Lisp_Object | ||
| 146 | sfnt_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 | |||
| 156 | static int | ||
| 157 | sfnt_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 | |||
| 186 | static Lisp_Object | ||
| 187 | sfnt_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 | |||
| 212 | static int | ||
| 213 | sfnt_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 | |||
| 243 | struct 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. */ | ||
| 253 | static 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. */ | ||
| 274 | static struct sfnt_style_desc sfnt_slant_descriptions = | ||
| 275 | { | ||
| 276 | { "italic", 100, }, | ||
| 277 | { "oblique", 110, }, | ||
| 278 | }; | ||
| 279 | |||
| 280 | /* Array of style descriptions describing width. */ | ||
| 281 | static 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 | |||
| 296 | static void | ||
| 297 | sfnt_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 | |||
| 381 | int | ||
| 382 | sfnt_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 | |||
| 475 | void | ||
| 476 | syms_of_sfntfont (void) | ||
| 477 | { | ||
| 478 | DEFSYM (Qutf_16be, "utf-16be"); | ||
| 479 | DEFSYM (Qmac_roman, "mac-roman"); | ||
| 480 | } | ||
| 481 | |||
| 482 | void | ||
| 483 | mark_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 | |||
| 3 | Copyright (C) 2023 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | This file is part of GNU Emacs. | ||
| 6 | |||
| 7 | GNU Emacs is free software: you can redistribute it and/or modify | ||
| 8 | it under the terms of the GNU General Public License as published by | ||
| 9 | the Free Software Foundation, either version 3 of the License, or (at | ||
| 10 | your option) any later version. | ||
| 11 | |||
| 12 | GNU Emacs is distributed in the hope that it will be useful, | ||
| 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | GNU General Public License for more details. | ||
| 16 | |||
| 17 | You should have received a copy of the GNU General Public License | ||
| 18 | along with GNU Emacs. If not, write to the Free Software Foundation, | ||
| 19 | Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | ||
| 20 | |||
| 21 | #ifndef _SFNTFONT_H_ | ||
| 22 | #define _SFNTFONT_H_ | ||
| 23 | |||
| 24 | extern int sfnt_enum_font (const char *); | ||
| 25 | |||
| 26 | #endif /* _SFNTFONT_H_ */ | ||