Tizen 2.0 Release
[framework/graphics/freetype.git] / src / pfr / pfrcmap.c
1 /***************************************************************************/
2 /*                                                                         */
3 /*  pfrcmap.c                                                              */
4 /*                                                                         */
5 /*    FreeType PFR cmap handling (body).                                   */
6 /*                                                                         */
7 /*  Copyright 2002, 2007, 2009 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 "pfrcmap.h"
20 #include "pfrobjs.h"
21
22 #include "pfrerror.h"
23
24
25   FT_CALLBACK_DEF( FT_Error )
26   pfr_cmap_init( PFR_CMap  cmap )
27   {
28     FT_Error  error = PFR_Err_Ok;
29     PFR_Face  face  = (PFR_Face)FT_CMAP_FACE( cmap );
30
31
32     cmap->num_chars = face->phy_font.num_chars;
33     cmap->chars     = face->phy_font.chars;
34
35     /* just for safety, check that the character entries are correctly */
36     /* sorted in increasing character code order                       */
37     {
38       FT_UInt  n;
39
40
41       for ( n = 1; n < cmap->num_chars; n++ )
42       {
43         if ( cmap->chars[n - 1].char_code >= cmap->chars[n].char_code )
44         {
45           error = PFR_Err_Invalid_Table;
46           goto Exit;
47         }
48       }
49     }
50
51   Exit:
52     return error;
53   }
54
55
56   FT_CALLBACK_DEF( void )
57   pfr_cmap_done( PFR_CMap  cmap )
58   {
59     cmap->chars     = NULL;
60     cmap->num_chars = 0;
61   }
62
63
64   FT_CALLBACK_DEF( FT_UInt )
65   pfr_cmap_char_index( PFR_CMap   cmap,
66                        FT_UInt32  char_code )
67   {
68     FT_UInt   min = 0;
69     FT_UInt   max = cmap->num_chars;
70     FT_UInt   mid;
71     PFR_Char  gchar;
72
73
74     while ( min < max )
75     {
76       mid   = min + ( max - min ) / 2;
77       gchar = cmap->chars + mid;
78
79       if ( gchar->char_code == char_code )
80         return mid + 1;
81
82       if ( gchar->char_code < char_code )
83         min = mid + 1;
84       else
85         max = mid;
86     }
87     return 0;
88   }
89
90
91   FT_CALLBACK_DEF( FT_UInt32 )
92   pfr_cmap_char_next( PFR_CMap    cmap,
93                       FT_UInt32  *pchar_code )
94   {
95     FT_UInt    result    = 0;
96     FT_UInt32  char_code = *pchar_code + 1;
97
98
99   Restart:
100     {
101       FT_UInt   min = 0;
102       FT_UInt   max = cmap->num_chars;
103       FT_UInt   mid;
104       PFR_Char  gchar;
105
106
107       while ( min < max )
108       {
109         mid   = min + ( ( max - min ) >> 1 );
110         gchar = cmap->chars + mid;
111
112         if ( gchar->char_code == char_code )
113         {
114           result = mid;
115           if ( result != 0 )
116           {
117             result++;
118             goto Exit;
119           }
120
121           char_code++;
122           goto Restart;
123         }
124
125         if ( gchar->char_code < char_code )
126           min = mid+1;
127         else
128           max = mid;
129       }
130
131       /* we didn't find it, but we have a pair just above it */
132       char_code = 0;
133
134       if ( min < cmap->num_chars )
135       {
136         gchar  = cmap->chars + min;
137         result = min;
138         if ( result != 0 )
139         {
140           result++;
141           char_code = gchar->char_code;
142         }
143       }
144     }
145
146   Exit:
147     *pchar_code = char_code;
148     return result;
149   }
150
151
152   FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec
153   pfr_cmap_class_rec =
154   {
155     sizeof ( PFR_CMapRec ),
156
157     (FT_CMap_InitFunc)     pfr_cmap_init,
158     (FT_CMap_DoneFunc)     pfr_cmap_done,
159     (FT_CMap_CharIndexFunc)pfr_cmap_char_index,
160     (FT_CMap_CharNextFunc) pfr_cmap_char_next,
161
162     NULL, NULL, NULL, NULL, NULL
163   };
164
165
166 /* END */