ReactOS  0.4.14-dev-55-g2da92ac
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,
98  FT_Validator valid )
99  {
100  FT_Byte* p;
101  FT_UInt length;
102 
103 
104  if ( table + 2 + 2 > valid->limit )
106 
107  p = table + 2; /* skip format */
108  length = TT_NEXT_USHORT( p );
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,
297  FT_Validator valid )
298  {
299  FT_Byte* p;
300  FT_UInt length;
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 */
312  length = TT_NEXT_USHORT( p );
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 );
354  offset = TT_NEXT_USHORT( 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;
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  {
408  FT_Byte* result = NULL;
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;
472  FT_UInt offset;
473 
474 
475  start = TT_NEXT_USHORT( p );
476  count = TT_NEXT_USHORT( p );
477  delta = TT_NEXT_SHORT ( p );
478  offset = TT_PEEK_USHORT( 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  {
732  FT_UInt offset;
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;
745  offset = FT_PEEK_USHORT( p );
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,
888  FT_Validator valid )
889  {
890  FT_Byte* p;
891  FT_UInt length;
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 */
902  length = TT_NEXT_USHORT( p );
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  {
972  FT_UInt start, end, offset, n;
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  {
1085  TT_Face face = (TT_Face)cmap->cmap.charmap.face;
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  {
1220  TT_Face face = (TT_Face)cmap->cmap.charmap.face;
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,
1591  FT_Validator valid )
1592  {
1593  FT_Byte* p;
1594  FT_UInt length, count;
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,
1789  FT_Validator valid )
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,
2054  FT_Validator valid )
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,
2257  FT_Validator valid )
2258  {
2259  FT_Byte* p;
2260  FT_ULong length;
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,
2613  FT_Validator valid )
2614  {
2615  FT_Byte* p;
2616  FT_ULong length;
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;
2953  FT_Memory memory;
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,
2973  FT_Memory memory )
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,
3010  FT_Validator valid )
3011  {
3012  FT_Byte* p;
3013  FT_ULong length;
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,
3333  FT_Memory memory )
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,
3359  FT_Memory memory,
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,
3416  FT_Memory memory )
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,
3453  FT_Memory memory )
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,
3480  FT_Memory memory,
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;
3774  FT_Error error;
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 
3868  ft_validator_init( FT_VALIDATOR( &valid ), cmap, limit,
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 
3917  FT_LOCAL( FT_Error )
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 */
#define FT_ALLOC(ptr, size)
Definition: ftmemory.h:303
int FT_Error
Definition: fttypes.h:300
#define FT_QRENEW_ARRAY(ptr, curcnt, newcnt)
Definition: ftmemory.h:345
#define max(a, b)
Definition: svc.c:63
FT_Face face
Definition: freetype.h:842
#define TRUE
Definition: types.h:120
FT_CharMapRec charmap
Definition: ftobjs.h:153
unsigned long FT_ULong
Definition: fttypes.h:253
FT_UShort encoding_id
Definition: freetype.h:845
FT_UInt num_maps
Definition: svpscmap.h:67
FT_Byte * data
Definition: ttcmap.h:37
FT_Memory memory
Definition: ftobjs.h:918
#define error(str)
Definition: mkdosfs.c:1605
#define FT_CMAP_FACE(x)
Definition: ftobjs.h:165
FT_UInt(* FT_CMap_CharIndexFunc)(FT_CMap cmap, FT_UInt32 char_code)
Definition: ftobjs.h:177
GLsizei const GLvoid * pointer
Definition: glext.h:5848
POINT last
Definition: font.c:46
FT_Error(* TT_CMap_ValidateFunc)(FT_Byte *data, FT_Validator valid)
Definition: ttcmap.h:46
tt_face_build_cmaps(TT_Face face)
Definition: ttcmap.c:3814
signed int FT_Int
Definition: fttypes.h:220
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
static struct netconfig_info ni
Definition: getnetconfig.c:158
GLuint GLuint GLsizei count
Definition: gl.h:1545
#define U(x)
Definition: wordpad.c:44
FT_UInt32 *(* FT_CMap_VariantCharListFunc)(FT_CMap cmap, FT_Memory mem, FT_UInt32 variant_selector)
Definition: ftobjs.h:205
GLboolean GLenum GLenum GLvoid * values
Definition: glext.h:5666
GLintptr offset
Definition: glext.h:5920
static const TT_CMap_Class tt_cmap_classes[]
Definition: ttcmap.c:3747
GLdouble n
Definition: glext.h:7729
tt_cmap_init(TT_CMap cmap, FT_Byte *table)
Definition: ttcmap.c:64
FT_UInt num_glyphs
Definition: ttcmap.h:135
void(* FT_CMap_DoneFunc)(FT_CMap cmap)
Definition: ftobjs.h:174
#define FT_NEXT_BYTE(buffer)
Definition: ftstream.h:220
GLenum GLsizei GLenum GLenum const GLvoid * table
Definition: glext.h:5644
#define FT_INVALID_TOO_SHORT
Definition: ftvalid.h:134
#define FT_PAD_FLOOR(x, n)
Definition: ftobjs.h:88
GLuint GLuint end
Definition: gl.h:1545
FT_Library library
Definition: cffdrivr.c:654
return FT_Err_Ok
Definition: ftbbox.c:511
tt_get_cmap_info(FT_CharMap charmap, TT_CMapInfo *cmap_info)
Definition: ttcmap.c:3918
static char memory[1024 *256]
Definition: process.c:116
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
GLint limit
Definition: glext.h:10326
TT_CMap_Info_GetFunc get_cmap_info
Definition: ttcmap.h:54
FT_BEGIN_HEADER typedef unsigned char FT_Bool
Definition: fttypes.h:108
GLuint * ids
Definition: glext.h:5907
#define TT_NEXT_SHORT
Definition: ttcmap.c:49
#define TT_PEEK_SHORT
Definition: ttcmap.c:43
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
TT_CMapInfo * cmap_info
Definition: cffdrivr.c:649
#define FT_ERROR(varformat)
Definition: ftdebug.h:181
const struct TT_CMap_ClassRec_ * TT_CMap_Class
Definition: ttcmap.h:42
FT_CharMap charmap
Definition: freetype.h:1107
unsigned char FT_Byte
Definition: fttypes.h:154
#define FT_THROW(e)
Definition: ftdebug.h:213
#define FT_ASSERT(condition)
Definition: ftdebug.h:211
#define TT_PEEK_ULONG
Definition: ttcmap.c:47
#define FT_LOCAL(x)
Definition: ftconfig.h:387
struct FT_CMapRec_ * FT_CMap
Definition: ftobjs.h:145
unsigned int idx
Definition: utils.c:41
FT_CALLBACK_TABLE const TT_CMap_ClassRec tt_cmap_unicode_class_rec
Definition: ttcmap.h:144
PS_UniMap * maps
Definition: svpscmap.h:68
smooth NULL
Definition: ftsmooth.c:416
FT_UInt32 *(* FT_CMap_VariantListFunc)(FT_CMap cmap, FT_Memory mem)
Definition: ftobjs.h:196
#define FT_PEEK_ULONG(p)
Definition: ftstream.h:179
#define TT_NEXT_ULONG
Definition: ttcmap.c:53
#define FT_FREE(ptr)
Definition: ftmemory.h:329
#define FT_LOCAL_DEF(x)
Definition: ftconfig.h:388
struct TT_FaceRec_ * TT_Face
Definition: tttypes.h:973
const char *(* PS_GetGlyphNameFunc)(FT_Pointer data, FT_UInt string_index)
Definition: svpscmap.h:78
#define FT_TRACE0(varformat)
Definition: ftdebug.h:157
char FT_String
Definition: fttypes.h:187
FT_UInt format
Definition: ttcmap.h:52
#define d
Definition: ke_i.h:81
if(!(yy_init))
Definition: macro.lex.yy.c:714
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
static void Exit(void)
Definition: sock.c:1331
typedefFT_BEGIN_HEADER struct FT_ValidatorRec_ volatile * FT_Validator
Definition: ftvalid.h:42
void(* PS_FreeGlyphNameFunc)(FT_Pointer data, const char *name)
Definition: svpscmap.h:86
#define TT_NEXT_USHORT
Definition: ttcmap.c:50
#define ft_setjmp(b)
Definition: ftstdlib.h:163
TT_CMap_ValidateFunc validate
Definition: ttcmap.h:53
GLdouble GLdouble GLdouble GLdouble q
Definition: gl.h:2063
struct _test_info results[8]
Definition: SetCursorPos.c:29
#define FT_VALIDATOR(x)
Definition: ftvalid.h:103
FT_ULong language
Definition: svttcmap.h:60
#define FT_CALLBACK_DEF(x)
Definition: ftconfig.h:533
#define FT_PEEK_USHORT(p)
Definition: ftstream.h:171
FT_Encoding encoding
Definition: freetype.h:843
int ret
#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
static const WCHAR L[]
Definition: oid.c:1250
#define TT_PEEK_USHORT
Definition: ttcmap.c:44
FT_ValidatorRec validator
Definition: ttcmap.h:134
typedefFT_BEGIN_HEADER struct FT_MemoryRec_ * FT_Memory
Definition: ftsystem.h:66
#define TT_NEXT_UINT24
Definition: ttcmap.c:51
#define FT_NEXT_USHORT(buffer)
Definition: ftstream.h:226
FT_Error(* TT_CMap_Info_GetFunc)(FT_CharMap charmap, TT_CMapInfo *cmap_info)
Definition: svttcmap.h:67
basic_ostream< _CharT, _Traits > &_STLP_CALL ends(basic_ostream< _CharT, _Traits > &__os)
Definition: _ostream.h:365
struct TT_CMapRec_ * TT_CMap
#define FT_INVALID_OFFSET
Definition: ftvalid.h:138
FT_Byte * cmap_table
Definition: tttypes.h:1415
#define FT_FACE_MEMORY(x)
Definition: ftobjs.h:636
FT_Int flags
Definition: ttcmap.h:38
Definition: hiveinit.c:368
FT_CMap_New(FT_CMap_Class clazz, FT_Pointer init_data, FT_CharMap charmap, FT_CMap *acmap)
Definition: ftobjs.c:3614
FT_UShort platform_id
Definition: freetype.h:844
static unsigned __int64 next
Definition: rand_nt.c:6
#define FT_FACE(x)
Definition: ftobjs.h:630
FT_Error error
Definition: ftvalid.h:95
FT_Long format
Definition: svttcmap.h:61
BYTE * data
unsigned int FT_UInt
Definition: fttypes.h:231
GLuint start
Definition: gl.h:1545
FT_CMap_CharIndexFunc char_index
Definition: ftobjs.h:216
#define TT_VALID_GLYPH_COUNT(x)
Definition: ttcmap.h:141
#define min(a, b)
Definition: monoChain.cc:55
#define TT_CMAP_FLAG_UNSORTED
Definition: ttcmap.h:31
ft_validator_init(FT_Validator valid, const FT_Byte *base, const FT_Byte *limit, FT_ValidationLevel level)
Definition: ftobjs.c:122
#define TT_CMAP_FLAG_OVERLAPPING
Definition: ttcmap.h:32
FT_UInt(* FT_CMap_CharNextFunc)(FT_CMap cmap, FT_UInt32 *achar_code)
Definition: ftobjs.h:181
#define FT_INVALID_DATA
Definition: ftvalid.h:150
#define TT_CMAP_CLASSES_GET
Definition: sfntpic.h:32
#define FT_INVALID_GLYPH_ID
Definition: ftvalid.h:146
FT_BEGIN_HEADER tt_face_get_ps_name(TT_Face face, FT_UInt idx, FT_String **PSname)
GLfloat GLfloat p
Definition: glext.h:8902
#define FT_FACE_LIBRARY(x)
Definition: ftobjs.h:635
FT_Error(* FT_CMap_InitFunc)(FT_CMap cmap, FT_Pointer init_data)
Definition: ftobjs.h:170
GLuint64EXT * result
Definition: glext.h:11304
#define FT_UNUSED(arg)
Definition: ftconfig.h:101
FT_UInt32 *(* FT_CMap_CharVariantListFunc)(FT_CMap cmap, FT_Memory mem, FT_UInt32 char_code)
Definition: ftobjs.h:200
FT_CMapRec cmap
Definition: ttcmap.h:36
#define UL
Definition: tui.h:83
int k
Definition: mpi.c:3369
FT_UInt(* FT_CMap_CharVarIndexFunc)(FT_CMap cmap, FT_CMap unicode_cmap, FT_UInt32 char_code, FT_UInt32 variant_selector)
Definition: ftobjs.h:185
GLenum GLuint GLint GLenum face
Definition: glext.h:7025
FT_Bool(* FT_CMap_CharVarIsDefaultFunc)(FT_CMap cmap, FT_UInt32 char_code, FT_UInt32 variant_selector)
Definition: ftobjs.h:191
FT_CMap_Class clazz
Definition: ftobjs.h:154
#define FT_PEEK_SHORT(p)
Definition: ftstream.h:168