xref: /inferno-os/libfreetype/t1cmap.c (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
1*37da2899SCharles.Forsyth /***************************************************************************/
2*37da2899SCharles.Forsyth /*                                                                         */
3*37da2899SCharles.Forsyth /*  t1cmap.c                                                               */
4*37da2899SCharles.Forsyth /*                                                                         */
5*37da2899SCharles.Forsyth /*    Type 1 character map support (body).                                 */
6*37da2899SCharles.Forsyth /*                                                                         */
7*37da2899SCharles.Forsyth /*  Copyright 2002 by                                                      */
8*37da2899SCharles.Forsyth /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
9*37da2899SCharles.Forsyth /*                                                                         */
10*37da2899SCharles.Forsyth /*  This file is part of the FreeType project, and may only be used,       */
11*37da2899SCharles.Forsyth /*  modified, and distributed under the terms of the FreeType project      */
12*37da2899SCharles.Forsyth /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
13*37da2899SCharles.Forsyth /*  this file you indicate that you have read the license and              */
14*37da2899SCharles.Forsyth /*  understand and accept it fully.                                        */
15*37da2899SCharles.Forsyth /*                                                                         */
16*37da2899SCharles.Forsyth /***************************************************************************/
17*37da2899SCharles.Forsyth 
18*37da2899SCharles.Forsyth 
19*37da2899SCharles.Forsyth #include "t1cmap.h"
20*37da2899SCharles.Forsyth 
21*37da2899SCharles.Forsyth #include FT_INTERNAL_DEBUG_H
22*37da2899SCharles.Forsyth 
23*37da2899SCharles.Forsyth 
24*37da2899SCharles.Forsyth   /*************************************************************************/
25*37da2899SCharles.Forsyth   /*************************************************************************/
26*37da2899SCharles.Forsyth   /*****                                                               *****/
27*37da2899SCharles.Forsyth   /*****          TYPE1 STANDARD (AND EXPERT) ENCODING CMAPS           *****/
28*37da2899SCharles.Forsyth   /*****                                                               *****/
29*37da2899SCharles.Forsyth   /*************************************************************************/
30*37da2899SCharles.Forsyth   /*************************************************************************/
31*37da2899SCharles.Forsyth 
32*37da2899SCharles.Forsyth   static void
t1_cmap_std_init(T1_CMapStd cmap,FT_Int is_expert)33*37da2899SCharles.Forsyth   t1_cmap_std_init( T1_CMapStd  cmap,
34*37da2899SCharles.Forsyth                     FT_Int      is_expert )
35*37da2899SCharles.Forsyth   {
36*37da2899SCharles.Forsyth     T1_Face          face    = (T1_Face)FT_CMAP_FACE( cmap );
37*37da2899SCharles.Forsyth     PSNames_Service  psnames = (PSNames_Service)face->psnames;
38*37da2899SCharles.Forsyth 
39*37da2899SCharles.Forsyth 
40*37da2899SCharles.Forsyth     cmap->num_glyphs    = face->type1.num_glyphs;
41*37da2899SCharles.Forsyth     cmap->glyph_names   = (const char* const*)face->type1.glyph_names;
42*37da2899SCharles.Forsyth     cmap->sid_to_string = psnames->adobe_std_strings;
43*37da2899SCharles.Forsyth     cmap->code_to_sid   = is_expert ? psnames->adobe_expert_encoding
44*37da2899SCharles.Forsyth                                     : psnames->adobe_std_encoding;
45*37da2899SCharles.Forsyth 
46*37da2899SCharles.Forsyth     FT_ASSERT( cmap->code_to_sid != NULL );
47*37da2899SCharles.Forsyth   }
48*37da2899SCharles.Forsyth 
49*37da2899SCharles.Forsyth 
50*37da2899SCharles.Forsyth   FT_CALLBACK_DEF( void )
t1_cmap_std_done(T1_CMapStd cmap)51*37da2899SCharles.Forsyth   t1_cmap_std_done( T1_CMapStd  cmap )
52*37da2899SCharles.Forsyth   {
53*37da2899SCharles.Forsyth     cmap->num_glyphs    = 0;
54*37da2899SCharles.Forsyth     cmap->glyph_names   = NULL;
55*37da2899SCharles.Forsyth     cmap->sid_to_string = NULL;
56*37da2899SCharles.Forsyth     cmap->code_to_sid   = NULL;
57*37da2899SCharles.Forsyth   }
58*37da2899SCharles.Forsyth 
59*37da2899SCharles.Forsyth 
60*37da2899SCharles.Forsyth   FT_CALLBACK_DEF( FT_UInt )
t1_cmap_std_char_index(T1_CMapStd cmap,FT_UInt32 char_code)61*37da2899SCharles.Forsyth   t1_cmap_std_char_index( T1_CMapStd  cmap,
62*37da2899SCharles.Forsyth                           FT_UInt32   char_code )
63*37da2899SCharles.Forsyth   {
64*37da2899SCharles.Forsyth     FT_UInt  result = 0;
65*37da2899SCharles.Forsyth 
66*37da2899SCharles.Forsyth 
67*37da2899SCharles.Forsyth     if ( char_code < 256 )
68*37da2899SCharles.Forsyth     {
69*37da2899SCharles.Forsyth       FT_UInt      code, n;
70*37da2899SCharles.Forsyth       const char*  glyph_name;
71*37da2899SCharles.Forsyth 
72*37da2899SCharles.Forsyth 
73*37da2899SCharles.Forsyth       /* convert character code to Adobe SID string */
74*37da2899SCharles.Forsyth       code       = cmap->code_to_sid[char_code];
75*37da2899SCharles.Forsyth       glyph_name = cmap->sid_to_string( code );
76*37da2899SCharles.Forsyth 
77*37da2899SCharles.Forsyth       /* look for the corresponding glyph name */
78*37da2899SCharles.Forsyth       for ( n = 0; n < cmap->num_glyphs; n++ )
79*37da2899SCharles.Forsyth       {
80*37da2899SCharles.Forsyth         const char* gname = cmap->glyph_names[n];
81*37da2899SCharles.Forsyth 
82*37da2899SCharles.Forsyth 
83*37da2899SCharles.Forsyth         if ( gname && gname[0] == glyph_name[0]  &&
84*37da2899SCharles.Forsyth              ft_strcmp( gname, glyph_name ) == 0 )
85*37da2899SCharles.Forsyth         {
86*37da2899SCharles.Forsyth           result = n;
87*37da2899SCharles.Forsyth           break;
88*37da2899SCharles.Forsyth         }
89*37da2899SCharles.Forsyth       }
90*37da2899SCharles.Forsyth     }
91*37da2899SCharles.Forsyth 
92*37da2899SCharles.Forsyth     return result;
93*37da2899SCharles.Forsyth   }
94*37da2899SCharles.Forsyth 
95*37da2899SCharles.Forsyth 
96*37da2899SCharles.Forsyth   FT_CALLBACK_DEF( FT_UInt )
t1_cmap_std_char_next(T1_CMapStd cmap,FT_UInt32 * pchar_code)97*37da2899SCharles.Forsyth   t1_cmap_std_char_next( T1_CMapStd   cmap,
98*37da2899SCharles.Forsyth                          FT_UInt32   *pchar_code )
99*37da2899SCharles.Forsyth   {
100*37da2899SCharles.Forsyth     FT_UInt    result    = 0;
101*37da2899SCharles.Forsyth     FT_UInt32  char_code = *pchar_code + 1;
102*37da2899SCharles.Forsyth 
103*37da2899SCharles.Forsyth 
104*37da2899SCharles.Forsyth     while ( char_code < 256 )
105*37da2899SCharles.Forsyth     {
106*37da2899SCharles.Forsyth       result = t1_cmap_std_char_index( cmap, char_code );
107*37da2899SCharles.Forsyth       if ( result != 0 )
108*37da2899SCharles.Forsyth         goto Exit;
109*37da2899SCharles.Forsyth 
110*37da2899SCharles.Forsyth       char_code++;
111*37da2899SCharles.Forsyth     }
112*37da2899SCharles.Forsyth     char_code = 0;
113*37da2899SCharles.Forsyth 
114*37da2899SCharles.Forsyth   Exit:
115*37da2899SCharles.Forsyth     *pchar_code = char_code;
116*37da2899SCharles.Forsyth     return result;
117*37da2899SCharles.Forsyth   }
118*37da2899SCharles.Forsyth 
119*37da2899SCharles.Forsyth 
120*37da2899SCharles.Forsyth   FT_CALLBACK_DEF( FT_Error )
t1_cmap_standard_init(T1_CMapStd cmap)121*37da2899SCharles.Forsyth   t1_cmap_standard_init( T1_CMapStd  cmap )
122*37da2899SCharles.Forsyth   {
123*37da2899SCharles.Forsyth     t1_cmap_std_init( cmap, 0 );
124*37da2899SCharles.Forsyth     return 0;
125*37da2899SCharles.Forsyth   }
126*37da2899SCharles.Forsyth 
127*37da2899SCharles.Forsyth 
128*37da2899SCharles.Forsyth   FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec
129*37da2899SCharles.Forsyth   t1_cmap_standard_class_rec =
130*37da2899SCharles.Forsyth   {
131*37da2899SCharles.Forsyth     sizeof ( T1_CMapStdRec ),
132*37da2899SCharles.Forsyth 
133*37da2899SCharles.Forsyth     (FT_CMap_InitFunc)     t1_cmap_standard_init,
134*37da2899SCharles.Forsyth     (FT_CMap_DoneFunc)     t1_cmap_std_done,
135*37da2899SCharles.Forsyth     (FT_CMap_CharIndexFunc)t1_cmap_std_char_index,
136*37da2899SCharles.Forsyth     (FT_CMap_CharNextFunc) t1_cmap_std_char_next
137*37da2899SCharles.Forsyth   };
138*37da2899SCharles.Forsyth 
139*37da2899SCharles.Forsyth 
140*37da2899SCharles.Forsyth   FT_CALLBACK_DEF( FT_Error )
t1_cmap_expert_init(T1_CMapStd cmap)141*37da2899SCharles.Forsyth   t1_cmap_expert_init( T1_CMapStd  cmap )
142*37da2899SCharles.Forsyth   {
143*37da2899SCharles.Forsyth     t1_cmap_std_init( cmap, 1 );
144*37da2899SCharles.Forsyth     return 0;
145*37da2899SCharles.Forsyth   }
146*37da2899SCharles.Forsyth 
147*37da2899SCharles.Forsyth   FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec
148*37da2899SCharles.Forsyth   t1_cmap_expert_class_rec =
149*37da2899SCharles.Forsyth   {
150*37da2899SCharles.Forsyth     sizeof ( T1_CMapStdRec ),
151*37da2899SCharles.Forsyth 
152*37da2899SCharles.Forsyth     (FT_CMap_InitFunc)     t1_cmap_expert_init,
153*37da2899SCharles.Forsyth     (FT_CMap_DoneFunc)     t1_cmap_std_done,
154*37da2899SCharles.Forsyth     (FT_CMap_CharIndexFunc)t1_cmap_std_char_index,
155*37da2899SCharles.Forsyth     (FT_CMap_CharNextFunc) t1_cmap_std_char_next
156*37da2899SCharles.Forsyth   };
157*37da2899SCharles.Forsyth 
158*37da2899SCharles.Forsyth 
159*37da2899SCharles.Forsyth   /*************************************************************************/
160*37da2899SCharles.Forsyth   /*************************************************************************/
161*37da2899SCharles.Forsyth   /*****                                                               *****/
162*37da2899SCharles.Forsyth   /*****                    TYPE1 CUSTOM ENCODING CMAP                 *****/
163*37da2899SCharles.Forsyth   /*****                                                               *****/
164*37da2899SCharles.Forsyth   /*************************************************************************/
165*37da2899SCharles.Forsyth   /*************************************************************************/
166*37da2899SCharles.Forsyth 
167*37da2899SCharles.Forsyth 
168*37da2899SCharles.Forsyth   FT_CALLBACK_DEF( FT_Error )
t1_cmap_custom_init(T1_CMapCustom cmap)169*37da2899SCharles.Forsyth   t1_cmap_custom_init( T1_CMapCustom  cmap )
170*37da2899SCharles.Forsyth   {
171*37da2899SCharles.Forsyth     T1_Face      face     = (T1_Face)FT_CMAP_FACE( cmap );
172*37da2899SCharles.Forsyth     T1_Encoding  encoding = &face->type1.encoding;
173*37da2899SCharles.Forsyth 
174*37da2899SCharles.Forsyth 
175*37da2899SCharles.Forsyth     cmap->first   = encoding->code_first;
176*37da2899SCharles.Forsyth     cmap->count   = (FT_UInt)( encoding->code_last - cmap->first + 1 );
177*37da2899SCharles.Forsyth     cmap->indices = encoding->char_index;
178*37da2899SCharles.Forsyth 
179*37da2899SCharles.Forsyth     FT_ASSERT( cmap->indices != NULL );
180*37da2899SCharles.Forsyth     FT_ASSERT( encoding->code_first <= encoding->code_last );
181*37da2899SCharles.Forsyth 
182*37da2899SCharles.Forsyth     return 0;
183*37da2899SCharles.Forsyth   }
184*37da2899SCharles.Forsyth 
185*37da2899SCharles.Forsyth 
186*37da2899SCharles.Forsyth   FT_CALLBACK_DEF( void )
t1_cmap_custom_done(T1_CMapCustom cmap)187*37da2899SCharles.Forsyth   t1_cmap_custom_done( T1_CMapCustom  cmap )
188*37da2899SCharles.Forsyth   {
189*37da2899SCharles.Forsyth     cmap->indices = NULL;
190*37da2899SCharles.Forsyth     cmap->first   = 0;
191*37da2899SCharles.Forsyth     cmap->count   = 0;
192*37da2899SCharles.Forsyth   }
193*37da2899SCharles.Forsyth 
194*37da2899SCharles.Forsyth 
195*37da2899SCharles.Forsyth   FT_CALLBACK_DEF( FT_UInt )
t1_cmap_custom_char_index(T1_CMapCustom cmap,FT_UInt32 char_code)196*37da2899SCharles.Forsyth   t1_cmap_custom_char_index( T1_CMapCustom  cmap,
197*37da2899SCharles.Forsyth                              FT_UInt32      char_code )
198*37da2899SCharles.Forsyth   {
199*37da2899SCharles.Forsyth     FT_UInt    result = 0;
200*37da2899SCharles.Forsyth 
201*37da2899SCharles.Forsyth 
202*37da2899SCharles.Forsyth     if ( ( char_code >= cmap->first )                  &&
203*37da2899SCharles.Forsyth          ( char_code < ( cmap->first + cmap->count ) ) )
204*37da2899SCharles.Forsyth       result = cmap->indices[char_code];
205*37da2899SCharles.Forsyth 
206*37da2899SCharles.Forsyth     return result;
207*37da2899SCharles.Forsyth   }
208*37da2899SCharles.Forsyth 
209*37da2899SCharles.Forsyth 
210*37da2899SCharles.Forsyth   FT_CALLBACK_DEF( FT_UInt )
t1_cmap_custom_char_next(T1_CMapCustom cmap,FT_UInt32 * pchar_code)211*37da2899SCharles.Forsyth   t1_cmap_custom_char_next( T1_CMapCustom  cmap,
212*37da2899SCharles.Forsyth                             FT_UInt32     *pchar_code )
213*37da2899SCharles.Forsyth   {
214*37da2899SCharles.Forsyth     FT_UInt    result = 0;
215*37da2899SCharles.Forsyth     FT_UInt32  char_code = *pchar_code;
216*37da2899SCharles.Forsyth 
217*37da2899SCharles.Forsyth 
218*37da2899SCharles.Forsyth     ++char_code;
219*37da2899SCharles.Forsyth 
220*37da2899SCharles.Forsyth     if ( char_code < cmap->first )
221*37da2899SCharles.Forsyth       char_code = cmap->first;
222*37da2899SCharles.Forsyth 
223*37da2899SCharles.Forsyth     for ( ; char_code < ( cmap->first + cmap->count ); char_code++ )
224*37da2899SCharles.Forsyth     {
225*37da2899SCharles.Forsyth       result = cmap->indices[char_code];
226*37da2899SCharles.Forsyth       if ( result != 0 )
227*37da2899SCharles.Forsyth         goto Exit;
228*37da2899SCharles.Forsyth     }
229*37da2899SCharles.Forsyth 
230*37da2899SCharles.Forsyth     char_code = 0;
231*37da2899SCharles.Forsyth 
232*37da2899SCharles.Forsyth   Exit:
233*37da2899SCharles.Forsyth     *pchar_code = char_code;
234*37da2899SCharles.Forsyth     return result;
235*37da2899SCharles.Forsyth   }
236*37da2899SCharles.Forsyth 
237*37da2899SCharles.Forsyth 
238*37da2899SCharles.Forsyth   FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec
239*37da2899SCharles.Forsyth   t1_cmap_custom_class_rec =
240*37da2899SCharles.Forsyth   {
241*37da2899SCharles.Forsyth     sizeof ( T1_CMapCustomRec ),
242*37da2899SCharles.Forsyth 
243*37da2899SCharles.Forsyth     (FT_CMap_InitFunc)     t1_cmap_custom_init,
244*37da2899SCharles.Forsyth     (FT_CMap_DoneFunc)     t1_cmap_custom_done,
245*37da2899SCharles.Forsyth     (FT_CMap_CharIndexFunc)t1_cmap_custom_char_index,
246*37da2899SCharles.Forsyth     (FT_CMap_CharNextFunc) t1_cmap_custom_char_next
247*37da2899SCharles.Forsyth   };
248*37da2899SCharles.Forsyth 
249*37da2899SCharles.Forsyth 
250*37da2899SCharles.Forsyth   /*************************************************************************/
251*37da2899SCharles.Forsyth   /*************************************************************************/
252*37da2899SCharles.Forsyth   /*****                                                               *****/
253*37da2899SCharles.Forsyth   /*****            TYPE1 SYNTHETIC UNICODE ENCODING CMAP              *****/
254*37da2899SCharles.Forsyth   /*****                                                               *****/
255*37da2899SCharles.Forsyth   /*************************************************************************/
256*37da2899SCharles.Forsyth   /*************************************************************************/
257*37da2899SCharles.Forsyth 
258*37da2899SCharles.Forsyth   FT_CALLBACK_DEF( FT_Int )
t1_cmap_uni_pair_compare(const void * pair1,const void * pair2)259*37da2899SCharles.Forsyth   t1_cmap_uni_pair_compare( const void*  pair1,
260*37da2899SCharles.Forsyth                             const void*  pair2 )
261*37da2899SCharles.Forsyth   {
262*37da2899SCharles.Forsyth     FT_UInt32  u1 = ((T1_CMapUniPair)pair1)->unicode;
263*37da2899SCharles.Forsyth     FT_UInt32  u2 = ((T1_CMapUniPair)pair2)->unicode;
264*37da2899SCharles.Forsyth 
265*37da2899SCharles.Forsyth 
266*37da2899SCharles.Forsyth     if ( u1 < u2 )
267*37da2899SCharles.Forsyth       return -1;
268*37da2899SCharles.Forsyth 
269*37da2899SCharles.Forsyth     if ( u1 > u2 )
270*37da2899SCharles.Forsyth       return +1;
271*37da2899SCharles.Forsyth 
272*37da2899SCharles.Forsyth     return 0;
273*37da2899SCharles.Forsyth   }
274*37da2899SCharles.Forsyth 
275*37da2899SCharles.Forsyth 
276*37da2899SCharles.Forsyth   FT_CALLBACK_DEF( FT_Error )
t1_cmap_unicode_init(T1_CMapUnicode cmap)277*37da2899SCharles.Forsyth   t1_cmap_unicode_init( T1_CMapUnicode  cmap )
278*37da2899SCharles.Forsyth   {
279*37da2899SCharles.Forsyth     FT_Error         error;
280*37da2899SCharles.Forsyth     FT_UInt          count;
281*37da2899SCharles.Forsyth     T1_Face          face    = (T1_Face)FT_CMAP_FACE( cmap );
282*37da2899SCharles.Forsyth     FT_Memory        memory  = FT_FACE_MEMORY( face );
283*37da2899SCharles.Forsyth     PSNames_Service  psnames = (PSNames_Service)face->psnames;
284*37da2899SCharles.Forsyth 
285*37da2899SCharles.Forsyth 
286*37da2899SCharles.Forsyth     cmap->num_pairs = 0;
287*37da2899SCharles.Forsyth     cmap->pairs     = NULL;
288*37da2899SCharles.Forsyth 
289*37da2899SCharles.Forsyth     count = face->type1.num_glyphs;
290*37da2899SCharles.Forsyth 
291*37da2899SCharles.Forsyth     if ( !FT_NEW_ARRAY( cmap->pairs, count ) )
292*37da2899SCharles.Forsyth     {
293*37da2899SCharles.Forsyth       FT_UInt         n, new_count;
294*37da2899SCharles.Forsyth       T1_CMapUniPair  pair;
295*37da2899SCharles.Forsyth       FT_UInt32       uni_code;
296*37da2899SCharles.Forsyth 
297*37da2899SCharles.Forsyth 
298*37da2899SCharles.Forsyth       pair = cmap->pairs;
299*37da2899SCharles.Forsyth       for ( n = 0; n < count; n++ )
300*37da2899SCharles.Forsyth       {
301*37da2899SCharles.Forsyth         const char*  gname = face->type1.glyph_names[n];
302*37da2899SCharles.Forsyth 
303*37da2899SCharles.Forsyth 
304*37da2899SCharles.Forsyth         /* build unsorted pair table by matching glyph names */
305*37da2899SCharles.Forsyth         if ( gname )
306*37da2899SCharles.Forsyth         {
307*37da2899SCharles.Forsyth           uni_code = psnames->unicode_value( gname );
308*37da2899SCharles.Forsyth 
309*37da2899SCharles.Forsyth           if ( uni_code != 0 )
310*37da2899SCharles.Forsyth           {
311*37da2899SCharles.Forsyth             pair->unicode = uni_code;
312*37da2899SCharles.Forsyth             pair->gindex  = n;
313*37da2899SCharles.Forsyth             pair++;
314*37da2899SCharles.Forsyth           }
315*37da2899SCharles.Forsyth         }
316*37da2899SCharles.Forsyth       }
317*37da2899SCharles.Forsyth 
318*37da2899SCharles.Forsyth       new_count = (FT_UInt)( pair - cmap->pairs );
319*37da2899SCharles.Forsyth       if ( new_count == 0 )
320*37da2899SCharles.Forsyth       {
321*37da2899SCharles.Forsyth         /* there are no unicode characters in here! */
322*37da2899SCharles.Forsyth         FT_FREE( cmap->pairs );
323*37da2899SCharles.Forsyth         error = FT_Err_Invalid_Argument;
324*37da2899SCharles.Forsyth       }
325*37da2899SCharles.Forsyth       else
326*37da2899SCharles.Forsyth       {
327*37da2899SCharles.Forsyth         /* re-allocate if the new array is much smaller than the original */
328*37da2899SCharles.Forsyth         /* one                                                            */
329*37da2899SCharles.Forsyth         if ( new_count != count && new_count < count / 2 )
330*37da2899SCharles.Forsyth         {
331*37da2899SCharles.Forsyth           (void)FT_RENEW_ARRAY( cmap->pairs, count, new_count );
332*37da2899SCharles.Forsyth           error = 0;
333*37da2899SCharles.Forsyth         }
334*37da2899SCharles.Forsyth 
335*37da2899SCharles.Forsyth         /* sort the pairs table to allow efficient binary searches */
336*37da2899SCharles.Forsyth         ft_qsort( cmap->pairs,
337*37da2899SCharles.Forsyth                   new_count,
338*37da2899SCharles.Forsyth                   sizeof ( T1_CMapUniPairRec ),
339*37da2899SCharles.Forsyth                   t1_cmap_uni_pair_compare );
340*37da2899SCharles.Forsyth 
341*37da2899SCharles.Forsyth         cmap->num_pairs = new_count;
342*37da2899SCharles.Forsyth       }
343*37da2899SCharles.Forsyth     }
344*37da2899SCharles.Forsyth 
345*37da2899SCharles.Forsyth     return error;
346*37da2899SCharles.Forsyth   }
347*37da2899SCharles.Forsyth 
348*37da2899SCharles.Forsyth 
349*37da2899SCharles.Forsyth   FT_CALLBACK_DEF( void )
t1_cmap_unicode_done(T1_CMapUnicode cmap)350*37da2899SCharles.Forsyth   t1_cmap_unicode_done( T1_CMapUnicode  cmap )
351*37da2899SCharles.Forsyth   {
352*37da2899SCharles.Forsyth     FT_Face    face   = FT_CMAP_FACE(cmap);
353*37da2899SCharles.Forsyth     FT_Memory  memory = FT_FACE_MEMORY(face);
354*37da2899SCharles.Forsyth 
355*37da2899SCharles.Forsyth     FT_FREE( cmap->pairs );
356*37da2899SCharles.Forsyth     cmap->num_pairs = 0;
357*37da2899SCharles.Forsyth   }
358*37da2899SCharles.Forsyth 
359*37da2899SCharles.Forsyth 
360*37da2899SCharles.Forsyth   FT_CALLBACK_DEF( FT_UInt )
t1_cmap_unicode_char_index(T1_CMapUnicode cmap,FT_UInt32 char_code)361*37da2899SCharles.Forsyth   t1_cmap_unicode_char_index( T1_CMapUnicode  cmap,
362*37da2899SCharles.Forsyth                               FT_UInt32       char_code )
363*37da2899SCharles.Forsyth   {
364*37da2899SCharles.Forsyth     FT_UInt         min = 0;
365*37da2899SCharles.Forsyth     FT_UInt         max = cmap->num_pairs;
366*37da2899SCharles.Forsyth     FT_UInt         mid;
367*37da2899SCharles.Forsyth     T1_CMapUniPair  pair;
368*37da2899SCharles.Forsyth 
369*37da2899SCharles.Forsyth 
370*37da2899SCharles.Forsyth     while ( min < max )
371*37da2899SCharles.Forsyth     {
372*37da2899SCharles.Forsyth       mid  = min + ( max - min ) / 2;
373*37da2899SCharles.Forsyth       pair = cmap->pairs + mid;
374*37da2899SCharles.Forsyth 
375*37da2899SCharles.Forsyth       if ( pair->unicode == char_code )
376*37da2899SCharles.Forsyth         return pair->gindex;
377*37da2899SCharles.Forsyth 
378*37da2899SCharles.Forsyth       if ( pair->unicode < char_code )
379*37da2899SCharles.Forsyth         min = mid + 1;
380*37da2899SCharles.Forsyth       else
381*37da2899SCharles.Forsyth         max = mid;
382*37da2899SCharles.Forsyth     }
383*37da2899SCharles.Forsyth     return 0;
384*37da2899SCharles.Forsyth   }
385*37da2899SCharles.Forsyth 
386*37da2899SCharles.Forsyth 
387*37da2899SCharles.Forsyth   FT_CALLBACK_DEF( FT_UInt )
t1_cmap_unicode_char_next(T1_CMapUnicode cmap,FT_UInt32 * pchar_code)388*37da2899SCharles.Forsyth   t1_cmap_unicode_char_next( T1_CMapUnicode  cmap,
389*37da2899SCharles.Forsyth                              FT_UInt32      *pchar_code )
390*37da2899SCharles.Forsyth   {
391*37da2899SCharles.Forsyth     FT_UInt    result    = 0;
392*37da2899SCharles.Forsyth     FT_UInt32  char_code = *pchar_code + 1;
393*37da2899SCharles.Forsyth 
394*37da2899SCharles.Forsyth 
395*37da2899SCharles.Forsyth   Restart:
396*37da2899SCharles.Forsyth     {
397*37da2899SCharles.Forsyth       FT_UInt         min = 0;
398*37da2899SCharles.Forsyth       FT_UInt         max = cmap->num_pairs;
399*37da2899SCharles.Forsyth       FT_UInt         mid;
400*37da2899SCharles.Forsyth       T1_CMapUniPair  pair;
401*37da2899SCharles.Forsyth 
402*37da2899SCharles.Forsyth 
403*37da2899SCharles.Forsyth       while ( min < max )
404*37da2899SCharles.Forsyth       {
405*37da2899SCharles.Forsyth         mid  = min + ( ( max - min ) >> 1 );
406*37da2899SCharles.Forsyth         pair = cmap->pairs + mid;
407*37da2899SCharles.Forsyth 
408*37da2899SCharles.Forsyth         if ( pair->unicode == char_code )
409*37da2899SCharles.Forsyth         {
410*37da2899SCharles.Forsyth           result = pair->gindex;
411*37da2899SCharles.Forsyth           if ( result != 0 )
412*37da2899SCharles.Forsyth             goto Exit;
413*37da2899SCharles.Forsyth 
414*37da2899SCharles.Forsyth           char_code++;
415*37da2899SCharles.Forsyth           goto Restart;
416*37da2899SCharles.Forsyth         }
417*37da2899SCharles.Forsyth 
418*37da2899SCharles.Forsyth         if ( pair->unicode < char_code )
419*37da2899SCharles.Forsyth           min = mid+1;
420*37da2899SCharles.Forsyth         else
421*37da2899SCharles.Forsyth           max = mid;
422*37da2899SCharles.Forsyth       }
423*37da2899SCharles.Forsyth 
424*37da2899SCharles.Forsyth       /* we didn't find it, but we have a pair just above it */
425*37da2899SCharles.Forsyth       char_code = 0;
426*37da2899SCharles.Forsyth 
427*37da2899SCharles.Forsyth       if ( min < cmap->num_pairs )
428*37da2899SCharles.Forsyth       {
429*37da2899SCharles.Forsyth         pair   = cmap->pairs + min;
430*37da2899SCharles.Forsyth         result = pair->gindex;
431*37da2899SCharles.Forsyth         if ( result != 0 )
432*37da2899SCharles.Forsyth           char_code = pair->unicode;
433*37da2899SCharles.Forsyth       }
434*37da2899SCharles.Forsyth     }
435*37da2899SCharles.Forsyth 
436*37da2899SCharles.Forsyth   Exit:
437*37da2899SCharles.Forsyth     *pchar_code = char_code;
438*37da2899SCharles.Forsyth     return result;
439*37da2899SCharles.Forsyth   }
440*37da2899SCharles.Forsyth 
441*37da2899SCharles.Forsyth 
442*37da2899SCharles.Forsyth   FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec
443*37da2899SCharles.Forsyth   t1_cmap_unicode_class_rec =
444*37da2899SCharles.Forsyth   {
445*37da2899SCharles.Forsyth     sizeof ( T1_CMapUnicodeRec ),
446*37da2899SCharles.Forsyth 
447*37da2899SCharles.Forsyth     (FT_CMap_InitFunc)     t1_cmap_unicode_init,
448*37da2899SCharles.Forsyth     (FT_CMap_DoneFunc)     t1_cmap_unicode_done,
449*37da2899SCharles.Forsyth     (FT_CMap_CharIndexFunc)t1_cmap_unicode_char_index,
450*37da2899SCharles.Forsyth     (FT_CMap_CharNextFunc) t1_cmap_unicode_char_next
451*37da2899SCharles.Forsyth   };
452*37da2899SCharles.Forsyth 
453*37da2899SCharles.Forsyth 
454*37da2899SCharles.Forsyth /* END */
455