• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /****************************************************************************
2  *
3  * pfrcmap.c
4  *
5  *   FreeType PFR cmap handling (body).
6  *
7  * Copyright (C) 2002-2023 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 <freetype/internal/ftdebug.h>
20 #include "pfrcmap.h"
21 #include "pfrobjs.h"
22 
23 #include "pfrerror.h"
24 
25 
26   FT_CALLBACK_DEF( FT_Error )
pfr_cmap_init(PFR_CMap cmap,FT_Pointer pointer)27   pfr_cmap_init( PFR_CMap    cmap,
28                  FT_Pointer  pointer )
29   {
30     FT_Error  error = FT_Err_Ok;
31     PFR_Face  face  = (PFR_Face)FT_CMAP_FACE( cmap );
32 
33     FT_UNUSED( pointer );
34 
35 
36     cmap->num_chars = face->phy_font.num_chars;
37     cmap->chars     = face->phy_font.chars;
38 
39     /* just for safety, check that the character entries are correctly */
40     /* sorted in increasing character code order                       */
41     {
42       FT_UInt  n;
43 
44 
45       for ( n = 1; n < cmap->num_chars; n++ )
46       {
47         if ( cmap->chars[n - 1].char_code >= cmap->chars[n].char_code )
48         {
49           error = FT_THROW( Invalid_Table );
50           goto Exit;
51         }
52       }
53     }
54 
55   Exit:
56     return error;
57   }
58 
59 
60   FT_CALLBACK_DEF( void )
pfr_cmap_done(PFR_CMap cmap)61   pfr_cmap_done( PFR_CMap  cmap )
62   {
63     cmap->chars     = NULL;
64     cmap->num_chars = 0;
65   }
66 
67 
68   FT_CALLBACK_DEF( FT_UInt )
pfr_cmap_char_index(PFR_CMap cmap,FT_UInt32 char_code)69   pfr_cmap_char_index( PFR_CMap   cmap,
70                        FT_UInt32  char_code )
71   {
72     FT_UInt   min = 0;
73     FT_UInt   max = cmap->num_chars;
74     FT_UInt   mid = min + ( max - min ) / 2;
75     PFR_Char  gchar;
76 
77 
78     while ( min < max )
79     {
80       gchar = cmap->chars + mid;
81 
82       if ( gchar->char_code == char_code )
83         return mid + 1;
84 
85       if ( gchar->char_code < char_code )
86         min = mid + 1;
87       else
88         max = mid;
89 
90       /* reasonable prediction in a continuous block */
91       mid += char_code - gchar->char_code;
92       if ( mid >= max || mid < min )
93         mid = min + ( max - min ) / 2;
94     }
95     return 0;
96   }
97 
98 
99   FT_CALLBACK_DEF( FT_UInt32 )
pfr_cmap_char_next(PFR_CMap cmap,FT_UInt32 * pchar_code)100   pfr_cmap_char_next( PFR_CMap    cmap,
101                       FT_UInt32  *pchar_code )
102   {
103     FT_UInt    result    = 0;
104     FT_UInt32  char_code = *pchar_code + 1;
105 
106 
107   Restart:
108     {
109       FT_UInt   min = 0;
110       FT_UInt   max = cmap->num_chars;
111       FT_UInt   mid = min + ( max - min ) / 2;
112       PFR_Char  gchar;
113 
114 
115       while ( min < max )
116       {
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         /* reasonable prediction in a continuous block */
138         mid += char_code - gchar->char_code;
139         if ( mid >= max || mid < min )
140           mid = min + ( max - min ) / 2;
141       }
142 
143       /* we didn't find it, but we have a pair just above it */
144       char_code = 0;
145 
146       if ( min < cmap->num_chars )
147       {
148         gchar  = cmap->chars + min;
149         result = min;
150         if ( result != 0 )
151         {
152           result++;
153           char_code = gchar->char_code;
154         }
155       }
156     }
157 
158   Exit:
159     *pchar_code = char_code;
160     return result;
161   }
162 
163 
164   FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec
165   pfr_cmap_class_rec =
166   {
167     sizeof ( PFR_CMapRec ),
168 
169     (FT_CMap_InitFunc)     pfr_cmap_init,        /* init       */
170     (FT_CMap_DoneFunc)     pfr_cmap_done,        /* done       */
171     (FT_CMap_CharIndexFunc)pfr_cmap_char_index,  /* char_index */
172     (FT_CMap_CharNextFunc) pfr_cmap_char_next,   /* char_next  */
173 
174     (FT_CMap_CharVarIndexFunc)    NULL,  /* char_var_index   */
175     (FT_CMap_CharVarIsDefaultFunc)NULL,  /* char_var_default */
176     (FT_CMap_VariantListFunc)     NULL,  /* variant_list     */
177     (FT_CMap_CharVariantListFunc) NULL,  /* charvariant_list */
178     (FT_CMap_VariantCharListFunc) NULL   /* variantchar_list */
179   };
180 
181 
182 /* END */
183