1 /****************************************************************************
2  *
3  * pfrcmap.c
4  *
5  *   FreeType PFR cmap handling (body).
6  *
7  * Copyright (C) 2002-2020 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 )
pfr_cmap_init(PFR_CMap cmap,FT_Pointer pointer)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 )
pfr_cmap_done(PFR_CMap cmap)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 )
pfr_cmap_char_index(PFR_CMap cmap,FT_UInt32 char_code)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 )
pfr_cmap_char_next(PFR_CMap cmap,FT_UInt32 * pchar_code)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,        /* init       */
165     (FT_CMap_DoneFunc)     pfr_cmap_done,        /* done       */
166     (FT_CMap_CharIndexFunc)pfr_cmap_char_index,  /* char_index */
167     (FT_CMap_CharNextFunc) pfr_cmap_char_next,   /* char_next  */
168 
169     (FT_CMap_CharVarIndexFunc)    NULL,  /* char_var_index   */
170     (FT_CMap_CharVarIsDefaultFunc)NULL,  /* char_var_default */
171     (FT_CMap_VariantListFunc)     NULL,  /* variant_list     */
172     (FT_CMap_CharVariantListFunc) NULL,  /* charvariant_list */
173     (FT_CMap_VariantCharListFunc) NULL   /* variantchar_list */
174   };
175 
176 
177 /* END */
178