ReactOS 0.4.16-dev-1025-gd3456f5
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
1237 p = cmap->data + 6;
1238 num_segs2 = FT_PAD_FLOOR( TT_PEEK_USHORT( p ), 2 );
1239
1240 if ( !num_segs2 )
1241 return 0;
1242
1243 num_segs = num_segs2 >> 1;
1244
1245 /* make compiler happy */
1246 mid = num_segs;
1247 end = 0xFFFFU;
1248
1249 if ( next )
1250 charcode++;
1251
1252 min = 0;
1253 max = num_segs;
1254
1255 /* binary search */
1256 while ( min < max )
1257 {
1258 mid = ( min + max ) >> 1;
1259 p = cmap->data + 14 + mid * 2;
1260 end = TT_PEEK_USHORT( p );
1261 p += 2 + num_segs2;
1262 start = TT_PEEK_USHORT( p );
1263
1264 if ( charcode < start )
1265 max = mid;
1266 else if ( charcode > end )
1267 min = mid + 1;
1268 else
1269 {
1270 p += num_segs2;
1271 delta = TT_PEEK_SHORT( p );
1272 p += num_segs2;
1273 offset = TT_PEEK_USHORT( p );
1274
1275 /* some fonts have an incorrect last segment; */
1276 /* we have to catch it */
1277 if ( mid >= num_segs - 1 &&
1278 start == 0xFFFFU && end == 0xFFFFU )
1279 {
1280 if ( offset && p + offset + 2 > limit )
1281 {
1282 delta = 1;
1283 offset = 0;
1284 }
1285 }
1286
1287 /* search the first segment containing `charcode' */
1288 if ( cmap->flags & TT_CMAP_FLAG_OVERLAPPING )
1289 {
1290 FT_UInt i;
1291
1292
1293 /* call the current segment `max' */
1294 max = mid;
1295
1296 if ( offset == 0xFFFFU )
1297 mid = max + 1;
1298
1299 /* search in segments before the current segment */
1300 for ( i = max; i > 0; i-- )
1301 {
1302 FT_UInt prev_end;
1303 FT_Byte* old_p;
1304
1305
1306 old_p = p;
1307 p = cmap->data + 14 + ( i - 1 ) * 2;
1308 prev_end = TT_PEEK_USHORT( p );
1309
1310 if ( charcode > prev_end )
1311 {
1312 p = old_p;
1313 break;
1314 }
1315
1316 end = prev_end;
1317 p += 2 + num_segs2;
1318 start = TT_PEEK_USHORT( p );
1319 p += num_segs2;
1320 delta = TT_PEEK_SHORT( p );
1321 p += num_segs2;
1322 offset = TT_PEEK_USHORT( p );
1323
1324 if ( offset != 0xFFFFU )
1325 mid = i - 1;
1326 }
1327
1328 /* no luck */
1329 if ( mid == max + 1 )
1330 {
1331 if ( i != max )
1332 {
1333 p = cmap->data + 14 + max * 2;
1334 end = TT_PEEK_USHORT( p );
1335 p += 2 + num_segs2;
1336 start = TT_PEEK_USHORT( p );
1337 p += num_segs2;
1338 delta = TT_PEEK_SHORT( p );
1339 p += num_segs2;
1340 offset = TT_PEEK_USHORT( p );
1341 }
1342
1343 mid = max;
1344
1345 /* search in segments after the current segment */
1346 for ( i = max + 1; i < num_segs; i++ )
1347 {
1348 FT_UInt next_end, next_start;
1349
1350
1351 p = cmap->data + 14 + i * 2;
1352 next_end = TT_PEEK_USHORT( p );
1353 p += 2 + num_segs2;
1354 next_start = TT_PEEK_USHORT( p );
1355
1356 if ( charcode < next_start )
1357 break;
1358
1359 end = next_end;
1360 start = next_start;
1361 p += num_segs2;
1362 delta = TT_PEEK_SHORT( p );
1363 p += num_segs2;
1364 offset = TT_PEEK_USHORT( p );
1365
1366 if ( offset != 0xFFFFU )
1367 mid = i;
1368 }
1369 i--;
1370
1371 /* still no luck */
1372 if ( mid == max )
1373 {
1374 mid = i;
1375
1376 break;
1377 }
1378 }
1379
1380 /* end, start, delta, and offset are for the i'th segment */
1381 if ( mid != i )
1382 {
1383 p = cmap->data + 14 + mid * 2;
1384 end = TT_PEEK_USHORT( p );
1385 p += 2 + num_segs2;
1386 start = TT_PEEK_USHORT( p );
1387 p += num_segs2;
1388 delta = TT_PEEK_SHORT( p );
1389 p += num_segs2;
1390 offset = TT_PEEK_USHORT( p );
1391 }
1392 }
1393 else
1394 {
1395 if ( offset == 0xFFFFU )
1396 break;
1397 }
1398
1399 if ( offset )
1400 {
1401 p += offset + ( charcode - start ) * 2;
1402
1403 /* if p > limit, the whole segment is invalid */
1404 if ( next && p > limit )
1405 break;
1406
1407 gindex = TT_PEEK_USHORT( p );
1408 if ( gindex )
1409 {
1410 gindex = (FT_UInt)( (FT_Int)gindex + delta ) & 0xFFFFU;
1411 if ( gindex >= (FT_UInt)face->root.num_glyphs )
1412 gindex = 0;
1413 }
1414 }
1415 else
1416 {
1417 gindex = (FT_UInt)( (FT_Int)charcode + delta ) & 0xFFFFU;
1418
1419 if ( next && gindex >= (FT_UInt)face->root.num_glyphs )
1420 {
1421 /* we have an invalid glyph index; if there is an overflow, */
1422 /* we can adjust `charcode', otherwise the whole segment is */
1423 /* invalid */
1424 gindex = 0;
1425
1426 if ( (FT_Int)charcode + delta < 0 &&
1427 (FT_Int)end + delta >= 0 )
1428 charcode = (FT_UInt)( -delta );
1429
1430 else if ( (FT_Int)charcode + delta < 0x10000L &&
1431 (FT_Int)end + delta >= 0x10000L )
1432 charcode = (FT_UInt)( 0x10000L - delta );
1433 }
1434 }
1435
1436 break;
1437 }
1438 }
1439
1440 if ( next )
1441 {
1442 TT_CMap4 cmap4 = (TT_CMap4)cmap;
1443
1444
1445 /* if `charcode' is not in any segment, then `mid' is */
1446 /* the segment nearest to `charcode' */
1447
1448 if ( charcode > end )
1449 {
1450 mid++;
1451 if ( mid == num_segs )
1452 return 0;
1453 }
1454
1455 if ( tt_cmap4_set_range( cmap4, mid ) )
1456 {
1457 if ( gindex )
1458 *pcharcode = charcode;
1459 }
1460 else
1461 {
1462 cmap4->cur_charcode = charcode;
1463
1464 if ( gindex )
1465 cmap4->cur_gindex = gindex;
1466 else
1467 {
1468 cmap4->cur_charcode = charcode;
1469 tt_cmap4_next( cmap4 );
1470 gindex = cmap4->cur_gindex;
1471 }
1472
1473 if ( gindex )
1474 *pcharcode = cmap4->cur_charcode;
1475 }
1476 }
1477
1478 return gindex;
1479 }
1480
1481
1483 tt_cmap4_char_index( TT_CMap cmap,
1484 FT_UInt32 char_code )
1485 {
1486 if ( char_code >= 0x10000UL )
1487 return 0;
1488
1489 if ( cmap->flags & TT_CMAP_FLAG_UNSORTED )
1490 return tt_cmap4_char_map_linear( cmap, &char_code, 0 );
1491 else
1492 return tt_cmap4_char_map_binary( cmap, &char_code, 0 );
1493 }
1494
1495
1496 FT_CALLBACK_DEF( FT_UInt32 )
1497 tt_cmap4_char_next( TT_CMap cmap,
1498 FT_UInt32 *pchar_code )
1499 {
1500 FT_UInt gindex;
1501
1502
1503 if ( *pchar_code >= 0xFFFFU )
1504 return 0;
1505
1506 if ( cmap->flags & TT_CMAP_FLAG_UNSORTED )
1507 gindex = tt_cmap4_char_map_linear( cmap, pchar_code, 1 );
1508 else
1509 {
1510 TT_CMap4 cmap4 = (TT_CMap4)cmap;
1511
1512
1513 /* no need to search */
1514 if ( *pchar_code == cmap4->cur_charcode )
1515 {
1516 tt_cmap4_next( cmap4 );
1517 gindex = cmap4->cur_gindex;
1518 if ( gindex )
1519 *pchar_code = cmap4->cur_charcode;
1520 }
1521 else
1522 gindex = tt_cmap4_char_map_binary( cmap, pchar_code, 1 );
1523 }
1524
1525 return gindex;
1526 }
1527
1528
1530 tt_cmap4_get_info( TT_CMap cmap,
1532 {
1533 FT_Byte* p = cmap->data + 4;
1534
1535
1536 cmap_info->format = 4;
1538
1539 return FT_Err_Ok;
1540 }
1541
1542
1544 tt_cmap4_class_rec,
1545
1546 sizeof ( TT_CMap4Rec ),
1547
1548 (FT_CMap_InitFunc) tt_cmap4_init, /* init */
1549 (FT_CMap_DoneFunc) NULL, /* done */
1550 (FT_CMap_CharIndexFunc)tt_cmap4_char_index, /* char_index */
1551 (FT_CMap_CharNextFunc) tt_cmap4_char_next, /* char_next */
1552
1553 (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */
1554 (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */
1555 (FT_CMap_VariantListFunc) NULL, /* variant_list */
1556 (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */
1557 (FT_CMap_VariantCharListFunc) NULL, /* variantchar_list */
1558
1559 4,
1560 (TT_CMap_ValidateFunc)tt_cmap4_validate, /* validate */
1561 (TT_CMap_Info_GetFunc)tt_cmap4_get_info /* get_cmap_info */
1562 )
1563
1564#endif /* TT_CONFIG_CMAP_FORMAT_4 */
1565
1566
1567 /*************************************************************************/
1568 /*************************************************************************/
1569 /***** *****/
1570 /***** FORMAT 6 *****/
1571 /***** *****/
1572 /*************************************************************************/
1573 /*************************************************************************/
1574
1575 /**************************************************************************
1576 *
1577 * TABLE OVERVIEW
1578 * --------------
1579 *
1580 * NAME OFFSET TYPE DESCRIPTION
1581 *
1582 * format 0 USHORT must be 6
1583 * length 2 USHORT table length in bytes
1584 * language 4 USHORT Mac language code
1585 *
1586 * first 6 USHORT first segment code
1587 * count 8 USHORT segment size in chars
1588 * glyphIds 10 USHORT[count] glyph IDs
1589 *
1590 * A very simplified segment mapping.
1591 */
1592
1593#ifdef TT_CONFIG_CMAP_FORMAT_6
1594
1596 tt_cmap6_validate( FT_Byte* table,
1598 {
1599 FT_Byte* p;
1601
1602
1603 if ( table + 10 > valid->limit )
1605
1606 p = table + 2;
1607 length = TT_NEXT_USHORT( p );
1608
1609 p = table + 8; /* skip language and start index */
1610 count = TT_NEXT_USHORT( p );
1611
1612 if ( table + length > valid->limit || length < 10 + count * 2 )
1614
1615 /* check glyph indices */
1616 if ( valid->level >= FT_VALIDATE_TIGHT )
1617 {
1618 FT_UInt gindex;
1619
1620
1621 for ( ; count > 0; count-- )
1622 {
1623 gindex = TT_NEXT_USHORT( p );
1624 if ( gindex >= TT_VALID_GLYPH_COUNT( valid ) )
1626 }
1627 }
1628
1629 return FT_Err_Ok;
1630 }
1631
1632
1634 tt_cmap6_char_index( TT_CMap cmap,
1635 FT_UInt32 char_code )
1636 {
1637 FT_Byte* table = cmap->data;
1638 FT_UInt result = 0;
1639 FT_Byte* p = table + 6;
1642 FT_UInt idx = (FT_UInt)( char_code - start );
1643
1644
1645 if ( idx < count )
1646 {
1647 p += 2 * idx;
1648 result = TT_PEEK_USHORT( p );
1649 }
1650
1651 return result;
1652 }
1653
1654
1655 FT_CALLBACK_DEF( FT_UInt32 )
1656 tt_cmap6_char_next( TT_CMap cmap,
1657 FT_UInt32 *pchar_code )
1658 {
1659 FT_Byte* table = cmap->data;
1660 FT_UInt32 result = 0;
1661 FT_UInt32 char_code = *pchar_code + 1;
1662 FT_UInt gindex = 0;
1663
1664 FT_Byte* p = table + 6;
1667 FT_UInt idx;
1668
1669
1670 if ( char_code >= 0x10000UL )
1671 return 0;
1672
1673 if ( char_code < start )
1674 char_code = start;
1675
1676 idx = (FT_UInt)( char_code - start );
1677 p += 2 * idx;
1678
1679 for ( ; idx < count; idx++ )
1680 {
1681 gindex = TT_NEXT_USHORT( p );
1682 if ( gindex != 0 )
1683 {
1684 result = char_code;
1685 break;
1686 }
1687
1688 if ( char_code >= 0xFFFFU )
1689 return 0;
1690
1691 char_code++;
1692 }
1693
1694 *pchar_code = result;
1695 return gindex;
1696 }
1697
1698
1700 tt_cmap6_get_info( TT_CMap cmap,
1702 {
1703 FT_Byte* p = cmap->data + 4;
1704
1705
1706 cmap_info->format = 6;
1708
1709 return FT_Err_Ok;
1710 }
1711
1712
1714 tt_cmap6_class_rec,
1715
1716 sizeof ( TT_CMapRec ),
1717
1718 (FT_CMap_InitFunc) tt_cmap_init, /* init */
1719 (FT_CMap_DoneFunc) NULL, /* done */
1720 (FT_CMap_CharIndexFunc)tt_cmap6_char_index, /* char_index */
1721 (FT_CMap_CharNextFunc) tt_cmap6_char_next, /* char_next */
1722
1723 (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */
1724 (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */
1725 (FT_CMap_VariantListFunc) NULL, /* variant_list */
1726 (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */
1727 (FT_CMap_VariantCharListFunc) NULL, /* variantchar_list */
1728
1729 6,
1730 (TT_CMap_ValidateFunc)tt_cmap6_validate, /* validate */
1731 (TT_CMap_Info_GetFunc)tt_cmap6_get_info /* get_cmap_info */
1732 )
1733
1734#endif /* TT_CONFIG_CMAP_FORMAT_6 */
1735
1736
1737 /*************************************************************************/
1738 /*************************************************************************/
1739 /***** *****/
1740 /***** FORMAT 8 *****/
1741 /***** *****/
1742 /***** It is hard to completely understand what the OpenType spec *****/
1743 /***** says about this format, but here is my conclusion. *****/
1744 /***** *****/
1745 /***** The purpose of this format is to easily map UTF-16 text to *****/
1746 /***** glyph indices. Basically, the `char_code' must be in one of *****/
1747 /***** the following formats. *****/
1748 /***** *****/
1749 /***** - A 16-bit value that isn't part of the Unicode Surrogates *****/
1750 /***** Area (i.e. U+D800-U+DFFF). *****/
1751 /***** *****/
1752 /***** - A 32-bit value, made of two surrogate values, i.e.. if *****/
1753 /***** `char_code = (char_hi << 16) | char_lo', then both *****/
1754 /***** `char_hi' and `char_lo' must be in the Surrogates Area. *****/
1755 /***** Area. *****/
1756 /***** *****/
1757 /***** The `is32' table embedded in the charmap indicates whether a *****/
1758 /***** given 16-bit value is in the surrogates area or not. *****/
1759 /***** *****/
1760 /***** So, for any given `char_code', we can assert the following. *****/
1761 /***** *****/
1762 /***** If `char_hi == 0' then we must have `is32[char_lo] == 0'. *****/
1763 /***** *****/
1764 /***** If `char_hi != 0' then we must have both *****/
1765 /***** `is32[char_hi] != 0' and `is32[char_lo] != 0'. *****/
1766 /***** *****/
1767 /*************************************************************************/
1768 /*************************************************************************/
1769
1770 /**************************************************************************
1771 *
1772 * TABLE OVERVIEW
1773 * --------------
1774 *
1775 * NAME OFFSET TYPE DESCRIPTION
1776 *
1777 * format 0 USHORT must be 8
1778 * reserved 2 USHORT reserved
1779 * length 4 ULONG length in bytes
1780 * language 8 ULONG Mac language code
1781 * is32 12 BYTE[8192] 32-bitness bitmap
1782 * count 8204 ULONG number of groups
1783 *
1784 * This header is followed by `count' groups of the following format:
1785 *
1786 * start 0 ULONG first charcode
1787 * end 4 ULONG last charcode
1788 * startId 8 ULONG start glyph ID for the group
1789 */
1790
1791#ifdef TT_CONFIG_CMAP_FORMAT_8
1792
1794 tt_cmap8_validate( FT_Byte* table,
1796 {
1797 FT_Byte* p = table + 4;
1798 FT_Byte* is32;
1799 FT_UInt32 length;
1800 FT_UInt32 num_groups;
1801
1802
1803 if ( table + 16 + 8192 > valid->limit )
1805
1806 length = TT_NEXT_ULONG( p );
1807 if ( length > (FT_UInt32)( valid->limit - table ) || length < 8192 + 16 )
1809
1810 is32 = table + 12;
1811 p = is32 + 8192; /* skip `is32' array */
1812 num_groups = TT_NEXT_ULONG( p );
1813
1814 /* p + num_groups * 12 > valid->limit ? */
1815 if ( num_groups > (FT_UInt32)( valid->limit - p ) / 12 )
1817
1818 /* check groups, they must be in increasing order */
1819 {
1820 FT_UInt32 n, start, end, start_id, count, last = 0;
1821
1822
1823 for ( n = 0; n < num_groups; n++ )
1824 {
1825 FT_UInt hi, lo;
1826
1827
1828 start = TT_NEXT_ULONG( p );
1829 end = TT_NEXT_ULONG( p );
1830 start_id = TT_NEXT_ULONG( p );
1831
1832 if ( start > end )
1834
1835 if ( n > 0 && start <= last )
1837
1838 if ( valid->level >= FT_VALIDATE_TIGHT )
1839 {
1840 FT_UInt32 d = end - start;
1841
1842
1843 /* start_id + end - start >= TT_VALID_GLYPH_COUNT( valid ) ? */
1844 if ( d > TT_VALID_GLYPH_COUNT( valid ) ||
1845 start_id >= TT_VALID_GLYPH_COUNT( valid ) - d )
1847
1848 count = (FT_UInt32)( end - start + 1 );
1849
1850 if ( start & ~0xFFFFU )
1851 {
1852 /* start_hi != 0; check that is32[i] is 1 for each i in */
1853 /* the `hi' and `lo' of the range [start..end] */
1854 for ( ; count > 0; count--, start++ )
1855 {
1856 hi = (FT_UInt)( start >> 16 );
1857 lo = (FT_UInt)( start & 0xFFFFU );
1858
1859 if ( (is32[hi >> 3] & ( 0x80 >> ( hi & 7 ) ) ) == 0 )
1861
1862 if ( (is32[lo >> 3] & ( 0x80 >> ( lo & 7 ) ) ) == 0 )
1864 }
1865 }
1866 else
1867 {
1868 /* start_hi == 0; check that is32[i] is 0 for each i in */
1869 /* the range [start..end] */
1870
1871 /* end_hi cannot be != 0! */
1872 if ( end & ~0xFFFFU )
1874
1875 for ( ; count > 0; count--, start++ )
1876 {
1877 lo = (FT_UInt)( start & 0xFFFFU );
1878
1879 if ( (is32[lo >> 3] & ( 0x80 >> ( lo & 7 ) ) ) != 0 )
1881 }
1882 }
1883 }
1884
1885 last = end;
1886 }
1887 }
1888
1889 return FT_Err_Ok;
1890 }
1891
1892
1894 tt_cmap8_char_index( TT_CMap cmap,
1895 FT_UInt32 char_code )
1896 {
1897 FT_Byte* table = cmap->data;
1898 FT_UInt result = 0;
1899 FT_Byte* p = table + 8204;
1900 FT_UInt32 num_groups = TT_NEXT_ULONG( p );
1901 FT_UInt32 start, end, start_id;
1902
1903
1904 for ( ; num_groups > 0; num_groups-- )
1905 {
1906 start = TT_NEXT_ULONG( p );
1907 end = TT_NEXT_ULONG( p );
1908 start_id = TT_NEXT_ULONG( p );
1909
1910 if ( char_code < start )
1911 break;
1912
1913 if ( char_code <= end )
1914 {
1915 if ( start_id > 0xFFFFFFFFUL - ( char_code - start ) )
1916 return 0;
1917
1918 result = (FT_UInt)( start_id + ( char_code - start ) );
1919 break;
1920 }
1921 }
1922 return result;
1923 }
1924
1925
1926 FT_CALLBACK_DEF( FT_UInt32 )
1927 tt_cmap8_char_next( TT_CMap cmap,
1928 FT_UInt32 *pchar_code )
1929 {
1930 FT_Face face = cmap->cmap.charmap.face;
1931 FT_UInt32 result = 0;
1932 FT_UInt32 char_code;
1933 FT_UInt gindex = 0;
1934 FT_Byte* table = cmap->data;
1935 FT_Byte* p = table + 8204;
1936 FT_UInt32 num_groups = TT_NEXT_ULONG( p );
1937 FT_UInt32 start, end, start_id;
1938
1939
1940 if ( *pchar_code >= 0xFFFFFFFFUL )
1941 return 0;
1942
1943 char_code = *pchar_code + 1;
1944
1945 p = table + 8208;
1946
1947 for ( ; num_groups > 0; num_groups-- )
1948 {
1949 start = TT_NEXT_ULONG( p );
1950 end = TT_NEXT_ULONG( p );
1951 start_id = TT_NEXT_ULONG( p );
1952
1953 if ( char_code < start )
1954 char_code = start;
1955
1956 Again:
1957 if ( char_code <= end )
1958 {
1959 /* ignore invalid group */
1960 if ( start_id > 0xFFFFFFFFUL - ( char_code - start ) )
1961 continue;
1962
1963 gindex = (FT_UInt)( start_id + ( char_code - start ) );
1964
1965 /* does first element of group point to `.notdef' glyph? */
1966 if ( gindex == 0 )
1967 {
1968 if ( char_code >= 0xFFFFFFFFUL )
1969 break;
1970
1971 char_code++;
1972 goto Again;
1973 }
1974
1975 /* if `gindex' is invalid, the remaining values */
1976 /* in this group are invalid, too */
1977 if ( gindex >= (FT_UInt)face->num_glyphs )
1978 {
1979 gindex = 0;
1980 continue;
1981 }
1982
1983 result = char_code;
1984 break;
1985 }
1986 }
1987
1988 *pchar_code = result;
1989 return gindex;
1990 }
1991
1992
1994 tt_cmap8_get_info( TT_CMap cmap,
1996 {
1997 FT_Byte* p = cmap->data + 8;
1998
1999
2000 cmap_info->format = 8;
2002
2003 return FT_Err_Ok;
2004 }
2005
2006
2008 tt_cmap8_class_rec,
2009
2010 sizeof ( TT_CMapRec ),
2011
2012 (FT_CMap_InitFunc) tt_cmap_init, /* init */
2013 (FT_CMap_DoneFunc) NULL, /* done */
2014 (FT_CMap_CharIndexFunc)tt_cmap8_char_index, /* char_index */
2015 (FT_CMap_CharNextFunc) tt_cmap8_char_next, /* char_next */
2016
2017 (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */
2018 (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */
2019 (FT_CMap_VariantListFunc) NULL, /* variant_list */
2020 (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */
2021 (FT_CMap_VariantCharListFunc) NULL, /* variantchar_list */
2022
2023 8,
2024 (TT_CMap_ValidateFunc)tt_cmap8_validate, /* validate */
2025 (TT_CMap_Info_GetFunc)tt_cmap8_get_info /* get_cmap_info */
2026 )
2027
2028#endif /* TT_CONFIG_CMAP_FORMAT_8 */
2029
2030
2031 /*************************************************************************/
2032 /*************************************************************************/
2033 /***** *****/
2034 /***** FORMAT 10 *****/
2035 /***** *****/
2036 /*************************************************************************/
2037 /*************************************************************************/
2038
2039 /**************************************************************************
2040 *
2041 * TABLE OVERVIEW
2042 * --------------
2043 *
2044 * NAME OFFSET TYPE DESCRIPTION
2045 *
2046 * format 0 USHORT must be 10
2047 * reserved 2 USHORT reserved
2048 * length 4 ULONG length in bytes
2049 * language 8 ULONG Mac language code
2050 *
2051 * start 12 ULONG first char in range
2052 * count 16 ULONG number of chars in range
2053 * glyphIds 20 USHORT[count] glyph indices covered
2054 */
2055
2056#ifdef TT_CONFIG_CMAP_FORMAT_10
2057
2059 tt_cmap10_validate( FT_Byte* table,
2061 {
2062 FT_Byte* p = table + 4;
2064
2065
2066 if ( table + 20 > valid->limit )
2068
2069 length = TT_NEXT_ULONG( p );
2070 p = table + 16;
2071 count = TT_NEXT_ULONG( p );
2072
2073 if ( length > (FT_ULong)( valid->limit - table ) ||
2074 /* length < 20 + count * 2 ? */
2075 length < 20 ||
2076 ( length - 20 ) / 2 < count )
2078
2079 /* check glyph indices */
2080 if ( valid->level >= FT_VALIDATE_TIGHT )
2081 {
2082 FT_UInt gindex;
2083
2084
2085 for ( ; count > 0; count-- )
2086 {
2087 gindex = TT_NEXT_USHORT( p );
2088 if ( gindex >= TT_VALID_GLYPH_COUNT( valid ) )
2090 }
2091 }
2092
2093 return FT_Err_Ok;
2094 }
2095
2096
2098 tt_cmap10_char_index( TT_CMap cmap,
2099 FT_UInt32 char_code )
2100 {
2101 FT_Byte* table = cmap->data;
2102 FT_UInt result = 0;
2103 FT_Byte* p = table + 12;
2104 FT_UInt32 start = TT_NEXT_ULONG( p );
2105 FT_UInt32 count = TT_NEXT_ULONG( p );
2106 FT_UInt32 idx;
2107
2108
2109 if ( char_code < start )
2110 return 0;
2111
2112 idx = char_code - start;
2113
2114 if ( idx < count )
2115 {
2116 p += 2 * idx;
2117 result = TT_PEEK_USHORT( p );
2118 }
2119
2120 return result;
2121 }
2122
2123
2124 FT_CALLBACK_DEF( FT_UInt32 )
2125 tt_cmap10_char_next( TT_CMap cmap,
2126 FT_UInt32 *pchar_code )
2127 {
2128 FT_Byte* table = cmap->data;
2129 FT_UInt32 char_code;
2130 FT_UInt gindex = 0;
2131 FT_Byte* p = table + 12;
2132 FT_UInt32 start = TT_NEXT_ULONG( p );
2133 FT_UInt32 count = TT_NEXT_ULONG( p );
2134 FT_UInt32 idx;
2135
2136
2137 if ( *pchar_code >= 0xFFFFFFFFUL )
2138 return 0;
2139
2140 char_code = *pchar_code + 1;
2141
2142 if ( char_code < start )
2143 char_code = start;
2144
2145 idx = char_code - start;
2146 p += 2 * idx;
2147
2148 for ( ; idx < count; idx++ )
2149 {
2150 gindex = TT_NEXT_USHORT( p );
2151 if ( gindex != 0 )
2152 break;
2153
2154 if ( char_code >= 0xFFFFFFFFUL )
2155 return 0;
2156
2157 char_code++;
2158 }
2159
2160 *pchar_code = char_code;
2161 return gindex;
2162 }
2163
2164
2166 tt_cmap10_get_info( TT_CMap cmap,
2168 {
2169 FT_Byte* p = cmap->data + 8;
2170
2171
2172 cmap_info->format = 10;
2174
2175 return FT_Err_Ok;
2176 }
2177
2178
2180 tt_cmap10_class_rec,
2181
2182 sizeof ( TT_CMapRec ),
2183
2184 (FT_CMap_InitFunc) tt_cmap_init, /* init */
2185 (FT_CMap_DoneFunc) NULL, /* done */
2186 (FT_CMap_CharIndexFunc)tt_cmap10_char_index, /* char_index */
2187 (FT_CMap_CharNextFunc) tt_cmap10_char_next, /* char_next */
2188
2189 (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */
2190 (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */
2191 (FT_CMap_VariantListFunc) NULL, /* variant_list */
2192 (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */
2193 (FT_CMap_VariantCharListFunc) NULL, /* variantchar_list */
2194
2195 10,
2196 (TT_CMap_ValidateFunc)tt_cmap10_validate, /* validate */
2197 (TT_CMap_Info_GetFunc)tt_cmap10_get_info /* get_cmap_info */
2198 )
2199
2200#endif /* TT_CONFIG_CMAP_FORMAT_10 */
2201
2202
2203 /*************************************************************************/
2204 /*************************************************************************/
2205 /***** *****/
2206 /***** FORMAT 12 *****/
2207 /***** *****/
2208 /*************************************************************************/
2209 /*************************************************************************/
2210
2211 /**************************************************************************
2212 *
2213 * TABLE OVERVIEW
2214 * --------------
2215 *
2216 * NAME OFFSET TYPE DESCRIPTION
2217 *
2218 * format 0 USHORT must be 12
2219 * reserved 2 USHORT reserved
2220 * length 4 ULONG length in bytes
2221 * language 8 ULONG Mac language code
2222 * count 12 ULONG number of groups
2223 * 16
2224 *
2225 * This header is followed by `count' groups of the following format:
2226 *
2227 * start 0 ULONG first charcode
2228 * end 4 ULONG last charcode
2229 * startId 8 ULONG start glyph ID for the group
2230 */
2231
2232#ifdef TT_CONFIG_CMAP_FORMAT_12
2233
2234 typedef struct TT_CMap12Rec_
2235 {
2236 TT_CMapRec cmap;
2237 FT_Bool valid;
2238 FT_ULong cur_charcode;
2239 FT_UInt cur_gindex;
2240 FT_ULong cur_group;
2241 FT_ULong num_groups;
2242
2243 } TT_CMap12Rec, *TT_CMap12;
2244
2245
2247 tt_cmap12_init( TT_CMap12 cmap,
2248 FT_Byte* table )
2249 {
2250 cmap->cmap.data = table;
2251
2252 table += 12;
2253 cmap->num_groups = FT_PEEK_ULONG( table );
2254
2255 cmap->valid = 0;
2256
2257 return FT_Err_Ok;
2258 }
2259
2260
2262 tt_cmap12_validate( FT_Byte* table,
2264 {
2265 FT_Byte* p;
2267 FT_ULong num_groups;
2268
2269
2270 if ( table + 16 > valid->limit )
2272
2273 p = table + 4;
2274 length = TT_NEXT_ULONG( p );
2275
2276 p = table + 12;
2277 num_groups = TT_NEXT_ULONG( p );
2278
2279 if ( length > (FT_ULong)( valid->limit - table ) ||
2280 /* length < 16 + 12 * num_groups ? */
2281 length < 16 ||
2282 ( length - 16 ) / 12 < num_groups )
2284
2285 /* check groups, they must be in increasing order */
2286 {
2287 FT_ULong n, start, end, start_id, last = 0;
2288
2289
2290 for ( n = 0; n < num_groups; n++ )
2291 {
2292 start = TT_NEXT_ULONG( p );
2293 end = TT_NEXT_ULONG( p );
2294 start_id = TT_NEXT_ULONG( p );
2295
2296 if ( start > end )
2298
2299 if ( n > 0 && start <= last )
2301
2302 if ( valid->level >= FT_VALIDATE_TIGHT )
2303 {
2304 FT_UInt32 d = end - start;
2305
2306
2307 /* start_id + end - start >= TT_VALID_GLYPH_COUNT( valid ) ? */
2308 if ( d > TT_VALID_GLYPH_COUNT( valid ) ||
2309 start_id >= TT_VALID_GLYPH_COUNT( valid ) - d )
2311 }
2312
2313 last = end;
2314 }
2315 }
2316
2317 return FT_Err_Ok;
2318 }
2319
2320
2321 /* search the index of the charcode next to cmap->cur_charcode */
2322 /* cmap->cur_group should be set up properly by caller */
2323 /* */
2324 static void
2325 tt_cmap12_next( TT_CMap12 cmap )
2326 {
2327 FT_Face face = cmap->cmap.cmap.charmap.face;
2328 FT_Byte* p;
2329 FT_ULong start, end, start_id, char_code;
2330 FT_ULong n;
2331 FT_UInt gindex;
2332
2333
2334 if ( cmap->cur_charcode >= 0xFFFFFFFFUL )
2335 goto Fail;
2336
2337 char_code = cmap->cur_charcode + 1;
2338
2339 for ( n = cmap->cur_group; n < cmap->num_groups; n++ )
2340 {
2341 p = cmap->cmap.data + 16 + 12 * n;
2342 start = TT_NEXT_ULONG( p );
2343 end = TT_NEXT_ULONG( p );
2344 start_id = TT_PEEK_ULONG( p );
2345
2346 if ( char_code < start )
2347 char_code = start;
2348
2349 Again:
2350 if ( char_code <= end )
2351 {
2352 /* ignore invalid group */
2353 if ( start_id > 0xFFFFFFFFUL - ( char_code - start ) )
2354 continue;
2355
2356 gindex = (FT_UInt)( start_id + ( char_code - start ) );
2357
2358 /* does first element of group point to `.notdef' glyph? */
2359 if ( gindex == 0 )
2360 {
2361 if ( char_code >= 0xFFFFFFFFUL )
2362 goto Fail;
2363
2364 char_code++;
2365 goto Again;
2366 }
2367
2368 /* if `gindex' is invalid, the remaining values */
2369 /* in this group are invalid, too */
2370 if ( gindex >= (FT_UInt)face->num_glyphs )
2371 {
2372 gindex = 0;
2373 continue;
2374 }
2375
2376 cmap->cur_charcode = char_code;
2377 cmap->cur_gindex = gindex;
2378 cmap->cur_group = n;
2379
2380 return;
2381 }
2382 }
2383
2384 Fail:
2385 cmap->valid = 0;
2386 }
2387
2388
2389 static FT_UInt
2390 tt_cmap12_char_map_binary( TT_CMap cmap,
2391 FT_UInt32* pchar_code,
2392 FT_Bool next )
2393 {
2394 FT_UInt gindex = 0;
2395 FT_Byte* p = cmap->data + 12;
2396 FT_UInt32 num_groups = TT_PEEK_ULONG( p );
2397 FT_UInt32 char_code = *pchar_code;
2398 FT_UInt32 start, end, start_id;
2399 FT_UInt32 max, min, mid;
2400
2401
2402 if ( !num_groups )
2403 return 0;
2404
2405 /* make compiler happy */
2406 mid = num_groups;
2407 end = 0xFFFFFFFFUL;
2408
2409 if ( next )
2410 {
2411 if ( char_code >= 0xFFFFFFFFUL )
2412 return 0;
2413
2414 char_code++;
2415 }
2416
2417 min = 0;
2418 max = num_groups;
2419
2420 /* binary search */
2421 while ( min < max )
2422 {
2423 mid = ( min + max ) >> 1;
2424 p = cmap->data + 16 + 12 * mid;
2425
2426 start = TT_NEXT_ULONG( p );
2427 end = TT_NEXT_ULONG( p );
2428
2429 if ( char_code < start )
2430 max = mid;
2431 else if ( char_code > end )
2432 min = mid + 1;
2433 else
2434 {
2435 start_id = TT_PEEK_ULONG( p );
2436
2437 /* reject invalid glyph index */
2438 if ( start_id > 0xFFFFFFFFUL - ( char_code - start ) )
2439 gindex = 0;
2440 else
2441 gindex = (FT_UInt)( start_id + ( char_code - start ) );
2442 break;
2443 }
2444 }
2445
2446 if ( next )
2447 {
2448 FT_Face face = cmap->cmap.charmap.face;
2449 TT_CMap12 cmap12 = (TT_CMap12)cmap;
2450
2451
2452 /* if `char_code' is not in any group, then `mid' is */
2453 /* the group nearest to `char_code' */
2454
2455 if ( char_code > end )
2456 {
2457 mid++;
2458 if ( mid == num_groups )
2459 return 0;
2460 }
2461
2462 cmap12->valid = 1;
2463 cmap12->cur_charcode = char_code;
2464 cmap12->cur_group = mid;
2465
2466 if ( gindex >= (FT_UInt)face->num_glyphs )
2467 gindex = 0;
2468
2469 if ( !gindex )
2470 {
2471 tt_cmap12_next( cmap12 );
2472
2473 if ( cmap12->valid )
2474 gindex = cmap12->cur_gindex;
2475 }
2476 else
2477 cmap12->cur_gindex = gindex;
2478
2479 *pchar_code = cmap12->cur_charcode;
2480 }
2481
2482 return gindex;
2483 }
2484
2485
2487 tt_cmap12_char_index( TT_CMap cmap,
2488 FT_UInt32 char_code )
2489 {
2490 return tt_cmap12_char_map_binary( cmap, &char_code, 0 );
2491 }
2492
2493
2494 FT_CALLBACK_DEF( FT_UInt32 )
2495 tt_cmap12_char_next( TT_CMap cmap,
2496 FT_UInt32 *pchar_code )
2497 {
2498 TT_CMap12 cmap12 = (TT_CMap12)cmap;
2499 FT_UInt gindex;
2500
2501
2502 /* no need to search */
2503 if ( cmap12->valid && cmap12->cur_charcode == *pchar_code )
2504 {
2505 tt_cmap12_next( cmap12 );
2506 if ( cmap12->valid )
2507 {
2508 gindex = cmap12->cur_gindex;
2509 *pchar_code = (FT_UInt32)cmap12->cur_charcode;
2510 }
2511 else
2512 gindex = 0;
2513 }
2514 else
2515 gindex = tt_cmap12_char_map_binary( cmap, pchar_code, 1 );
2516
2517 return gindex;
2518 }
2519
2520
2522 tt_cmap12_get_info( TT_CMap cmap,
2524 {
2525 FT_Byte* p = cmap->data + 8;
2526
2527
2528 cmap_info->format = 12;
2530
2531 return FT_Err_Ok;
2532 }
2533
2534
2536 tt_cmap12_class_rec,
2537
2538 sizeof ( TT_CMap12Rec ),
2539
2540 (FT_CMap_InitFunc) tt_cmap12_init, /* init */
2541 (FT_CMap_DoneFunc) NULL, /* done */
2542 (FT_CMap_CharIndexFunc)tt_cmap12_char_index, /* char_index */
2543 (FT_CMap_CharNextFunc) tt_cmap12_char_next, /* char_next */
2544
2545 (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */
2546 (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */
2547 (FT_CMap_VariantListFunc) NULL, /* variant_list */
2548 (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */
2549 (FT_CMap_VariantCharListFunc) NULL, /* variantchar_list */
2550
2551 12,
2552 (TT_CMap_ValidateFunc)tt_cmap12_validate, /* validate */
2553 (TT_CMap_Info_GetFunc)tt_cmap12_get_info /* get_cmap_info */
2554 )
2555
2556#endif /* TT_CONFIG_CMAP_FORMAT_12 */
2557
2558
2559 /*************************************************************************/
2560 /*************************************************************************/
2561 /***** *****/
2562 /***** FORMAT 13 *****/
2563 /***** *****/
2564 /*************************************************************************/
2565 /*************************************************************************/
2566
2567 /**************************************************************************
2568 *
2569 * TABLE OVERVIEW
2570 * --------------
2571 *
2572 * NAME OFFSET TYPE DESCRIPTION
2573 *
2574 * format 0 USHORT must be 13
2575 * reserved 2 USHORT reserved
2576 * length 4 ULONG length in bytes
2577 * language 8 ULONG Mac language code
2578 * count 12 ULONG number of groups
2579 * 16
2580 *
2581 * This header is followed by `count' groups of the following format:
2582 *
2583 * start 0 ULONG first charcode
2584 * end 4 ULONG last charcode
2585 * glyphId 8 ULONG glyph ID for the whole group
2586 */
2587
2588#ifdef TT_CONFIG_CMAP_FORMAT_13
2589
2590 typedef struct TT_CMap13Rec_
2591 {
2592 TT_CMapRec cmap;
2593 FT_Bool valid;
2594 FT_ULong cur_charcode;
2595 FT_UInt cur_gindex;
2596 FT_ULong cur_group;
2597 FT_ULong num_groups;
2598
2599 } TT_CMap13Rec, *TT_CMap13;
2600
2601
2603 tt_cmap13_init( TT_CMap13 cmap,
2604 FT_Byte* table )
2605 {
2606 cmap->cmap.data = table;
2607
2608 table += 12;
2609 cmap->num_groups = FT_PEEK_ULONG( table );
2610
2611 cmap->valid = 0;
2612
2613 return FT_Err_Ok;
2614 }
2615
2616
2618 tt_cmap13_validate( FT_Byte* table,
2620 {
2621 FT_Byte* p;
2623 FT_ULong num_groups;
2624
2625
2626 if ( table + 16 > valid->limit )
2628
2629 p = table + 4;
2630 length = TT_NEXT_ULONG( p );
2631
2632 p = table + 12;
2633 num_groups = TT_NEXT_ULONG( p );
2634
2635 if ( length > (FT_ULong)( valid->limit - table ) ||
2636 /* length < 16 + 12 * num_groups ? */
2637 length < 16 ||
2638 ( length - 16 ) / 12 < num_groups )
2640
2641 /* check groups, they must be in increasing order */
2642 {
2643 FT_ULong n, start, end, glyph_id, last = 0;
2644
2645
2646 for ( n = 0; n < num_groups; n++ )
2647 {
2648 start = TT_NEXT_ULONG( p );
2649 end = TT_NEXT_ULONG( p );
2650 glyph_id = TT_NEXT_ULONG( p );
2651
2652 if ( start > end )
2654
2655 if ( n > 0 && start <= last )
2657
2658 if ( valid->level >= FT_VALIDATE_TIGHT )
2659 {
2660 if ( glyph_id >= TT_VALID_GLYPH_COUNT( valid ) )
2662 }
2663
2664 last = end;
2665 }
2666 }
2667
2668 return FT_Err_Ok;
2669 }
2670
2671
2672 /* search the index of the charcode next to cmap->cur_charcode */
2673 /* cmap->cur_group should be set up properly by caller */
2674 /* */
2675 static void
2676 tt_cmap13_next( TT_CMap13 cmap )
2677 {
2678 FT_Face face = cmap->cmap.cmap.charmap.face;
2679 FT_Byte* p;
2680 FT_ULong start, end, glyph_id, char_code;
2681 FT_ULong n;
2682 FT_UInt gindex;
2683
2684
2685 if ( cmap->cur_charcode >= 0xFFFFFFFFUL )
2686 goto Fail;
2687
2688 char_code = cmap->cur_charcode + 1;
2689
2690 for ( n = cmap->cur_group; n < cmap->num_groups; n++ )
2691 {
2692 p = cmap->cmap.data + 16 + 12 * n;
2693 start = TT_NEXT_ULONG( p );
2694 end = TT_NEXT_ULONG( p );
2695 glyph_id = TT_PEEK_ULONG( p );
2696
2697 if ( char_code < start )
2698 char_code = start;
2699
2700 if ( char_code <= end )
2701 {
2702 gindex = (FT_UInt)glyph_id;
2703
2704 if ( gindex && gindex < (FT_UInt)face->num_glyphs )
2705 {
2706 cmap->cur_charcode = char_code;
2707 cmap->cur_gindex = gindex;
2708 cmap->cur_group = n;
2709
2710 return;
2711 }
2712 }
2713 }
2714
2715 Fail:
2716 cmap->valid = 0;
2717 }
2718
2719
2720 static FT_UInt
2721 tt_cmap13_char_map_binary( TT_CMap cmap,
2722 FT_UInt32* pchar_code,
2723 FT_Bool next )
2724 {
2725 FT_UInt gindex = 0;
2726 FT_Byte* p = cmap->data + 12;
2727 FT_UInt32 num_groups = TT_PEEK_ULONG( p );
2728 FT_UInt32 char_code = *pchar_code;
2729 FT_UInt32 start, end;
2730 FT_UInt32 max, min, mid;
2731
2732
2733 if ( !num_groups )
2734 return 0;
2735
2736 /* make compiler happy */
2737 mid = num_groups;
2738 end = 0xFFFFFFFFUL;
2739
2740 if ( next )
2741 {
2742 if ( char_code >= 0xFFFFFFFFUL )
2743 return 0;
2744
2745 char_code++;
2746 }
2747
2748 min = 0;
2749 max = num_groups;
2750
2751 /* binary search */
2752 while ( min < max )
2753 {
2754 mid = ( min + max ) >> 1;
2755 p = cmap->data + 16 + 12 * mid;
2756
2757 start = TT_NEXT_ULONG( p );
2758 end = TT_NEXT_ULONG( p );
2759
2760 if ( char_code < start )
2761 max = mid;
2762 else if ( char_code > end )
2763 min = mid + 1;
2764 else
2765 {
2766 gindex = (FT_UInt)TT_PEEK_ULONG( p );
2767
2768 break;
2769 }
2770 }
2771
2772 if ( next )
2773 {
2774 FT_Face face = cmap->cmap.charmap.face;
2775 TT_CMap13 cmap13 = (TT_CMap13)cmap;
2776
2777
2778 /* if `char_code' is not in any group, then `mid' is */
2779 /* the group nearest to `char_code' */
2780
2781 if ( char_code > end )
2782 {
2783 mid++;
2784 if ( mid == num_groups )
2785 return 0;
2786 }
2787
2788 cmap13->valid = 1;
2789 cmap13->cur_charcode = char_code;
2790 cmap13->cur_group = mid;
2791
2792 if ( gindex >= (FT_UInt)face->num_glyphs )
2793 gindex = 0;
2794
2795 if ( !gindex )
2796 {
2797 tt_cmap13_next( cmap13 );
2798
2799 if ( cmap13->valid )
2800 gindex = cmap13->cur_gindex;
2801 }
2802 else
2803 cmap13->cur_gindex = gindex;
2804
2805 *pchar_code = cmap13->cur_charcode;
2806 }
2807
2808 return gindex;
2809 }
2810
2811
2813 tt_cmap13_char_index( TT_CMap cmap,
2814 FT_UInt32 char_code )
2815 {
2816 return tt_cmap13_char_map_binary( cmap, &char_code, 0 );
2817 }
2818
2819
2820 FT_CALLBACK_DEF( FT_UInt32 )
2821 tt_cmap13_char_next( TT_CMap cmap,
2822 FT_UInt32 *pchar_code )
2823 {
2824 TT_CMap13 cmap13 = (TT_CMap13)cmap;
2825 FT_UInt gindex;
2826
2827
2828 /* no need to search */
2829 if ( cmap13->valid && cmap13->cur_charcode == *pchar_code )
2830 {
2831 tt_cmap13_next( cmap13 );
2832 if ( cmap13->valid )
2833 {
2834 gindex = cmap13->cur_gindex;
2835 *pchar_code = cmap13->cur_charcode;
2836 }
2837 else
2838 gindex = 0;
2839 }
2840 else
2841 gindex = tt_cmap13_char_map_binary( cmap, pchar_code, 1 );
2842
2843 return gindex;
2844 }
2845
2846
2848 tt_cmap13_get_info( TT_CMap cmap,
2850 {
2851 FT_Byte* p = cmap->data + 8;
2852
2853
2854 cmap_info->format = 13;
2856
2857 return FT_Err_Ok;
2858 }
2859
2860
2862 tt_cmap13_class_rec,
2863
2864 sizeof ( TT_CMap13Rec ),
2865
2866 (FT_CMap_InitFunc) tt_cmap13_init, /* init */
2867 (FT_CMap_DoneFunc) NULL, /* done */
2868 (FT_CMap_CharIndexFunc)tt_cmap13_char_index, /* char_index */
2869 (FT_CMap_CharNextFunc) tt_cmap13_char_next, /* char_next */
2870
2871 (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */
2872 (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */
2873 (FT_CMap_VariantListFunc) NULL, /* variant_list */
2874 (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */
2875 (FT_CMap_VariantCharListFunc) NULL, /* variantchar_list */
2876
2877 13,
2878 (TT_CMap_ValidateFunc)tt_cmap13_validate, /* validate */
2879 (TT_CMap_Info_GetFunc)tt_cmap13_get_info /* get_cmap_info */
2880 )
2881
2882#endif /* TT_CONFIG_CMAP_FORMAT_13 */
2883
2884
2885 /*************************************************************************/
2886 /*************************************************************************/
2887 /***** *****/
2888 /***** FORMAT 14 *****/
2889 /***** *****/
2890 /*************************************************************************/
2891 /*************************************************************************/
2892
2893 /**************************************************************************
2894 *
2895 * TABLE OVERVIEW
2896 * --------------
2897 *
2898 * NAME OFFSET TYPE DESCRIPTION
2899 *
2900 * format 0 USHORT must be 14
2901 * length 2 ULONG table length in bytes
2902 * numSelector 6 ULONG number of variation sel. records
2903 *
2904 * Followed by numSelector records, each of which looks like
2905 *
2906 * varSelector 0 UINT24 Unicode codepoint of sel.
2907 * defaultOff 3 ULONG offset to a default UVS table
2908 * describing any variants to be found in
2909 * the normal Unicode subtable.
2910 * nonDefOff 7 ULONG offset to a non-default UVS table
2911 * describing any variants not in the
2912 * standard cmap, with GIDs here
2913 * (either offset may be 0 NULL)
2914 *
2915 * Selectors are sorted by code point.
2916 *
2917 * A default Unicode Variation Selector (UVS) subtable is just a list of
2918 * ranges of code points which are to be found in the standard cmap. No
2919 * glyph IDs (GIDs) here.
2920 *
2921 * numRanges 0 ULONG number of ranges following
2922 *
2923 * A range looks like
2924 *
2925 * uniStart 0 UINT24 code point of the first character in
2926 * this range
2927 * additionalCnt 3 UBYTE count of additional characters in this
2928 * range (zero means a range of a single
2929 * character)
2930 *
2931 * Ranges are sorted by `uniStart'.
2932 *
2933 * A non-default Unicode Variation Selector (UVS) subtable is a list of
2934 * mappings from codepoint to GID.
2935 *
2936 * numMappings 0 ULONG number of mappings
2937 *
2938 * A range looks like
2939 *
2940 * uniStart 0 UINT24 code point of the first character in
2941 * this range
2942 * GID 3 USHORT and its GID
2943 *
2944 * Ranges are sorted by `uniStart'.
2945 */
2946
2947#ifdef TT_CONFIG_CMAP_FORMAT_14
2948
2949 typedef struct TT_CMap14Rec_
2950 {
2951 TT_CMapRec cmap;
2952 FT_ULong num_selectors;
2953
2954 /* This array is used to store the results of various
2955 * cmap 14 query functions. The data is overwritten
2956 * on each call to these functions.
2957 */
2958 FT_UInt32 max_results;
2959 FT_UInt32* results;
2961
2962 } TT_CMap14Rec, *TT_CMap14;
2963
2964
2965 FT_CALLBACK_DEF( void )
2966 tt_cmap14_done( TT_CMap14 cmap )
2967 {
2968 FT_Memory memory = cmap->memory;
2969
2970
2971 cmap->max_results = 0;
2972 if ( memory && cmap->results )
2973 FT_FREE( cmap->results );
2974 }
2975
2976
2977 static FT_Error
2978 tt_cmap14_ensure( TT_CMap14 cmap,
2979 FT_UInt32 num_results,
2981 {
2982 FT_UInt32 old_max = cmap->max_results;
2984
2985
2986 if ( num_results > cmap->max_results )
2987 {
2988 cmap->memory = memory;
2989
2990 if ( FT_QRENEW_ARRAY( cmap->results, old_max, num_results ) )
2991 return error;
2992
2993 cmap->max_results = num_results;
2994 }
2995
2996 return error;
2997 }
2998
2999
3001 tt_cmap14_init( TT_CMap14 cmap,
3002 FT_Byte* table )
3003 {
3004 cmap->cmap.data = table;
3005
3006 table += 6;
3007 cmap->num_selectors = FT_PEEK_ULONG( table );
3008 cmap->max_results = 0;
3009 cmap->results = NULL;
3010
3011 return FT_Err_Ok;
3012 }
3013
3014
3016 tt_cmap14_validate( FT_Byte* table,
3018 {
3019 FT_Byte* p;
3021 FT_ULong num_selectors;
3022
3023
3024 if ( table + 2 + 4 + 4 > valid->limit )
3026
3027 p = table + 2;
3028 length = TT_NEXT_ULONG( p );
3029 num_selectors = TT_NEXT_ULONG( p );
3030
3031 if ( length > (FT_ULong)( valid->limit - table ) ||
3032 /* length < 10 + 11 * num_selectors ? */
3033 length < 10 ||
3034 ( length - 10 ) / 11 < num_selectors )
3036
3037 /* check selectors, they must be in increasing order */
3038 {
3039 /* we start lastVarSel at 1 because a variant selector value of 0
3040 * isn't valid.
3041 */
3042 FT_ULong n, lastVarSel = 1;
3043
3044
3045 for ( n = 0; n < num_selectors; n++ )
3046 {
3047 FT_ULong varSel = TT_NEXT_UINT24( p );
3048 FT_ULong defOff = TT_NEXT_ULONG( p );
3049 FT_ULong nondefOff = TT_NEXT_ULONG( p );
3050
3051
3052 if ( defOff >= length || nondefOff >= length )
3054
3055 if ( varSel < lastVarSel )
3057
3058 lastVarSel = varSel + 1;
3059
3060 /* check the default table (these glyphs should be reached */
3061 /* through the normal Unicode cmap, no GIDs, just check order) */
3062 if ( defOff != 0 )
3063 {
3064 FT_Byte* defp = table + defOff;
3065 FT_ULong numRanges;
3066 FT_ULong i;
3067 FT_ULong lastBase = 0;
3068
3069
3070 if ( defp + 4 > valid->limit )
3072
3073 numRanges = TT_NEXT_ULONG( defp );
3074
3075 /* defp + numRanges * 4 > valid->limit ? */
3076 if ( numRanges > (FT_ULong)( valid->limit - defp ) / 4 )
3078
3079 for ( i = 0; i < numRanges; i++ )
3080 {
3081 FT_ULong base = TT_NEXT_UINT24( defp );
3082 FT_ULong cnt = FT_NEXT_BYTE( defp );
3083
3084
3085 if ( base + cnt >= 0x110000UL ) /* end of Unicode */
3087
3088 if ( base < lastBase )
3090
3091 lastBase = base + cnt + 1U;
3092 }
3093 }
3094
3095 /* and the non-default table (these glyphs are specified here) */
3096 if ( nondefOff != 0 )
3097 {
3098 FT_Byte* ndp = table + nondefOff;
3099 FT_ULong numMappings;
3100 FT_ULong i, lastUni = 0;
3101
3102
3103 if ( ndp + 4 > valid->limit )
3105
3106 numMappings = TT_NEXT_ULONG( ndp );
3107
3108 /* numMappings * 5 > (FT_ULong)( valid->limit - ndp ) ? */
3109 if ( numMappings > ( (FT_ULong)( valid->limit - ndp ) ) / 5 )
3111
3112 for ( i = 0; i < numMappings; i++ )
3113 {
3114 FT_ULong uni = TT_NEXT_UINT24( ndp );
3115 FT_ULong gid = TT_NEXT_USHORT( ndp );
3116
3117
3118 if ( uni >= 0x110000UL ) /* end of Unicode */
3120
3121 if ( uni < lastUni )
3123
3124 lastUni = uni + 1U;
3125
3126 if ( valid->level >= FT_VALIDATE_TIGHT &&
3127 gid >= TT_VALID_GLYPH_COUNT( valid ) )
3129 }
3130 }
3131 }
3132 }
3133
3134 return FT_Err_Ok;
3135 }
3136
3137
3139 tt_cmap14_char_index( TT_CMap cmap,
3140 FT_UInt32 char_code )
3141 {
3142 FT_UNUSED( cmap );
3143 FT_UNUSED( char_code );
3144
3145 /* This can't happen */
3146 return 0;
3147 }
3148
3149
3150 FT_CALLBACK_DEF( FT_UInt32 )
3151 tt_cmap14_char_next( TT_CMap cmap,
3152 FT_UInt32 *pchar_code )
3153 {
3154 FT_UNUSED( cmap );
3155
3156 /* This can't happen */
3157 *pchar_code = 0;
3158 return 0;
3159 }
3160
3161
3163 tt_cmap14_get_info( TT_CMap cmap,
3165 {
3166 FT_UNUSED( cmap );
3167
3168 cmap_info->format = 14;
3169 /* subtable 14 does not define a language field */
3170 cmap_info->language = 0xFFFFFFFFUL;
3171
3172 return FT_Err_Ok;
3173 }
3174
3175
3176 static FT_UInt
3177 tt_cmap14_char_map_def_binary( FT_Byte *base,
3178 FT_UInt32 char_code )
3179 {
3180 FT_UInt32 numRanges = TT_PEEK_ULONG( base );
3181 FT_UInt32 max, min;
3182
3183
3184 min = 0;
3185 max = numRanges;
3186
3187 base += 4;
3188
3189 /* binary search */
3190 while ( min < max )
3191 {
3192 FT_UInt32 mid = ( min + max ) >> 1;
3193 FT_Byte* p = base + 4 * mid;
3196
3197
3198 if ( char_code < start )
3199 max = mid;
3200 else if ( char_code > start + cnt )
3201 min = mid + 1;
3202 else
3203 return TRUE;
3204 }
3205
3206 return FALSE;
3207 }
3208
3209
3210 static FT_UInt
3211 tt_cmap14_char_map_nondef_binary( FT_Byte *base,
3212 FT_UInt32 char_code )
3213 {
3214 FT_UInt32 numMappings = TT_PEEK_ULONG( base );
3215 FT_UInt32 max, min;
3216
3217
3218 min = 0;
3219 max = numMappings;
3220
3221 base += 4;
3222
3223 /* binary search */
3224 while ( min < max )
3225 {
3226 FT_UInt32 mid = ( min + max ) >> 1;
3227 FT_Byte* p = base + 5 * mid;
3228 FT_UInt32 uni = (FT_UInt32)TT_NEXT_UINT24( p );
3229
3230
3231 if ( char_code < uni )
3232 max = mid;
3233 else if ( char_code > uni )
3234 min = mid + 1;
3235 else
3236 return TT_PEEK_USHORT( p );
3237 }
3238
3239 return 0;
3240 }
3241
3242
3243 static FT_Byte*
3244 tt_cmap14_find_variant( FT_Byte *base,
3245 FT_UInt32 variantCode )
3246 {
3247 FT_UInt32 numVar = TT_PEEK_ULONG( base );
3248 FT_UInt32 max, min;
3249
3250
3251 min = 0;
3252 max = numVar;
3253
3254 base += 4;
3255
3256 /* binary search */
3257 while ( min < max )
3258 {
3259 FT_UInt32 mid = ( min + max ) >> 1;
3260 FT_Byte* p = base + 11 * mid;
3261 FT_ULong varSel = TT_NEXT_UINT24( p );
3262
3263
3264 if ( variantCode < varSel )
3265 max = mid;
3266 else if ( variantCode > varSel )
3267 min = mid + 1;
3268 else
3269 return p;
3270 }
3271
3272 return NULL;
3273 }
3274
3275
3277 tt_cmap14_char_var_index( TT_CMap cmap,
3278 TT_CMap ucmap,
3279 FT_UInt32 charcode,
3280 FT_UInt32 variantSelector )
3281 {
3282 FT_Byte* p = tt_cmap14_find_variant( cmap->data + 6, variantSelector );
3283 FT_ULong defOff;
3284 FT_ULong nondefOff;
3285
3286
3287 if ( !p )
3288 return 0;
3289
3290 defOff = TT_NEXT_ULONG( p );
3291 nondefOff = TT_PEEK_ULONG( p );
3292
3293 if ( defOff != 0 &&
3294 tt_cmap14_char_map_def_binary( cmap->data + defOff, charcode ) )
3295 {
3296 /* This is the default variant of this charcode. GID not stored */
3297 /* here; stored in the normal Unicode charmap instead. */
3298 return ucmap->cmap.clazz->char_index( &ucmap->cmap, charcode );
3299 }
3300
3301 if ( nondefOff != 0 )
3302 return tt_cmap14_char_map_nondef_binary( cmap->data + nondefOff,
3303 charcode );
3304
3305 return 0;
3306 }
3307
3308
3310 tt_cmap14_char_var_isdefault( TT_CMap cmap,
3311 FT_UInt32 charcode,
3312 FT_UInt32 variantSelector )
3313 {
3314 FT_Byte* p = tt_cmap14_find_variant( cmap->data + 6, variantSelector );
3315 FT_ULong defOff;
3316 FT_ULong nondefOff;
3317
3318
3319 if ( !p )
3320 return -1;
3321
3322 defOff = TT_NEXT_ULONG( p );
3323 nondefOff = TT_NEXT_ULONG( p );
3324
3325 if ( defOff != 0 &&
3326 tt_cmap14_char_map_def_binary( cmap->data + defOff, charcode ) )
3327 return 1;
3328
3329 if ( nondefOff != 0 &&
3330 tt_cmap14_char_map_nondef_binary( cmap->data + nondefOff,
3331 charcode ) != 0 )
3332 return 0;
3333
3334 return -1;
3335 }
3336
3337
3338 FT_CALLBACK_DEF( FT_UInt32* )
3339 tt_cmap14_variants( TT_CMap cmap,
3341 {
3342 TT_CMap14 cmap14 = (TT_CMap14)cmap;
3343 FT_UInt32 count = cmap14->num_selectors;
3344 FT_Byte* p = cmap->data + 10;
3345 FT_UInt32* result;
3346 FT_UInt32 i;
3347
3348
3349 if ( tt_cmap14_ensure( cmap14, ( count + 1 ), memory ) )
3350 return NULL;
3351
3352 result = cmap14->results;
3353 for ( i = 0; i < count; i++ )
3354 {
3355 result[i] = (FT_UInt32)TT_NEXT_UINT24( p );
3356 p += 8;
3357 }
3358 result[i] = 0;
3359
3360 return result;
3361 }
3362
3363
3364 FT_CALLBACK_DEF( FT_UInt32 * )
3365 tt_cmap14_char_variants( TT_CMap cmap,
3367 FT_UInt32 charCode )
3368 {
3369 TT_CMap14 cmap14 = (TT_CMap14) cmap;
3370 FT_UInt32 count = cmap14->num_selectors;
3371 FT_Byte* p = cmap->data + 10;
3372 FT_UInt32* q;
3373
3374
3375 if ( tt_cmap14_ensure( cmap14, ( count + 1 ), memory ) )
3376 return NULL;
3377
3378 for ( q = cmap14->results; count > 0; count-- )
3379 {
3380 FT_UInt32 varSel = TT_NEXT_UINT24( p );
3381 FT_ULong defOff = TT_NEXT_ULONG( p );
3382 FT_ULong nondefOff = TT_NEXT_ULONG( p );
3383
3384
3385 if ( ( defOff != 0 &&
3386 tt_cmap14_char_map_def_binary( cmap->data + defOff,
3387 charCode ) ) ||
3388 ( nondefOff != 0 &&
3389 tt_cmap14_char_map_nondef_binary( cmap->data + nondefOff,
3390 charCode ) != 0 ) )
3391 {
3392 q[0] = varSel;
3393 q++;
3394 }
3395 }
3396 q[0] = 0;
3397
3398 return cmap14->results;
3399 }
3400
3401
3402 static FT_UInt
3403 tt_cmap14_def_char_count( FT_Byte *p )
3404 {
3405 FT_UInt32 numRanges = (FT_UInt32)TT_NEXT_ULONG( p );
3406 FT_UInt tot = 0;
3407
3408
3409 p += 3; /* point to the first `cnt' field */
3410 for ( ; numRanges > 0; numRanges-- )
3411 {
3412 tot += 1 + p[0];
3413 p += 4;
3414 }
3415
3416 return tot;
3417 }
3418
3419
3420 static FT_UInt32*
3421 tt_cmap14_get_def_chars( TT_CMap cmap,
3422 FT_Byte* p,
3424 {
3425 TT_CMap14 cmap14 = (TT_CMap14) cmap;
3426 FT_UInt32 numRanges;
3427 FT_UInt cnt;
3428 FT_UInt32* q;
3429
3430
3431 cnt = tt_cmap14_def_char_count( p );
3432 numRanges = (FT_UInt32)TT_NEXT_ULONG( p );
3433
3434 if ( tt_cmap14_ensure( cmap14, ( cnt + 1 ), memory ) )
3435 return NULL;
3436
3437 for ( q = cmap14->results; numRanges > 0; numRanges-- )
3438 {
3439 FT_UInt32 uni = (FT_UInt32)TT_NEXT_UINT24( p );
3440
3441
3442 cnt = FT_NEXT_BYTE( p ) + 1;
3443 do
3444 {
3445 q[0] = uni;
3446 uni += 1;
3447 q += 1;
3448
3449 } while ( --cnt != 0 );
3450 }
3451 q[0] = 0;
3452
3453 return cmap14->results;
3454 }
3455
3456
3457 static FT_UInt32*
3458 tt_cmap14_get_nondef_chars( TT_CMap cmap,
3459 FT_Byte *p,
3461 {
3462 TT_CMap14 cmap14 = (TT_CMap14) cmap;
3463 FT_UInt32 numMappings;
3464 FT_UInt i;
3465 FT_UInt32 *ret;
3466
3467
3468 numMappings = (FT_UInt32)TT_NEXT_ULONG( p );
3469
3470 if ( tt_cmap14_ensure( cmap14, ( numMappings + 1 ), memory ) )
3471 return NULL;
3472
3473 ret = cmap14->results;
3474 for ( i = 0; i < numMappings; i++ )
3475 {
3476 ret[i] = (FT_UInt32)TT_NEXT_UINT24( p );
3477 p += 2;
3478 }
3479 ret[i] = 0;
3480
3481 return ret;
3482 }
3483
3484
3485 FT_CALLBACK_DEF( FT_UInt32 * )
3486 tt_cmap14_variant_chars( TT_CMap cmap,
3488 FT_UInt32 variantSelector )
3489 {
3490 FT_Byte *p = tt_cmap14_find_variant( cmap->data + 6,
3491 variantSelector );
3492 FT_Int i;
3493 FT_ULong defOff;
3494 FT_ULong nondefOff;
3495
3496
3497 if ( !p )
3498 return NULL;
3499
3500 defOff = TT_NEXT_ULONG( p );
3501 nondefOff = TT_NEXT_ULONG( p );
3502
3503 if ( defOff == 0 && nondefOff == 0 )
3504 return NULL;
3505
3506 if ( defOff == 0 )
3507 return tt_cmap14_get_nondef_chars( cmap, cmap->data + nondefOff,
3508 memory );
3509 else if ( nondefOff == 0 )
3510 return tt_cmap14_get_def_chars( cmap, cmap->data + defOff,
3511 memory );
3512 else
3513 {
3514 /* Both a default and a non-default glyph set? That's probably not */
3515 /* good font design, but the spec allows for it... */
3516 TT_CMap14 cmap14 = (TT_CMap14) cmap;
3517 FT_UInt32 numRanges;
3518 FT_UInt32 numMappings;
3519 FT_UInt32 duni;
3520 FT_UInt32 dcnt;
3521 FT_UInt32 nuni;
3522 FT_Byte* dp;
3523 FT_UInt di, ni, k;
3524
3525 FT_UInt32 *ret;
3526
3527
3528 p = cmap->data + nondefOff;
3529 dp = cmap->data + defOff;
3530
3531 numMappings = (FT_UInt32)TT_NEXT_ULONG( p );
3532 dcnt = tt_cmap14_def_char_count( dp );
3533 numRanges = (FT_UInt32)TT_NEXT_ULONG( dp );
3534
3535 if ( numMappings == 0 )
3536 return tt_cmap14_get_def_chars( cmap, cmap->data + defOff,
3537 memory );
3538 if ( dcnt == 0 )
3539 return tt_cmap14_get_nondef_chars( cmap, cmap->data + nondefOff,
3540 memory );
3541
3542 if ( tt_cmap14_ensure( cmap14, ( dcnt + numMappings + 1 ), memory ) )
3543 return NULL;
3544
3545 ret = cmap14->results;
3546 duni = (FT_UInt32)TT_NEXT_UINT24( dp );
3547 dcnt = FT_NEXT_BYTE( dp );
3548 di = 1;
3549 nuni = (FT_UInt32)TT_NEXT_UINT24( p );
3550 p += 2;
3551 ni = 1;
3552 i = 0;
3553
3554 for (;;)
3555 {
3556 if ( nuni > duni + dcnt )
3557 {
3558 for ( k = 0; k <= dcnt; k++ )
3559 ret[i++] = duni + k;
3560
3561 di++;
3562
3563 if ( di > numRanges )
3564 break;
3565
3566 duni = (FT_UInt32)TT_NEXT_UINT24( dp );
3567 dcnt = FT_NEXT_BYTE( dp );
3568 }
3569 else
3570 {
3571 if ( nuni < duni )
3572 ret[i++] = nuni;
3573 /* If it is within the default range then ignore it -- */
3574 /* that should not have happened */
3575 ni++;
3576 if ( ni > numMappings )
3577 break;
3578
3579 nuni = (FT_UInt32)TT_NEXT_UINT24( p );
3580 p += 2;
3581 }
3582 }
3583
3584 if ( ni <= numMappings )
3585 {
3586 /* If we get here then we have run out of all default ranges. */
3587 /* We have read one non-default mapping which we haven't stored */
3588 /* and there may be others that need to be read. */
3589 ret[i++] = nuni;
3590 while ( ni < numMappings )
3591 {
3592 ret[i++] = (FT_UInt32)TT_NEXT_UINT24( p );
3593 p += 2;
3594 ni++;
3595 }
3596 }
3597 else if ( di <= numRanges )
3598 {
3599 /* If we get here then we have run out of all non-default */
3600 /* mappings. We have read one default range which we haven't */
3601 /* stored and there may be others that need to be read. */
3602 for ( k = 0; k <= dcnt; k++ )
3603 ret[i++] = duni + k;
3604
3605 while ( di < numRanges )
3606 {
3607 duni = (FT_UInt32)TT_NEXT_UINT24( dp );
3608 dcnt = FT_NEXT_BYTE( dp );
3609
3610 for ( k = 0; k <= dcnt; k++ )
3611 ret[i++] = duni + k;
3612 di++;
3613 }
3614 }
3615
3616 ret[i] = 0;
3617
3618 return ret;
3619 }
3620 }
3621
3622
3624 tt_cmap14_class_rec,
3625
3626 sizeof ( TT_CMap14Rec ),
3627
3628 (FT_CMap_InitFunc) tt_cmap14_init, /* init */
3629 (FT_CMap_DoneFunc) tt_cmap14_done, /* done */
3630 (FT_CMap_CharIndexFunc)tt_cmap14_char_index, /* char_index */
3631 (FT_CMap_CharNextFunc) tt_cmap14_char_next, /* char_next */
3632
3633 /* Format 14 extension functions */
3634 (FT_CMap_CharVarIndexFunc) tt_cmap14_char_var_index,
3635 (FT_CMap_CharVarIsDefaultFunc)tt_cmap14_char_var_isdefault,
3636 (FT_CMap_VariantListFunc) tt_cmap14_variants,
3637 (FT_CMap_CharVariantListFunc) tt_cmap14_char_variants,
3638 (FT_CMap_VariantCharListFunc) tt_cmap14_variant_chars,
3639
3640 14,
3641 (TT_CMap_ValidateFunc)tt_cmap14_validate, /* validate */
3642 (TT_CMap_Info_GetFunc)tt_cmap14_get_info /* get_cmap_info */
3643 )
3644
3645#endif /* TT_CONFIG_CMAP_FORMAT_14 */
3646
3647
3648 /*************************************************************************/
3649 /*************************************************************************/
3650 /***** *****/
3651 /***** SYNTHETIC UNICODE *****/
3652 /***** *****/
3653 /*************************************************************************/
3654 /*************************************************************************/
3655
3656 /* This charmap is generated using postscript glyph names. */
3657
3658#ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES
3659
3660 FT_CALLBACK_DEF( const char * )
3661 tt_get_glyph_name( TT_Face face,
3662 FT_UInt idx )
3663 {
3664 FT_String* PSname;
3665
3666
3667 tt_face_get_ps_name( face, idx, &PSname );
3668
3669 return PSname;
3670 }
3671
3672
3674 tt_cmap_unicode_init( PS_Unicodes unicodes,
3676 {
3677 TT_Face face = (TT_Face)FT_CMAP_FACE( unicodes );
3679 FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames;
3680
3681 FT_UNUSED( pointer );
3682
3683
3684 if ( !psnames->unicodes_init )
3685 return FT_THROW( Unimplemented_Feature );
3686
3687 return psnames->unicodes_init( memory,
3688 unicodes,
3689 face->root.num_glyphs,
3690 (PS_GetGlyphNameFunc)&tt_get_glyph_name,
3692 (FT_Pointer)face );
3693 }
3694
3695
3696 FT_CALLBACK_DEF( void )
3697 tt_cmap_unicode_done( PS_Unicodes unicodes )
3698 {
3699 FT_Face face = FT_CMAP_FACE( unicodes );
3701
3702
3703 FT_FREE( unicodes->maps );
3704 unicodes->num_maps = 0;
3705 }
3706
3707
3709 tt_cmap_unicode_char_index( PS_Unicodes unicodes,
3710 FT_UInt32 char_code )
3711 {
3712 TT_Face face = (TT_Face)FT_CMAP_FACE( unicodes );
3713 FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames;
3714
3715
3716 return psnames->unicodes_char_index( unicodes, char_code );
3717 }
3718
3719
3720 FT_CALLBACK_DEF( FT_UInt32 )
3721 tt_cmap_unicode_char_next( PS_Unicodes unicodes,
3722 FT_UInt32 *pchar_code )
3723 {
3724 TT_Face face = (TT_Face)FT_CMAP_FACE( unicodes );
3725 FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames;
3726
3727
3728 return psnames->unicodes_char_next( unicodes, pchar_code );
3729 }
3730
3731
3734
3735 sizeof ( PS_UnicodesRec ),
3736
3737 (FT_CMap_InitFunc) tt_cmap_unicode_init, /* init */
3738 (FT_CMap_DoneFunc) tt_cmap_unicode_done, /* done */
3739 (FT_CMap_CharIndexFunc)tt_cmap_unicode_char_index, /* char_index */
3740 (FT_CMap_CharNextFunc) tt_cmap_unicode_char_next, /* char_next */
3741
3742 (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */
3743 (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */
3744 (FT_CMap_VariantListFunc) NULL, /* variant_list */
3745 (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */
3746 (FT_CMap_VariantCharListFunc) NULL, /* variantchar_list */
3747
3748 ~0U,
3749 (TT_CMap_ValidateFunc)NULL, /* validate */
3750 (TT_CMap_Info_GetFunc)NULL /* get_cmap_info */
3751 )
3752
3753#endif /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */
3754
3755
3757 {
3758#define TTCMAPCITEM( a ) &a,
3759#include "ttcmapc.h"
3760 NULL,
3761 };
3762
3763
3764 /* parse the `cmap' table and build the corresponding TT_CMap objects */
3765 /* in the current face */
3766 /* */
3769 {
3770 FT_Byte* table = face->cmap_table;
3771 FT_Byte* limit = table + face->cmap_size;
3772 FT_UInt volatile num_cmaps;
3773 FT_Byte* volatile p = table;
3775
3776 FT_UNUSED( library );
3777
3778
3779 if ( !p || p + 4 > limit )
3780 return FT_THROW( Invalid_Table );
3781
3782 /* only recognize format 0 */
3783 if ( TT_NEXT_USHORT( p ) != 0 )
3784 {
3785 FT_ERROR(( "tt_face_build_cmaps:"
3786 " unsupported `cmap' table format = %d\n",
3787 TT_PEEK_USHORT( p - 2 ) ));
3788 return FT_THROW( Invalid_Table );
3789 }
3790
3791 num_cmaps = TT_NEXT_USHORT( p );
3792
3793 for ( ; num_cmaps > 0 && p + 8 <= limit; num_cmaps-- )
3794 {
3795 FT_CharMapRec charmap;
3796 FT_UInt32 offset;
3797
3798
3799 charmap.platform_id = TT_NEXT_USHORT( p );
3800 charmap.encoding_id = TT_NEXT_USHORT( p );
3801 charmap.face = FT_FACE( face );
3802 charmap.encoding = FT_ENCODING_NONE; /* will be filled later */
3803 offset = TT_NEXT_ULONG( p );
3804
3805 if ( offset && offset <= face->cmap_size - 2 )
3806 {
3807 FT_Byte* volatile cmap = table + offset;
3808 volatile FT_UInt format = TT_PEEK_USHORT( cmap );
3809 const TT_CMap_Class* volatile pclazz = tt_cmap_classes;
3810 TT_CMap_Class volatile clazz;
3811
3812
3813 for ( ; *pclazz; pclazz++ )
3814 {
3815 clazz = *pclazz;
3816 if ( clazz->format == format )
3817 {
3818 volatile TT_ValidatorRec valid;
3819 volatile FT_Error error = FT_Err_Ok;
3820
3821
3824
3825 valid.num_glyphs = (FT_UInt)face->max_profile.numGlyphs;
3826
3827 if ( ft_setjmp( FT_VALIDATOR( &valid )->jump_buffer) == 0 )
3828 {
3829 /* validate this cmap sub-table */
3830 error = clazz->validate( cmap, FT_VALIDATOR( &valid ) );
3831 }
3832
3833 if ( !valid.validator.error )
3834 {
3835 FT_CMap ttcmap;
3836
3837
3838 /* It might make sense to store the single variation */
3839 /* selector cmap somewhere special. But it would have to be */
3840 /* in the public FT_FaceRec, and we can't change that. */
3841
3842 if ( !FT_CMap_New( (FT_CMap_Class)clazz,
3843 cmap, &charmap, &ttcmap ) )
3844 {
3845 /* it is simpler to directly set `flags' than adding */
3846 /* a parameter to FT_CMap_New */
3847 ((TT_CMap)ttcmap)->flags = (FT_Int)error;
3848 }
3849 }
3850 else
3851 {
3852 FT_TRACE0(( "tt_face_build_cmaps:"
3853 " broken cmap sub-table ignored\n" ));
3854 }
3855 break;
3856 }
3857 }
3858
3859 if ( !*pclazz )
3860 {
3861 FT_TRACE0(( "tt_face_build_cmaps:"
3862 " unsupported cmap sub-table ignored\n" ));
3863 }
3864 }
3865 }
3866
3867 return FT_Err_Ok;
3868 }
3869
3870
3874 {
3875 FT_CMap cmap = (FT_CMap)charmap;
3876 TT_CMap_Class clazz = (TT_CMap_Class)cmap->clazz;
3877
3878 if ( clazz->get_cmap_info )
3879 return clazz->get_cmap_info( charmap, cmap_info );
3880 else
3881 return FT_THROW( Invalid_CharMap_Format );
3882 }
3883
3884
3885/* 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
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:116
#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:3872
#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:3756
tt_face_build_cmaps(TT_Face face)
Definition: ttcmap.c:3768
#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
int ret
_In_ size_t cnt
Definition: wcstombs.cpp:43