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