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