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