ReactOS 0.4.16-dev-2354-g16de117
ttcmap.c
Go to the documentation of this file.
1/****************************************************************************
2 *
3 * ttcmap.c
4 *
5 * TrueType character mapping table (cmap) support (body).
6 *
7 * Copyright (C) 2002-2020 by
8 * David Turner, Robert Wilhelm, and Werner Lemberg.
9 *
10 * This file is part of the FreeType project, and may only be used,
11 * modified, and distributed under the terms of the FreeType project
12 * license, LICENSE.TXT. By continuing to use, modify, or distribute
13 * this file you indicate that you have read the license and
14 * understand and accept it fully.
15 *
16 */
17
18
20
21#include "sferrors.h" /* must come before `ftvalid.h' */
22
26#include "ttload.h"
27#include "ttcmap.h"
28#include "ttpost.h"
29
30
31 /**************************************************************************
32 *
33 * The macro FT_COMPONENT is used in trace mode. It is an implicit
34 * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
35 * messages during execution.
36 */
37#undef FT_COMPONENT
38#define FT_COMPONENT ttcmap
39
40
41#define TT_PEEK_SHORT FT_PEEK_SHORT
42#define TT_PEEK_USHORT FT_PEEK_USHORT
43#define TT_PEEK_UINT24 FT_PEEK_UOFF3
44#define TT_PEEK_LONG FT_PEEK_LONG
45#define TT_PEEK_ULONG FT_PEEK_ULONG
46
47#define TT_NEXT_SHORT FT_NEXT_SHORT
48#define TT_NEXT_USHORT FT_NEXT_USHORT
49#define TT_NEXT_UINT24 FT_NEXT_UOFF3
50#define TT_NEXT_LONG FT_NEXT_LONG
51#define TT_NEXT_ULONG FT_NEXT_ULONG
52
53
54 /* Too large glyph index return values are caught in `FT_Get_Char_Index' */
55 /* and `FT_Get_Next_Char' (the latter calls the internal `next' function */
56 /* again in this case). To mark character code return values as invalid */
57 /* it is sufficient to set the corresponding glyph index return value to */
58 /* zero. */
59
60
63 FT_Byte* table )
64 {
65 cmap->data = table;
66 return FT_Err_Ok;
67 }
68
69
70 /*************************************************************************/
71 /*************************************************************************/
72 /***** *****/
73 /***** FORMAT 0 *****/
74 /***** *****/
75 /*************************************************************************/
76 /*************************************************************************/
77
78 /**************************************************************************
79 *
80 * TABLE OVERVIEW
81 * --------------
82 *
83 * NAME OFFSET TYPE DESCRIPTION
84 *
85 * format 0 USHORT must be 0
86 * length 2 USHORT table length in bytes
87 * language 4 USHORT Mac language code
88 * glyph_ids 6 BYTE[256] array of glyph indices
89 * 262
90 */
91
92#ifdef TT_CONFIG_CMAP_FORMAT_0
93
95 tt_cmap0_validate( FT_Byte* table,
97 {
98 FT_Byte* p;
100
101
102 if ( table + 2 + 2 > valid->limit )
104
105 p = table + 2; /* skip format */
107
108 if ( table + length > valid->limit || length < 262 )
110
111 /* check glyph indices whenever necessary */
112 if ( valid->level >= FT_VALIDATE_TIGHT )
113 {
114 FT_UInt n, idx;
115
116
117 p = table + 6;
118 for ( n = 0; n < 256; n++ )
119 {
120 idx = *p++;
121 if ( idx >= TT_VALID_GLYPH_COUNT( valid ) )
123 }
124 }
125
126 return FT_Err_Ok;
127 }
128
129
131 tt_cmap0_char_index( TT_CMap cmap,
132 FT_UInt32 char_code )
133 {
134 FT_Byte* table = cmap->data;
135
136
137 return char_code < 256 ? table[6 + char_code] : 0;
138 }
139
140
141 FT_CALLBACK_DEF( FT_UInt32 )
142 tt_cmap0_char_next( TT_CMap cmap,
143 FT_UInt32 *pchar_code )
144 {
145 FT_Byte* table = cmap->data;
146 FT_UInt32 charcode = *pchar_code;
147 FT_UInt32 result = 0;
148 FT_UInt gindex = 0;
149
150
151 table += 6; /* go to glyph IDs */
152 while ( ++charcode < 256 )
153 {
154 gindex = table[charcode];
155 if ( gindex != 0 )
156 {
157 result = charcode;
158 break;
159 }
160 }
161
162 *pchar_code = result;
163 return gindex;
164 }
165
166
168 tt_cmap0_get_info( TT_CMap cmap,
170 {
171 FT_Byte* p = cmap->data + 4;
172
173
174 cmap_info->format = 0;
176
177 return FT_Err_Ok;
178 }
179
180
182 tt_cmap0_class_rec,
183
184 sizeof ( TT_CMapRec ),
185
186 (FT_CMap_InitFunc) tt_cmap_init, /* init */
187 (FT_CMap_DoneFunc) NULL, /* done */
188 (FT_CMap_CharIndexFunc)tt_cmap0_char_index, /* char_index */
189 (FT_CMap_CharNextFunc) tt_cmap0_char_next, /* char_next */
190
191 (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */
192 (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */
193 (FT_CMap_VariantListFunc) NULL, /* variant_list */
194 (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */
195 (FT_CMap_VariantCharListFunc) NULL, /* variantchar_list */
196
197 0,
198 (TT_CMap_ValidateFunc)tt_cmap0_validate, /* validate */
199 (TT_CMap_Info_GetFunc)tt_cmap0_get_info /* get_cmap_info */
200 )
201
202#endif /* TT_CONFIG_CMAP_FORMAT_0 */
203
204
205 /*************************************************************************/
206 /*************************************************************************/
207 /***** *****/
208 /***** FORMAT 2 *****/
209 /***** *****/
210 /***** This is used for certain CJK encodings that encode text in a *****/
211 /***** mixed 8/16 bits encoding along the following lines. *****/
212 /***** *****/
213 /***** * Certain byte values correspond to an 8-bit character code *****/
214 /***** (typically in the range 0..127 for ASCII compatibility). *****/
215 /***** *****/
216 /***** * Certain byte values signal the first byte of a 2-byte *****/
217 /***** character code (but these values are also valid as the *****/
218 /***** second byte of a 2-byte character). *****/
219 /***** *****/
220 /***** The following charmap lookup and iteration functions all *****/
221 /***** assume that the value `charcode' fulfills the following. *****/
222 /***** *****/
223 /***** - For one-byte characters, `charcode' is simply the *****/
224 /***** character code. *****/
225 /***** *****/
226 /***** - For two-byte characters, `charcode' is the 2-byte *****/
227 /***** character code in big endian format. More precisely: *****/
228 /***** *****/
229 /***** (charcode >> 8) is the first byte value *****/
230 /***** (charcode & 0xFF) is the second byte value *****/
231 /***** *****/
232 /***** Note that not all values of `charcode' are valid according *****/
233 /***** to these rules, and the function moderately checks the *****/
234 /***** arguments. *****/
235 /***** *****/
236 /*************************************************************************/
237 /*************************************************************************/
238
239 /**************************************************************************
240 *
241 * TABLE OVERVIEW
242 * --------------
243 *
244 * NAME OFFSET TYPE DESCRIPTION
245 *
246 * format 0 USHORT must be 2
247 * length 2 USHORT table length in bytes
248 * language 4 USHORT Mac language code
249 * keys 6 USHORT[256] sub-header keys
250 * subs 518 SUBHEAD[NSUBS] sub-headers array
251 * glyph_ids 518+NSUB*8 USHORT[] glyph ID array
252 *
253 * The `keys' table is used to map charcode high bytes to sub-headers.
254 * The value of `NSUBS' is the number of sub-headers defined in the
255 * table and is computed by finding the maximum of the `keys' table.
256 *
257 * Note that for any `n', `keys[n]' is a byte offset within the `subs'
258 * table, i.e., it is the corresponding sub-header index multiplied
259 * by 8.
260 *
261 * Each sub-header has the following format.
262 *
263 * NAME OFFSET TYPE DESCRIPTION
264 *
265 * first 0 USHORT first valid low-byte
266 * count 2 USHORT number of valid low-bytes
267 * delta 4 SHORT see below
268 * offset 6 USHORT see below
269 *
270 * A sub-header defines, for each high byte, the range of valid
271 * low bytes within the charmap. Note that the range defined by `first'
272 * and `count' must be completely included in the interval [0..255]
273 * according to the specification.
274 *
275 * If a character code is contained within a given sub-header, then
276 * mapping it to a glyph index is done as follows.
277 *
278 * - The value of `offset' is read. This is a _byte_ distance from the
279 * location of the `offset' field itself into a slice of the
280 * `glyph_ids' table. Let's call it `slice' (it is a USHORT[], too).
281 *
282 * - The value `slice[char.lo - first]' is read. If it is 0, there is
283 * no glyph for the charcode. Otherwise, the value of `delta' is
284 * added to it (modulo 65536) to form a new glyph index.
285 *
286 * It is up to the validation routine to check that all offsets fall
287 * within the glyph IDs table (and not within the `subs' table itself or
288 * outside of the CMap).
289 */
290
291#ifdef TT_CONFIG_CMAP_FORMAT_2
292
294 tt_cmap2_validate( FT_Byte* table,
296 {
297 FT_Byte* p;
299
300 FT_UInt n, max_subs;
301 FT_Byte* keys; /* keys table */
302 FT_Byte* subs; /* sub-headers */
303 FT_Byte* glyph_ids; /* glyph ID array */
304
305
306 if ( table + 2 + 2 > valid->limit )
308
309 p = table + 2; /* skip format */
311
312 if ( table + length > valid->limit || length < 6 + 512 )
314
315 keys = table + 6;
316
317 /* parse keys to compute sub-headers count */
318 p = keys;
319 max_subs = 0;
320 for ( n = 0; n < 256; n++ )
321 {
323
324
325 /* value must be multiple of 8 */
326 if ( valid->level >= FT_VALIDATE_PARANOID && ( idx & 7 ) != 0 )
328
329 idx >>= 3;
330
331 if ( idx > max_subs )
332 max_subs = idx;
333 }
334
335 FT_ASSERT( p == table + 518 );
336
337 subs = p;
338 glyph_ids = subs + ( max_subs + 1 ) * 8;
339 if ( glyph_ids > valid->limit )
341
342 /* parse sub-headers */
343 for ( n = 0; n <= max_subs; n++ )
344 {
345 FT_UInt first_code, code_count, offset;
346 FT_Int delta;
347
348
349 first_code = TT_NEXT_USHORT( p );
350 code_count = TT_NEXT_USHORT( p );
351 delta = TT_NEXT_SHORT( p );
353
354 /* many Dynalab fonts have empty sub-headers */
355 if ( code_count == 0 )
356 continue;
357
358 /* check range within 0..255 */
359 if ( valid->level >= FT_VALIDATE_PARANOID )
360 {
361 if ( first_code >= 256 || code_count > 256 - first_code )
363 }
364
365 /* check offset */
366 if ( offset != 0 )
367 {
368 FT_Byte* ids;
369
370
371 ids = p - 2 + offset;
372 if ( ids < glyph_ids || ids + code_count * 2 > table + length )
374
375 /* check glyph IDs */
376 if ( valid->level >= FT_VALIDATE_TIGHT )
377 {
378 FT_Byte* limit = p + code_count * 2;
379 FT_UInt idx;
380
381
382 for ( ; p < limit; )
383 {
384 idx = TT_NEXT_USHORT( p );
385 if ( idx != 0 )
386 {
387 idx = (FT_UInt)( (FT_Int)idx + delta ) & 0xFFFFU;
388 if ( idx >= TT_VALID_GLYPH_COUNT( valid ) )
390 }
391 }
392 }
393 }
394 }
395
396 return FT_Err_Ok;
397 }
398
399
400 /* return sub header corresponding to a given character code */
401 /* NULL on invalid charcode */
402 static FT_Byte*
403 tt_cmap2_get_subheader( FT_Byte* table,
404 FT_UInt32 char_code )
405 {
407
408
409 if ( char_code < 0x10000UL )
410 {
411 FT_UInt char_lo = (FT_UInt)( char_code & 0xFF );
412 FT_UInt char_hi = (FT_UInt)( char_code >> 8 );
413 FT_Byte* p = table + 6; /* keys table */
414 FT_Byte* subs = table + 518; /* subheaders table */
415 FT_Byte* sub;
416
417
418 if ( char_hi == 0 )
419 {
420 /* an 8-bit character code -- we use subHeader 0 in this case */
421 /* to test whether the character code is in the charmap */
422 /* */
423 sub = subs; /* jump to first sub-header */
424
425 /* check that the sub-header for this byte is 0, which */
426 /* indicates that it is really a valid one-byte value; */
427 /* otherwise, return 0 */
428 /* */
429 p += char_lo * 2;
430 if ( TT_PEEK_USHORT( p ) != 0 )
431 goto Exit;
432 }
433 else
434 {
435 /* a 16-bit character code */
436
437 /* jump to key entry */
438 p += char_hi * 2;
439 /* jump to sub-header */
440 sub = subs + ( FT_PAD_FLOOR( TT_PEEK_USHORT( p ), 8 ) );
441
442 /* check that the high byte isn't a valid one-byte value */
443 if ( sub == subs )
444 goto Exit;
445 }
446
447 result = sub;
448 }
449
450 Exit:
451 return result;
452 }
453
454
456 tt_cmap2_char_index( TT_CMap cmap,
457 FT_UInt32 char_code )
458 {
459 FT_Byte* table = cmap->data;
460 FT_UInt result = 0;
461 FT_Byte* subheader;
462
463
464 subheader = tt_cmap2_get_subheader( table, char_code );
465 if ( subheader )
466 {
467 FT_Byte* p = subheader;
468 FT_UInt idx = (FT_UInt)(char_code & 0xFF);
470 FT_Int delta;
472
473
476 delta = TT_NEXT_SHORT ( p );
478
479 idx -= start;
480 if ( idx < count && offset != 0 )
481 {
482 p += offset + 2 * idx;
483 idx = TT_PEEK_USHORT( p );
484
485 if ( idx != 0 )
486 result = (FT_UInt)( (FT_Int)idx + delta ) & 0xFFFFU;
487 }
488 }
489
490 return result;
491 }
492
493
494 FT_CALLBACK_DEF( FT_UInt32 )
495 tt_cmap2_char_next( TT_CMap cmap,
496 FT_UInt32 *pcharcode )
497 {
498 FT_Byte* table = cmap->data;
499 FT_UInt gindex = 0;
500 FT_UInt32 result = 0;
501 FT_UInt32 charcode = *pcharcode + 1;
502 FT_Byte* subheader;
503
504
505 while ( charcode < 0x10000UL )
506 {
507 subheader = tt_cmap2_get_subheader( table, charcode );
508 if ( subheader )
509 {
510 FT_Byte* p = subheader;
513 FT_Int delta = TT_NEXT_SHORT ( p );
515 FT_UInt char_lo = (FT_UInt)( charcode & 0xFF );
516 FT_UInt pos, idx;
517
518
519 if ( char_lo >= start + count && charcode <= 0xFF )
520 {
521 /* this happens only for a malformed cmap */
522 charcode = 0x100;
523 continue;
524 }
525
526 if ( offset == 0 )
527 {
528 if ( charcode == 0x100 )
529 goto Exit; /* this happens only for a malformed cmap */
530 goto Next_SubHeader;
531 }
532
533 if ( char_lo < start )
534 {
535 char_lo = start;
536 pos = 0;
537 }
538 else
539 pos = (FT_UInt)( char_lo - start );
540
541 p += offset + pos * 2;
542 charcode = FT_PAD_FLOOR( charcode, 256 ) + char_lo;
543
544 for ( ; pos < count; pos++, charcode++ )
545 {
546 idx = TT_NEXT_USHORT( p );
547
548 if ( idx != 0 )
549 {
550 gindex = (FT_UInt)( (FT_Int)idx + delta ) & 0xFFFFU;
551 if ( gindex != 0 )
552 {
553 result = charcode;
554 goto Exit;
555 }
556 }
557 }
558
559 /* if unsuccessful, avoid `charcode' leaving */
560 /* the current 256-character block */
561 if ( count )
562 charcode--;
563 }
564
565 /* If `charcode' is <= 0xFF, retry with `charcode + 1'. */
566 /* Otherwise jump to the next 256-character block and retry. */
567 Next_SubHeader:
568 if ( charcode <= 0xFF )
569 charcode++;
570 else
571 charcode = FT_PAD_FLOOR( charcode, 0x100 ) + 0x100;
572 }
573
574 Exit:
575 *pcharcode = result;
576
577 return gindex;
578 }
579
580
582 tt_cmap2_get_info( TT_CMap cmap,
584 {
585 FT_Byte* p = cmap->data + 4;
586
587
588 cmap_info->format = 2;
590
591 return FT_Err_Ok;
592 }
593
594
596 tt_cmap2_class_rec,
597
598 sizeof ( TT_CMapRec ),
599
600 (FT_CMap_InitFunc) tt_cmap_init, /* init */
601 (FT_CMap_DoneFunc) NULL, /* done */
602 (FT_CMap_CharIndexFunc)tt_cmap2_char_index, /* char_index */
603 (FT_CMap_CharNextFunc) tt_cmap2_char_next, /* char_next */
604
605 (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */
606 (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */
607 (FT_CMap_VariantListFunc) NULL, /* variant_list */
608 (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */
609 (FT_CMap_VariantCharListFunc) NULL, /* variantchar_list */
610
611 2,
612 (TT_CMap_ValidateFunc)tt_cmap2_validate, /* validate */
613 (TT_CMap_Info_GetFunc)tt_cmap2_get_info /* get_cmap_info */
614 )
615
616#endif /* TT_CONFIG_CMAP_FORMAT_2 */
617
618
619 /*************************************************************************/
620 /*************************************************************************/
621 /***** *****/
622 /***** FORMAT 4 *****/
623 /***** *****/
624 /*************************************************************************/
625 /*************************************************************************/
626
627 /**************************************************************************
628 *
629 * TABLE OVERVIEW
630 * --------------
631 *
632 * NAME OFFSET TYPE DESCRIPTION
633 *
634 * format 0 USHORT must be 4
635 * length 2 USHORT table length
636 * in bytes
637 * language 4 USHORT Mac language code
638 *
639 * segCountX2 6 USHORT 2*NUM_SEGS
640 * searchRange 8 USHORT 2*(1 << LOG_SEGS)
641 * entrySelector 10 USHORT LOG_SEGS
642 * rangeShift 12 USHORT segCountX2 -
643 * searchRange
644 *
645 * endCount 14 USHORT[NUM_SEGS] end charcode for
646 * each segment; last
647 * is 0xFFFF
648 *
649 * pad 14+NUM_SEGS*2 USHORT padding
650 *
651 * startCount 16+NUM_SEGS*2 USHORT[NUM_SEGS] first charcode for
652 * each segment
653 *
654 * idDelta 16+NUM_SEGS*4 SHORT[NUM_SEGS] delta for each
655 * segment
656 * idOffset 16+NUM_SEGS*6 SHORT[NUM_SEGS] range offset for
657 * each segment; can be
658 * zero
659 *
660 * glyphIds 16+NUM_SEGS*8 USHORT[] array of glyph ID
661 * ranges
662 *
663 * Character codes are modelled by a series of ordered (increasing)
664 * intervals called segments. Each segment has start and end codes,
665 * provided by the `startCount' and `endCount' arrays. Segments must
666 * not overlap, and the last segment should always contain the value
667 * 0xFFFF for `endCount'.
668 *
669 * The fields `searchRange', `entrySelector' and `rangeShift' are better
670 * ignored (they are traces of over-engineering in the TrueType
671 * specification).
672 *
673 * Each segment also has a signed `delta', as well as an optional offset
674 * within the `glyphIds' table.
675 *
676 * If a segment's idOffset is 0, the glyph index corresponding to any
677 * charcode within the segment is obtained by adding the value of
678 * `idDelta' directly to the charcode, modulo 65536.
679 *
680 * Otherwise, a glyph index is taken from the glyph IDs sub-array for
681 * the segment, and the value of `idDelta' is added to it.
682 *
683 *
684 * Finally, note that a lot of fonts contain an invalid last segment,
685 * where `start' and `end' are correctly set to 0xFFFF but both `delta'
686 * and `offset' are incorrect (e.g., `opens___.ttf' which comes with
687 * OpenOffice.org). We need special code to deal with them correctly.
688 */
689
690#ifdef TT_CONFIG_CMAP_FORMAT_4
691
692 typedef struct TT_CMap4Rec_
693 {
694 TT_CMapRec cmap;
695 FT_UInt32 cur_charcode; /* current charcode */
696 FT_UInt cur_gindex; /* current glyph index */
697
698 FT_UInt num_ranges;
699 FT_UInt cur_range;
700 FT_UInt cur_start;
701 FT_UInt cur_end;
702 FT_Int cur_delta;
703 FT_Byte* cur_values;
704
705 } TT_CMap4Rec, *TT_CMap4;
706
707
709 tt_cmap4_init( TT_CMap4 cmap,
710 FT_Byte* table )
711 {
712 FT_Byte* p;
713
714
715 cmap->cmap.data = table;
716
717 p = table + 6;
718 cmap->num_ranges = FT_PEEK_USHORT( p ) >> 1;
719 cmap->cur_charcode = (FT_UInt32)0xFFFFFFFFUL;
720 cmap->cur_gindex = 0;
721
722 return FT_Err_Ok;
723 }
724
725
726 static FT_Int
727 tt_cmap4_set_range( TT_CMap4 cmap,
728 FT_UInt range_index )
729 {
730 FT_Byte* table = cmap->cmap.data;
731 FT_Byte* p;
732 FT_UInt num_ranges = cmap->num_ranges;
733
734
735 while ( range_index < num_ranges )
736 {
738
739
740 p = table + 14 + range_index * 2;
741 cmap->cur_end = FT_PEEK_USHORT( p );
742
743 p += 2 + num_ranges * 2;
744 cmap->cur_start = FT_PEEK_USHORT( p );
745
746 p += num_ranges * 2;
747 cmap->cur_delta = FT_PEEK_SHORT( p );
748
749 p += num_ranges * 2;
751
752 /* some fonts have an incorrect last segment; */
753 /* we have to catch it */
754 if ( range_index >= num_ranges - 1 &&
755 cmap->cur_start == 0xFFFFU &&
756 cmap->cur_end == 0xFFFFU )
757 {
758 TT_Face face = (TT_Face)cmap->cmap.cmap.charmap.face;
759 FT_Byte* limit = face->cmap_table + face->cmap_size;
760
761
762 if ( offset && p + offset + 2 > limit )
763 {
764 cmap->cur_delta = 1;
765 offset = 0;
766 }
767 }
768
769 if ( offset != 0xFFFFU )
770 {
771 cmap->cur_values = offset ? p + offset : NULL;
772 cmap->cur_range = range_index;
773 return 0;
774 }
775
776 /* we skip empty segments */
777 range_index++;
778 }
779
780 return -1;
781 }
782
783
784 /* search the index of the charcode next to cmap->cur_charcode; */
785 /* caller should call tt_cmap4_set_range with proper range */
786 /* before calling this function */
787 /* */
788 static void
789 tt_cmap4_next( TT_CMap4 cmap )
790 {
791 TT_Face face = (TT_Face)cmap->cmap.cmap.charmap.face;
792 FT_Byte* limit = face->cmap_table + face->cmap_size;
793
794 FT_UInt charcode;
795
796
797 if ( cmap->cur_charcode >= 0xFFFFUL )
798 goto Fail;
799
800 charcode = (FT_UInt)cmap->cur_charcode + 1;
801
802 if ( charcode < cmap->cur_start )
803 charcode = cmap->cur_start;
804
805 for (;;)
806 {
807 FT_Byte* values = cmap->cur_values;
808 FT_UInt end = cmap->cur_end;
809 FT_Int delta = cmap->cur_delta;
810
811
812 if ( charcode <= end )
813 {
814 if ( values )
815 {
816 FT_Byte* p = values + 2 * ( charcode - cmap->cur_start );
817
818
819 /* if p > limit, the whole segment is invalid */
820 if ( p > limit )
821 goto Next_Segment;
822
823 do
824 {
825 FT_UInt gindex = FT_NEXT_USHORT( p );
826
827
828 if ( gindex )
829 {
830 gindex = (FT_UInt)( (FT_Int)gindex + delta ) & 0xFFFFU;
831 if ( gindex )
832 {
833 cmap->cur_charcode = charcode;
834 cmap->cur_gindex = gindex;
835 return;
836 }
837 }
838 } while ( ++charcode <= end );
839 }
840 else
841 {
842 do
843 {
844 FT_UInt gindex = (FT_UInt)( (FT_Int)charcode + delta ) & 0xFFFFU;
845
846
847 if ( gindex >= (FT_UInt)face->root.num_glyphs )
848 {
849 /* we have an invalid glyph index; if there is an overflow, */
850 /* we can adjust `charcode', otherwise the whole segment is */
851 /* invalid */
852 gindex = 0;
853
854 if ( (FT_Int)charcode + delta < 0 &&
855 (FT_Int)end + delta >= 0 )
856 charcode = (FT_UInt)( -delta );
857
858 else if ( (FT_Int)charcode + delta < 0x10000L &&
859 (FT_Int)end + delta >= 0x10000L )
860 charcode = (FT_UInt)( 0x10000L - delta );
861
862 else
863 goto Next_Segment;
864 }
865
866 if ( gindex )
867 {
868 cmap->cur_charcode = charcode;
869 cmap->cur_gindex = gindex;
870 return;
871 }
872 } while ( ++charcode <= end );
873 }
874 }
875
876 Next_Segment:
877 /* we need to find another range */
878 if ( tt_cmap4_set_range( cmap, cmap->cur_range + 1 ) < 0 )
879 break;
880
881 if ( charcode < cmap->cur_start )
882 charcode = cmap->cur_start;
883 }
884
885 Fail:
886 cmap->cur_charcode = (FT_UInt32)0xFFFFFFFFUL;
887 cmap->cur_gindex = 0;
888 }
889
890
892 tt_cmap4_validate( FT_Byte* table,
894 {
895 FT_Byte* p;
897
898 FT_Byte *ends, *starts, *offsets, *deltas, *glyph_ids;
899 FT_UInt num_segs;
901
902
903 if ( table + 2 + 2 > valid->limit )
905
906 p = table + 2; /* skip format */
908
909 /* in certain fonts, the `length' field is invalid and goes */
910 /* out of bound. We try to correct this here... */
911 if ( table + length > valid->limit )
912 {
913 if ( valid->level >= FT_VALIDATE_TIGHT )
915
916 length = (FT_UInt)( valid->limit - table );
917 }
918
919 if ( length < 16 )
921
922 p = table + 6;
923 num_segs = TT_NEXT_USHORT( p ); /* read segCountX2 */
924
925 if ( valid->level >= FT_VALIDATE_PARANOID )
926 {
927 /* check that we have an even value here */
928 if ( num_segs & 1 )
930 }
931
932 num_segs /= 2;
933
934 if ( length < 16 + num_segs * 2 * 4 )
936
937 /* check the search parameters - even though we never use them */
938 /* */
939 if ( valid->level >= FT_VALIDATE_PARANOID )
940 {
941 /* check the values of `searchRange', `entrySelector', `rangeShift' */
942 FT_UInt search_range = TT_NEXT_USHORT( p );
943 FT_UInt entry_selector = TT_NEXT_USHORT( p );
944 FT_UInt range_shift = TT_NEXT_USHORT( p );
945
946
947 if ( ( search_range | range_shift ) & 1 ) /* must be even values */
949
950 search_range /= 2;
951 range_shift /= 2;
952
953 /* `search range' is the greatest power of 2 that is <= num_segs */
954
955 if ( search_range > num_segs ||
956 search_range * 2 < num_segs ||
957 search_range + range_shift != num_segs ||
958 search_range != ( 1U << entry_selector ) )
960 }
961
962 ends = table + 14;
963 starts = table + 16 + num_segs * 2;
964 deltas = starts + num_segs * 2;
965 offsets = deltas + num_segs * 2;
966 glyph_ids = offsets + num_segs * 2;
967
968 /* check last segment; its end count value must be 0xFFFF */
969 if ( valid->level >= FT_VALIDATE_PARANOID )
970 {
971 p = ends + ( num_segs - 1 ) * 2;
972 if ( TT_PEEK_USHORT( p ) != 0xFFFFU )
974 }
975
976 {
978 FT_UInt last_start = 0, last_end = 0;
979 FT_Int delta;
980 FT_Byte* p_start = starts;
981 FT_Byte* p_end = ends;
982 FT_Byte* p_delta = deltas;
983 FT_Byte* p_offset = offsets;
984
985
986 for ( n = 0; n < num_segs; n++ )
987 {
988 p = p_offset;
989 start = TT_NEXT_USHORT( p_start );
990 end = TT_NEXT_USHORT( p_end );
991 delta = TT_NEXT_SHORT( p_delta );
992 offset = TT_NEXT_USHORT( p_offset );
993
994 if ( start > end )
996
997 /* this test should be performed at default validation level; */
998 /* unfortunately, some popular Asian fonts have overlapping */
999 /* ranges in their charmaps */
1000 /* */
1001 if ( start <= last_end && n > 0 )
1002 {
1003 if ( valid->level >= FT_VALIDATE_TIGHT )
1005 else
1006 {
1007 /* allow overlapping segments, provided their start points */
1008 /* and end points, respectively, are in ascending order */
1009 /* */
1010 if ( last_start > start || last_end > end )
1012 else
1014 }
1015 }
1016
1017 if ( offset && offset != 0xFFFFU )
1018 {
1019 p += offset; /* start of glyph ID array */
1020
1021 /* check that we point within the glyph IDs table only */
1022 if ( valid->level >= FT_VALIDATE_TIGHT )
1023 {
1024 if ( p < glyph_ids ||
1025 p + ( end - start + 1 ) * 2 > table + length )
1027 }
1028 /* Some fonts handle the last segment incorrectly. In */
1029 /* theory, 0xFFFF might point to an ordinary glyph -- */
1030 /* a cmap 4 is versatile and could be used for any */
1031 /* encoding, not only Unicode. However, reality shows */
1032 /* that far too many fonts are sloppy and incorrectly */
1033 /* set all fields but `start' and `end' for the last */
1034 /* segment if it contains only a single character. */
1035 /* */
1036 /* We thus omit the test here, delaying it to the */
1037 /* routines that actually access the cmap. */
1038 else if ( n != num_segs - 1 ||
1039 !( start == 0xFFFFU && end == 0xFFFFU ) )
1040 {
1041 if ( p < glyph_ids ||
1042 p + ( end - start + 1 ) * 2 > valid->limit )
1044 }
1045
1046 /* check glyph indices within the segment range */
1047 if ( valid->level >= FT_VALIDATE_TIGHT )
1048 {
1049 FT_UInt i, idx;
1050
1051
1052 for ( i = start; i < end; i++ )
1053 {
1054 idx = FT_NEXT_USHORT( p );
1055 if ( idx != 0 )
1056 {
1057 idx = (FT_UInt)( (FT_Int)idx + delta ) & 0xFFFFU;
1058
1059 if ( idx >= TT_VALID_GLYPH_COUNT( valid ) )
1061 }
1062 }
1063 }
1064 }
1065 else if ( offset == 0xFFFFU )
1066 {
1067 /* some fonts (erroneously?) use a range offset of 0xFFFF */
1068 /* to mean missing glyph in cmap table */
1069 /* */
1070 if ( valid->level >= FT_VALIDATE_PARANOID ||
1071 n != num_segs - 1 ||
1072 !( start == 0xFFFFU && end == 0xFFFFU ) )
1074 }
1075
1076 last_start = start;
1077 last_end = end;
1078 }
1079 }
1080
1081 return error;
1082 }
1083
1084
1085 static FT_UInt
1086 tt_cmap4_char_map_linear( TT_CMap cmap,
1087 FT_UInt32* pcharcode,
1088 FT_Bool next )
1089 {
1091 FT_Byte* limit = face->cmap_table + face->cmap_size;
1092
1093
1094 FT_UInt num_segs2, start, end, offset;
1095 FT_Int delta;
1096 FT_UInt i, num_segs;
1097 FT_UInt32 charcode = *pcharcode;
1098 FT_UInt gindex = 0;
1099 FT_Byte* p;
1100 FT_Byte* q;
1101
1102
1103 p = cmap->data + 6;
1104 num_segs2 = FT_PAD_FLOOR( TT_PEEK_USHORT( p ), 2 );
1105
1106 num_segs = num_segs2 >> 1;
1107
1108 if ( !num_segs )
1109 return 0;
1110
1111 if ( next )
1112 charcode++;
1113
1114 if ( charcode > 0xFFFFU )
1115 return 0;
1116
1117 /* linear search */
1118 p = cmap->data + 14; /* ends table */
1119 q = cmap->data + 16 + num_segs2; /* starts table */
1120
1121 for ( i = 0; i < num_segs; i++ )
1122 {
1123 end = TT_NEXT_USHORT( p );
1124 start = TT_NEXT_USHORT( q );
1125
1126 if ( charcode < start )
1127 {
1128 if ( next )
1129 charcode = start;
1130 else
1131 break;
1132 }
1133
1134 Again:
1135 if ( charcode <= end )
1136 {
1137 FT_Byte* r;
1138
1139
1140 r = q - 2 + num_segs2;
1141 delta = TT_PEEK_SHORT( r );
1142 r += num_segs2;
1143 offset = TT_PEEK_USHORT( r );
1144
1145 /* some fonts have an incorrect last segment; */
1146 /* we have to catch it */
1147 if ( i >= num_segs - 1 &&
1148 start == 0xFFFFU && end == 0xFFFFU )
1149 {
1150 if ( offset && r + offset + 2 > limit )
1151 {
1152 delta = 1;
1153 offset = 0;
1154 }
1155 }
1156
1157 if ( offset == 0xFFFFU )
1158 continue;
1159
1160 if ( offset )
1161 {
1162 r += offset + ( charcode - start ) * 2;
1163
1164 /* if r > limit, the whole segment is invalid */
1165 if ( next && r > limit )
1166 continue;
1167
1168 gindex = TT_PEEK_USHORT( r );
1169 if ( gindex )
1170 {
1171 gindex = (FT_UInt)( (FT_Int)gindex + delta ) & 0xFFFFU;
1172 if ( gindex >= (FT_UInt)face->root.num_glyphs )
1173 gindex = 0;
1174 }
1175 }
1176 else
1177 {
1178 gindex = (FT_UInt)( (FT_Int)charcode + delta ) & 0xFFFFU;
1179
1180 if ( next && gindex >= (FT_UInt)face->root.num_glyphs )
1181 {
1182 /* we have an invalid glyph index; if there is an overflow, */
1183 /* we can adjust `charcode', otherwise the whole segment is */
1184 /* invalid */
1185 gindex = 0;
1186
1187 if ( (FT_Int)charcode + delta < 0 &&
1188 (FT_Int)end + delta >= 0 )
1189 charcode = (FT_UInt)( -delta );
1190
1191 else if ( (FT_Int)charcode + delta < 0x10000L &&
1192 (FT_Int)end + delta >= 0x10000L )
1193 charcode = (FT_UInt)( 0x10000L - delta );
1194
1195 else
1196 continue;
1197 }
1198 }
1199
1200 if ( next && !gindex )
1201 {
1202 if ( charcode >= 0xFFFFU )
1203 break;
1204
1205 charcode++;
1206 goto Again;
1207 }
1208
1209 break;
1210 }
1211 }
1212
1213 if ( next )
1214 *pcharcode = charcode;
1215
1216 return gindex;
1217 }
1218
1219
1220 static FT_UInt
1221 tt_cmap4_char_map_binary( TT_CMap cmap,
1222 FT_UInt32* pcharcode,
1223 FT_Bool next )
1224 {
1226 FT_Byte* limit = face->cmap_table + face->cmap_size;
1227
1228 FT_UInt num_segs2, start, end, offset;
1229 FT_Int delta;
1230 FT_UInt max, min, mid, num_segs;
1231 FT_UInt charcode = (FT_UInt)*pcharcode;
1232 FT_UInt gindex = 0;
1233 FT_Byte* p;
1234
1235#ifdef __REACTOS__
1236 static FT_UInt bWarnOnce = 0;
1237 /* FIXME: HACK for ReactOS not updating fonts when new font copied
1238 * over existing one. Verify that the table number is 4. CORE-12549 */
1239 if (TT_PEEK_USHORT(cmap->data) != 4)
1240 {
1241 if (!bWarnOnce)
1242 {
1243 FT_ERROR(( "Bad cmap table number. Probable update font error in file\n"
1244 "'%s'\nPlease reboot and try again.\n", __FILE__ ));
1245 bWarnOnce++;
1246 }
1247 return 0;
1248 }
1249#endif
1250
1251 p = cmap->data + 6;
1252 num_segs2 = FT_PAD_FLOOR( TT_PEEK_USHORT( p ), 2 );
1253
1254 if ( !num_segs2 )
1255 return 0;
1256
1257 num_segs = num_segs2 >> 1;
1258
1259 /* make compiler happy */
1260 mid = num_segs;
1261 end = 0xFFFFU;
1262
1263 if ( next )
1264 charcode++;
1265
1266 min = 0;
1267 max = num_segs;
1268
1269 /* binary search */
1270 while ( min < max )
1271 {
1272 mid = ( min + max ) >> 1;
1273 p = cmap->data + 14 + mid * 2;
1274 end = TT_PEEK_USHORT( p );
1275 p += 2 + num_segs2;
1276 start = TT_PEEK_USHORT( p );
1277
1278 if ( charcode < start )
1279 max = mid;
1280 else if ( charcode > end )
1281 min = mid + 1;
1282 else
1283 {
1284 p += num_segs2;
1285 delta = TT_PEEK_SHORT( p );
1286 p += num_segs2;
1287 offset = TT_PEEK_USHORT( p );
1288
1289 /* some fonts have an incorrect last segment; */
1290 /* we have to catch it */
1291 if ( mid >= num_segs - 1 &&
1292 start == 0xFFFFU && end == 0xFFFFU )
1293 {
1294 if ( offset && p + offset + 2 > limit )
1295 {
1296 delta = 1;
1297 offset = 0;
1298 }
1299 }
1300
1301 /* search the first segment containing `charcode' */
1302 if ( cmap->flags & TT_CMAP_FLAG_OVERLAPPING )
1303 {
1304 FT_UInt i;
1305
1306
1307 /* call the current segment `max' */
1308 max = mid;
1309
1310 if ( offset == 0xFFFFU )
1311 mid = max + 1;
1312
1313 /* search in segments before the current segment */
1314 for ( i = max; i > 0; i-- )
1315 {
1316 FT_UInt prev_end;
1317 FT_Byte* old_p;
1318
1319
1320 old_p = p;
1321 p = cmap->data + 14 + ( i - 1 ) * 2;
1322 prev_end = TT_PEEK_USHORT( p );
1323
1324 if ( charcode > prev_end )
1325 {
1326 p = old_p;
1327 break;
1328 }
1329
1330 end = prev_end;
1331 p += 2 + num_segs2;
1332 start = TT_PEEK_USHORT( p );
1333 p += num_segs2;
1334 delta = TT_PEEK_SHORT( p );
1335 p += num_segs2;
1336 offset = TT_PEEK_USHORT( p );
1337
1338 if ( offset != 0xFFFFU )
1339 mid = i - 1;
1340 }
1341
1342 /* no luck */
1343 if ( mid == max + 1 )
1344 {
1345 if ( i != max )
1346 {
1347 p = cmap->data + 14 + max * 2;
1348 end = TT_PEEK_USHORT( p );
1349 p += 2 + num_segs2;
1350 start = TT_PEEK_USHORT( p );
1351 p += num_segs2;
1352 delta = TT_PEEK_SHORT( p );
1353 p += num_segs2;
1354 offset = TT_PEEK_USHORT( p );
1355 }
1356
1357 mid = max;
1358
1359 /* search in segments after the current segment */
1360 for ( i = max + 1; i < num_segs; i++ )
1361 {
1362 FT_UInt next_end, next_start;
1363
1364
1365 p = cmap->data + 14 + i * 2;
1366 next_end = TT_PEEK_USHORT( p );
1367 p += 2 + num_segs2;
1368 next_start = TT_PEEK_USHORT( p );
1369
1370 if ( charcode < next_start )
1371 break;
1372
1373 end = next_end;
1374 start = next_start;
1375 p += num_segs2;
1376 delta = TT_PEEK_SHORT( p );
1377 p += num_segs2;
1378 offset = TT_PEEK_USHORT( p );
1379
1380 if ( offset != 0xFFFFU )
1381 mid = i;
1382 }
1383 i--;
1384
1385 /* still no luck */
1386 if ( mid == max )
1387 {
1388 mid = i;
1389
1390 break;
1391 }
1392 }
1393
1394 /* end, start, delta, and offset are for the i'th segment */
1395 if ( mid != i )
1396 {
1397 p = cmap->data + 14 + mid * 2;
1398 end = TT_PEEK_USHORT( p );
1399 p += 2 + num_segs2;
1400 start = TT_PEEK_USHORT( p );
1401 p += num_segs2;
1402 delta = TT_PEEK_SHORT( p );
1403 p += num_segs2;
1404 offset = TT_PEEK_USHORT( p );
1405 }
1406 }
1407 else
1408 {
1409 if ( offset == 0xFFFFU )
1410 break;
1411 }
1412
1413 if ( offset )
1414 {
1415 p += offset + ( charcode - start ) * 2;
1416
1417 /* if p > limit, the whole segment is invalid */
1418 if ( next && p > limit )
1419 break;
1420
1421 gindex = TT_PEEK_USHORT( p );
1422 if ( gindex )
1423 {
1424 gindex = (FT_UInt)( (FT_Int)gindex + delta ) & 0xFFFFU;
1425 if ( gindex >= (FT_UInt)face->root.num_glyphs )
1426 gindex = 0;
1427 }
1428 }
1429 else
1430 {
1431 gindex = (FT_UInt)( (FT_Int)charcode + delta ) & 0xFFFFU;
1432
1433 if ( next && gindex >= (FT_UInt)face->root.num_glyphs )
1434 {
1435 /* we have an invalid glyph index; if there is an overflow, */
1436 /* we can adjust `charcode', otherwise the whole segment is */
1437 /* invalid */
1438 gindex = 0;
1439
1440 if ( (FT_Int)charcode + delta < 0 &&
1441 (FT_Int)end + delta >= 0 )
1442 charcode = (FT_UInt)( -delta );
1443
1444 else if ( (FT_Int)charcode + delta < 0x10000L &&
1445 (FT_Int)end + delta >= 0x10000L )
1446 charcode = (FT_UInt)( 0x10000L - delta );
1447 }
1448 }
1449
1450 break;
1451 }
1452 }
1453
1454 if ( next )
1455 {
1456 TT_CMap4 cmap4 = (TT_CMap4)cmap;
1457
1458
1459 /* if `charcode' is not in any segment, then `mid' is */
1460 /* the segment nearest to `charcode' */
1461
1462 if ( charcode > end )
1463 {
1464 mid++;
1465 if ( mid == num_segs )
1466 return 0;
1467 }
1468
1469 if ( tt_cmap4_set_range( cmap4, mid ) )
1470 {
1471 if ( gindex )
1472 *pcharcode = charcode;
1473 }
1474 else
1475 {
1476 cmap4->cur_charcode = charcode;
1477
1478 if ( gindex )
1479 cmap4->cur_gindex = gindex;
1480 else
1481 {
1482 cmap4->cur_charcode = charcode;
1483 tt_cmap4_next( cmap4 );
1484 gindex = cmap4->cur_gindex;
1485 }
1486
1487 if ( gindex )
1488 *pcharcode = cmap4->cur_charcode;
1489 }
1490 }
1491
1492 return gindex;
1493 }
1494
1495
1497 tt_cmap4_char_index( TT_CMap cmap,
1498 FT_UInt32 char_code )
1499 {
1500 if ( char_code >= 0x10000UL )
1501 return 0;
1502
1503 if ( cmap->flags & TT_CMAP_FLAG_UNSORTED )
1504 return tt_cmap4_char_map_linear( cmap, &char_code, 0 );
1505 else
1506 return tt_cmap4_char_map_binary( cmap, &char_code, 0 );
1507 }
1508
1509
1510 FT_CALLBACK_DEF( FT_UInt32 )
1511 tt_cmap4_char_next( TT_CMap cmap,
1512 FT_UInt32 *pchar_code )
1513 {
1514 FT_UInt gindex;
1515
1516
1517 if ( *pchar_code >= 0xFFFFU )
1518 return 0;
1519
1520 if ( cmap->flags & TT_CMAP_FLAG_UNSORTED )
1521 gindex = tt_cmap4_char_map_linear( cmap, pchar_code, 1 );
1522 else
1523 {
1524 TT_CMap4 cmap4 = (TT_CMap4)cmap;
1525
1526
1527 /* no need to search */
1528 if ( *pchar_code == cmap4->cur_charcode )
1529 {
1530 tt_cmap4_next( cmap4 );
1531 gindex = cmap4->cur_gindex;
1532 if ( gindex )
1533 *pchar_code = cmap4->cur_charcode;
1534 }
1535 else
1536 gindex = tt_cmap4_char_map_binary( cmap, pchar_code, 1 );
1537 }
1538
1539 return gindex;
1540 }
1541
1542
1544 tt_cmap4_get_info( TT_CMap cmap,
1546 {
1547 FT_Byte* p = cmap->data + 4;
1548
1549
1550 cmap_info->format = 4;
1552
1553 return FT_Err_Ok;
1554 }
1555
1556
1558 tt_cmap4_class_rec,
1559
1560 sizeof ( TT_CMap4Rec ),
1561
1562 (FT_CMap_InitFunc) tt_cmap4_init, /* init */
1563 (FT_CMap_DoneFunc) NULL, /* done */
1564 (FT_CMap_CharIndexFunc)tt_cmap4_char_index, /* char_index */
1565 (FT_CMap_CharNextFunc) tt_cmap4_char_next, /* char_next */
1566
1567 (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */
1568 (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */
1569 (FT_CMap_VariantListFunc) NULL, /* variant_list */
1570 (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */
1571 (FT_CMap_VariantCharListFunc) NULL, /* variantchar_list */
1572
1573 4,
1574 (TT_CMap_ValidateFunc)tt_cmap4_validate, /* validate */
1575 (TT_CMap_Info_GetFunc)tt_cmap4_get_info /* get_cmap_info */
1576 )
1577
1578#endif /* TT_CONFIG_CMAP_FORMAT_4 */
1579
1580
1581 /*************************************************************************/
1582 /*************************************************************************/
1583 /***** *****/
1584 /***** FORMAT 6 *****/
1585 /***** *****/
1586 /*************************************************************************/
1587 /*************************************************************************/
1588
1589 /**************************************************************************
1590 *
1591 * TABLE OVERVIEW
1592 * --------------
1593 *
1594 * NAME OFFSET TYPE DESCRIPTION
1595 *
1596 * format 0 USHORT must be 6
1597 * length 2 USHORT table length in bytes
1598 * language 4 USHORT Mac language code
1599 *
1600 * first 6 USHORT first segment code
1601 * count 8 USHORT segment size in chars
1602 * glyphIds 10 USHORT[count] glyph IDs
1603 *
1604 * A very simplified segment mapping.
1605 */
1606
1607#ifdef TT_CONFIG_CMAP_FORMAT_6
1608
1610 tt_cmap6_validate( FT_Byte* table,
1612 {
1613 FT_Byte* p;
1615
1616
1617 if ( table + 10 > valid->limit )
1619
1620 p = table + 2;
1621 length = TT_NEXT_USHORT( p );
1622
1623 p = table + 8; /* skip language and start index */
1624 count = TT_NEXT_USHORT( p );
1625
1626 if ( table + length > valid->limit || length < 10 + count * 2 )
1628
1629 /* check glyph indices */
1630 if ( valid->level >= FT_VALIDATE_TIGHT )
1631 {
1632 FT_UInt gindex;
1633
1634
1635 for ( ; count > 0; count-- )
1636 {
1637 gindex = TT_NEXT_USHORT( p );
1638 if ( gindex >= TT_VALID_GLYPH_COUNT( valid ) )
1640 }
1641 }
1642
1643 return FT_Err_Ok;
1644 }
1645
1646
1648 tt_cmap6_char_index( TT_CMap cmap,
1649 FT_UInt32 char_code )
1650 {
1651 FT_Byte* table = cmap->data;
1652 FT_UInt result = 0;
1653 FT_Byte* p = table + 6;
1656 FT_UInt idx = (FT_UInt)( char_code - start );
1657
1658
1659 if ( idx < count )
1660 {
1661 p += 2 * idx;
1662 result = TT_PEEK_USHORT( p );
1663 }
1664
1665 return result;
1666 }
1667
1668
1669 FT_CALLBACK_DEF( FT_UInt32 )
1670 tt_cmap6_char_next( TT_CMap cmap,
1671 FT_UInt32 *pchar_code )
1672 {
1673 FT_Byte* table = cmap->data;
1674 FT_UInt32 result = 0;
1675 FT_UInt32 char_code = *pchar_code + 1;
1676 FT_UInt gindex = 0;
1677
1678 FT_Byte* p = table + 6;
1681 FT_UInt idx;
1682
1683
1684 if ( char_code >= 0x10000UL )
1685 return 0;
1686
1687 if ( char_code < start )
1688 char_code = start;
1689
1690 idx = (FT_UInt)( char_code - start );
1691 p += 2 * idx;
1692
1693 for ( ; idx < count; idx++ )
1694 {
1695 gindex = TT_NEXT_USHORT( p );
1696 if ( gindex != 0 )
1697 {
1698 result = char_code;
1699 break;
1700 }
1701
1702 if ( char_code >= 0xFFFFU )
1703 return 0;
1704
1705 char_code++;
1706 }
1707
1708 *pchar_code = result;
1709 return gindex;
1710 }
1711
1712
1714 tt_cmap6_get_info( TT_CMap cmap,
1716 {
1717 FT_Byte* p = cmap->data + 4;
1718
1719
1720 cmap_info->format = 6;
1722
1723 return FT_Err_Ok;
1724 }
1725
1726
1728 tt_cmap6_class_rec,
1729
1730 sizeof ( TT_CMapRec ),
1731
1732 (FT_CMap_InitFunc) tt_cmap_init, /* init */
1733 (FT_CMap_DoneFunc) NULL, /* done */
1734 (FT_CMap_CharIndexFunc)tt_cmap6_char_index, /* char_index */
1735 (FT_CMap_CharNextFunc) tt_cmap6_char_next, /* char_next */
1736
1737 (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */
1738 (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */
1739 (FT_CMap_VariantListFunc) NULL, /* variant_list */
1740 (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */
1741 (FT_CMap_VariantCharListFunc) NULL, /* variantchar_list */
1742
1743 6,
1744 (TT_CMap_ValidateFunc)tt_cmap6_validate, /* validate */
1745 (TT_CMap_Info_GetFunc)tt_cmap6_get_info /* get_cmap_info */
1746 )
1747
1748#endif /* TT_CONFIG_CMAP_FORMAT_6 */
1749
1750
1751 /*************************************************************************/
1752 /*************************************************************************/
1753 /***** *****/
1754 /***** FORMAT 8 *****/
1755 /***** *****/
1756 /***** It is hard to completely understand what the OpenType spec *****/
1757 /***** says about this format, but here is my conclusion. *****/
1758 /***** *****/
1759 /***** The purpose of this format is to easily map UTF-16 text to *****/
1760 /***** glyph indices. Basically, the `char_code' must be in one of *****/
1761 /***** the following formats. *****/
1762 /***** *****/
1763 /***** - A 16-bit value that isn't part of the Unicode Surrogates *****/
1764 /***** Area (i.e. U+D800-U+DFFF). *****/
1765 /***** *****/
1766 /***** - A 32-bit value, made of two surrogate values, i.e.. if *****/
1767 /***** `char_code = (char_hi << 16) | char_lo', then both *****/
1768 /***** `char_hi' and `char_lo' must be in the Surrogates Area. *****/
1769 /***** Area. *****/
1770 /***** *****/
1771 /***** The `is32' table embedded in the charmap indicates whether a *****/
1772 /***** given 16-bit value is in the surrogates area or not. *****/
1773 /***** *****/
1774 /***** So, for any given `char_code', we can assert the following. *****/
1775 /***** *****/
1776 /***** If `char_hi == 0' then we must have `is32[char_lo] == 0'. *****/
1777 /***** *****/
1778 /***** If `char_hi != 0' then we must have both *****/
1779 /***** `is32[char_hi] != 0' and `is32[char_lo] != 0'. *****/
1780 /***** *****/
1781 /*************************************************************************/
1782 /*************************************************************************/
1783
1784 /**************************************************************************
1785 *
1786 * TABLE OVERVIEW
1787 * --------------
1788 *
1789 * NAME OFFSET TYPE DESCRIPTION
1790 *
1791 * format 0 USHORT must be 8
1792 * reserved 2 USHORT reserved
1793 * length 4 ULONG length in bytes
1794 * language 8 ULONG Mac language code
1795 * is32 12 BYTE[8192] 32-bitness bitmap
1796 * count 8204 ULONG number of groups
1797 *
1798 * This header is followed by `count' groups of the following format:
1799 *
1800 * start 0 ULONG first charcode
1801 * end 4 ULONG last charcode
1802 * startId 8 ULONG start glyph ID for the group
1803 */
1804
1805#ifdef TT_CONFIG_CMAP_FORMAT_8
1806
1808 tt_cmap8_validate( FT_Byte* table,
1810 {
1811 FT_Byte* p = table + 4;
1812 FT_Byte* is32;
1813 FT_UInt32 length;
1814 FT_UInt32 num_groups;
1815
1816
1817 if ( table + 16 + 8192 > valid->limit )
1819
1820 length = TT_NEXT_ULONG( p );
1821 if ( length > (FT_UInt32)( valid->limit - table ) || length < 8192 + 16 )
1823
1824 is32 = table + 12;
1825 p = is32 + 8192; /* skip `is32' array */
1826 num_groups = TT_NEXT_ULONG( p );
1827
1828 /* p + num_groups * 12 > valid->limit ? */
1829 if ( num_groups > (FT_UInt32)( valid->limit - p ) / 12 )
1831
1832 /* check groups, they must be in increasing order */
1833 {
1834 FT_UInt32 n, start, end, start_id, count, last = 0;
1835
1836
1837 for ( n = 0; n < num_groups; n++ )
1838 {
1839 FT_UInt hi, lo;
1840
1841
1842 start = TT_NEXT_ULONG( p );
1843 end = TT_NEXT_ULONG( p );
1844 start_id = TT_NEXT_ULONG( p );
1845
1846 if ( start > end )
1848
1849 if ( n > 0 && start <= last )
1851
1852 if ( valid->level >= FT_VALIDATE_TIGHT )
1853 {
1854 FT_UInt32 d = end - start;
1855
1856
1857 /* start_id + end - start >= TT_VALID_GLYPH_COUNT( valid ) ? */
1858 if ( d > TT_VALID_GLYPH_COUNT( valid ) ||
1859 start_id >= TT_VALID_GLYPH_COUNT( valid ) - d )
1861
1862 count = (FT_UInt32)( end - start + 1 );
1863
1864 if ( start & ~0xFFFFU )
1865 {
1866 /* start_hi != 0; check that is32[i] is 1 for each i in */
1867 /* the `hi' and `lo' of the range [start..end] */
1868 for ( ; count > 0; count--, start++ )
1869 {
1870 hi = (FT_UInt)( start >> 16 );
1871 lo = (FT_UInt)( start & 0xFFFFU );
1872
1873 if ( (is32[hi >> 3] & ( 0x80 >> ( hi & 7 ) ) ) == 0 )
1875
1876 if ( (is32[lo >> 3] & ( 0x80 >> ( lo & 7 ) ) ) == 0 )
1878 }
1879 }
1880 else
1881 {
1882 /* start_hi == 0; check that is32[i] is 0 for each i in */
1883 /* the range [start..end] */
1884
1885 /* end_hi cannot be != 0! */
1886 if ( end & ~0xFFFFU )
1888
1889 for ( ; count > 0; count--, start++ )
1890 {
1891 lo = (FT_UInt)( start & 0xFFFFU );
1892
1893 if ( (is32[lo >> 3] & ( 0x80 >> ( lo & 7 ) ) ) != 0 )
1895 }
1896 }
1897 }
1898
1899 last = end;
1900 }
1901 }
1902
1903 return FT_Err_Ok;
1904 }
1905
1906
1908 tt_cmap8_char_index( TT_CMap cmap,
1909 FT_UInt32 char_code )
1910 {
1911 FT_Byte* table = cmap->data;
1912 FT_UInt result = 0;
1913 FT_Byte* p = table + 8204;
1914 FT_UInt32 num_groups = TT_NEXT_ULONG( p );
1915 FT_UInt32 start, end, start_id;
1916
1917
1918 for ( ; num_groups > 0; num_groups-- )
1919 {
1920 start = TT_NEXT_ULONG( p );
1921 end = TT_NEXT_ULONG( p );
1922 start_id = TT_NEXT_ULONG( p );
1923
1924 if ( char_code < start )
1925 break;
1926
1927 if ( char_code <= end )
1928 {
1929 if ( start_id > 0xFFFFFFFFUL - ( char_code - start ) )
1930 return 0;
1931
1932 result = (FT_UInt)( start_id + ( char_code - start ) );
1933 break;
1934 }
1935 }
1936 return result;
1937 }
1938
1939
1940 FT_CALLBACK_DEF( FT_UInt32 )
1941 tt_cmap8_char_next( TT_CMap cmap,
1942 FT_UInt32 *pchar_code )
1943 {
1944 FT_Face face = cmap->cmap.charmap.face;
1945 FT_UInt32 result = 0;
1946 FT_UInt32 char_code;
1947 FT_UInt gindex = 0;
1948 FT_Byte* table = cmap->data;
1949 FT_Byte* p = table + 8204;
1950 FT_UInt32 num_groups = TT_NEXT_ULONG( p );
1951 FT_UInt32 start, end, start_id;
1952
1953
1954 if ( *pchar_code >= 0xFFFFFFFFUL )
1955 return 0;
1956
1957 char_code = *pchar_code + 1;
1958
1959 p = table + 8208;
1960
1961 for ( ; num_groups > 0; num_groups-- )
1962 {
1963 start = TT_NEXT_ULONG( p );
1964 end = TT_NEXT_ULONG( p );
1965 start_id = TT_NEXT_ULONG( p );
1966
1967 if ( char_code < start )
1968 char_code = start;
1969
1970 Again:
1971 if ( char_code <= end )
1972 {
1973 /* ignore invalid group */
1974 if ( start_id > 0xFFFFFFFFUL - ( char_code - start ) )
1975 continue;
1976
1977 gindex = (FT_UInt)( start_id + ( char_code - start ) );
1978
1979 /* does first element of group point to `.notdef' glyph? */
1980 if ( gindex == 0 )
1981 {
1982 if ( char_code >= 0xFFFFFFFFUL )
1983 break;
1984
1985 char_code++;
1986 goto Again;
1987 }
1988
1989 /* if `gindex' is invalid, the remaining values */
1990 /* in this group are invalid, too */
1991 if ( gindex >= (FT_UInt)face->num_glyphs )
1992 {
1993 gindex = 0;
1994 continue;
1995 }
1996
1997 result = char_code;
1998 break;
1999 }
2000 }
2001
2002 *pchar_code = result;
2003 return gindex;
2004 }
2005
2006
2008 tt_cmap8_get_info( TT_CMap cmap,
2010 {
2011 FT_Byte* p = cmap->data + 8;
2012
2013
2014 cmap_info->format = 8;
2016
2017 return FT_Err_Ok;
2018 }
2019
2020
2022 tt_cmap8_class_rec,
2023
2024 sizeof ( TT_CMapRec ),
2025
2026 (FT_CMap_InitFunc) tt_cmap_init, /* init */
2027 (FT_CMap_DoneFunc) NULL, /* done */
2028 (FT_CMap_CharIndexFunc)tt_cmap8_char_index, /* char_index */
2029 (FT_CMap_CharNextFunc) tt_cmap8_char_next, /* char_next */
2030
2031 (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */
2032 (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */
2033 (FT_CMap_VariantListFunc) NULL, /* variant_list */
2034 (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */
2035 (FT_CMap_VariantCharListFunc) NULL, /* variantchar_list */
2036
2037 8,
2038 (TT_CMap_ValidateFunc)tt_cmap8_validate, /* validate */
2039 (TT_CMap_Info_GetFunc)tt_cmap8_get_info /* get_cmap_info */
2040 )
2041
2042#endif /* TT_CONFIG_CMAP_FORMAT_8 */
2043
2044
2045 /*************************************************************************/
2046 /*************************************************************************/
2047 /***** *****/
2048 /***** FORMAT 10 *****/
2049 /***** *****/
2050 /*************************************************************************/
2051 /*************************************************************************/
2052
2053 /**************************************************************************
2054 *
2055 * TABLE OVERVIEW
2056 * --------------
2057 *
2058 * NAME OFFSET TYPE DESCRIPTION
2059 *
2060 * format 0 USHORT must be 10
2061 * reserved 2 USHORT reserved
2062 * length 4 ULONG length in bytes
2063 * language 8 ULONG Mac language code
2064 *
2065 * start 12 ULONG first char in range
2066 * count 16 ULONG number of chars in range
2067 * glyphIds 20 USHORT[count] glyph indices covered
2068 */
2069
2070#ifdef TT_CONFIG_CMAP_FORMAT_10
2071
2073 tt_cmap10_validate( FT_Byte* table,
2075 {
2076 FT_Byte* p = table + 4;
2078
2079
2080 if ( table + 20 > valid->limit )
2082
2083 length = TT_NEXT_ULONG( p );
2084 p = table + 16;
2085 count = TT_NEXT_ULONG( p );
2086
2087 if ( length > (FT_ULong)( valid->limit - table ) ||
2088 /* length < 20 + count * 2 ? */
2089 length < 20 ||
2090 ( length - 20 ) / 2 < count )
2092
2093 /* check glyph indices */
2094 if ( valid->level >= FT_VALIDATE_TIGHT )
2095 {
2096 FT_UInt gindex;
2097
2098
2099 for ( ; count > 0; count-- )
2100 {
2101 gindex = TT_NEXT_USHORT( p );
2102 if ( gindex >= TT_VALID_GLYPH_COUNT( valid ) )
2104 }
2105 }
2106
2107 return FT_Err_Ok;
2108 }
2109
2110
2112 tt_cmap10_char_index( TT_CMap cmap,
2113 FT_UInt32 char_code )
2114 {
2115 FT_Byte* table = cmap->data;
2116 FT_UInt result = 0;
2117 FT_Byte* p = table + 12;
2118 FT_UInt32 start = TT_NEXT_ULONG( p );
2119 FT_UInt32 count = TT_NEXT_ULONG( p );
2120 FT_UInt32 idx;
2121
2122
2123 if ( char_code < start )
2124 return 0;
2125
2126 idx = char_code - start;
2127
2128 if ( idx < count )
2129 {
2130 p += 2 * idx;
2131 result = TT_PEEK_USHORT( p );
2132 }
2133
2134 return result;
2135 }
2136
2137
2138 FT_CALLBACK_DEF( FT_UInt32 )
2139 tt_cmap10_char_next( TT_CMap cmap,
2140 FT_UInt32 *pchar_code )
2141 {
2142 FT_Byte* table = cmap->data;
2143 FT_UInt32 char_code;
2144 FT_UInt gindex = 0;
2145 FT_Byte* p = table + 12;
2146 FT_UInt32 start = TT_NEXT_ULONG( p );
2147 FT_UInt32 count = TT_NEXT_ULONG( p );
2148 FT_UInt32 idx;
2149
2150
2151 if ( *pchar_code >= 0xFFFFFFFFUL )
2152 return 0;
2153
2154 char_code = *pchar_code + 1;
2155
2156 if ( char_code < start )
2157 char_code = start;
2158
2159 idx = char_code - start;
2160 p += 2 * idx;
2161
2162 for ( ; idx < count; idx++ )
2163 {
2164 gindex = TT_NEXT_USHORT( p );
2165 if ( gindex != 0 )
2166 break;
2167
2168 if ( char_code >= 0xFFFFFFFFUL )
2169 return 0;
2170
2171 char_code++;
2172 }
2173
2174 *pchar_code = char_code;
2175 return gindex;
2176 }
2177
2178
2180 tt_cmap10_get_info( TT_CMap cmap,
2182 {
2183 FT_Byte* p = cmap->data + 8;
2184
2185
2186 cmap_info->format = 10;
2188
2189 return FT_Err_Ok;
2190 }
2191
2192
2194 tt_cmap10_class_rec,
2195
2196 sizeof ( TT_CMapRec ),
2197
2198 (FT_CMap_InitFunc) tt_cmap_init, /* init */
2199 (FT_CMap_DoneFunc) NULL, /* done */
2200 (FT_CMap_CharIndexFunc)tt_cmap10_char_index, /* char_index */
2201 (FT_CMap_CharNextFunc) tt_cmap10_char_next, /* char_next */
2202
2203 (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */
2204 (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */
2205 (FT_CMap_VariantListFunc) NULL, /* variant_list */
2206 (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */
2207 (FT_CMap_VariantCharListFunc) NULL, /* variantchar_list */
2208
2209 10,
2210 (TT_CMap_ValidateFunc)tt_cmap10_validate, /* validate */
2211 (TT_CMap_Info_GetFunc)tt_cmap10_get_info /* get_cmap_info */
2212 )
2213
2214#endif /* TT_CONFIG_CMAP_FORMAT_10 */
2215
2216
2217 /*************************************************************************/
2218 /*************************************************************************/
2219 /***** *****/
2220 /***** FORMAT 12 *****/
2221 /***** *****/
2222 /*************************************************************************/
2223 /*************************************************************************/
2224
2225 /**************************************************************************
2226 *
2227 * TABLE OVERVIEW
2228 * --------------
2229 *
2230 * NAME OFFSET TYPE DESCRIPTION
2231 *
2232 * format 0 USHORT must be 12
2233 * reserved 2 USHORT reserved
2234 * length 4 ULONG length in bytes
2235 * language 8 ULONG Mac language code
2236 * count 12 ULONG number of groups
2237 * 16
2238 *
2239 * This header is followed by `count' groups of the following format:
2240 *
2241 * start 0 ULONG first charcode
2242 * end 4 ULONG last charcode
2243 * startId 8 ULONG start glyph ID for the group
2244 */
2245
2246#ifdef TT_CONFIG_CMAP_FORMAT_12
2247
2248 typedef struct TT_CMap12Rec_
2249 {
2250 TT_CMapRec cmap;
2251 FT_Bool valid;
2252 FT_ULong cur_charcode;
2253 FT_UInt cur_gindex;
2254 FT_ULong cur_group;
2255 FT_ULong num_groups;
2256
2257 } TT_CMap12Rec, *TT_CMap12;
2258
2259
2261 tt_cmap12_init( TT_CMap12 cmap,
2262 FT_Byte* table )
2263 {
2264 cmap->cmap.data = table;
2265
2266 table += 12;
2267 cmap->num_groups = FT_PEEK_ULONG( table );
2268
2269 cmap->valid = 0;
2270
2271 return FT_Err_Ok;
2272 }
2273
2274
2276 tt_cmap12_validate( FT_Byte* table,
2278 {
2279 FT_Byte* p;
2281 FT_ULong num_groups;
2282
2283
2284 if ( table + 16 > valid->limit )
2286
2287 p = table + 4;
2288 length = TT_NEXT_ULONG( p );
2289
2290 p = table + 12;
2291 num_groups = TT_NEXT_ULONG( p );
2292
2293 if ( length > (FT_ULong)( valid->limit - table ) ||
2294 /* length < 16 + 12 * num_groups ? */
2295 length < 16 ||
2296 ( length - 16 ) / 12 < num_groups )
2298
2299 /* check groups, they must be in increasing order */
2300 {
2301 FT_ULong n, start, end, start_id, last = 0;
2302
2303
2304 for ( n = 0; n < num_groups; n++ )
2305 {
2306 start = TT_NEXT_ULONG( p );
2307 end = TT_NEXT_ULONG( p );
2308 start_id = TT_NEXT_ULONG( p );
2309
2310 if ( start > end )
2312
2313 if ( n > 0 && start <= last )
2315
2316 if ( valid->level >= FT_VALIDATE_TIGHT )
2317 {
2318 FT_UInt32 d = end - start;
2319
2320
2321 /* start_id + end - start >= TT_VALID_GLYPH_COUNT( valid ) ? */
2322 if ( d > TT_VALID_GLYPH_COUNT( valid ) ||
2323 start_id >= TT_VALID_GLYPH_COUNT( valid ) - d )
2325 }
2326
2327 last = end;
2328 }
2329 }
2330
2331 return FT_Err_Ok;
2332 }
2333
2334
2335 /* search the index of the charcode next to cmap->cur_charcode */
2336 /* cmap->cur_group should be set up properly by caller */
2337 /* */
2338 static void
2339 tt_cmap12_next( TT_CMap12 cmap )
2340 {
2341 FT_Face face = cmap->cmap.cmap.charmap.face;
2342 FT_Byte* p;
2343 FT_ULong start, end, start_id, char_code;
2344 FT_ULong n;
2345 FT_UInt gindex;
2346
2347
2348 if ( cmap->cur_charcode >= 0xFFFFFFFFUL )
2349 goto Fail;
2350
2351 char_code = cmap->cur_charcode + 1;
2352
2353 for ( n = cmap->cur_group; n < cmap->num_groups; n++ )
2354 {
2355 p = cmap->cmap.data + 16 + 12 * n;
2356 start = TT_NEXT_ULONG( p );
2357 end = TT_NEXT_ULONG( p );
2358 start_id = TT_PEEK_ULONG( p );
2359
2360 if ( char_code < start )
2361 char_code = start;
2362
2363 Again:
2364 if ( char_code <= end )
2365 {
2366 /* ignore invalid group */
2367 if ( start_id > 0xFFFFFFFFUL - ( char_code - start ) )
2368 continue;
2369
2370 gindex = (FT_UInt)( start_id + ( char_code - start ) );
2371
2372 /* does first element of group point to `.notdef' glyph? */
2373 if ( gindex == 0 )
2374 {
2375 if ( char_code >= 0xFFFFFFFFUL )
2376 goto Fail;
2377
2378 char_code++;
2379 goto Again;
2380 }
2381
2382 /* if `gindex' is invalid, the remaining values */
2383 /* in this group are invalid, too */
2384 if ( gindex >= (FT_UInt)face->num_glyphs )
2385 continue;
2386
2387 cmap->cur_charcode = char_code;
2388 cmap->cur_gindex = gindex;
2389 cmap->cur_group = n;
2390
2391 return;
2392 }
2393 }
2394
2395 Fail:
2396 cmap->valid = 0;
2397 }
2398
2399
2400 static FT_UInt
2401 tt_cmap12_char_map_binary( TT_CMap cmap,
2402 FT_UInt32* pchar_code,
2403 FT_Bool next )
2404 {
2405 FT_UInt gindex = 0;
2406 FT_Byte* p = cmap->data + 12;
2407 FT_UInt32 num_groups = TT_PEEK_ULONG( p );
2408 FT_UInt32 char_code = *pchar_code;
2409 FT_UInt32 start, end, start_id;
2410 FT_UInt32 max, min, mid;
2411
2412
2413 if ( !num_groups )
2414 return 0;
2415
2416 /* make compiler happy */
2417 mid = num_groups;
2418 end = 0xFFFFFFFFUL;
2419
2420 if ( next )
2421 {
2422 if ( char_code >= 0xFFFFFFFFUL )
2423 return 0;
2424
2425 char_code++;
2426 }
2427
2428 min = 0;
2429 max = num_groups;
2430
2431 /* binary search */
2432 while ( min < max )
2433 {
2434 mid = ( min + max ) >> 1;
2435 p = cmap->data + 16 + 12 * mid;
2436
2437 start = TT_NEXT_ULONG( p );
2438 end = TT_NEXT_ULONG( p );
2439
2440 if ( char_code < start )
2441 max = mid;
2442 else if ( char_code > end )
2443 min = mid + 1;
2444 else
2445 {
2446 start_id = TT_PEEK_ULONG( p );
2447
2448 /* reject invalid glyph index */
2449 if ( start_id > 0xFFFFFFFFUL - ( char_code - start ) )
2450 gindex = 0;
2451 else
2452 gindex = (FT_UInt)( start_id + ( char_code - start ) );
2453 break;
2454 }
2455 }
2456
2457 if ( next )
2458 {
2459 FT_Face face = cmap->cmap.charmap.face;
2460 TT_CMap12 cmap12 = (TT_CMap12)cmap;
2461
2462
2463 /* if `char_code' is not in any group, then `mid' is */
2464 /* the group nearest to `char_code' */
2465
2466 if ( char_code > end )
2467 {
2468 mid++;
2469 if ( mid == num_groups )
2470 return 0;
2471 }
2472
2473 cmap12->valid = 1;
2474 cmap12->cur_charcode = char_code;
2475 cmap12->cur_group = mid;
2476
2477 if ( gindex >= (FT_UInt)face->num_glyphs )
2478 gindex = 0;
2479
2480 if ( !gindex )
2481 {
2482 tt_cmap12_next( cmap12 );
2483
2484 if ( cmap12->valid )
2485 gindex = cmap12->cur_gindex;
2486 }
2487 else
2488 cmap12->cur_gindex = gindex;
2489
2490 *pchar_code = cmap12->cur_charcode;
2491 }
2492
2493 return gindex;
2494 }
2495
2496
2498 tt_cmap12_char_index( TT_CMap cmap,
2499 FT_UInt32 char_code )
2500 {
2501 return tt_cmap12_char_map_binary( cmap, &char_code, 0 );
2502 }
2503
2504
2505 FT_CALLBACK_DEF( FT_UInt32 )
2506 tt_cmap12_char_next( TT_CMap cmap,
2507 FT_UInt32 *pchar_code )
2508 {
2509 TT_CMap12 cmap12 = (TT_CMap12)cmap;
2510 FT_UInt gindex;
2511
2512
2513 /* no need to search */
2514 if ( cmap12->valid && cmap12->cur_charcode == *pchar_code )
2515 {
2516 tt_cmap12_next( cmap12 );
2517 if ( cmap12->valid )
2518 {
2519 gindex = cmap12->cur_gindex;
2520 *pchar_code = (FT_UInt32)cmap12->cur_charcode;
2521 }
2522 else
2523 gindex = 0;
2524 }
2525 else
2526 gindex = tt_cmap12_char_map_binary( cmap, pchar_code, 1 );
2527
2528 return gindex;
2529 }
2530
2531
2533 tt_cmap12_get_info( TT_CMap cmap,
2535 {
2536 FT_Byte* p = cmap->data + 8;
2537
2538
2539 cmap_info->format = 12;
2541
2542 return FT_Err_Ok;
2543 }
2544
2545
2547 tt_cmap12_class_rec,
2548
2549 sizeof ( TT_CMap12Rec ),
2550
2551 (FT_CMap_InitFunc) tt_cmap12_init, /* init */
2552 (FT_CMap_DoneFunc) NULL, /* done */
2553 (FT_CMap_CharIndexFunc)tt_cmap12_char_index, /* char_index */
2554 (FT_CMap_CharNextFunc) tt_cmap12_char_next, /* char_next */
2555
2556 (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */
2557 (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */
2558 (FT_CMap_VariantListFunc) NULL, /* variant_list */
2559 (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */
2560 (FT_CMap_VariantCharListFunc) NULL, /* variantchar_list */
2561
2562 12,
2563 (TT_CMap_ValidateFunc)tt_cmap12_validate, /* validate */
2564 (TT_CMap_Info_GetFunc)tt_cmap12_get_info /* get_cmap_info */
2565 )
2566
2567#endif /* TT_CONFIG_CMAP_FORMAT_12 */
2568
2569
2570 /*************************************************************************/
2571 /*************************************************************************/
2572 /***** *****/
2573 /***** FORMAT 13 *****/
2574 /***** *****/
2575 /*************************************************************************/
2576 /*************************************************************************/
2577
2578 /**************************************************************************
2579 *
2580 * TABLE OVERVIEW
2581 * --------------
2582 *
2583 * NAME OFFSET TYPE DESCRIPTION
2584 *
2585 * format 0 USHORT must be 13
2586 * reserved 2 USHORT reserved
2587 * length 4 ULONG length in bytes
2588 * language 8 ULONG Mac language code
2589 * count 12 ULONG number of groups
2590 * 16
2591 *
2592 * This header is followed by `count' groups of the following format:
2593 *
2594 * start 0 ULONG first charcode
2595 * end 4 ULONG last charcode
2596 * glyphId 8 ULONG glyph ID for the whole group
2597 */
2598
2599#ifdef TT_CONFIG_CMAP_FORMAT_13
2600
2601 typedef struct TT_CMap13Rec_
2602 {
2603 TT_CMapRec cmap;
2604 FT_Bool valid;
2605 FT_ULong cur_charcode;
2606 FT_UInt cur_gindex;
2607 FT_ULong cur_group;
2608 FT_ULong num_groups;
2609
2610 } TT_CMap13Rec, *TT_CMap13;
2611
2612
2614 tt_cmap13_init( TT_CMap13 cmap,
2615 FT_Byte* table )
2616 {
2617 cmap->cmap.data = table;
2618
2619 table += 12;
2620 cmap->num_groups = FT_PEEK_ULONG( table );
2621
2622 cmap->valid = 0;
2623
2624 return FT_Err_Ok;
2625 }
2626
2627
2629 tt_cmap13_validate( FT_Byte* table,
2631 {
2632 FT_Byte* p;
2634 FT_ULong num_groups;
2635
2636
2637 if ( table + 16 > valid->limit )
2639
2640 p = table + 4;
2641 length = TT_NEXT_ULONG( p );
2642
2643 p = table + 12;
2644 num_groups = TT_NEXT_ULONG( p );
2645
2646 if ( length > (FT_ULong)( valid->limit - table ) ||
2647 /* length < 16 + 12 * num_groups ? */
2648 length < 16 ||
2649 ( length - 16 ) / 12 < num_groups )
2651
2652 /* check groups, they must be in increasing order */
2653 {
2654 FT_ULong n, start, end, glyph_id, last = 0;
2655
2656
2657 for ( n = 0; n < num_groups; n++ )
2658 {
2659 start = TT_NEXT_ULONG( p );
2660 end = TT_NEXT_ULONG( p );
2661 glyph_id = TT_NEXT_ULONG( p );
2662
2663 if ( start > end )
2665
2666 if ( n > 0 && start <= last )
2668
2669 if ( valid->level >= FT_VALIDATE_TIGHT )
2670 {
2671 if ( glyph_id >= TT_VALID_GLYPH_COUNT( valid ) )
2673 }
2674
2675 last = end;
2676 }
2677 }
2678
2679 return FT_Err_Ok;
2680 }
2681
2682
2683 /* search the index of the charcode next to cmap->cur_charcode */
2684 /* cmap->cur_group should be set up properly by caller */
2685 /* */
2686 static void
2687 tt_cmap13_next( TT_CMap13 cmap )
2688 {
2689 FT_Face face = cmap->cmap.cmap.charmap.face;
2690 FT_Byte* p;
2691 FT_ULong start, end, glyph_id, char_code;
2692 FT_ULong n;
2693 FT_UInt gindex;
2694
2695
2696 if ( cmap->cur_charcode >= 0xFFFFFFFFUL )
2697 goto Fail;
2698
2699 char_code = cmap->cur_charcode + 1;
2700
2701 for ( n = cmap->cur_group; n < cmap->num_groups; n++ )
2702 {
2703 p = cmap->cmap.data + 16 + 12 * n;
2704 start = TT_NEXT_ULONG( p );
2705 end = TT_NEXT_ULONG( p );
2706 glyph_id = TT_PEEK_ULONG( p );
2707
2708 if ( char_code < start )
2709 char_code = start;
2710
2711 if ( char_code <= end )
2712 {
2713 gindex = (FT_UInt)glyph_id;
2714
2715 if ( gindex && gindex < (FT_UInt)face->num_glyphs )
2716 {
2717 cmap->cur_charcode = char_code;
2718 cmap->cur_gindex = gindex;
2719 cmap->cur_group = n;
2720
2721 return;
2722 }
2723 }
2724 }
2725
2726 Fail:
2727 cmap->valid = 0;
2728 }
2729
2730
2731 static FT_UInt
2732 tt_cmap13_char_map_binary( TT_CMap cmap,
2733 FT_UInt32* pchar_code,
2734 FT_Bool next )
2735 {
2736 FT_UInt gindex = 0;
2737 FT_Byte* p = cmap->data + 12;
2738 FT_UInt32 num_groups = TT_PEEK_ULONG( p );
2739 FT_UInt32 char_code = *pchar_code;
2740 FT_UInt32 start, end;
2741 FT_UInt32 max, min, mid;
2742
2743
2744 if ( !num_groups )
2745 return 0;
2746
2747 /* make compiler happy */
2748 mid = num_groups;
2749 end = 0xFFFFFFFFUL;
2750
2751 if ( next )
2752 {
2753 if ( char_code >= 0xFFFFFFFFUL )
2754 return 0;
2755
2756 char_code++;
2757 }
2758
2759 min = 0;
2760 max = num_groups;
2761
2762 /* binary search */
2763 while ( min < max )
2764 {
2765 mid = ( min + max ) >> 1;
2766 p = cmap->data + 16 + 12 * mid;
2767
2768 start = TT_NEXT_ULONG( p );
2769 end = TT_NEXT_ULONG( p );
2770
2771 if ( char_code < start )
2772 max = mid;
2773 else if ( char_code > end )
2774 min = mid + 1;
2775 else
2776 {
2777 gindex = (FT_UInt)TT_PEEK_ULONG( p );
2778
2779 break;
2780 }
2781 }
2782
2783 if ( next )
2784 {
2785 FT_Face face = cmap->cmap.charmap.face;
2786 TT_CMap13 cmap13 = (TT_CMap13)cmap;
2787
2788
2789 /* if `char_code' is not in any group, then `mid' is */
2790 /* the group nearest to `char_code' */
2791
2792 if ( char_code > end )
2793 {
2794 mid++;
2795 if ( mid == num_groups )
2796 return 0;
2797 }
2798
2799 cmap13->valid = 1;
2800 cmap13->cur_charcode = char_code;
2801 cmap13->cur_group = mid;
2802
2803 if ( gindex >= (FT_UInt)face->num_glyphs )
2804 gindex = 0;
2805
2806 if ( !gindex )
2807 {
2808 tt_cmap13_next( cmap13 );
2809
2810 if ( cmap13->valid )
2811 gindex = cmap13->cur_gindex;
2812 }
2813 else
2814 cmap13->cur_gindex = gindex;
2815
2816 *pchar_code = cmap13->cur_charcode;
2817 }
2818
2819 return gindex;
2820 }
2821
2822
2824 tt_cmap13_char_index( TT_CMap cmap,
2825 FT_UInt32 char_code )
2826 {
2827 return tt_cmap13_char_map_binary( cmap, &char_code, 0 );
2828 }
2829
2830
2831 FT_CALLBACK_DEF( FT_UInt32 )
2832 tt_cmap13_char_next( TT_CMap cmap,
2833 FT_UInt32 *pchar_code )
2834 {
2835 TT_CMap13 cmap13 = (TT_CMap13)cmap;
2836 FT_UInt gindex;
2837
2838
2839 /* no need to search */
2840 if ( cmap13->valid && cmap13->cur_charcode == *pchar_code )
2841 {
2842 tt_cmap13_next( cmap13 );
2843 if ( cmap13->valid )
2844 {
2845 gindex = cmap13->cur_gindex;
2846 *pchar_code = cmap13->cur_charcode;
2847 }
2848 else
2849 gindex = 0;
2850 }
2851 else
2852 gindex = tt_cmap13_char_map_binary( cmap, pchar_code, 1 );
2853
2854 return gindex;
2855 }
2856
2857
2859 tt_cmap13_get_info( TT_CMap cmap,
2861 {
2862 FT_Byte* p = cmap->data + 8;
2863
2864
2865 cmap_info->format = 13;
2867
2868 return FT_Err_Ok;
2869 }
2870
2871
2873 tt_cmap13_class_rec,
2874
2875 sizeof ( TT_CMap13Rec ),
2876
2877 (FT_CMap_InitFunc) tt_cmap13_init, /* init */
2878 (FT_CMap_DoneFunc) NULL, /* done */
2879 (FT_CMap_CharIndexFunc)tt_cmap13_char_index, /* char_index */
2880 (FT_CMap_CharNextFunc) tt_cmap13_char_next, /* char_next */
2881
2882 (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */
2883 (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */
2884 (FT_CMap_VariantListFunc) NULL, /* variant_list */
2885 (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */
2886 (FT_CMap_VariantCharListFunc) NULL, /* variantchar_list */
2887
2888 13,
2889 (TT_CMap_ValidateFunc)tt_cmap13_validate, /* validate */
2890 (TT_CMap_Info_GetFunc)tt_cmap13_get_info /* get_cmap_info */
2891 )
2892
2893#endif /* TT_CONFIG_CMAP_FORMAT_13 */
2894
2895
2896 /*************************************************************************/
2897 /*************************************************************************/
2898 /***** *****/
2899 /***** FORMAT 14 *****/
2900 /***** *****/
2901 /*************************************************************************/
2902 /*************************************************************************/
2903
2904 /**************************************************************************
2905 *
2906 * TABLE OVERVIEW
2907 * --------------
2908 *
2909 * NAME OFFSET TYPE DESCRIPTION
2910 *
2911 * format 0 USHORT must be 14
2912 * length 2 ULONG table length in bytes
2913 * numSelector 6 ULONG number of variation sel. records
2914 *
2915 * Followed by numSelector records, each of which looks like
2916 *
2917 * varSelector 0 UINT24 Unicode codepoint of sel.
2918 * defaultOff 3 ULONG offset to a default UVS table
2919 * describing any variants to be found in
2920 * the normal Unicode subtable.
2921 * nonDefOff 7 ULONG offset to a non-default UVS table
2922 * describing any variants not in the
2923 * standard cmap, with GIDs here
2924 * (either offset may be 0 NULL)
2925 *
2926 * Selectors are sorted by code point.
2927 *
2928 * A default Unicode Variation Selector (UVS) subtable is just a list of
2929 * ranges of code points which are to be found in the standard cmap. No
2930 * glyph IDs (GIDs) here.
2931 *
2932 * numRanges 0 ULONG number of ranges following
2933 *
2934 * A range looks like
2935 *
2936 * uniStart 0 UINT24 code point of the first character in
2937 * this range
2938 * additionalCnt 3 UBYTE count of additional characters in this
2939 * range (zero means a range of a single
2940 * character)
2941 *
2942 * Ranges are sorted by `uniStart'.
2943 *
2944 * A non-default Unicode Variation Selector (UVS) subtable is a list of
2945 * mappings from codepoint to GID.
2946 *
2947 * numMappings 0 ULONG number of mappings
2948 *
2949 * A range looks like
2950 *
2951 * uniStart 0 UINT24 code point of the first character in
2952 * this range
2953 * GID 3 USHORT and its GID
2954 *
2955 * Ranges are sorted by `uniStart'.
2956 */
2957
2958#ifdef TT_CONFIG_CMAP_FORMAT_14
2959
2960 typedef struct TT_CMap14Rec_
2961 {
2962 TT_CMapRec cmap;
2963 FT_ULong num_selectors;
2964
2965 /* This array is used to store the results of various
2966 * cmap 14 query functions. The data is overwritten
2967 * on each call to these functions.
2968 */
2969 FT_UInt32 max_results;
2970 FT_UInt32* results;
2972
2973 } TT_CMap14Rec, *TT_CMap14;
2974
2975
2976 FT_CALLBACK_DEF( void )
2977 tt_cmap14_done( TT_CMap14 cmap )
2978 {
2979 FT_Memory memory = cmap->memory;
2980
2981
2982 cmap->max_results = 0;
2983 if ( memory && cmap->results )
2984 FT_FREE( cmap->results );
2985 }
2986
2987
2988 static FT_Error
2989 tt_cmap14_ensure( TT_CMap14 cmap,
2990 FT_UInt32 num_results,
2992 {
2993 FT_UInt32 old_max = cmap->max_results;
2995
2996
2997 if ( num_results > cmap->max_results )
2998 {
2999 cmap->memory = memory;
3000
3001 if ( FT_QRENEW_ARRAY( cmap->results, old_max, num_results ) )
3002 return error;
3003
3004 cmap->max_results = num_results;
3005 }
3006
3007 return error;
3008 }
3009
3010
3012 tt_cmap14_init( TT_CMap14 cmap,
3013 FT_Byte* table )
3014 {
3015 cmap->cmap.data = table;
3016
3017 table += 6;
3018 cmap->num_selectors = FT_PEEK_ULONG( table );
3019 cmap->max_results = 0;
3020 cmap->results = NULL;
3021
3022 return FT_Err_Ok;
3023 }
3024
3025
3027 tt_cmap14_validate( FT_Byte* table,
3029 {
3030 FT_Byte* p;
3032 FT_ULong num_selectors;
3033
3034
3035 if ( table + 2 + 4 + 4 > valid->limit )
3037
3038 p = table + 2;
3039 length = TT_NEXT_ULONG( p );
3040 num_selectors = TT_NEXT_ULONG( p );
3041
3042 if ( length > (FT_ULong)( valid->limit - table ) ||
3043 /* length < 10 + 11 * num_selectors ? */
3044 length < 10 ||
3045 ( length - 10 ) / 11 < num_selectors )
3047
3048 /* check selectors, they must be in increasing order */
3049 {
3050 /* we start lastVarSel at 1 because a variant selector value of 0
3051 * isn't valid.
3052 */
3053 FT_ULong n, lastVarSel = 1;
3054
3055
3056 for ( n = 0; n < num_selectors; n++ )
3057 {
3058 FT_ULong varSel = TT_NEXT_UINT24( p );
3059 FT_ULong defOff = TT_NEXT_ULONG( p );
3060 FT_ULong nondefOff = TT_NEXT_ULONG( p );
3061
3062
3063 if ( defOff >= length || nondefOff >= length )
3065
3066 if ( varSel < lastVarSel )
3068
3069 lastVarSel = varSel + 1;
3070
3071 /* check the default table (these glyphs should be reached */
3072 /* through the normal Unicode cmap, no GIDs, just check order) */
3073 if ( defOff != 0 )
3074 {
3075 FT_Byte* defp = table + defOff;
3076 FT_ULong numRanges;
3077 FT_ULong i;
3078 FT_ULong lastBase = 0;
3079
3080
3081 if ( defp + 4 > valid->limit )
3083
3084 numRanges = TT_NEXT_ULONG( defp );
3085
3086 /* defp + numRanges * 4 > valid->limit ? */
3087 if ( numRanges > (FT_ULong)( valid->limit - defp ) / 4 )
3089
3090 for ( i = 0; i < numRanges; i++ )
3091 {
3092 FT_ULong base = TT_NEXT_UINT24( defp );
3093 FT_ULong cnt = FT_NEXT_BYTE( defp );
3094
3095
3096 if ( base + cnt >= 0x110000UL ) /* end of Unicode */
3098
3099 if ( base < lastBase )
3101
3102 lastBase = base + cnt + 1U;
3103 }
3104 }
3105
3106 /* and the non-default table (these glyphs are specified here) */
3107 if ( nondefOff != 0 )
3108 {
3109 FT_Byte* ndp = table + nondefOff;
3110 FT_ULong numMappings;
3111 FT_ULong i, lastUni = 0;
3112
3113
3114 if ( ndp + 4 > valid->limit )
3116
3117 numMappings = TT_NEXT_ULONG( ndp );
3118
3119 /* numMappings * 5 > (FT_ULong)( valid->limit - ndp ) ? */
3120 if ( numMappings > ( (FT_ULong)( valid->limit - ndp ) ) / 5 )
3122
3123 for ( i = 0; i < numMappings; i++ )
3124 {
3125 FT_ULong uni = TT_NEXT_UINT24( ndp );
3126 FT_ULong gid = TT_NEXT_USHORT( ndp );
3127
3128
3129 if ( uni >= 0x110000UL ) /* end of Unicode */
3131
3132 if ( uni < lastUni )
3134
3135 lastUni = uni + 1U;
3136
3137 if ( valid->level >= FT_VALIDATE_TIGHT &&
3138 gid >= TT_VALID_GLYPH_COUNT( valid ) )
3140 }
3141 }
3142 }
3143 }
3144
3145 return FT_Err_Ok;
3146 }
3147
3148
3150 tt_cmap14_char_index( TT_CMap cmap,
3151 FT_UInt32 char_code )
3152 {
3153 FT_UNUSED( cmap );
3154 FT_UNUSED( char_code );
3155
3156 /* This can't happen */
3157 return 0;
3158 }
3159
3160
3161 FT_CALLBACK_DEF( FT_UInt32 )
3162 tt_cmap14_char_next( TT_CMap cmap,
3163 FT_UInt32 *pchar_code )
3164 {
3165 FT_UNUSED( cmap );
3166
3167 /* This can't happen */
3168 *pchar_code = 0;
3169 return 0;
3170 }
3171
3172
3174 tt_cmap14_get_info( TT_CMap cmap,
3176 {
3177 FT_UNUSED( cmap );
3178
3179 cmap_info->format = 14;
3180 /* subtable 14 does not define a language field */
3181 cmap_info->language = 0xFFFFFFFFUL;
3182
3183 return FT_Err_Ok;
3184 }
3185
3186
3187 static FT_UInt
3188 tt_cmap14_char_map_def_binary( FT_Byte *base,
3189 FT_UInt32 char_code )
3190 {
3191 FT_UInt32 numRanges = TT_PEEK_ULONG( base );
3192 FT_UInt32 max, min;
3193
3194
3195 min = 0;
3196 max = numRanges;
3197
3198 base += 4;
3199
3200 /* binary search */
3201 while ( min < max )
3202 {
3203 FT_UInt32 mid = ( min + max ) >> 1;
3204 FT_Byte* p = base + 4 * mid;
3207
3208
3209 if ( char_code < start )
3210 max = mid;
3211 else if ( char_code > start + cnt )
3212 min = mid + 1;
3213 else
3214 return TRUE;
3215 }
3216
3217 return FALSE;
3218 }
3219
3220
3221 static FT_UInt
3222 tt_cmap14_char_map_nondef_binary( FT_Byte *base,
3223 FT_UInt32 char_code )
3224 {
3225 FT_UInt32 numMappings = TT_PEEK_ULONG( base );
3226 FT_UInt32 max, min;
3227
3228
3229 min = 0;
3230 max = numMappings;
3231
3232 base += 4;
3233
3234 /* binary search */
3235 while ( min < max )
3236 {
3237 FT_UInt32 mid = ( min + max ) >> 1;
3238 FT_Byte* p = base + 5 * mid;
3239 FT_UInt32 uni = (FT_UInt32)TT_NEXT_UINT24( p );
3240
3241
3242 if ( char_code < uni )
3243 max = mid;
3244 else if ( char_code > uni )
3245 min = mid + 1;
3246 else
3247 return TT_PEEK_USHORT( p );
3248 }
3249
3250 return 0;
3251 }
3252
3253
3254 static FT_Byte*
3255 tt_cmap14_find_variant( FT_Byte *base,
3256 FT_UInt32 variantCode )
3257 {
3258 FT_UInt32 numVar = TT_PEEK_ULONG( base );
3259 FT_UInt32 max, min;
3260
3261
3262 min = 0;
3263 max = numVar;
3264
3265 base += 4;
3266
3267 /* binary search */
3268 while ( min < max )
3269 {
3270 FT_UInt32 mid = ( min + max ) >> 1;
3271 FT_Byte* p = base + 11 * mid;
3272 FT_ULong varSel = TT_NEXT_UINT24( p );
3273
3274
3275 if ( variantCode < varSel )
3276 max = mid;
3277 else if ( variantCode > varSel )
3278 min = mid + 1;
3279 else
3280 return p;
3281 }
3282
3283 return NULL;
3284 }
3285
3286
3288 tt_cmap14_char_var_index( TT_CMap cmap,
3289 TT_CMap ucmap,
3290 FT_UInt32 charcode,
3291 FT_UInt32 variantSelector )
3292 {
3293 FT_Byte* p = tt_cmap14_find_variant( cmap->data + 6, variantSelector );
3294 FT_ULong defOff;
3295 FT_ULong nondefOff;
3296
3297
3298 if ( !p )
3299 return 0;
3300
3301 defOff = TT_NEXT_ULONG( p );
3302 nondefOff = TT_PEEK_ULONG( p );
3303
3304 if ( defOff != 0 &&
3305 tt_cmap14_char_map_def_binary( cmap->data + defOff, charcode ) )
3306 {
3307 /* This is the default variant of this charcode. GID not stored */
3308 /* here; stored in the normal Unicode charmap instead. */
3309 return ucmap->cmap.clazz->char_index( &ucmap->cmap, charcode );
3310 }
3311
3312 if ( nondefOff != 0 )
3313 return tt_cmap14_char_map_nondef_binary( cmap->data + nondefOff,
3314 charcode );
3315
3316 return 0;
3317 }
3318
3319
3321 tt_cmap14_char_var_isdefault( TT_CMap cmap,
3322 FT_UInt32 charcode,
3323 FT_UInt32 variantSelector )
3324 {
3325 FT_Byte* p = tt_cmap14_find_variant( cmap->data + 6, variantSelector );
3326 FT_ULong defOff;
3327 FT_ULong nondefOff;
3328
3329
3330 if ( !p )
3331 return -1;
3332
3333 defOff = TT_NEXT_ULONG( p );
3334 nondefOff = TT_NEXT_ULONG( p );
3335
3336 if ( defOff != 0 &&
3337 tt_cmap14_char_map_def_binary( cmap->data + defOff, charcode ) )
3338 return 1;
3339
3340 if ( nondefOff != 0 &&
3341 tt_cmap14_char_map_nondef_binary( cmap->data + nondefOff,
3342 charcode ) != 0 )
3343 return 0;
3344
3345 return -1;
3346 }
3347
3348
3349 FT_CALLBACK_DEF( FT_UInt32* )
3350 tt_cmap14_variants( TT_CMap cmap,
3352 {
3353 TT_CMap14 cmap14 = (TT_CMap14)cmap;
3354 FT_UInt32 count = cmap14->num_selectors;
3355 FT_Byte* p = cmap->data + 10;
3356 FT_UInt32* result;
3357 FT_UInt32 i;
3358
3359
3360 if ( tt_cmap14_ensure( cmap14, ( count + 1 ), memory ) )
3361 return NULL;
3362
3363 result = cmap14->results;
3364 for ( i = 0; i < count; i++ )
3365 {
3366 result[i] = (FT_UInt32)TT_NEXT_UINT24( p );
3367 p += 8;
3368 }
3369 result[i] = 0;
3370
3371 return result;
3372 }
3373
3374
3375 FT_CALLBACK_DEF( FT_UInt32 * )
3376 tt_cmap14_char_variants( TT_CMap cmap,
3378 FT_UInt32 charCode )
3379 {
3380 TT_CMap14 cmap14 = (TT_CMap14) cmap;
3381 FT_UInt32 count = cmap14->num_selectors;
3382 FT_Byte* p = cmap->data + 10;
3383 FT_UInt32* q;
3384
3385
3386 if ( tt_cmap14_ensure( cmap14, ( count + 1 ), memory ) )
3387 return NULL;
3388
3389 for ( q = cmap14->results; count > 0; count-- )
3390 {
3391 FT_UInt32 varSel = TT_NEXT_UINT24( p );
3392 FT_ULong defOff = TT_NEXT_ULONG( p );
3393 FT_ULong nondefOff = TT_NEXT_ULONG( p );
3394
3395
3396 if ( ( defOff != 0 &&
3397 tt_cmap14_char_map_def_binary( cmap->data + defOff,
3398 charCode ) ) ||
3399 ( nondefOff != 0 &&
3400 tt_cmap14_char_map_nondef_binary( cmap->data + nondefOff,
3401 charCode ) != 0 ) )
3402 {
3403 q[0] = varSel;
3404 q++;
3405 }
3406 }
3407 q[0] = 0;
3408
3409 return cmap14->results;
3410 }
3411
3412
3413 static FT_UInt
3414 tt_cmap14_def_char_count( FT_Byte *p )
3415 {
3416 FT_UInt32 numRanges = (FT_UInt32)TT_NEXT_ULONG( p );
3417 FT_UInt tot = 0;
3418
3419
3420 p += 3; /* point to the first `cnt' field */
3421 for ( ; numRanges > 0; numRanges-- )
3422 {
3423 tot += 1 + p[0];
3424 p += 4;
3425 }
3426
3427 return tot;
3428 }
3429
3430
3431 static FT_UInt32*
3432 tt_cmap14_get_def_chars( TT_CMap cmap,
3433 FT_Byte* p,
3435 {
3436 TT_CMap14 cmap14 = (TT_CMap14) cmap;
3437 FT_UInt32 numRanges;
3438 FT_UInt cnt;
3439 FT_UInt32* q;
3440
3441
3442 cnt = tt_cmap14_def_char_count( p );
3443 numRanges = (FT_UInt32)TT_NEXT_ULONG( p );
3444
3445 if ( tt_cmap14_ensure( cmap14, ( cnt + 1 ), memory ) )
3446 return NULL;
3447
3448 for ( q = cmap14->results; numRanges > 0; numRanges-- )
3449 {
3450 FT_UInt32 uni = (FT_UInt32)TT_NEXT_UINT24( p );
3451
3452
3453 cnt = FT_NEXT_BYTE( p ) + 1;
3454 do
3455 {
3456 q[0] = uni;
3457 uni += 1;
3458 q += 1;
3459
3460 } while ( --cnt != 0 );
3461 }
3462 q[0] = 0;
3463
3464 return cmap14->results;
3465 }
3466
3467
3468 static FT_UInt32*
3469 tt_cmap14_get_nondef_chars( TT_CMap cmap,
3470 FT_Byte *p,
3472 {
3473 TT_CMap14 cmap14 = (TT_CMap14) cmap;
3474 FT_UInt32 numMappings;
3475 FT_UInt i;
3476 FT_UInt32 *ret;
3477
3478
3479 numMappings = (FT_UInt32)TT_NEXT_ULONG( p );
3480
3481 if ( tt_cmap14_ensure( cmap14, ( numMappings + 1 ), memory ) )
3482 return NULL;
3483
3484 ret = cmap14->results;
3485 for ( i = 0; i < numMappings; i++ )
3486 {
3487 ret[i] = (FT_UInt32)TT_NEXT_UINT24( p );
3488 p += 2;
3489 }
3490 ret[i] = 0;
3491
3492 return ret;
3493 }
3494
3495
3496 FT_CALLBACK_DEF( FT_UInt32 * )
3497 tt_cmap14_variant_chars( TT_CMap cmap,
3499 FT_UInt32 variantSelector )
3500 {
3501 FT_Byte *p = tt_cmap14_find_variant( cmap->data + 6,
3502 variantSelector );
3503 FT_Int i;
3504 FT_ULong defOff;
3505 FT_ULong nondefOff;
3506
3507
3508 if ( !p )
3509 return NULL;
3510
3511 defOff = TT_NEXT_ULONG( p );
3512 nondefOff = TT_NEXT_ULONG( p );
3513
3514 if ( defOff == 0 && nondefOff == 0 )
3515 return NULL;
3516
3517 if ( defOff == 0 )
3518 return tt_cmap14_get_nondef_chars( cmap, cmap->data + nondefOff,
3519 memory );
3520 else if ( nondefOff == 0 )
3521 return tt_cmap14_get_def_chars( cmap, cmap->data + defOff,
3522 memory );
3523 else
3524 {
3525 /* Both a default and a non-default glyph set? That's probably not */
3526 /* good font design, but the spec allows for it... */
3527 TT_CMap14 cmap14 = (TT_CMap14) cmap;
3528 FT_UInt32 numRanges;
3529 FT_UInt32 numMappings;
3530 FT_UInt32 duni;
3531 FT_UInt32 dcnt;
3532 FT_UInt32 nuni;
3533 FT_Byte* dp;
3534 FT_UInt di, ni, k;
3535
3536 FT_UInt32 *ret;
3537
3538
3539 p = cmap->data + nondefOff;
3540 dp = cmap->data + defOff;
3541
3542 numMappings = (FT_UInt32)TT_NEXT_ULONG( p );
3543 dcnt = tt_cmap14_def_char_count( dp );
3544 numRanges = (FT_UInt32)TT_NEXT_ULONG( dp );
3545
3546 if ( numMappings == 0 )
3547 return tt_cmap14_get_def_chars( cmap, cmap->data + defOff,
3548 memory );
3549 if ( dcnt == 0 )
3550 return tt_cmap14_get_nondef_chars( cmap, cmap->data + nondefOff,
3551 memory );
3552
3553 if ( tt_cmap14_ensure( cmap14, ( dcnt + numMappings + 1 ), memory ) )
3554 return NULL;
3555
3556 ret = cmap14->results;
3557 duni = (FT_UInt32)TT_NEXT_UINT24( dp );
3558 dcnt = FT_NEXT_BYTE( dp );
3559 di = 1;
3560 nuni = (FT_UInt32)TT_NEXT_UINT24( p );
3561 p += 2;
3562 ni = 1;
3563 i = 0;
3564
3565 for (;;)
3566 {
3567 if ( nuni > duni + dcnt )
3568 {
3569 for ( k = 0; k <= dcnt; k++ )
3570 ret[i++] = duni + k;
3571
3572 di++;
3573
3574 if ( di > numRanges )
3575 break;
3576
3577 duni = (FT_UInt32)TT_NEXT_UINT24( dp );
3578 dcnt = FT_NEXT_BYTE( dp );
3579 }
3580 else
3581 {
3582 if ( nuni < duni )
3583 ret[i++] = nuni;
3584 /* If it is within the default range then ignore it -- */
3585 /* that should not have happened */
3586 ni++;
3587 if ( ni > numMappings )
3588 break;
3589
3590 nuni = (FT_UInt32)TT_NEXT_UINT24( p );
3591 p += 2;
3592 }
3593 }
3594
3595 if ( ni <= numMappings )
3596 {
3597 /* If we get here then we have run out of all default ranges. */
3598 /* We have read one non-default mapping which we haven't stored */
3599 /* and there may be others that need to be read. */
3600 ret[i++] = nuni;
3601 while ( ni < numMappings )
3602 {
3603 ret[i++] = (FT_UInt32)TT_NEXT_UINT24( p );
3604 p += 2;
3605 ni++;
3606 }
3607 }
3608 else if ( di <= numRanges )
3609 {
3610 /* If we get here then we have run out of all non-default */
3611 /* mappings. We have read one default range which we haven't */
3612 /* stored and there may be others that need to be read. */
3613 for ( k = 0; k <= dcnt; k++ )
3614 ret[i++] = duni + k;
3615
3616 while ( di < numRanges )
3617 {
3618 duni = (FT_UInt32)TT_NEXT_UINT24( dp );
3619 dcnt = FT_NEXT_BYTE( dp );
3620
3621 for ( k = 0; k <= dcnt; k++ )
3622 ret[i++] = duni + k;
3623 di++;
3624 }
3625 }
3626
3627 ret[i] = 0;
3628
3629 return ret;
3630 }
3631 }
3632
3633
3635 tt_cmap14_class_rec,
3636
3637 sizeof ( TT_CMap14Rec ),
3638
3639 (FT_CMap_InitFunc) tt_cmap14_init, /* init */
3640 (FT_CMap_DoneFunc) tt_cmap14_done, /* done */
3641 (FT_CMap_CharIndexFunc)tt_cmap14_char_index, /* char_index */
3642 (FT_CMap_CharNextFunc) tt_cmap14_char_next, /* char_next */
3643
3644 /* Format 14 extension functions */
3645 (FT_CMap_CharVarIndexFunc) tt_cmap14_char_var_index,
3646 (FT_CMap_CharVarIsDefaultFunc)tt_cmap14_char_var_isdefault,
3647 (FT_CMap_VariantListFunc) tt_cmap14_variants,
3648 (FT_CMap_CharVariantListFunc) tt_cmap14_char_variants,
3649 (FT_CMap_VariantCharListFunc) tt_cmap14_variant_chars,
3650
3651 14,
3652 (TT_CMap_ValidateFunc)tt_cmap14_validate, /* validate */
3653 (TT_CMap_Info_GetFunc)tt_cmap14_get_info /* get_cmap_info */
3654 )
3655
3656#endif /* TT_CONFIG_CMAP_FORMAT_14 */
3657
3658
3659 /*************************************************************************/
3660 /*************************************************************************/
3661 /***** *****/
3662 /***** SYNTHETIC UNICODE *****/
3663 /***** *****/
3664 /*************************************************************************/
3665 /*************************************************************************/
3666
3667 /* This charmap is generated using postscript glyph names. */
3668
3669#ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES
3670
3671 FT_CALLBACK_DEF( const char * )
3672 tt_get_glyph_name( TT_Face face,
3673 FT_UInt idx )
3674 {
3675 FT_String* PSname = NULL;
3676
3677
3678 tt_face_get_ps_name( face, idx, &PSname );
3679
3680 return PSname;
3681 }
3682
3683
3685 tt_cmap_unicode_init( PS_Unicodes unicodes,
3687 {
3688 TT_Face face = (TT_Face)FT_CMAP_FACE( unicodes );
3690 FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames;
3691
3692 FT_UNUSED( pointer );
3693
3694
3695 if ( !psnames->unicodes_init )
3696 return FT_THROW( Unimplemented_Feature );
3697
3698 return psnames->unicodes_init( memory,
3699 unicodes,
3700 face->root.num_glyphs,
3701 (PS_GetGlyphNameFunc)&tt_get_glyph_name,
3703 (FT_Pointer)face );
3704 }
3705
3706
3707 FT_CALLBACK_DEF( void )
3708 tt_cmap_unicode_done( PS_Unicodes unicodes )
3709 {
3710 FT_Face face = FT_CMAP_FACE( unicodes );
3712
3713
3714 FT_FREE( unicodes->maps );
3715 unicodes->num_maps = 0;
3716 }
3717
3718
3720 tt_cmap_unicode_char_index( PS_Unicodes unicodes,
3721 FT_UInt32 char_code )
3722 {
3723 TT_Face face = (TT_Face)FT_CMAP_FACE( unicodes );
3724 FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames;
3725
3726
3727 return psnames->unicodes_char_index( unicodes, char_code );
3728 }
3729
3730
3731 FT_CALLBACK_DEF( FT_UInt32 )
3732 tt_cmap_unicode_char_next( PS_Unicodes unicodes,
3733 FT_UInt32 *pchar_code )
3734 {
3735 TT_Face face = (TT_Face)FT_CMAP_FACE( unicodes );
3736 FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames;
3737
3738
3739 return psnames->unicodes_char_next( unicodes, pchar_code );
3740 }
3741
3742
3745
3746 sizeof ( PS_UnicodesRec ),
3747
3748 (FT_CMap_InitFunc) tt_cmap_unicode_init, /* init */
3749 (FT_CMap_DoneFunc) tt_cmap_unicode_done, /* done */
3750 (FT_CMap_CharIndexFunc)tt_cmap_unicode_char_index, /* char_index */
3751 (FT_CMap_CharNextFunc) tt_cmap_unicode_char_next, /* char_next */
3752
3753 (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */
3754 (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */
3755 (FT_CMap_VariantListFunc) NULL, /* variant_list */
3756 (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */
3757 (FT_CMap_VariantCharListFunc) NULL, /* variantchar_list */
3758
3759 ~0U,
3760 (TT_CMap_ValidateFunc)NULL, /* validate */
3761 (TT_CMap_Info_GetFunc)NULL /* get_cmap_info */
3762 )
3763
3764#endif /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */
3765
3766
3768 {
3769#undef TTCMAPCITEM
3770#define TTCMAPCITEM( a ) &a,
3771#include "ttcmapc.h"
3772 NULL,
3773 };
3774
3775
3776 /* parse the `cmap' table and build the corresponding TT_CMap objects */
3777 /* in the current face */
3778 /* */
3781 {
3782 FT_Byte* const table = face->cmap_table;
3783 FT_Byte* limit;
3784 FT_UInt volatile num_cmaps;
3785 FT_Byte* volatile p = table;
3787
3788 FT_UNUSED( library );
3789
3790
3791 if ( !p || face->cmap_size < 4 )
3792 return FT_THROW( Invalid_Table );
3793
3794 /* Version 1.8.3 of the OpenType specification contains the following */
3795 /* (https://docs.microsoft.com/en-us/typography/opentype/spec/cmap): */
3796 /* */
3797 /* The 'cmap' table version number remains at 0x0000 for fonts that */
3798 /* make use of the newer subtable formats. */
3799 /* */
3800 /* This essentially means that a version format test is useless. */
3801
3802 /* ignore format */
3803 p += 2;
3804
3805 num_cmaps = TT_NEXT_USHORT( p );
3806 FT_TRACE4(( "tt_face_build_cmaps: %d cmaps\n", num_cmaps ));
3807
3808 limit = table + face->cmap_size;
3809 for ( ; num_cmaps > 0 && p + 8 <= limit; num_cmaps-- )
3810 {
3811 FT_CharMapRec charmap;
3812 FT_UInt32 offset;
3813
3814
3815 charmap.platform_id = TT_NEXT_USHORT( p );
3816 charmap.encoding_id = TT_NEXT_USHORT( p );
3817 charmap.face = FT_FACE( face );
3818 charmap.encoding = FT_ENCODING_NONE; /* will be filled later */
3819 offset = TT_NEXT_ULONG( p );
3820
3821 if ( offset && offset <= face->cmap_size - 2 )
3822 {
3823 FT_Byte* volatile cmap = table + offset;
3824 volatile FT_UInt format = TT_PEEK_USHORT( cmap );
3825 const TT_CMap_Class* volatile pclazz = tt_cmap_classes;
3826 TT_CMap_Class volatile clazz;
3827
3828
3829 for ( ; *pclazz; pclazz++ )
3830 {
3831 clazz = *pclazz;
3832 if ( clazz->format == format )
3833 {
3834 volatile TT_ValidatorRec valid;
3835 volatile FT_Error error = FT_Err_Ok;
3836
3837
3840
3841 valid.num_glyphs = (FT_UInt)face->max_profile.numGlyphs;
3842
3843 if ( ft_setjmp( FT_VALIDATOR( &valid )->jump_buffer) == 0 )
3844 {
3845 /* validate this cmap sub-table */
3846 error = clazz->validate( cmap, FT_VALIDATOR( &valid ) );
3847 }
3848
3849 if ( !valid.validator.error )
3850 {
3851 FT_CMap ttcmap;
3852
3853
3854 /* It might make sense to store the single variation */
3855 /* selector cmap somewhere special. But it would have to be */
3856 /* in the public FT_FaceRec, and we can't change that. */
3857
3858 if ( !FT_CMap_New( (FT_CMap_Class)clazz,
3859 cmap, &charmap, &ttcmap ) )
3860 {
3861 /* it is simpler to directly set `flags' than adding */
3862 /* a parameter to FT_CMap_New */
3863 ((TT_CMap)ttcmap)->flags = (FT_Int)error;
3864 }
3865 }
3866 else
3867 {
3868 FT_TRACE0(( "tt_face_build_cmaps:"
3869 " broken cmap sub-table ignored\n" ));
3870 }
3871 break;
3872 }
3873 }
3874
3875 if ( !*pclazz )
3876 {
3877 FT_TRACE0(( "tt_face_build_cmaps:"
3878 " unsupported cmap sub-table ignored\n" ));
3879 }
3880 }
3881 }
3882
3883 return FT_Err_Ok;
3884 }
3885
3886
3890 {
3891 FT_CMap cmap = (FT_CMap)charmap;
3892 TT_CMap_Class clazz = (TT_CMap_Class)cmap->clazz;
3893
3894 if ( clazz->get_cmap_info )
3895 return clazz->get_cmap_info( charmap, cmap_info );
3896 else
3897 return FT_THROW( Invalid_CharMap_Format );
3898 }
3899
3900
3901/* END */
static struct _test_info results[8]
Definition: SetCursorPos.c:31
basic_ostream< _CharT, _Traits > &_STLP_CALL ends(basic_ostream< _CharT, _Traits > &__os)
Definition: _ostream.h:365
#define U(x)
Definition: wordpad.c:45
FT_Library library
Definition: cffdrivr.c:660
TT_CMapInfo * cmap_info
Definition: cffdrivr.c:655
#define FT_CALLBACK_DEF(x)
#define FT_LOCAL_DEF(x)
#define FT_LOCAL(x)
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
unsigned int idx
Definition: utils.c:41
const UINT * keys
Definition: locale.c:416
return ret
Definition: mutex.c:146
int Fail
Definition: ehthrow.cxx:24
return FT_Err_Ok
Definition: ftbbox.c:526
#define FT_ASSERT(condition)
Definition: ftdebug.h:241
#define FT_TRACE0(varformat)
Definition: ftdebug.h:187
#define FT_ERROR(varformat)
Definition: ftdebug.h:211
#define FT_THROW(e)
Definition: ftdebug.h:243
#define FT_TRACE4(varformat)
Definition: ftdebug.h:191
#define FT_FREE(ptr)
Definition: ftmemory.h:337
#define FT_QRENEW_ARRAY(ptr, curcnt, newcnt)
Definition: ftmemory.h:353
FT_UInt(* FT_CMap_CharNextFunc)(FT_CMap cmap, FT_UInt32 *achar_code)
Definition: ftobjs.h:179
#define FT_FACE_LIBRARY(x)
Definition: ftobjs.h:602
#define FT_FACE(x)
Definition: ftobjs.h:597
#define FT_PAD_FLOOR(x, n)
Definition: ftobjs.h:87
FT_UInt(* FT_CMap_CharVarIndexFunc)(FT_CMap cmap, FT_CMap unicode_cmap, FT_UInt32 char_code, FT_UInt32 variant_selector)
Definition: ftobjs.h:183
FT_UInt32 *(* FT_CMap_CharVariantListFunc)(FT_CMap cmap, FT_Memory mem, FT_UInt32 char_code)
Definition: ftobjs.h:198
FT_Int(* FT_CMap_CharVarIsDefaultFunc)(FT_CMap cmap, FT_UInt32 char_code, FT_UInt32 variant_selector)
Definition: ftobjs.h:189
#define FT_FACE_MEMORY(x)
Definition: ftobjs.h:603
FT_CMap_New(FT_CMap_Class clazz, FT_Pointer init_data, FT_CharMap charmap, FT_CMap *acmap)
Definition: ftobjs.c:3677
struct FT_CMapRec_ * FT_CMap
Definition: ftobjs.h:143
FT_UInt32 *(* FT_CMap_VariantCharListFunc)(FT_CMap cmap, FT_Memory mem, FT_UInt32 variant_selector)
Definition: ftobjs.h:203
FT_UInt32 *(* FT_CMap_VariantListFunc)(FT_CMap cmap, FT_Memory mem)
Definition: ftobjs.h:194
FT_Error(* FT_CMap_InitFunc)(FT_CMap cmap, FT_Pointer init_data)
Definition: ftobjs.h:168
void(* FT_CMap_DoneFunc)(FT_CMap cmap)
Definition: ftobjs.h:172
FT_UInt(* FT_CMap_CharIndexFunc)(FT_CMap cmap, FT_UInt32 char_code)
Definition: ftobjs.h:175
#define FT_CMAP_FACE(x)
Definition: ftobjs.h:163
#define ft_setjmp(b)
Definition: ftstdlib.h:163
#define FT_NEXT_USHORT(buffer)
Definition: ftstream.h:244
#define FT_PEEK_USHORT(p)
Definition: ftstream.h:186
#define FT_PEEK_SHORT(p)
Definition: ftstream.h:183
#define FT_PEEK_ULONG(p)
Definition: ftstream.h:194
#define FT_NEXT_BYTE(buffer)
Definition: ftstream.h:238
typedefFT_BEGIN_HEADER struct FT_MemoryRec_ * FT_Memory
Definition: ftsystem.h:64
FT_BEGIN_HEADER typedef unsigned char FT_Bool
Definition: fttypes.h:108
unsigned long FT_ULong
Definition: fttypes.h:253
unsigned char FT_Byte
Definition: fttypes.h:154
int FT_Error
Definition: fttypes.h:299
char FT_String
Definition: fttypes.h:187
unsigned int FT_UInt
Definition: fttypes.h:231
signed int FT_Int
Definition: fttypes.h:220
@ FT_VALIDATE_DEFAULT
Definition: ftvalid.h:73
@ FT_VALIDATE_TIGHT
Definition: ftvalid.h:74
@ FT_VALIDATE_PARANOID
Definition: ftvalid.h:75
#define FT_INVALID_TOO_SHORT
Definition: ftvalid.h:135
#define FT_INVALID_OFFSET
Definition: ftvalid.h:139
#define FT_VALIDATOR(x)
Definition: ftvalid.h:104
ft_validator_init(FT_Validator valid, const FT_Byte *base, const FT_Byte *limit, FT_ValidationLevel level)
Definition: ftobjs.c:133
#define FT_INVALID_DATA
Definition: ftvalid.h:151
typedefFT_BEGIN_HEADER struct FT_ValidatorRec_ volatile * FT_Validator
Definition: ftvalid.h:43
#define FT_INVALID_GLYPH_ID
Definition: ftvalid.h:147
static const FxOffsetAndName offsets[]
BOOLEAN valid
static struct netconfig_info ni
Definition: getnetconfig.c:158
GLuint start
Definition: gl.h:1545
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLuint GLuint end
Definition: gl.h:1545
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLdouble GLdouble GLdouble GLdouble q
Definition: gl.h:2063
GLdouble n
Definition: glext.h:7729
GLuint * ids
Definition: glext.h:5907
GLintptr offset
Definition: glext.h:5920
GLsizei const GLvoid * pointer
Definition: glext.h:5848
GLenum GLuint GLint GLenum face
Definition: glext.h:7025
GLint limit
Definition: glext.h:10326
GLboolean GLenum GLenum GLvoid * values
Definition: glext.h:5666
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLuint64EXT * result
Definition: glext.h:11304
GLfloat GLfloat p
Definition: glext.h:8902
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define d
Definition: ke_i.h:81
if(dx< 0)
Definition: linetemp.h:194
#define error(str)
Definition: mkdosfs.c:1605
static UINT UINT last
Definition: font.c:45
static char memory[1024 *256]
Definition: process.c:122
#define min(a, b)
Definition: monoChain.cc:55
int k
Definition: mpi.c:3369
#define FT_UNUSED(arg)
static unsigned __int64 next
Definition: rand_nt.c:6
static void Exit(void)
Definition: sock.c:1330
FT_CharMapRec charmap
Definition: ftobjs.h:151
FT_CMap_Class clazz
Definition: ftobjs.h:152
FT_CMap_CharIndexFunc char_index
Definition: ftobjs.h:214
FT_Face face
Definition: freetype.h:819
FT_Encoding encoding
Definition: freetype.h:820
FT_UShort platform_id
Definition: freetype.h:821
FT_UShort encoding_id
Definition: freetype.h:822
FT_CharMap charmap
Definition: freetype.h:1067
FT_UInt num_maps
Definition: svpscmap.h:66
PS_UniMap * maps
Definition: svpscmap.h:67
FT_Long format
Definition: svttcmap.h:60
FT_ULong language
Definition: svttcmap.h:59
FT_CMapRec cmap
Definition: ttcmap.h:35
FT_Int flags
Definition: ttcmap.h:37
FT_Byte * data
Definition: ttcmap.h:36
FT_UInt format
Definition: ttcmap.h:51
TT_CMap_ValidateFunc validate
Definition: ttcmap.h:52
TT_CMap_Info_GetFunc get_cmap_info
Definition: ttcmap.h:53
FT_Byte * cmap_table
Definition: tttypes.h:1486
Definition: format.c:58
BYTE * data
#define max(a, b)
Definition: svc.c:63
const char *(* PS_GetGlyphNameFunc)(FT_Pointer data, FT_UInt string_index)
Definition: svpscmap.h:77
void(* PS_FreeGlyphNameFunc)(FT_Pointer data, const char *name)
Definition: svpscmap.h:85
FT_Error(* TT_CMap_Info_GetFunc)(FT_CharMap charmap, TT_CMapInfo *cmap_info)
Definition: svttcmap.h:66
#define TT_NEXT_USHORT
Definition: ttcmap.c:48
#define TT_NEXT_ULONG
Definition: ttcmap.c:51
#define TT_PEEK_SHORT
Definition: ttcmap.c:41
#define TT_PEEK_USHORT
Definition: ttcmap.c:42
tt_get_cmap_info(FT_CharMap charmap, TT_CMapInfo *cmap_info)
Definition: ttcmap.c:3888
#define TT_NEXT_SHORT
Definition: ttcmap.c:47
tt_cmap_init(TT_CMap cmap, FT_Byte *table)
Definition: ttcmap.c:62
#define TT_NEXT_UINT24
Definition: ttcmap.c:49
#define TT_PEEK_ULONG
Definition: ttcmap.c:45
static const TT_CMap_Class tt_cmap_classes[]
Definition: ttcmap.c:3767
tt_face_build_cmaps(TT_Face face)
Definition: ttcmap.c:3780
#define TT_CMAP_FLAG_OVERLAPPING
Definition: ttcmap.h:31
struct TT_CMapRec_ * TT_CMap
#define TT_VALID_GLYPH_COUNT(x)
Definition: ttcmap.h:107
FT_CALLBACK_TABLE const TT_CMap_ClassRec tt_cmap_unicode_class_rec
Definition: ttcmap.h:110
const struct TT_CMap_ClassRec_ * TT_CMap_Class
Definition: ttcmap.h:41
#define FT_DEFINE_TT_CMAP(class_, size_, init_, done_, char_index_, char_next_, char_var_index_, char_var_default_, variant_list_, charvariant_list_, variantchar_list_, format_, validate_, get_cmap_info_)
Definition: ttcmap.h:58
FT_Error(* TT_CMap_ValidateFunc)(FT_Byte *data, FT_Validator valid)
Definition: ttcmap.h:45
#define TT_CMAP_FLAG_UNSORTED
Definition: ttcmap.h:30
FT_BEGIN_HEADER tt_face_get_ps_name(TT_Face face, FT_UInt idx, FT_String **PSname)
struct TT_FaceRec_ * TT_Face
Definition: tttypes.h:988
_In_ size_t cnt
Definition: wcstombs.cpp:43