[FREETYPE] Update to v2.7.1. Patch by Katayama Hirofumi MZ, verified by me. CORE...
[reactos.git] / reactos / sdk / lib / 3rdparty / freetype / src / cff / cffobjs.c
1 /***************************************************************************/
2 /* */
3 /* cffobjs.c */
4 /* */
5 /* OpenType objects manager (body). */
6 /* */
7 /* Copyright 1996-2016 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
21 #include FT_INTERNAL_DEBUG_H
22 #include FT_INTERNAL_CALC_H
23 #include FT_INTERNAL_STREAM_H
24 #include FT_ERRORS_H
25 #include FT_TRUETYPE_IDS_H
26 #include FT_TRUETYPE_TAGS_H
27 #include FT_INTERNAL_SFNT_H
28 #include FT_CFF_DRIVER_H
29
30 #include "cffobjs.h"
31 #include "cffload.h"
32 #include "cffcmap.h"
33 #include "cffpic.h"
34
35 #include "cfferrs.h"
36
37
38 /*************************************************************************/
39 /* */
40 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
41 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
42 /* messages during execution. */
43 /* */
44 #undef FT_COMPONENT
45 #define FT_COMPONENT trace_cffobjs
46
47
48 /*************************************************************************/
49 /* */
50 /* SIZE FUNCTIONS */
51 /* */
52 /* Note that we store the global hints in the size's `internal' root */
53 /* field. */
54 /* */
55 /*************************************************************************/
56
57
58 static PSH_Globals_Funcs
59 cff_size_get_globals_funcs( CFF_Size size )
60 {
61 CFF_Face face = (CFF_Face)size->root.face;
62 CFF_Font font = (CFF_Font)face->extra.data;
63 PSHinter_Service pshinter = font->pshinter;
64 FT_Module module;
65
66
67 module = FT_Get_Module( size->root.face->driver->root.library,
68 "pshinter" );
69 return ( module && pshinter && pshinter->get_globals_funcs )
70 ? pshinter->get_globals_funcs( module )
71 : 0;
72 }
73
74
75 FT_LOCAL_DEF( void )
76 cff_size_done( FT_Size cffsize ) /* CFF_Size */
77 {
78 CFF_Size size = (CFF_Size)cffsize;
79 CFF_Face face = (CFF_Face)size->root.face;
80 CFF_Font font = (CFF_Font)face->extra.data;
81 CFF_Internal internal = (CFF_Internal)cffsize->internal;
82
83
84 if ( internal )
85 {
86 PSH_Globals_Funcs funcs;
87
88
89 funcs = cff_size_get_globals_funcs( size );
90 if ( funcs )
91 {
92 FT_UInt i;
93
94
95 funcs->destroy( internal->topfont );
96
97 for ( i = font->num_subfonts; i > 0; i-- )
98 funcs->destroy( internal->subfonts[i - 1] );
99 }
100
101 /* `internal' is freed by destroy_size (in ftobjs.c) */
102 }
103 }
104
105
106 /* CFF and Type 1 private dictionaries have slightly different */
107 /* structures; we need to synthesize a Type 1 dictionary on the fly */
108
109 static void
110 cff_make_private_dict( CFF_SubFont subfont,
111 PS_Private priv )
112 {
113 CFF_Private cpriv = &subfont->private_dict;
114 FT_UInt n, count;
115
116
117 FT_ZERO( priv );
118
119 count = priv->num_blue_values = cpriv->num_blue_values;
120 for ( n = 0; n < count; n++ )
121 priv->blue_values[n] = (FT_Short)cpriv->blue_values[n];
122
123 count = priv->num_other_blues = cpriv->num_other_blues;
124 for ( n = 0; n < count; n++ )
125 priv->other_blues[n] = (FT_Short)cpriv->other_blues[n];
126
127 count = priv->num_family_blues = cpriv->num_family_blues;
128 for ( n = 0; n < count; n++ )
129 priv->family_blues[n] = (FT_Short)cpriv->family_blues[n];
130
131 count = priv->num_family_other_blues = cpriv->num_family_other_blues;
132 for ( n = 0; n < count; n++ )
133 priv->family_other_blues[n] = (FT_Short)cpriv->family_other_blues[n];
134
135 priv->blue_scale = cpriv->blue_scale;
136 priv->blue_shift = (FT_Int)cpriv->blue_shift;
137 priv->blue_fuzz = (FT_Int)cpriv->blue_fuzz;
138
139 priv->standard_width[0] = (FT_UShort)cpriv->standard_width;
140 priv->standard_height[0] = (FT_UShort)cpriv->standard_height;
141
142 count = priv->num_snap_widths = cpriv->num_snap_widths;
143 for ( n = 0; n < count; n++ )
144 priv->snap_widths[n] = (FT_Short)cpriv->snap_widths[n];
145
146 count = priv->num_snap_heights = cpriv->num_snap_heights;
147 for ( n = 0; n < count; n++ )
148 priv->snap_heights[n] = (FT_Short)cpriv->snap_heights[n];
149
150 priv->force_bold = cpriv->force_bold;
151 priv->language_group = cpriv->language_group;
152 priv->lenIV = cpriv->lenIV;
153 }
154
155
156 FT_LOCAL_DEF( FT_Error )
157 cff_size_init( FT_Size cffsize ) /* CFF_Size */
158 {
159 CFF_Size size = (CFF_Size)cffsize;
160 FT_Error error = FT_Err_Ok;
161 PSH_Globals_Funcs funcs = cff_size_get_globals_funcs( size );
162
163
164 if ( funcs )
165 {
166 CFF_Face face = (CFF_Face)cffsize->face;
167 CFF_Font font = (CFF_Font)face->extra.data;
168 CFF_Internal internal = NULL;
169
170 PS_PrivateRec priv;
171 FT_Memory memory = cffsize->face->memory;
172
173 FT_UInt i;
174
175
176 if ( FT_NEW( internal ) )
177 goto Exit;
178
179 cff_make_private_dict( &font->top_font, &priv );
180 error = funcs->create( cffsize->face->memory, &priv,
181 &internal->topfont );
182 if ( error )
183 goto Exit;
184
185 for ( i = font->num_subfonts; i > 0; i-- )
186 {
187 CFF_SubFont sub = font->subfonts[i - 1];
188
189
190 cff_make_private_dict( sub, &priv );
191 error = funcs->create( cffsize->face->memory, &priv,
192 &internal->subfonts[i - 1] );
193 if ( error )
194 goto Exit;
195 }
196
197 cffsize->internal = (FT_Size_Internal)(void*)internal;
198 }
199
200 size->strike_index = 0xFFFFFFFFUL;
201
202 Exit:
203 return error;
204 }
205
206
207 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
208
209 FT_LOCAL_DEF( FT_Error )
210 cff_size_select( FT_Size size,
211 FT_ULong strike_index )
212 {
213 CFF_Size cffsize = (CFF_Size)size;
214 PSH_Globals_Funcs funcs;
215
216
217 cffsize->strike_index = strike_index;
218
219 FT_Select_Metrics( size->face, strike_index );
220
221 funcs = cff_size_get_globals_funcs( cffsize );
222
223 if ( funcs )
224 {
225 CFF_Face face = (CFF_Face)size->face;
226 CFF_Font font = (CFF_Font)face->extra.data;
227 CFF_Internal internal = (CFF_Internal)size->internal;
228
229 FT_Long top_upm = (FT_Long)font->top_font.font_dict.units_per_em;
230 FT_UInt i;
231
232
233 funcs->set_scale( internal->topfont,
234 size->metrics.x_scale, size->metrics.y_scale,
235 0, 0 );
236
237 for ( i = font->num_subfonts; i > 0; i-- )
238 {
239 CFF_SubFont sub = font->subfonts[i - 1];
240 FT_Long sub_upm = (FT_Long)sub->font_dict.units_per_em;
241 FT_Pos x_scale, y_scale;
242
243
244 if ( top_upm != sub_upm )
245 {
246 x_scale = FT_MulDiv( size->metrics.x_scale, top_upm, sub_upm );
247 y_scale = FT_MulDiv( size->metrics.y_scale, top_upm, sub_upm );
248 }
249 else
250 {
251 x_scale = size->metrics.x_scale;
252 y_scale = size->metrics.y_scale;
253 }
254
255 funcs->set_scale( internal->subfonts[i - 1],
256 x_scale, y_scale, 0, 0 );
257 }
258 }
259
260 return FT_Err_Ok;
261 }
262
263 #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
264
265
266 FT_LOCAL_DEF( FT_Error )
267 cff_size_request( FT_Size size,
268 FT_Size_Request req )
269 {
270 CFF_Size cffsize = (CFF_Size)size;
271 PSH_Globals_Funcs funcs;
272
273
274 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
275
276 if ( FT_HAS_FIXED_SIZES( size->face ) )
277 {
278 CFF_Face cffface = (CFF_Face)size->face;
279 SFNT_Service sfnt = (SFNT_Service)cffface->sfnt;
280 FT_ULong strike_index;
281
282
283 if ( sfnt->set_sbit_strike( cffface, req, &strike_index ) )
284 cffsize->strike_index = 0xFFFFFFFFUL;
285 else
286 return cff_size_select( size, strike_index );
287 }
288
289 #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
290
291 FT_Request_Metrics( size->face, req );
292
293 funcs = cff_size_get_globals_funcs( cffsize );
294
295 if ( funcs )
296 {
297 CFF_Face cffface = (CFF_Face)size->face;
298 CFF_Font font = (CFF_Font)cffface->extra.data;
299 CFF_Internal internal = (CFF_Internal)size->internal;
300
301 FT_Long top_upm = (FT_Long)font->top_font.font_dict.units_per_em;
302 FT_UInt i;
303
304
305 funcs->set_scale( internal->topfont,
306 size->metrics.x_scale, size->metrics.y_scale,
307 0, 0 );
308
309 for ( i = font->num_subfonts; i > 0; i-- )
310 {
311 CFF_SubFont sub = font->subfonts[i - 1];
312 FT_Long sub_upm = (FT_Long)sub->font_dict.units_per_em;
313 FT_Pos x_scale, y_scale;
314
315
316 if ( top_upm != sub_upm )
317 {
318 x_scale = FT_MulDiv( size->metrics.x_scale, top_upm, sub_upm );
319 y_scale = FT_MulDiv( size->metrics.y_scale, top_upm, sub_upm );
320 }
321 else
322 {
323 x_scale = size->metrics.x_scale;
324 y_scale = size->metrics.y_scale;
325 }
326
327 funcs->set_scale( internal->subfonts[i - 1],
328 x_scale, y_scale, 0, 0 );
329 }
330 }
331
332 return FT_Err_Ok;
333 }
334
335
336 /*************************************************************************/
337 /* */
338 /* SLOT FUNCTIONS */
339 /* */
340 /*************************************************************************/
341
342 FT_LOCAL_DEF( void )
343 cff_slot_done( FT_GlyphSlot slot )
344 {
345 slot->internal->glyph_hints = NULL;
346 }
347
348
349 FT_LOCAL_DEF( FT_Error )
350 cff_slot_init( FT_GlyphSlot slot )
351 {
352 CFF_Face face = (CFF_Face)slot->face;
353 CFF_Font font = (CFF_Font)face->extra.data;
354 PSHinter_Service pshinter = font->pshinter;
355
356
357 if ( pshinter )
358 {
359 FT_Module module;
360
361
362 module = FT_Get_Module( slot->face->driver->root.library,
363 "pshinter" );
364 if ( module )
365 {
366 T2_Hints_Funcs funcs;
367
368
369 funcs = pshinter->get_t2_funcs( module );
370 slot->internal->glyph_hints = (void*)funcs;
371 }
372 }
373
374 return FT_Err_Ok;
375 }
376
377
378 /*************************************************************************/
379 /* */
380 /* FACE FUNCTIONS */
381 /* */
382 /*************************************************************************/
383
384 static FT_String*
385 cff_strcpy( FT_Memory memory,
386 const FT_String* source )
387 {
388 FT_Error error;
389 FT_String* result;
390
391
392 (void)FT_STRDUP( result, source );
393
394 FT_UNUSED( error );
395
396 return result;
397 }
398
399
400 /* Strip all subset prefixes of the form `ABCDEF+'. Usually, there */
401 /* is only one, but font names like `APCOOG+JFABTD+FuturaBQ-Bold' */
402 /* have been seen in the wild. */
403
404 static void
405 remove_subset_prefix( FT_String* name )
406 {
407 FT_Int32 idx = 0;
408 FT_Int32 length = (FT_Int32)strlen( name ) + 1;
409 FT_Bool continue_search = 1;
410
411
412 while ( continue_search )
413 {
414 if ( length >= 7 && name[6] == '+' )
415 {
416 for ( idx = 0; idx < 6; idx++ )
417 {
418 /* ASCII uppercase letters */
419 if ( !( 'A' <= name[idx] && name[idx] <= 'Z' ) )
420 continue_search = 0;
421 }
422
423 if ( continue_search )
424 {
425 for ( idx = 7; idx < length; idx++ )
426 name[idx - 7] = name[idx];
427 length -= 7;
428 }
429 }
430 else
431 continue_search = 0;
432 }
433 }
434
435
436 /* Remove the style part from the family name (if present). */
437
438 static void
439 remove_style( FT_String* family_name,
440 const FT_String* style_name )
441 {
442 FT_Int32 family_name_length, style_name_length;
443
444
445 family_name_length = (FT_Int32)strlen( family_name );
446 style_name_length = (FT_Int32)strlen( style_name );
447
448 if ( family_name_length > style_name_length )
449 {
450 FT_Int idx;
451
452
453 for ( idx = 1; idx <= style_name_length; idx++ )
454 {
455 if ( family_name[family_name_length - idx] !=
456 style_name[style_name_length - idx] )
457 break;
458 }
459
460 if ( idx > style_name_length )
461 {
462 /* family_name ends with style_name; remove it */
463 idx = family_name_length - style_name_length - 1;
464
465 /* also remove special characters */
466 /* between real family name and style */
467 while ( idx > 0 &&
468 ( family_name[idx] == '-' ||
469 family_name[idx] == ' ' ||
470 family_name[idx] == '_' ||
471 family_name[idx] == '+' ) )
472 idx--;
473
474 if ( idx > 0 )
475 family_name[idx + 1] = '\0';
476 }
477 }
478 }
479
480
481 FT_LOCAL_DEF( FT_Error )
482 cff_face_init( FT_Stream stream,
483 FT_Face cffface, /* CFF_Face */
484 FT_Int face_index,
485 FT_Int num_params,
486 FT_Parameter* params )
487 {
488 CFF_Face face = (CFF_Face)cffface;
489 FT_Error error;
490 SFNT_Service sfnt;
491 FT_Service_PsCMaps psnames;
492 PSHinter_Service pshinter;
493 FT_Bool pure_cff = 1;
494 FT_Bool cff2 = 0;
495 FT_Bool sfnt_format = 0;
496 FT_Library library = cffface->driver->root.library;
497
498
499 sfnt = (SFNT_Service)FT_Get_Module_Interface(
500 library, "sfnt" );
501 if ( !sfnt )
502 {
503 FT_ERROR(( "cff_face_init: cannot access `sfnt' module\n" ));
504 error = FT_THROW( Missing_Module );
505 goto Exit;
506 }
507
508 FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS );
509
510 pshinter = (PSHinter_Service)FT_Get_Module_Interface(
511 library, "pshinter" );
512
513 FT_TRACE2(( "CFF driver\n" ));
514
515 /* create input stream from resource */
516 if ( FT_STREAM_SEEK( 0 ) )
517 goto Exit;
518
519 /* check whether we have a valid OpenType file */
520 error = sfnt->init_face( stream, face, face_index, num_params, params );
521 if ( !error )
522 {
523 if ( face->format_tag != TTAG_OTTO ) /* `OTTO'; OpenType/CFF font */
524 {
525 FT_TRACE2(( " not an OpenType/CFF font\n" ));
526 error = FT_THROW( Unknown_File_Format );
527 goto Exit;
528 }
529
530 /* if we are performing a simple font format check, exit immediately */
531 if ( face_index < 0 )
532 return FT_Err_Ok;
533
534 sfnt_format = 1;
535
536 /* now, the font can be either an OpenType/CFF font, or an SVG CEF */
537 /* font; in the latter case it doesn't have a `head' table */
538 error = face->goto_table( face, TTAG_head, stream, 0 );
539 if ( !error )
540 {
541 pure_cff = 0;
542
543 /* load font directory */
544 error = sfnt->load_face( stream, face, face_index,
545 num_params, params );
546 if ( error )
547 goto Exit;
548 }
549 else
550 {
551 /* load the `cmap' table explicitly */
552 error = sfnt->load_cmap( face, stream );
553 if ( error )
554 goto Exit;
555 }
556
557 /* now load the CFF part of the file; */
558 /* give priority to CFF2 */
559 error = face->goto_table( face, TTAG_CFF2, stream, 0 );
560 if ( !error )
561 {
562 cff2 = 1;
563 face->isCFF2 = cff2;
564 }
565
566 if ( FT_ERR_EQ( error, Table_Missing ) )
567 error = face->goto_table( face, TTAG_CFF, stream, 0 );
568
569 if ( error )
570 goto Exit;
571 }
572 else
573 {
574 /* rewind to start of file; we are going to load a pure-CFF font */
575 if ( FT_STREAM_SEEK( 0 ) )
576 goto Exit;
577 error = FT_Err_Ok;
578 }
579
580 /* now load and parse the CFF table in the file */
581 {
582 CFF_Font cff = NULL;
583 CFF_FontRecDict dict;
584 FT_Memory memory = cffface->memory;
585 FT_Int32 flags;
586 FT_UInt i;
587
588
589 if ( FT_NEW( cff ) )
590 goto Exit;
591
592 face->extra.data = cff;
593 error = cff_font_load( library,
594 stream,
595 face_index,
596 cff,
597 pure_cff,
598 cff2 );
599 if ( error )
600 goto Exit;
601
602 /* if we are performing a simple font format check, exit immediately */
603 /* (this is here for pure CFF) */
604 if ( face_index < 0 )
605 {
606 cffface->num_faces = (FT_Long)cff->num_faces;
607 return FT_Err_Ok;
608 }
609
610 cff->pshinter = pshinter;
611 cff->psnames = psnames;
612
613 cffface->face_index = face_index & 0xFFFF;
614
615 /* Complement the root flags with some interesting information. */
616 /* Note that this is only necessary for pure CFF and CEF fonts; */
617 /* SFNT based fonts use the `name' table instead. */
618
619 cffface->num_glyphs = (FT_Long)cff->num_glyphs;
620
621 dict = &cff->top_font.font_dict;
622
623 /* we need the `PSNames' module for CFF and CEF formats */
624 /* which aren't CID-keyed */
625 if ( dict->cid_registry == 0xFFFFU && !psnames )
626 {
627 FT_ERROR(( "cff_face_init:"
628 " cannot open CFF & CEF fonts\n"
629 " "
630 " without the `PSNames' module\n" ));
631 error = FT_THROW( Missing_Module );
632 goto Exit;
633 }
634
635 #ifdef FT_DEBUG_LEVEL_TRACE
636 {
637 FT_UInt idx;
638 FT_String* s;
639
640
641 FT_TRACE4(( "SIDs\n" ));
642
643 /* dump string index, including default strings for convenience */
644 for ( idx = 0; idx <= 390; idx++ )
645 {
646 s = cff_index_get_sid_string( cff, idx );
647 if ( s )
648 FT_TRACE4(( " %5d %s\n", idx, s ));
649 }
650
651 /* In Multiple Master CFFs, two SIDs hold the Normalize Design */
652 /* Vector (NDV) and Convert Design Vector (CDV) charstrings, */
653 /* which may contain NULL bytes in the middle of the data, too. */
654 /* We thus access `cff->strings' directly. */
655 for ( idx = 1; idx < cff->num_strings; idx++ )
656 {
657 FT_Byte* s1 = cff->strings[idx - 1];
658 FT_Byte* s2 = cff->strings[idx];
659 FT_PtrDist s1len = s2 - s1 - 1; /* without the final NULL byte */
660 FT_PtrDist l;
661
662
663 FT_TRACE4(( " %5d ", idx + 390 ));
664 for ( l = 0; l < s1len; l++ )
665 FT_TRACE4(( "%c", s1[l] ));
666 FT_TRACE4(( "\n" ));
667 }
668
669 /* print last element */
670 if ( cff->num_strings )
671 {
672 FT_Byte* s1 = cff->strings[cff->num_strings - 1];
673 FT_Byte* s2 = cff->string_pool + cff->string_pool_size;
674 FT_PtrDist s1len = s2 - s1 - 1;
675 FT_PtrDist l;
676
677
678 FT_TRACE4(( " %5d ", cff->num_strings + 390 ));
679 for ( l = 0; l < s1len; l++ )
680 FT_TRACE4(( "%c", s1[l] ));
681 FT_TRACE4(( "\n" ));
682 }
683 }
684 #endif /* FT_DEBUG_LEVEL_TRACE */
685
686
687
688 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
689
690 {
691 FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm;
692
693 FT_Int instance_index = face_index >> 16;
694
695
696 if ( FT_HAS_MULTIPLE_MASTERS( cffface ) &&
697 mm &&
698 instance_index > 0 )
699 {
700 FT_MM_Var* mm_var;
701
702
703 error = mm->get_mm_var( cffface, NULL );
704 if ( error )
705 goto Exit;
706
707 mm->get_var_blend( cffface, NULL, NULL, &mm_var );
708
709 if ( mm_var->namedstyle )
710 {
711 FT_Var_Named_Style* named_style;
712 FT_String* style_name;
713
714
715 /* in `face_index', the instance index starts with value 1 */
716 named_style = mm_var->namedstyle + instance_index - 1;
717 error = sfnt->get_name( face,
718 (FT_UShort)named_style->strid,
719 &style_name );
720 if ( error )
721 goto Exit;
722
723 /* set style name; if already set, replace it */
724 if ( face->root.style_name )
725 FT_FREE( face->root.style_name );
726 face->root.style_name = style_name;
727
728 /* finally, select the named instance */
729 error = mm->set_var_design( cffface,
730 mm_var->num_axis,
731 named_style->coords );
732 if ( error )
733 goto Exit;
734 }
735 }
736 }
737
738 #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
739
740
741
742 if ( !dict->has_font_matrix )
743 dict->units_per_em = pure_cff ? 1000 : face->root.units_per_EM;
744
745 /* Normalize the font matrix so that `matrix->yy' is 1; if */
746 /* it is zero, we use `matrix->yx' instead. The scaling is */
747 /* done with `units_per_em' then (at this point, it already */
748 /* contains the scaling factor, but without normalization */
749 /* of the matrix). */
750 /* */
751 /* Note that the offsets must be expressed in integer font */
752 /* units. */
753
754 {
755 FT_Matrix* matrix = &dict->font_matrix;
756 FT_Vector* offset = &dict->font_offset;
757 FT_ULong* upm = &dict->units_per_em;
758 FT_Fixed temp;
759
760
761 temp = matrix->yy ? FT_ABS( matrix->yy )
762 : FT_ABS( matrix->yx );
763
764 if ( temp != 0x10000L )
765 {
766 *upm = (FT_ULong)FT_DivFix( (FT_Long)*upm, temp );
767
768 matrix->xx = FT_DivFix( matrix->xx, temp );
769 matrix->yx = FT_DivFix( matrix->yx, temp );
770 matrix->xy = FT_DivFix( matrix->xy, temp );
771 matrix->yy = FT_DivFix( matrix->yy, temp );
772 offset->x = FT_DivFix( offset->x, temp );
773 offset->y = FT_DivFix( offset->y, temp );
774 }
775
776 offset->x >>= 16;
777 offset->y >>= 16;
778 }
779
780 for ( i = cff->num_subfonts; i > 0; i-- )
781 {
782 CFF_FontRecDict sub = &cff->subfonts[i - 1]->font_dict;
783 CFF_FontRecDict top = &cff->top_font.font_dict;
784
785 FT_Matrix* matrix;
786 FT_Vector* offset;
787 FT_ULong* upm;
788 FT_Fixed temp;
789
790
791 if ( sub->has_font_matrix )
792 {
793 FT_Long scaling;
794
795
796 /* if we have a top-level matrix, */
797 /* concatenate the subfont matrix */
798
799 if ( top->has_font_matrix )
800 {
801 if ( top->units_per_em > 1 && sub->units_per_em > 1 )
802 scaling = (FT_Long)FT_MIN( top->units_per_em,
803 sub->units_per_em );
804 else
805 scaling = 1;
806
807 FT_Matrix_Multiply_Scaled( &top->font_matrix,
808 &sub->font_matrix,
809 scaling );
810 FT_Vector_Transform_Scaled( &sub->font_offset,
811 &top->font_matrix,
812 scaling );
813
814 sub->units_per_em = (FT_ULong)
815 FT_MulDiv( (FT_Long)sub->units_per_em,
816 (FT_Long)top->units_per_em,
817 scaling );
818 }
819 }
820 else
821 {
822 sub->font_matrix = top->font_matrix;
823 sub->font_offset = top->font_offset;
824
825 sub->units_per_em = top->units_per_em;
826 }
827
828 matrix = &sub->font_matrix;
829 offset = &sub->font_offset;
830 upm = &sub->units_per_em;
831
832 temp = matrix->yy ? FT_ABS( matrix->yy )
833 : FT_ABS( matrix->yx );
834
835
836 if ( temp != 0x10000L )
837 {
838 *upm = (FT_ULong)FT_DivFix( (FT_Long)*upm, temp );
839
840 matrix->xx = FT_DivFix( matrix->xx, temp );
841 matrix->yx = FT_DivFix( matrix->yx, temp );
842 matrix->xy = FT_DivFix( matrix->xy, temp );
843 matrix->yy = FT_DivFix( matrix->yy, temp );
844 offset->x = FT_DivFix( offset->x, temp );
845 offset->y = FT_DivFix( offset->y, temp );
846 }
847
848 offset->x >>= 16;
849 offset->y >>= 16;
850 }
851
852 if ( pure_cff )
853 {
854 char* style_name = NULL;
855
856
857 /* set up num_faces */
858 cffface->num_faces = (FT_Long)cff->num_faces;
859
860 /* compute number of glyphs */
861 if ( dict->cid_registry != 0xFFFFU )
862 cffface->num_glyphs = (FT_Long)( cff->charset.max_cid + 1 );
863 else
864 cffface->num_glyphs = (FT_Long)cff->charstrings_index.count;
865
866 /* set global bbox, as well as EM size */
867 cffface->bbox.xMin = dict->font_bbox.xMin >> 16;
868 cffface->bbox.yMin = dict->font_bbox.yMin >> 16;
869 /* no `U' suffix here to 0xFFFF! */
870 cffface->bbox.xMax = ( dict->font_bbox.xMax + 0xFFFF ) >> 16;
871 cffface->bbox.yMax = ( dict->font_bbox.yMax + 0xFFFF ) >> 16;
872
873 cffface->units_per_EM = (FT_UShort)( dict->units_per_em );
874
875 cffface->ascender = (FT_Short)( cffface->bbox.yMax );
876 cffface->descender = (FT_Short)( cffface->bbox.yMin );
877
878 cffface->height = (FT_Short)( ( cffface->units_per_EM * 12 ) / 10 );
879 if ( cffface->height < cffface->ascender - cffface->descender )
880 cffface->height = (FT_Short)( cffface->ascender - cffface->descender );
881
882 cffface->underline_position =
883 (FT_Short)( dict->underline_position >> 16 );
884 cffface->underline_thickness =
885 (FT_Short)( dict->underline_thickness >> 16 );
886
887 /* retrieve font family & style name */
888 cffface->family_name = cff_index_get_name(
889 cff,
890 (FT_UInt)( face_index & 0xFFFF ) );
891 if ( cffface->family_name )
892 {
893 char* full = cff_index_get_sid_string( cff,
894 dict->full_name );
895 char* fullp = full;
896 char* family = cffface->family_name;
897 char* family_name = NULL;
898
899
900 remove_subset_prefix( cffface->family_name );
901
902 if ( dict->family_name )
903 {
904 family_name = cff_index_get_sid_string( cff,
905 dict->family_name );
906 if ( family_name )
907 family = family_name;
908 }
909
910 /* We try to extract the style name from the full name. */
911 /* We need to ignore spaces and dashes during the search. */
912 if ( full && family )
913 {
914 while ( *fullp )
915 {
916 /* skip common characters at the start of both strings */
917 if ( *fullp == *family )
918 {
919 family++;
920 fullp++;
921 continue;
922 }
923
924 /* ignore spaces and dashes in full name during comparison */
925 if ( *fullp == ' ' || *fullp == '-' )
926 {
927 fullp++;
928 continue;
929 }
930
931 /* ignore spaces and dashes in family name during comparison */
932 if ( *family == ' ' || *family == '-' )
933 {
934 family++;
935 continue;
936 }
937
938 if ( !*family && *fullp )
939 {
940 /* The full name begins with the same characters as the */
941 /* family name, with spaces and dashes removed. In this */
942 /* case, the remaining string in `fullp' will be used as */
943 /* the style name. */
944 style_name = cff_strcpy( memory, fullp );
945
946 /* remove the style part from the family name (if present) */
947 remove_style( cffface->family_name, style_name );
948 }
949 break;
950 }
951 }
952 }
953 else
954 {
955 char *cid_font_name =
956 cff_index_get_sid_string( cff,
957 dict->cid_font_name );
958
959
960 /* do we have a `/FontName' for a CID-keyed font? */
961 if ( cid_font_name )
962 cffface->family_name = cff_strcpy( memory, cid_font_name );
963 }
964
965 if ( style_name )
966 cffface->style_name = style_name;
967 else
968 /* assume "Regular" style if we don't know better */
969 cffface->style_name = cff_strcpy( memory, (char *)"Regular" );
970
971 /*******************************************************************/
972 /* */
973 /* Compute face flags. */
974 /* */
975 flags = FT_FACE_FLAG_SCALABLE | /* scalable outlines */
976 FT_FACE_FLAG_HORIZONTAL | /* horizontal data */
977 FT_FACE_FLAG_HINTER; /* has native hinter */
978
979 if ( sfnt_format )
980 flags |= FT_FACE_FLAG_SFNT;
981
982 /* fixed width font? */
983 if ( dict->is_fixed_pitch )
984 flags |= FT_FACE_FLAG_FIXED_WIDTH;
985
986 /* XXX: WE DO NOT SUPPORT KERNING METRICS IN THE GPOS TABLE FOR NOW */
987 #if 0
988 /* kerning available? */
989 if ( face->kern_pairs )
990 flags |= FT_FACE_FLAG_KERNING;
991 #endif
992
993 cffface->face_flags |= flags;
994
995 /*******************************************************************/
996 /* */
997 /* Compute style flags. */
998 /* */
999 flags = 0;
1000
1001 if ( dict->italic_angle )
1002 flags |= FT_STYLE_FLAG_ITALIC;
1003
1004 {
1005 char *weight = cff_index_get_sid_string( cff,
1006 dict->weight );
1007
1008
1009 if ( weight )
1010 if ( !ft_strcmp( weight, "Bold" ) ||
1011 !ft_strcmp( weight, "Black" ) )
1012 flags |= FT_STYLE_FLAG_BOLD;
1013 }
1014
1015 /* double check */
1016 if ( !(flags & FT_STYLE_FLAG_BOLD) && cffface->style_name )
1017 if ( !ft_strncmp( cffface->style_name, "Bold", 4 ) ||
1018 !ft_strncmp( cffface->style_name, "Black", 5 ) )
1019 flags |= FT_STYLE_FLAG_BOLD;
1020
1021 cffface->style_flags = flags;
1022 }
1023
1024
1025 #ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES
1026 /* CID-keyed CFF fonts don't have glyph names -- the SFNT loader */
1027 /* has unset this flag because of the 3.0 `post' table. */
1028 if ( dict->cid_registry == 0xFFFFU )
1029 cffface->face_flags |= FT_FACE_FLAG_GLYPH_NAMES;
1030 #endif
1031
1032 if ( dict->cid_registry != 0xFFFFU && pure_cff )
1033 cffface->face_flags |= FT_FACE_FLAG_CID_KEYED;
1034
1035
1036 /*******************************************************************/
1037 /* */
1038 /* Compute char maps. */
1039 /* */
1040
1041 /* Try to synthesize a Unicode charmap if there is none available */
1042 /* already. If an OpenType font contains a Unicode "cmap", we */
1043 /* will use it, whatever be in the CFF part of the file. */
1044 {
1045 FT_CharMapRec cmaprec;
1046 FT_CharMap cmap;
1047 FT_UInt nn;
1048 CFF_Encoding encoding = &cff->encoding;
1049
1050
1051 for ( nn = 0; nn < (FT_UInt)cffface->num_charmaps; nn++ )
1052 {
1053 cmap = cffface->charmaps[nn];
1054
1055 /* Windows Unicode? */
1056 if ( cmap->platform_id == TT_PLATFORM_MICROSOFT &&
1057 cmap->encoding_id == TT_MS_ID_UNICODE_CS )
1058 goto Skip_Unicode;
1059
1060 /* Apple Unicode platform id? */
1061 if ( cmap->platform_id == TT_PLATFORM_APPLE_UNICODE )
1062 goto Skip_Unicode; /* Apple Unicode */
1063 }
1064
1065 /* since CID-keyed fonts don't contain glyph names, we can't */
1066 /* construct a cmap */
1067 if ( pure_cff && cff->top_font.font_dict.cid_registry != 0xFFFFU )
1068 goto Exit;
1069
1070 /* we didn't find a Unicode charmap -- synthesize one */
1071 cmaprec.face = cffface;
1072 cmaprec.platform_id = TT_PLATFORM_MICROSOFT;
1073 cmaprec.encoding_id = TT_MS_ID_UNICODE_CS;
1074 cmaprec.encoding = FT_ENCODING_UNICODE;
1075
1076 nn = (FT_UInt)cffface->num_charmaps;
1077
1078 error = FT_CMap_New( &CFF_CMAP_UNICODE_CLASS_REC_GET, NULL,
1079 &cmaprec, NULL );
1080 if ( error &&
1081 FT_ERR_NEQ( error, No_Unicode_Glyph_Name ) )
1082 goto Exit;
1083 error = FT_Err_Ok;
1084
1085 /* if no Unicode charmap was previously selected, select this one */
1086 if ( !cffface->charmap && nn != (FT_UInt)cffface->num_charmaps )
1087 cffface->charmap = cffface->charmaps[nn];
1088
1089 Skip_Unicode:
1090 if ( encoding->count > 0 )
1091 {
1092 FT_CMap_Class clazz;
1093
1094
1095 cmaprec.face = cffface;
1096 cmaprec.platform_id = TT_PLATFORM_ADOBE; /* Adobe platform id */
1097
1098 if ( encoding->offset == 0 )
1099 {
1100 cmaprec.encoding_id = TT_ADOBE_ID_STANDARD;
1101 cmaprec.encoding = FT_ENCODING_ADOBE_STANDARD;
1102 clazz = &CFF_CMAP_ENCODING_CLASS_REC_GET;
1103 }
1104 else if ( encoding->offset == 1 )
1105 {
1106 cmaprec.encoding_id = TT_ADOBE_ID_EXPERT;
1107 cmaprec.encoding = FT_ENCODING_ADOBE_EXPERT;
1108 clazz = &CFF_CMAP_ENCODING_CLASS_REC_GET;
1109 }
1110 else
1111 {
1112 cmaprec.encoding_id = TT_ADOBE_ID_CUSTOM;
1113 cmaprec.encoding = FT_ENCODING_ADOBE_CUSTOM;
1114 clazz = &CFF_CMAP_ENCODING_CLASS_REC_GET;
1115 }
1116
1117 error = FT_CMap_New( clazz, NULL, &cmaprec, NULL );
1118 }
1119 }
1120 }
1121
1122 Exit:
1123 return error;
1124 }
1125
1126
1127 FT_LOCAL_DEF( void )
1128 cff_face_done( FT_Face cffface ) /* CFF_Face */
1129 {
1130 CFF_Face face = (CFF_Face)cffface;
1131 FT_Memory memory;
1132 SFNT_Service sfnt;
1133
1134
1135 if ( !face )
1136 return;
1137
1138 memory = cffface->memory;
1139 sfnt = (SFNT_Service)face->sfnt;
1140
1141 if ( sfnt )
1142 sfnt->done_face( face );
1143
1144 {
1145 CFF_Font cff = (CFF_Font)face->extra.data;
1146
1147
1148 if ( cff )
1149 {
1150 cff_font_done( cff );
1151 FT_FREE( face->extra.data );
1152 }
1153 }
1154
1155 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
1156 cff_done_blend( face );
1157 face->blend = NULL;
1158 #endif
1159 }
1160
1161
1162 FT_LOCAL_DEF( FT_Error )
1163 cff_driver_init( FT_Module module ) /* CFF_Driver */
1164 {
1165 CFF_Driver driver = (CFF_Driver)module;
1166
1167
1168 /* set default property values, cf. `ftcffdrv.h' */
1169 #ifdef CFF_CONFIG_OPTION_OLD_ENGINE
1170 driver->hinting_engine = FT_CFF_HINTING_FREETYPE;
1171 #else
1172 driver->hinting_engine = FT_CFF_HINTING_ADOBE;
1173 #endif
1174
1175 driver->no_stem_darkening = TRUE;
1176
1177 driver->darken_params[0] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1;
1178 driver->darken_params[1] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1;
1179 driver->darken_params[2] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2;
1180 driver->darken_params[3] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y2;
1181 driver->darken_params[4] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3;
1182 driver->darken_params[5] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y3;
1183 driver->darken_params[6] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X4;
1184 driver->darken_params[7] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4;
1185
1186 return FT_Err_Ok;
1187 }
1188
1189
1190 FT_LOCAL_DEF( void )
1191 cff_driver_done( FT_Module module ) /* CFF_Driver */
1192 {
1193 FT_UNUSED( module );
1194 }
1195
1196
1197 /* END */