Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(323)

Side by Side Diff: core/src/fxge/fx_freetype/fxft2.5.01/src/psnames/fxft_psmodule.c

Issue 815103002: Update freetype to 2.5.4. (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: Adjust GYP and GN Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 #if !defined(_FXFT_VERSION_) || _FXFT_VERSION_ == 2501
2 /***************************************************************************/
3 /* */
4 /* psmodule.c */
5 /* */
6 /* PSNames module implementation (body). */
7 /* */
8 /* Copyright 1996-2003, 2005-2008, 2012, 2013 by */
9 /* David Turner, Robert Wilhelm, and Werner Lemberg. */
10 /* */
11 /* This file is part of the FreeType project, and may only be used, */
12 /* modified, and distributed under the terms of the FreeType project */
13 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */
14 /* this file you indicate that you have read the license and */
15 /* understand and accept it fully. */
16 /* */
17 /***************************************************************************/
18
19 #define FT2_BUILD_LIBRARY
20 #include "../../include/ft2build.h"
21 #include "../../include/freetype/internal/ftdebug.h"
22 #include "../../include/freetype/internal/ftobjs.h"
23 #include "../../include/freetype/internal/services/svpscmap.h"
24
25 #include "psmodule.h"
26 #include "pstables.h"
27
28 #include "psnamerr.h"
29 #include "pspic.h"
30
31
32 #ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES
33
34
35 #ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST
36
37
38 #define VARIANT_BIT 0x80000000UL
39 #define BASE_GLYPH( code ) ( (FT_UInt32)( (code) & ~VARIANT_BIT ) )
40
41 #ifdef __cplusplus
42 extern "C" {
43 #endif
44 /* Return the Unicode value corresponding to a given glyph. Note that */
45 /* we do deal with glyph variants by detecting a non-initial dot in */
46 /* the name, as in `A.swash' or `e.final'; in this case, the */
47 /* VARIANT_BIT is set in the return value. */
48 /* */
49 int FXFT_unicode_from_adobe_name( const char* glyph_name )
50 {
51 /* If the name begins with `uni', then the glyph name may be a */
52 /* hard-coded unicode character code. */
53 if ( glyph_name[0] == 'u' &&
54 glyph_name[1] == 'n' &&
55 glyph_name[2] == 'i' )
56 {
57 /* determine whether the next four characters following are */
58 /* hexadecimal. */
59
60 /* XXX: Add code to deal with ligatures, i.e. glyph names like */
61 /* `uniXXXXYYYYZZZZ'... */
62
63 FT_Int count;
64 FT_UInt32 value = 0;
65 const char* p = glyph_name + 3;
66
67
68 for ( count = 4; count > 0; count--, p++ )
69 {
70 char c = *p;
71 unsigned int d;
72
73
74 d = (unsigned char)c - '0';
75 if ( d >= 10 )
76 {
77 d = (unsigned char)c - 'A';
78 if ( d >= 6 )
79 d = 16;
80 else
81 d += 10;
82 }
83
84 /* Exit if a non-uppercase hexadecimal character was found */
85 /* -- this also catches character codes below `0' since such */
86 /* negative numbers cast to `unsigned int' are far too big. */
87 if ( d >= 16 )
88 break;
89
90 value = ( value << 4 ) + d;
91 }
92
93 /* there must be exactly four hex digits */
94 if ( count == 0 )
95 {
96 if ( *p == '\0' )
97 return value;
98 if ( *p == '.' )
99 return (FT_UInt32)( value | VARIANT_BIT );
100 }
101 }
102
103 /* If the name begins with `u', followed by four to six uppercase */
104 /* hexadecimal digits, it is a hard-coded unicode character code. */
105 if ( glyph_name[0] == 'u' )
106 {
107 FT_Int count;
108 FT_UInt32 value = 0;
109 const char* p = glyph_name + 1;
110
111
112 for ( count = 6; count > 0; count--, p++ )
113 {
114 char c = *p;
115 unsigned int d;
116
117
118 d = (unsigned char)c - '0';
119 if ( d >= 10 )
120 {
121 d = (unsigned char)c - 'A';
122 if ( d >= 6 )
123 d = 16;
124 else
125 d += 10;
126 }
127
128 if ( d >= 16 )
129 break;
130
131 value = ( value << 4 ) + d;
132 }
133
134 if ( count <= 2 )
135 {
136 if ( *p == '\0' )
137 return value;
138 if ( *p == '.' )
139 return (FT_UInt32)( value | VARIANT_BIT );
140 }
141 }
142
143 /* Look for a non-initial dot in the glyph name in order to */
144 /* find variants like `A.swash', `e.final', etc. */
145 {
146 const char* p = glyph_name;
147 const char* dot = NULL;
148
149
150 for ( ; *p; p++ )
151 {
152 if ( *p == '.' && p > glyph_name )
153 {
154 dot = p;
155 break;
156 }
157 }
158
159 /* now look up the glyph in the Adobe Glyph List */
160 if ( !dot )
161 return (FT_UInt32)ft_get_adobe_glyph_index( glyph_name, p );
162 else
163 return (FT_UInt32)( ft_get_adobe_glyph_index( glyph_name, dot ) |
164 VARIANT_BIT );
165 }
166 }
167 #ifdef __cplusplus
168 }
169 #endif
170
171 static int xyq_search_node(char* glyph_name, int name_offset, int table_offset, FT_UInt32 unicode)
172 {
173 int i, count;
174
175 // copy letters
176 while (1) {
177 glyph_name[name_offset] = ft_adobe_glyph_list[table_offset] & 0x 7f;
178 name_offset ++;
179 table_offset ++;
180 if (!(ft_adobe_glyph_list[table_offset-1] & 0x80)) break;
181 }
182 glyph_name[name_offset] = 0;
183
184 // get child count
185 count = ft_adobe_glyph_list[table_offset] & 0x7f;
186
187 // check if we have value for this node
188 if (ft_adobe_glyph_list[table_offset] & 0x80) {
189 unsigned short thiscode = ft_adobe_glyph_list[table_offset+1] * 256 + ft_adobe_glyph_list[table_offset+2];
190 if (thiscode == unicode) // found it!
191 return 1;
192 table_offset += 3;
193 } else
194 table_offset ++;
195
196 // now search in sub-nodes
197 if (count == 0) return 0;
198 for (i = 0; i < count; i ++) {
199 int child_offset = ft_adobe_glyph_list[table_offset+i*2] * 256 + ft_adobe_glyph_list[table_offset+i*2+1];
200 if (xyq_search_node(glyph_name, name_offset, child_offset, unico de))
201 // found in child
202 return 1;
203 }
204 return 0;
205 }
206
207 // XYQ: function for searching Unicode in the glyph list
208 void FXFT_adobe_name_from_unicode(char* glyph_name, FT_UInt32 unicode)
209 {
210 int i, count;
211
212 // start from top level node
213 count = ft_adobe_glyph_list[1];
214 for (i = 0; i < count; i ++) {
215 int child_offset = ft_adobe_glyph_list[i*2+2] * 256 + ft_adobe_g lyph_list[i*2+3];
216 if (xyq_search_node(glyph_name, 0, child_offset, unicode))
217 return;
218 }
219
220 // failed, clear the buffer
221 glyph_name[0] = 0;
222 }
223
224 /* ft_qsort callback to sort the unicode map */
225 FT_CALLBACK_DEF( int )
226 compare_uni_maps( const void* a,
227 const void* b )
228 {
229 PS_UniMap* map1 = (PS_UniMap*)a;
230 PS_UniMap* map2 = (PS_UniMap*)b;
231 FT_UInt32 unicode1 = BASE_GLYPH( map1->unicode );
232 FT_UInt32 unicode2 = BASE_GLYPH( map2->unicode );
233
234
235 /* sort base glyphs before glyph variants */
236 if ( unicode1 == unicode2 )
237 {
238 if ( map1->unicode > map2->unicode )
239 return 1;
240 else if ( map1->unicode < map2->unicode )
241 return -1;
242 else
243 return 0;
244 }
245 else
246 {
247 if ( unicode1 > unicode2 )
248 return 1;
249 else if ( unicode1 < unicode2 )
250 return -1;
251 else
252 return 0;
253 }
254 }
255
256
257 /* support for extra glyphs not handled (well) in AGL; */
258 /* we add extra mappings for them if necessary */
259
260 #define EXTRA_GLYPH_LIST_SIZE 10
261
262 static const FT_UInt32 ft_extra_glyph_unicodes[EXTRA_GLYPH_LIST_SIZE] =
263 {
264 /* WGL 4 */
265 0x0394,
266 0x03A9,
267 0x2215,
268 0x00AD,
269 0x02C9,
270 0x03BC,
271 0x2219,
272 0x00A0,
273 /* Romanian */
274 0x021A,
275 0x021B
276 };
277
278 static const char ft_extra_glyph_names[] =
279 {
280 'D','e','l','t','a',0,
281 'O','m','e','g','a',0,
282 'f','r','a','c','t','i','o','n',0,
283 'h','y','p','h','e','n',0,
284 'm','a','c','r','o','n',0,
285 'm','u',0,
286 'p','e','r','i','o','d','c','e','n','t','e','r','e','d',0,
287 's','p','a','c','e',0,
288 'T','c','o','m','m','a','a','c','c','e','n','t',0,
289 't','c','o','m','m','a','a','c','c','e','n','t',0
290 };
291
292 static const FT_Int
293 ft_extra_glyph_name_offsets[EXTRA_GLYPH_LIST_SIZE] =
294 {
295 0,
296 6,
297 12,
298 21,
299 28,
300 35,
301 38,
302 53,
303 59,
304 72
305 };
306
307
308 static void
309 ps_check_extra_glyph_name( const char* gname,
310 FT_UInt glyph,
311 FT_UInt* extra_glyphs,
312 FT_UInt *states )
313 {
314 FT_UInt n;
315
316
317 for ( n = 0; n < EXTRA_GLYPH_LIST_SIZE; n++ )
318 {
319 if ( ft_strcmp( ft_extra_glyph_names +
320 ft_extra_glyph_name_offsets[n], gname ) == 0 )
321 {
322 if ( states[n] == 0 )
323 {
324 /* mark this extra glyph as a candidate for the cmap */
325 states[n] = 1;
326 extra_glyphs[n] = glyph;
327 }
328
329 return;
330 }
331 }
332 }
333
334
335 static void
336 ps_check_extra_glyph_unicode( FT_UInt32 uni_char,
337 FT_UInt *states )
338 {
339 FT_UInt n;
340
341
342 for ( n = 0; n < EXTRA_GLYPH_LIST_SIZE; n++ )
343 {
344 if ( uni_char == ft_extra_glyph_unicodes[n] )
345 {
346 /* disable this extra glyph from being added to the cmap */
347 states[n] = 2;
348
349 return;
350 }
351 }
352 }
353
354
355 /* Build a table that maps Unicode values to glyph indices. */
356 static FT_Error
357 ps_unicodes_init( FT_Memory memory,
358 PS_Unicodes table,
359 FT_UInt num_glyphs,
360 PS_GetGlyphNameFunc get_glyph_name,
361 PS_FreeGlyphNameFunc free_glyph_name,
362 FT_Pointer glyph_data )
363 {
364 FT_Error error;
365
366 FT_UInt extra_glyph_list_states[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
367 FT_UInt extra_glyphs[EXTRA_GLYPH_LIST_SIZE];
368
369
370 /* we first allocate the table */
371 table->num_maps = 0;
372 table->maps = 0;
373
374 if ( !FT_NEW_ARRAY( table->maps, num_glyphs + EXTRA_GLYPH_LIST_SIZE ) )
375 {
376 FT_UInt n;
377 FT_UInt count;
378 PS_UniMap* map;
379 FT_UInt32 uni_char;
380
381
382 map = table->maps;
383
384 for ( n = 0; n < num_glyphs; n++ )
385 {
386 const char* gname = get_glyph_name( glyph_data, n );
387
388
389 if ( gname )
390 {
391 ps_check_extra_glyph_name( gname, n,
392 extra_glyphs, extra_glyph_list_states );
393 uni_char = FXFT_unicode_from_adobe_name( gname );
394
395 if ( BASE_GLYPH( uni_char ) != 0 )
396 {
397 ps_check_extra_glyph_unicode( uni_char,
398 extra_glyph_list_states );
399 map->unicode = uni_char;
400 map->glyph_index = n;
401 map++;
402 }
403
404 if ( free_glyph_name )
405 free_glyph_name( glyph_data, gname );
406 }
407 }
408
409 for ( n = 0; n < EXTRA_GLYPH_LIST_SIZE; n++ )
410 {
411 if ( extra_glyph_list_states[n] == 1 )
412 {
413 /* This glyph name has an additional representation. */
414 /* Add it to the cmap. */
415
416 map->unicode = ft_extra_glyph_unicodes[n];
417 map->glyph_index = extra_glyphs[n];
418 map++;
419 }
420 }
421
422 /* now compress the table a bit */
423 count = (FT_UInt)( map - table->maps );
424
425 if ( count == 0 )
426 {
427 /* No unicode chars here! */
428 FT_FREE( table->maps );
429 if ( !error )
430 error = FT_THROW( No_Unicode_Glyph_Name );
431 }
432 else
433 {
434 /* Reallocate if the number of used entries is much smaller. */
435 if ( count < num_glyphs / 2 )
436 {
437 (void)FT_RENEW_ARRAY( table->maps, num_glyphs, count );
438 error = FT_Err_Ok;
439 }
440
441 /* Sort the table in increasing order of unicode values, */
442 /* taking care of glyph variants. */
443 ft_qsort( table->maps, count, sizeof ( PS_UniMap ),
444 compare_uni_maps );
445 }
446
447 table->num_maps = count;
448 }
449
450 return error;
451 }
452
453
454 static FT_UInt
455 ps_unicodes_char_index( PS_Unicodes table,
456 FT_UInt32 unicode )
457 {
458 PS_UniMap *min, *max, *mid, *result = NULL;
459
460
461 /* Perform a binary search on the table. */
462
463 min = table->maps;
464 max = min + table->num_maps - 1;
465
466 while ( min <= max )
467 {
468 FT_UInt32 base_glyph;
469
470
471 mid = min + ( ( max - min ) >> 1 );
472
473 if ( mid->unicode == unicode )
474 {
475 result = mid;
476 break;
477 }
478
479 base_glyph = BASE_GLYPH( mid->unicode );
480
481 if ( base_glyph == unicode )
482 result = mid; /* remember match but continue search for base glyph */
483
484 if ( min == max )
485 break;
486
487 if ( base_glyph < unicode )
488 min = mid + 1;
489 else
490 max = mid - 1;
491 }
492
493 if ( result )
494 return result->glyph_index;
495 else
496 return 0;
497 }
498
499
500 static FT_UInt32
501 ps_unicodes_char_next( PS_Unicodes table,
502 FT_UInt32 *unicode )
503 {
504 FT_UInt result = 0;
505 FT_UInt32 char_code = *unicode + 1;
506
507
508 {
509 FT_UInt min = 0;
510 FT_UInt max = table->num_maps;
511 FT_UInt mid;
512 PS_UniMap* map;
513 FT_UInt32 base_glyph;
514
515
516 while ( min < max )
517 {
518 mid = min + ( ( max - min ) >> 1 );
519 map = table->maps + mid;
520
521 if ( map->unicode == char_code )
522 {
523 result = map->glyph_index;
524 goto Exit;
525 }
526
527 base_glyph = BASE_GLYPH( map->unicode );
528
529 if ( base_glyph == char_code )
530 result = map->glyph_index;
531
532 if ( base_glyph < char_code )
533 min = mid + 1;
534 else
535 max = mid;
536 }
537
538 if ( result )
539 goto Exit; /* we have a variant glyph */
540
541 /* we didn't find it; check whether we have a map just above it */
542 char_code = 0;
543
544 if ( min < table->num_maps )
545 {
546 map = table->maps + min;
547 result = map->glyph_index;
548 char_code = BASE_GLYPH( map->unicode );
549 }
550 }
551
552 Exit:
553 *unicode = char_code;
554 return result;
555 }
556
557
558 #endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */
559
560
561 static const char*
562 ps_get_macintosh_name( FT_UInt name_index )
563 {
564 if ( name_index >= FT_NUM_MAC_NAMES )
565 name_index = 0;
566
567 return ft_standard_glyph_names + ft_mac_names[name_index];
568 }
569
570
571 static const char*
572 ps_get_standard_strings( FT_UInt sid )
573 {
574 if ( sid >= FT_NUM_SID_NAMES )
575 return 0;
576
577 return ft_standard_glyph_names + ft_sid_names[sid];
578 }
579
580
581 #ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST
582
583 FT_DEFINE_SERVICE_PSCMAPSREC(
584 pscmaps_interface,
585 (PS_Unicode_ValueFunc) FXFT_unicode_from_adobe_name,
586 (PS_Unicodes_InitFunc) ps_unicodes_init,
587 (PS_Unicodes_CharIndexFunc)ps_unicodes_char_index,
588 (PS_Unicodes_CharNextFunc) ps_unicodes_char_next,
589
590 (PS_Macintosh_NameFunc) ps_get_macintosh_name,
591 (PS_Adobe_Std_StringsFunc) ps_get_standard_strings,
592
593 t1_standard_encoding,
594 t1_expert_encoding )
595
596 #else
597
598 FT_DEFINE_SERVICE_PSCMAPSREC(
599 pscmaps_interface,
600 NULL,
601 NULL,
602 NULL,
603 NULL,
604
605 (PS_Macintosh_NameFunc) ps_get_macintosh_name,
606 (PS_Adobe_Std_StringsFunc) ps_get_standard_strings,
607
608 t1_standard_encoding,
609 t1_expert_encoding )
610
611 #endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */
612
613
614 FT_DEFINE_SERVICEDESCREC1(
615 pscmaps_services,
616 FT_SERVICE_ID_POSTSCRIPT_CMAPS, &PSCMAPS_INTERFACE_GET )
617
618
619 static FT_Pointer
620 psnames_get_service( FT_Module module,
621 const char* service_id )
622 {
623 /* PSCMAPS_SERVICES_GET derefers `library' in PIC mode */
624 #ifdef FT_CONFIG_OPTION_PIC
625 FT_Library library;
626
627
628 if ( !module )
629 return NULL;
630 library = module->library;
631 if ( !library )
632 return NULL;
633 #else
634 FT_UNUSED( module );
635 #endif
636
637 return ft_service_list_lookup( PSCMAPS_SERVICES_GET, service_id );
638 }
639
640 #endif /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */
641
642
643 #ifndef FT_CONFIG_OPTION_POSTSCRIPT_NAMES
644 #define PUT_PS_NAMES_SERVICE( a ) NULL
645 #else
646 #define PUT_PS_NAMES_SERVICE( a ) a
647 #endif
648
649 FT_DEFINE_MODULE(
650 psnames_module_class,
651
652 0, /* this is not a font driver, nor a renderer */
653 sizeof ( FT_ModuleRec ),
654
655 "psnames", /* driver name */
656 0x10000L, /* driver version */
657 0x20000L, /* driver requires FreeType 2 or above */
658
659 PUT_PS_NAMES_SERVICE(
660 (void*)&PSCMAPS_INTERFACE_GET ), /* module specific interface */
661 (FT_Module_Constructor)NULL,
662 (FT_Module_Destructor) NULL,
663 (FT_Module_Requester) PUT_PS_NAMES_SERVICE( psnames_get_service ) )
664
665
666 /* END */
667 #endif
668
OLDNEW
« no previous file with comments | « core/src/fxge/fx_freetype/fxft2.5.01/src/psnames/Jamfile ('k') | core/src/fxge/fx_freetype/fxft2.5.01/src/psnames/module.mk » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698