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