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