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 )
27 pfr_cmap_init( FT_CMap cmap, /* PFR_CMap */
28 FT_Pointer pointer )
29 {
30 PFR_CMap pfrcmap = (PFR_CMap)cmap;
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 pfrcmap->num_chars = face->phy_font.num_chars;
38 pfrcmap->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 < pfrcmap->num_chars; n++ )
47 {
48 if ( pfrcmap->chars[n - 1].char_code >= pfrcmap->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( FT_CMap cmap ) /* PFR_CMap */
63 {
64 PFR_CMap pfrcmap = (PFR_CMap)cmap;
65
66
67 pfrcmap->chars = NULL;
68 pfrcmap->num_chars = 0;
69 }
70
71
72 FT_CALLBACK_DEF( FT_UInt )
73 pfr_cmap_char_index( FT_CMap cmap, /* PFR_CMap */
74 FT_UInt32 char_code )
75 {
76 PFR_CMap pfrcmap = (PFR_CMap)cmap;
77 FT_UInt min = 0;
78 FT_UInt max = pfrcmap->num_chars;
79 FT_UInt mid = min + ( max - min ) / 2;
80 PFR_Char gchar;
81
82
83 while ( min < max )
84 {
85 gchar = pfrcmap->chars + mid;
86
87 if ( gchar->char_code == char_code )
88 return mid + 1;
89
90 if ( gchar->char_code < char_code )
91 min = mid + 1;
92 else
93 max = mid;
94
95 /* reasonable prediction in a continuous block */
96 mid += char_code - gchar->char_code;
97 if ( mid >= max || mid < min )
98 mid = min + ( max - min ) / 2;
99 }
100 return 0;
101 }
102
103
104 FT_CALLBACK_DEF( FT_UInt )
105 pfr_cmap_char_next( FT_CMap cmap, /* PFR_CMap */
106 FT_UInt32 *pchar_code )
107 {
108 PFR_CMap pfrcmap = (PFR_CMap)cmap;
109 FT_UInt result = 0;
110 FT_UInt32 char_code = *pchar_code + 1;
111
112
113 Restart:
114 {
115 FT_UInt min = 0;
116 FT_UInt max = pfrcmap->num_chars;
117 FT_UInt mid = min + ( max - min ) / 2;
118 PFR_Char gchar;
119
120
121 while ( min < max )
122 {
123 gchar = pfrcmap->chars + mid;
124
125 if ( gchar->char_code == char_code )
126 {
127 result = mid;
128 if ( result != 0 )
129 {
130 result++;
131 goto Exit;
132 }
133
134 char_code++;
135 goto Restart;
136 }
137
138 if ( gchar->char_code < char_code )
139 min = mid + 1;
140 else
141 max = mid;
142
143 /* reasonable prediction in a continuous block */
144 mid += char_code - gchar->char_code;
145 if ( mid >= max || mid < min )
146 mid = min + ( max - min ) / 2;
147 }
148
149 /* we didn't find it, but we have a pair just above it */
150 char_code = 0;
151
152 if ( min < pfrcmap->num_chars )
153 {
154 gchar = pfrcmap->chars + min;
155 result = min;
156 if ( result != 0 )
157 {
158 result++;
159 char_code = gchar->char_code;
160 }
161 }
162 }
163
164 Exit:
165 *pchar_code = char_code;
166 return result;
167 }
168
169
170 FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec
171 pfr_cmap_class_rec =
172 {
173 sizeof ( PFR_CMapRec ),
174
175 (FT_CMap_InitFunc) pfr_cmap_init, /* init */
176 (FT_CMap_DoneFunc) pfr_cmap_done, /* done */
177 (FT_CMap_CharIndexFunc)pfr_cmap_char_index, /* char_index */
178 (FT_CMap_CharNextFunc) pfr_cmap_char_next, /* char_next */
179
180 (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */
181 (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */
182 (FT_CMap_VariantListFunc) NULL, /* variant_list */
183 (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */
184 (FT_CMap_VariantCharListFunc) NULL /* variantchar_list */
185 };
186
187
188/* END */
189