1 | /**************************************************************************** |
2 | * |
3 | * t1cmap.c |
4 | * |
5 | * Type 1 character map support (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 "t1cmap.h" |
20 | |
21 | #include <freetype/internal/ftdebug.h> |
22 | |
23 | #include "psauxerr.h" |
24 | |
25 | |
26 | /*************************************************************************/ |
27 | /*************************************************************************/ |
28 | /***** *****/ |
29 | /***** TYPE1 STANDARD (AND EXPERT) ENCODING CMAPS *****/ |
30 | /***** *****/ |
31 | /*************************************************************************/ |
32 | /*************************************************************************/ |
33 | |
34 | static void |
35 | t1_cmap_std_init( T1_CMapStd cmap, |
36 | FT_Int is_expert ) |
37 | { |
38 | T1_Face face = (T1_Face)FT_CMAP_FACE( cmap ); |
39 | FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames; |
40 | |
41 | |
42 | cmap->num_glyphs = (FT_UInt)face->type1.num_glyphs; |
43 | cmap->glyph_names = (const char* const*)face->type1.glyph_names; |
44 | cmap->sid_to_string = psnames->adobe_std_strings; |
45 | cmap->code_to_sid = is_expert ? psnames->adobe_expert_encoding |
46 | : psnames->adobe_std_encoding; |
47 | |
48 | FT_ASSERT( cmap->code_to_sid ); |
49 | } |
50 | |
51 | |
52 | FT_CALLBACK_DEF( void ) |
53 | t1_cmap_std_done( FT_CMap cmap_ ) /* T1_CMapStd */ |
54 | { |
55 | T1_CMapStd cmap = (T1_CMapStd)cmap_; |
56 | |
57 | |
58 | cmap->num_glyphs = 0; |
59 | cmap->glyph_names = NULL; |
60 | cmap->sid_to_string = NULL; |
61 | cmap->code_to_sid = NULL; |
62 | } |
63 | |
64 | |
65 | FT_CALLBACK_DEF( FT_UInt ) |
66 | t1_cmap_std_char_index( FT_CMap cmap, /* T1_CMapStd */ |
67 | FT_UInt32 char_code ) |
68 | { |
69 | T1_CMapStd t1cmap = (T1_CMapStd)cmap; |
70 | FT_UInt result = 0; |
71 | |
72 | |
73 | if ( char_code < 256 ) |
74 | { |
75 | FT_UInt code, n; |
76 | const char* glyph_name; |
77 | |
78 | |
79 | /* convert character code to Adobe SID string */ |
80 | code = t1cmap->code_to_sid[char_code]; |
81 | glyph_name = t1cmap->sid_to_string( code ); |
82 | |
83 | /* look for the corresponding glyph name */ |
84 | for ( n = 0; n < t1cmap->num_glyphs; n++ ) |
85 | { |
86 | const char* gname = t1cmap->glyph_names[n]; |
87 | |
88 | |
89 | if ( gname && gname[0] == glyph_name[0] && |
90 | ft_strcmp( gname, glyph_name ) == 0 ) |
91 | { |
92 | result = n; |
93 | break; |
94 | } |
95 | } |
96 | } |
97 | |
98 | return result; |
99 | } |
100 | |
101 | |
102 | FT_CALLBACK_DEF( FT_UInt ) |
103 | t1_cmap_std_char_next( FT_CMap cmap, |
104 | FT_UInt32 *pchar_code ) |
105 | { |
106 | FT_UInt result = 0; |
107 | FT_UInt32 char_code = *pchar_code + 1; |
108 | |
109 | |
110 | while ( char_code < 256 ) |
111 | { |
112 | result = t1_cmap_std_char_index( cmap, char_code ); |
113 | if ( result != 0 ) |
114 | goto Exit; |
115 | |
116 | char_code++; |
117 | } |
118 | char_code = 0; |
119 | |
120 | Exit: |
121 | *pchar_code = char_code; |
122 | return result; |
123 | } |
124 | |
125 | |
126 | FT_CALLBACK_DEF( FT_Error ) |
127 | t1_cmap_standard_init( FT_CMap cmap, /* T1_CMapStd */ |
128 | FT_Pointer pointer ) |
129 | { |
130 | T1_CMapStd t1cmap = (T1_CMapStd)cmap; |
131 | FT_UNUSED( pointer ); |
132 | |
133 | |
134 | t1_cmap_std_init( t1cmap, 0 ); |
135 | return 0; |
136 | } |
137 | |
138 | |
139 | FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec |
140 | t1_cmap_standard_class_rec = |
141 | { |
142 | sizeof ( T1_CMapStdRec ), |
143 | |
144 | (FT_CMap_InitFunc) t1_cmap_standard_init, /* init */ |
145 | (FT_CMap_DoneFunc) t1_cmap_std_done, /* done */ |
146 | (FT_CMap_CharIndexFunc)t1_cmap_std_char_index, /* char_index */ |
147 | (FT_CMap_CharNextFunc) t1_cmap_std_char_next, /* char_next */ |
148 | |
149 | (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */ |
150 | (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */ |
151 | (FT_CMap_VariantListFunc) NULL, /* variant_list */ |
152 | (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */ |
153 | (FT_CMap_VariantCharListFunc) NULL /* variantchar_list */ |
154 | }; |
155 | |
156 | |
157 | FT_CALLBACK_DEF( FT_Error ) |
158 | t1_cmap_expert_init( FT_CMap cmap, /* T1_CMapStd */ |
159 | FT_Pointer pointer ) |
160 | { |
161 | T1_CMapStd t1cmap = (T1_CMapStd)cmap; |
162 | FT_UNUSED( pointer ); |
163 | |
164 | |
165 | t1_cmap_std_init( t1cmap, 1 ); |
166 | return 0; |
167 | } |
168 | |
169 | FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec |
170 | t1_cmap_expert_class_rec = |
171 | { |
172 | sizeof ( T1_CMapStdRec ), |
173 | |
174 | (FT_CMap_InitFunc) t1_cmap_expert_init, /* init */ |
175 | (FT_CMap_DoneFunc) t1_cmap_std_done, /* done */ |
176 | (FT_CMap_CharIndexFunc)t1_cmap_std_char_index, /* char_index */ |
177 | (FT_CMap_CharNextFunc) t1_cmap_std_char_next, /* char_next */ |
178 | |
179 | (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */ |
180 | (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */ |
181 | (FT_CMap_VariantListFunc) NULL, /* variant_list */ |
182 | (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */ |
183 | (FT_CMap_VariantCharListFunc) NULL /* variantchar_list */ |
184 | }; |
185 | |
186 | |
187 | /*************************************************************************/ |
188 | /*************************************************************************/ |
189 | /***** *****/ |
190 | /***** TYPE1 CUSTOM ENCODING CMAP *****/ |
191 | /***** *****/ |
192 | /*************************************************************************/ |
193 | /*************************************************************************/ |
194 | |
195 | |
196 | FT_CALLBACK_DEF( FT_Error ) |
197 | t1_cmap_custom_init( FT_CMap cmap, /* T1_CMapCustom */ |
198 | FT_Pointer pointer ) |
199 | { |
200 | T1_CMapCustom t1cmap = (T1_CMapCustom)cmap; |
201 | T1_Face face = (T1_Face)FT_CMAP_FACE( cmap ); |
202 | T1_Encoding encoding = &face->type1.encoding; |
203 | |
204 | FT_UNUSED( pointer ); |
205 | |
206 | |
207 | t1cmap->first = (FT_UInt)encoding->code_first; |
208 | t1cmap->count = (FT_UInt)encoding->code_last - t1cmap->first; |
209 | t1cmap->indices = encoding->char_index; |
210 | |
211 | FT_ASSERT( t1cmap->indices ); |
212 | FT_ASSERT( encoding->code_first <= encoding->code_last ); |
213 | |
214 | return 0; |
215 | } |
216 | |
217 | |
218 | FT_CALLBACK_DEF( void ) |
219 | t1_cmap_custom_done( FT_CMap cmap ) /* T1_CMapCustom */ |
220 | { |
221 | T1_CMapCustom t1cmap = (T1_CMapCustom)cmap; |
222 | |
223 | |
224 | t1cmap->indices = NULL; |
225 | t1cmap->first = 0; |
226 | t1cmap->count = 0; |
227 | } |
228 | |
229 | |
230 | FT_CALLBACK_DEF( FT_UInt ) |
231 | t1_cmap_custom_char_index( FT_CMap cmap, /* T1_CMapCustom */ |
232 | FT_UInt32 char_code ) |
233 | { |
234 | T1_CMapCustom t1cmap = (T1_CMapCustom)cmap; |
235 | FT_UInt result = 0; |
236 | |
237 | |
238 | if ( char_code >= t1cmap->first && |
239 | char_code < ( t1cmap->first + t1cmap->count ) ) |
240 | result = t1cmap->indices[char_code]; |
241 | |
242 | return result; |
243 | } |
244 | |
245 | |
246 | FT_CALLBACK_DEF( FT_UInt ) |
247 | t1_cmap_custom_char_next( FT_CMap cmap, /* T1_CMapCustom */ |
248 | FT_UInt32 *pchar_code ) |
249 | { |
250 | T1_CMapCustom t1cmap = (T1_CMapCustom)cmap; |
251 | FT_UInt result = 0; |
252 | FT_UInt32 char_code = *pchar_code; |
253 | |
254 | |
255 | char_code++; |
256 | |
257 | if ( char_code < t1cmap->first ) |
258 | char_code = t1cmap->first; |
259 | |
260 | for ( ; char_code < ( t1cmap->first + t1cmap->count ); char_code++ ) |
261 | { |
262 | result = t1cmap->indices[char_code]; |
263 | if ( result != 0 ) |
264 | goto Exit; |
265 | } |
266 | |
267 | char_code = 0; |
268 | |
269 | Exit: |
270 | *pchar_code = char_code; |
271 | return result; |
272 | } |
273 | |
274 | |
275 | FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec |
276 | t1_cmap_custom_class_rec = |
277 | { |
278 | sizeof ( T1_CMapCustomRec ), |
279 | |
280 | (FT_CMap_InitFunc) t1_cmap_custom_init, /* init */ |
281 | (FT_CMap_DoneFunc) t1_cmap_custom_done, /* done */ |
282 | (FT_CMap_CharIndexFunc)t1_cmap_custom_char_index, /* char_index */ |
283 | (FT_CMap_CharNextFunc) t1_cmap_custom_char_next, /* char_next */ |
284 | |
285 | (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */ |
286 | (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */ |
287 | (FT_CMap_VariantListFunc) NULL, /* variant_list */ |
288 | (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */ |
289 | (FT_CMap_VariantCharListFunc) NULL /* variantchar_list */ |
290 | }; |
291 | |
292 | |
293 | /*************************************************************************/ |
294 | /*************************************************************************/ |
295 | /***** *****/ |
296 | /***** TYPE1 SYNTHETIC UNICODE ENCODING CMAP *****/ |
297 | /***** *****/ |
298 | /*************************************************************************/ |
299 | /*************************************************************************/ |
300 | |
301 | FT_CALLBACK_DEF( const char * ) |
302 | psaux_get_glyph_name( void* face_, |
303 | FT_UInt idx ) |
304 | { |
305 | T1_Face face = (T1_Face)face_; |
306 | |
307 | |
308 | return face->type1.glyph_names[idx]; |
309 | } |
310 | |
311 | |
312 | FT_CALLBACK_DEF( FT_Error ) |
313 | t1_cmap_unicode_init( FT_CMap cmap, /* PS_Unicodes */ |
314 | FT_Pointer pointer ) |
315 | { |
316 | PS_Unicodes unicodes = (PS_Unicodes)cmap; |
317 | T1_Face face = (T1_Face)FT_CMAP_FACE( cmap ); |
318 | FT_Memory memory = FT_FACE_MEMORY( face ); |
319 | FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames; |
320 | |
321 | FT_UNUSED( pointer ); |
322 | |
323 | |
324 | if ( !psnames->unicodes_init ) |
325 | return FT_THROW( Unimplemented_Feature ); |
326 | |
327 | return psnames->unicodes_init( memory, |
328 | unicodes, |
329 | (FT_UInt)face->type1.num_glyphs, |
330 | &psaux_get_glyph_name, |
331 | (PS_FreeGlyphNameFunc)NULL, |
332 | (FT_Pointer)face ); |
333 | } |
334 | |
335 | |
336 | FT_CALLBACK_DEF( void ) |
337 | t1_cmap_unicode_done( FT_CMap cmap ) /* PS_Unicodes */ |
338 | { |
339 | PS_Unicodes unicodes = (PS_Unicodes)cmap; |
340 | FT_Face face = FT_CMAP_FACE( cmap ); |
341 | FT_Memory memory = FT_FACE_MEMORY( face ); |
342 | |
343 | |
344 | FT_FREE( unicodes->maps ); |
345 | unicodes->num_maps = 0; |
346 | } |
347 | |
348 | |
349 | FT_CALLBACK_DEF( FT_UInt ) |
350 | t1_cmap_unicode_char_index( FT_CMap cmap, /* PS_Unicodes */ |
351 | FT_UInt32 char_code ) |
352 | { |
353 | PS_Unicodes unicodes = (PS_Unicodes)cmap; |
354 | T1_Face face = (T1_Face)FT_CMAP_FACE( cmap ); |
355 | FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames; |
356 | |
357 | |
358 | return psnames->unicodes_char_index( unicodes, char_code ); |
359 | } |
360 | |
361 | |
362 | FT_CALLBACK_DEF( FT_UInt ) |
363 | t1_cmap_unicode_char_next( FT_CMap cmap, /* PS_Unicodes */ |
364 | FT_UInt32 *pchar_code ) |
365 | { |
366 | PS_Unicodes unicodes = (PS_Unicodes)cmap; |
367 | T1_Face face = (T1_Face)FT_CMAP_FACE( cmap ); |
368 | FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames; |
369 | |
370 | |
371 | return psnames->unicodes_char_next( unicodes, pchar_code ); |
372 | } |
373 | |
374 | |
375 | FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec |
376 | t1_cmap_unicode_class_rec = |
377 | { |
378 | sizeof ( PS_UnicodesRec ), |
379 | |
380 | (FT_CMap_InitFunc) t1_cmap_unicode_init, /* init */ |
381 | (FT_CMap_DoneFunc) t1_cmap_unicode_done, /* done */ |
382 | (FT_CMap_CharIndexFunc)t1_cmap_unicode_char_index, /* char_index */ |
383 | (FT_CMap_CharNextFunc) t1_cmap_unicode_char_next, /* char_next */ |
384 | |
385 | (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */ |
386 | (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */ |
387 | (FT_CMap_VariantListFunc) NULL, /* variant_list */ |
388 | (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */ |
389 | (FT_CMap_VariantCharListFunc) NULL /* variantchar_list */ |
390 | }; |
391 | |
392 | |
393 | /* END */ |
394 | |