65#include FT_CONFIG_CONFIG_H
75#ifdef FT_CONFIG_OPTION_INCREMENTAL
76#define IS_INCREMENTAL \
77 FT_BOOL( FT_FACE( face )->internal->incremental_interface )
79#define IS_INCREMENTAL 0
90#define FT_COMPONENT t1load
93#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT
105 t1_allocate_blend( T1_Face face,
110 FT_Memory memory = face->root.memory;
111 FT_Error error = FT_Err_Ok;
117 if ( FT_NEW( blend ) )
120 blend->num_default_design_vector = 0;
121 blend->weight_vector = NULL;
122 blend->default_weight_vector = NULL;
123 blend->design_pos[0] = NULL;
129 if ( num_designs > 0 )
131 if ( blend->num_designs == 0 )
137 if ( FT_NEW_ARRAY( blend->font_infos[1], num_designs ) ||
138 FT_NEW_ARRAY( blend->privates [1], num_designs ) ||
139 FT_NEW_ARRAY( blend->bboxes [1], num_designs ) )
142 blend->font_infos[0] = &face->type1.font_info;
143 blend->privates [0] = &face->type1.private_dict;
144 blend->bboxes [0] = &face->type1.font_bbox;
146 for ( nn = 2; nn <= num_designs; nn++ )
148 blend->font_infos[nn] = blend->font_infos[nn - 1] + 1;
149 blend->privates [nn] = blend->privates [nn - 1] + 1;
150 blend->bboxes [nn] = blend->bboxes [nn - 1] + 1;
153 blend->num_designs = num_designs;
155 else if ( blend->num_designs != num_designs )
162 if ( blend->num_axis != 0 && blend->num_axis != num_axis )
165 blend->num_axis = num_axis;
172 error = FT_THROW( Invalid_File_Format );
177 FT_LOCAL_DEF( FT_Error )
178 T1_Get_Multi_Master( FT_Face face,
179 FT_Multi_Master* master )
181 T1_Face t1face = (T1_Face)face;
182 PS_Blend blend = t1face->blend;
187 error = FT_THROW( Invalid_Argument );
191 master->num_axis = blend->num_axis;
192 master->num_designs = blend->num_designs;
194 for ( n = 0; n < blend->num_axis; n++ )
196 FT_MM_Axis* axis = master->axis + n;
197 PS_DesignMap map = blend->design_map + n;
200 axis->name = blend->axis_names[n];
201 axis->minimum = map->design_points[0];
202 axis->maximum = map->design_points[map->num_points - 1];
218 mm_axis_unmap( PS_DesignMap axismap,
224 if ( ncv <= axismap->blend_points[0] )
225 return INT_TO_FIXED( axismap->design_points[0] );
227 for ( j = 1; j < axismap->num_points; j++ )
229 if ( ncv <= axismap->blend_points[j] )
230 return INT_TO_FIXED( axismap->design_points[j - 1] +
231 FT_MulDiv( ncv - axismap->blend_points[j - 1],
232 axismap->design_points[j] -
233 axismap->design_points[j - 1],
234 axismap->blend_points[j] -
235 axismap->blend_points[j - 1] ) );
238 return INT_TO_FIXED( axismap->design_points[axismap->num_points - 1] );
248 mm_weights_unmap( FT_Fixed* weights,
249 FT_Fixed* axiscoords,
252 FT_ASSERT( axis_count <= T1_MAX_MM_AXIS );
254 if ( axis_count == 1 )
255 axiscoords[0] = weights[1];
257 else if ( axis_count == 2 )
259 axiscoords[0] = weights[3] + weights[1];
260 axiscoords[1] = weights[3] + weights[2];
263 else if ( axis_count == 3 )
265 axiscoords[0] = weights[7] + weights[5] + weights[3] + weights[1];
266 axiscoords[1] = weights[7] + weights[6] + weights[3] + weights[2];
267 axiscoords[2] = weights[7] + weights[6] + weights[5] + weights[4];
272 axiscoords[0] = weights[15] + weights[13] + weights[11] + weights[9] +
273 weights[7] + weights[5] + weights[3] + weights[1];
274 axiscoords[1] = weights[15] + weights[14] + weights[11] + weights[10] +
275 weights[7] + weights[6] + weights[3] + weights[2];
276 axiscoords[2] = weights[15] + weights[14] + weights[13] + weights[12] +
277 weights[7] + weights[6] + weights[5] + weights[4];
278 axiscoords[3] = weights[15] + weights[14] + weights[13] + weights[12] +
279 weights[11] + weights[10] + weights[9] + weights[8];
289 FT_LOCAL_DEF( FT_Error )
290 T1_Get_MM_Var( FT_Face face,
293 T1_Face t1face = (T1_Face)face;
294 FT_Memory memory = FT_FACE_MEMORY( face );
295 FT_MM_Var *mmvar = NULL;
296 FT_Multi_Master mmaster;
299 FT_Fixed axiscoords[T1_MAX_MM_AXIS];
300 PS_Blend blend = t1face->blend;
301 FT_UShort* axis_flags;
303 FT_Offset mmvar_size;
304 FT_Offset axis_flags_size;
308 error = T1_Get_Multi_Master( face, &mmaster );
318#define ALIGN_SIZE( n ) \
319 ( ( (n) + sizeof (void*) - 1 ) & ~( sizeof (void*) - 1 ) )
321 mmvar_size = ALIGN_SIZE(
sizeof ( FT_MM_Var ) );
322 axis_flags_size = ALIGN_SIZE( mmaster.num_axis *
323 sizeof ( FT_UShort ) );
324 axis_size = mmaster.num_axis *
sizeof ( FT_Var_Axis );
326 if ( FT_QALLOC( mmvar, mmvar_size +
331 mmvar->num_axis = mmaster.num_axis;
332 mmvar->num_designs = mmaster.num_designs;
333 mmvar->num_namedstyles = 0;
338 axis_flags = (FT_UShort*)( (
char*)mmvar + mmvar_size );
339 FT_ARRAY_ZERO( axis_flags, mmaster.num_axis );
341 mmvar->axis = (FT_Var_Axis*)( (
char*)axis_flags + axis_flags_size );
342 mmvar->namedstyle = NULL;
344 for ( i = 0; i < mmaster.num_axis; i++ )
346 mmvar->axis[i].name = mmaster.axis[i].name;
347 mmvar->axis[i].minimum = INT_TO_FIXED( mmaster.axis[i].minimum );
348 mmvar->axis[i].maximum = INT_TO_FIXED( mmaster.axis[i].maximum );
349 mmvar->axis[i].strid = ~0U;
350 mmvar->axis[i].tag = ~0U;
352 if ( !mmvar->axis[i].name )
355 if ( ft_strcmp( mmvar->axis[i].name,
"Weight" ) == 0 )
356 mmvar->axis[i].tag = FT_MAKE_TAG(
'w',
'g',
'h',
't' );
357 else if ( ft_strcmp( mmvar->axis[i].name,
"Width" ) == 0 )
358 mmvar->axis[i].tag = FT_MAKE_TAG(
'w',
'd',
't',
'h' );
359 else if ( ft_strcmp( mmvar->axis[i].name,
"OpticalSize" ) == 0 )
360 mmvar->axis[i].tag = FT_MAKE_TAG(
'o',
'p',
's',
'z' );
361 else if ( ft_strcmp( mmvar->axis[i].name,
"Slant" ) == 0 )
362 mmvar->axis[i].tag = FT_MAKE_TAG(
's',
'l',
'n',
't' );
363 else if ( ft_strcmp( mmvar->axis[i].name,
"Italic" ) == 0 )
364 mmvar->axis[i].tag = FT_MAKE_TAG(
'i',
't',
'a',
'l' );
367 mm_weights_unmap( blend->default_weight_vector,
371 for ( i = 0; i < mmaster.num_axis; i++ )
372 mmvar->axis[i].def = mm_axis_unmap( &blend->design_map[i],
383 t1_set_mm_blend( T1_Face face,
387 PS_Blend blend = face->blend;
390 FT_Bool have_diff = 0;
394 return FT_THROW( Invalid_Argument );
396 if ( num_coords > blend->num_axis )
397 num_coords = blend->num_axis;
400 for ( n = 0; n < blend->num_designs; n++ )
402 FT_Fixed result = 0x10000L;
406 for ( m = 0; m < blend->num_axis; m++ )
409 if ( m >= num_coords )
417 if ( ( n & ( 1 << m ) ) == 0 )
418 factor = 0x10000L - factor;
425 else if ( factor >= 0x10000L )
428 result = FT_MulFix( result, factor );
431 if ( blend->weight_vector[n] != result )
433 blend->weight_vector[n] = result;
439 return have_diff ? FT_Err_Ok : -1;
443 FT_LOCAL_DEF( FT_Error )
444 T1_Set_MM_Blend( FT_Face face,
448 return t1_set_mm_blend( (T1_Face)face, num_coords, coords );
452 FT_LOCAL_DEF( FT_Error )
453 T1_Get_MM_Blend( FT_Face face,
457 T1_Face t1face = (T1_Face)face;
458 PS_Blend blend = t1face->blend;
460 FT_Fixed axiscoords[4];
465 return FT_THROW( Invalid_Argument );
467 mm_weights_unmap( blend->weight_vector,
472 if ( num_coords > blend->num_axis )
474 FT_TRACE2((
"T1_Get_MM_Blend: only using first %u of %u coordinates\n",
475 blend->num_axis, num_coords ));
476 nc = blend->num_axis;
479 for ( i = 0; i < nc; i++ )
480 coords[i] = axiscoords[i];
481 for ( ; i < num_coords; i++ )
488 FT_LOCAL_DEF( FT_Error )
489 T1_Set_MM_WeightVector( FT_Face face,
491 FT_Fixed* weightvector )
493 T1_Face t1face = (T1_Face)face;
494 PS_Blend blend = t1face->blend;
499 return FT_THROW( Invalid_Argument );
501 if ( !len && !weightvector )
503 for ( i = 0; i < blend->num_designs; i++ )
504 blend->weight_vector[i] = blend->default_weight_vector[i];
509 return FT_THROW( Invalid_Argument );
511 n = len < blend->num_designs ? len : blend->num_designs;
513 for ( i = 0; i < n; i++ )
514 blend->weight_vector[i] = weightvector[i];
516 for ( ; i < blend->num_designs; i++ )
517 blend->weight_vector[i] = (FT_Fixed)0;
524 FT_LOCAL_DEF( FT_Error )
525 T1_Get_MM_WeightVector( FT_Face face,
527 FT_Fixed* weightvector )
529 T1_Face t1face = (T1_Face)face;
530 PS_Blend blend = t1face->blend;
535 return FT_THROW( Invalid_Argument );
537 if ( *len < blend->num_designs )
539 *len = blend->num_designs;
540 return FT_THROW( Invalid_Argument );
543 for ( i = 0; i < blend->num_designs; i++ )
544 weightvector[i] = blend->weight_vector[i];
545 for ( ; i < *len; i++ )
546 weightvector[i] = (FT_Fixed)0;
548 *len = blend->num_designs;
554 FT_LOCAL_DEF( FT_Error )
555 T1_Set_MM_Design( FT_Face face,
559 T1_Face t1face = (T1_Face)face;
561 PS_Blend blend = t1face->blend;
563 FT_Fixed final_blends[T1_MAX_MM_DESIGNS];
567 return FT_THROW( Invalid_Argument );
569 if ( num_coords > blend->num_axis )
570 num_coords = blend->num_axis;
574 for ( n = 0; n < blend->num_axis; n++ )
578 PS_DesignMap map = blend->design_map + n;
579 FT_Long* designs = map->design_points;
580 FT_Fixed* blends = map->blend_points;
581 FT_Int p, before = -1, after = -1;
585 if ( n < num_coords )
588 design = ( designs[map->num_points - 1] - designs[0] ) / 2;
590 for ( p = 0; p < (FT_Int)map->num_points; p++ )
592 FT_Long p_design = designs[p];
596 if ( design == p_design )
598 the_blend = blends[p];
602 if ( design < p_design )
613 the_blend = blends[0];
615 else if ( after < 0 )
616 the_blend = blends[map->num_points - 1];
619 the_blend = FT_MulDiv( design - designs[before],
620 blends [after] - blends [before],
621 designs[after] - designs[before] );
624 final_blends[n] = the_blend;
627 error = t1_set_mm_blend( t1face, blend->num_axis, final_blends );
637 FT_LOCAL_DEF( FT_Error )
638 T1_Reset_MM_Blend( FT_Face face,
639 FT_UInt instance_index )
641 FT_UNUSED( instance_index );
643 return T1_Set_MM_WeightVector( face, 0, NULL );
652 FT_LOCAL_DEF( FT_Error )
653 T1_Set_Var_Design( FT_Face face,
657 FT_Long lcoords[T1_MAX_MM_AXIS];
661 if ( num_coords > T1_MAX_MM_AXIS )
662 num_coords = T1_MAX_MM_AXIS;
664 for ( i = 0; i < num_coords; i++ )
665 lcoords[i] = FIXED_TO_INT( coords[i] );
667 return T1_Set_MM_Design( face, num_coords, lcoords );
671 FT_LOCAL_DEF( FT_Error )
672 T1_Get_Var_Design( FT_Face face,
676 T1_Face t1face = (T1_Face)face;
677 PS_Blend blend = t1face->blend;
679 FT_Fixed axiscoords[4];
684 return FT_THROW( Invalid_Argument );
686 mm_weights_unmap( blend->weight_vector,
691 if ( num_coords > blend->num_axis )
693 FT_TRACE2((
"T1_Get_Var_Design:"
694 " only using first %u of %u coordinates\n",
695 blend->num_axis, num_coords ));
696 nc = blend->num_axis;
699 for ( i = 0; i < nc; i++ )
700 coords[i] = mm_axis_unmap( &blend->design_map[i], axiscoords[i] );
701 for ( ; i < num_coords; i++ )
709 T1_Done_Blend( FT_Face face )
711 T1_Face t1face = (T1_Face)face;
712 FT_Memory memory = FT_FACE_MEMORY( face );
713 PS_Blend blend = t1face->blend;
718 FT_UInt num_designs = blend->num_designs;
719 FT_UInt num_axis = blend->num_axis;
724 FT_FREE( blend->design_pos[0] );
725 for ( n = 1; n < num_designs; n++ )
726 blend->design_pos[n] = NULL;
729 FT_FREE( blend->privates[1] );
730 FT_FREE( blend->font_infos[1] );
731 FT_FREE( blend->bboxes[1] );
733 for ( n = 0; n < num_designs; n++ )
735 blend->privates [n] = NULL;
736 blend->font_infos[n] = NULL;
737 blend->bboxes [n] = NULL;
741 FT_FREE( blend->weight_vector );
742 blend->default_weight_vector = NULL;
745 for ( n = 0; n < num_axis; n++ )
746 FT_FREE( blend->axis_names[n] );
749 for ( n = 0; n < num_axis; n++ )
751 PS_DesignMap dmap = blend->design_map + n;
754 FT_FREE( dmap->blend_points );
755 FT_FREE( dmap->design_points );
756 dmap->num_points = 0;
759 FT_FREE( t1face->blend );
765 parse_blend_axis_types( FT_Face face,
768 T1_Face t1face = (T1_Face)face;
769 T1_Loader loader = (T1_Loader)loader_;
770 T1_TokenRec axis_tokens[T1_MAX_MM_AXIS];
772 FT_Error error = FT_Err_Ok;
774 FT_Memory memory = FT_FACE_MEMORY( face );
778 T1_ToTokenArray( &loader->parser, axis_tokens,
779 T1_MAX_MM_AXIS, &num_axis );
782 error = FT_ERR( Ignore );
785 if ( num_axis == 0 || num_axis > T1_MAX_MM_AXIS )
787 FT_ERROR((
"parse_blend_axis_types: incorrect number of axes: %d\n",
789 error = FT_THROW( Invalid_File_Format );
794 error = t1_allocate_blend( t1face, 0, (FT_UInt)num_axis );
800 blend = t1face->blend;
803 for ( n = 0; n < num_axis; n++ )
805 T1_Token token = axis_tokens + n;
811 if ( token->start[0] ==
'/' )
814 len = (FT_UInt)( token->limit - token->start );
817 error = FT_THROW( Invalid_File_Format );
821 FT_TRACE4((
" /%.*s", len, token->start ));
823 name = (FT_Byte*)blend->axis_names[n];
826 FT_TRACE0((
"parse_blend_axis_types:"
827 " overwriting axis name `%s' with `%.*s'\n",
828 name, len, token->start ));
832 if ( FT_QALLOC( blend->axis_names[n], len + 1 ) )
835 name = (FT_Byte*)blend->axis_names[n];
836 FT_MEM_COPY( name, token->start, len );
840 FT_TRACE4((
"]\n" ));
843 loader->parser.root.error = error;
848 parse_blend_design_positions( FT_Face face,
851 T1_Face t1face = (T1_Face)face;
852 T1_Loader loader = (T1_Loader)loader_;
853 T1_TokenRec design_tokens[T1_MAX_MM_DESIGNS];
856 T1_Parser parser = &loader->parser;
857 FT_Memory memory = FT_FACE_MEMORY( face );
858 FT_Error error = FT_Err_Ok;
859 FT_Fixed* design_pos[T1_MAX_MM_DESIGNS];
862 design_pos[0] = NULL;
865 T1_ToTokenArray( parser, design_tokens,
866 T1_MAX_MM_DESIGNS, &num_designs );
867 if ( num_designs < 0 )
869 error = FT_ERR( Ignore );
872 if ( num_designs == 0 || num_designs > T1_MAX_MM_DESIGNS )
874 FT_ERROR((
"parse_blend_design_positions:"
875 " incorrect number of designs: %d\n",
877 error = FT_THROW( Invalid_File_Format );
882 FT_Byte* old_cursor = parser->root.cursor;
883 FT_Byte* old_limit = parser->root.limit;
890 for ( n = 0; n < num_designs; n++ )
892 T1_TokenRec axis_tokens[T1_MAX_MM_AXIS];
898 token = design_tokens + n;
899 parser->root.cursor = token->start;
900 parser->root.limit = token->limit;
901 T1_ToTokenArray( parser, axis_tokens, T1_MAX_MM_AXIS, &n_axis );
905 if ( n_axis <= 0 || n_axis > T1_MAX_MM_AXIS )
907 FT_ERROR((
"parse_blend_design_positions:"
908 " invalid number of axes: %d\n",
910 error = FT_THROW( Invalid_File_Format );
915 error = t1_allocate_blend( t1face,
916 (FT_UInt)num_designs,
922 if ( FT_QNEW_ARRAY( design_pos[0], num_designs * num_axis ) )
925 for ( nn = 1; nn < num_designs; nn++ )
926 design_pos[nn] = design_pos[0] + num_axis * nn;
928 else if ( n_axis != num_axis )
930 FT_ERROR((
"parse_blend_design_positions: incorrect table\n" ));
931 error = FT_THROW( Invalid_File_Format );
936 FT_TRACE4((
" [" )) ;
937 for ( axis = 0; axis < n_axis; axis++ )
939 T1_Token token2 = axis_tokens + axis;
942 parser->root.cursor = token2->start;
943 parser->root.limit = token2->limit;
944 design_pos[n][axis] = T1_ToFixed( parser, 0 );
945 FT_TRACE4((
" %f", (
double)design_pos[n][axis] / 65536 ));
950 FT_TRACE4((
"]\n" ));
952 loader->parser.root.cursor = old_cursor;
953 loader->parser.root.limit = old_limit;
956 blend = t1face->blend;
957 if ( blend->design_pos[0] )
958 FT_FREE( blend->design_pos[0] );
960 for ( n = 0; n < num_designs; n++ )
962 blend->design_pos[n] = design_pos[n];
963 design_pos[n] = NULL;
968 FT_FREE( design_pos[0] );
969 loader->parser.root.error = error;
974 parse_blend_design_map( FT_Face face,
977 T1_Face t1face = (T1_Face)face;
978 T1_Loader loader = (T1_Loader)loader_;
979 FT_Error error = FT_Err_Ok;
980 T1_Parser parser = &loader->parser;
982 T1_TokenRec axis_tokens[T1_MAX_MM_AXIS];
986 FT_Memory memory = FT_FACE_MEMORY( face );
989 T1_ToTokenArray( parser, axis_tokens,
990 T1_MAX_MM_AXIS, &num_axis );
993 error = FT_ERR( Ignore );
996 if ( num_axis == 0 || num_axis > T1_MAX_MM_AXIS )
998 FT_ERROR((
"parse_blend_design_map: incorrect number of axes: %d\n",
1000 error = FT_THROW( Invalid_File_Format );
1004 old_cursor = parser->root.cursor;
1005 old_limit = parser->root.limit;
1007 error = t1_allocate_blend( t1face, 0, (FT_UInt)num_axis );
1010 blend = t1face->blend;
1012 FT_TRACE4((
" [" ));
1015 for ( n = 0; n < num_axis; n++ )
1017 PS_DesignMap map = blend->design_map + n;
1018 T1_Token axis_token;
1019 T1_TokenRec point_tokens[T1_MAX_MM_MAP_POINTS];
1020 FT_Int p, num_points;
1023 axis_token = axis_tokens + n;
1025 parser->root.cursor = axis_token->start;
1026 parser->root.limit = axis_token->limit;
1027 T1_ToTokenArray( parser, point_tokens,
1028 T1_MAX_MM_MAP_POINTS, &num_points );
1030 FT_TRACE4((
" [" ));
1032 if ( num_points <= 0 || num_points > T1_MAX_MM_MAP_POINTS )
1034 FT_ERROR((
"parse_blend_design_map: incorrect table\n" ));
1035 error = FT_THROW( Invalid_File_Format );
1039 if ( map->design_points )
1041 FT_ERROR((
"parse_blend_design_map: duplicate table\n" ));
1042 error = FT_THROW( Invalid_File_Format );
1047 if ( FT_QNEW_ARRAY( map->design_points, num_points ) ||
1048 FT_QNEW_ARRAY( map->blend_points, num_points ) )
1050 map->num_points = (FT_Byte)num_points;
1052 for ( p = 0; p < num_points; p++ )
1054 T1_Token point_token;
1057 point_token = point_tokens + p;
1060 parser->root.cursor = point_token->start + 1;
1061 parser->root.limit = point_token->limit - 1;
1063 map->design_points[p] = T1_ToInt( parser );
1064 map->blend_points [p] = T1_ToFixed( parser, 0 );
1066 FT_TRACE4((
" [%ld %f]",
1067 map->design_points[p],
1068 (
double)map->blend_points[p] / 65536 ));
1074 FT_TRACE4((
"]\n" ));
1076 parser->root.cursor = old_cursor;
1077 parser->root.limit = old_limit;
1080 parser->root.error = error;
1085 parse_weight_vector( FT_Face face,
1088 T1_Face t1face = (T1_Face)face;
1089 T1_Loader loader = (T1_Loader)loader_;
1090 T1_TokenRec design_tokens[T1_MAX_MM_DESIGNS];
1092 FT_Error error = FT_Err_Ok;
1093 FT_Memory memory = FT_FACE_MEMORY( face );
1094 T1_Parser parser = &loader->parser;
1095 PS_Blend blend = t1face->blend;
1098 FT_Byte* old_cursor;
1102 T1_ToTokenArray( parser, design_tokens,
1103 T1_MAX_MM_DESIGNS, &num_designs );
1104 if ( num_designs < 0 )
1106 error = FT_ERR( Ignore );
1109 if ( num_designs == 0 || num_designs > T1_MAX_MM_DESIGNS )
1111 FT_ERROR((
"parse_weight_vector:"
1112 " incorrect number of designs: %d\n",
1114 error = FT_THROW( Invalid_File_Format );
1118 if ( !blend || !blend->num_designs )
1120 error = t1_allocate_blend( t1face, (FT_UInt)num_designs, 0 );
1123 blend = t1face->blend;
1125 else if ( blend->num_designs != (FT_UInt)num_designs )
1127 FT_ERROR((
"parse_weight_vector:"
1128 " /BlendDesignPosition and /WeightVector have\n" ));
1130 " different number of elements\n" ));
1131 error = FT_THROW( Invalid_File_Format );
1135 if ( !blend->weight_vector )
1136 if ( FT_QNEW_ARRAY( blend->weight_vector, num_designs * 2 ) )
1139 blend->default_weight_vector = blend->weight_vector + num_designs;
1141 old_cursor = parser->root.cursor;
1142 old_limit = parser->root.limit;
1146 for ( n = 0; n < num_designs; n++ )
1148 token = design_tokens + n;
1149 parser->root.cursor = token->start;
1150 parser->root.limit = token->limit;
1152 blend->default_weight_vector[n] =
1153 blend->weight_vector[n] = T1_ToFixed( parser, 0 );
1155 FT_TRACE4((
" %f", (
double)blend->weight_vector[n] / 65536 ));
1158 FT_TRACE4((
"]\n" ));
1160 parser->root.cursor = old_cursor;
1161 parser->root.limit = old_limit;
1164 parser->root.error = error;
1171 parse_buildchar( FT_Face face,
1174 T1_Face t1face = (T1_Face)face;
1175 T1_Loader loader = (T1_Loader)loader_;
1178 t1face->len_buildchar = (FT_UInt)T1_ToFixedArray( &loader->parser,
1181#ifdef FT_DEBUG_LEVEL_TRACE
1186 FT_TRACE4((
" [" ));
1187 for ( i = 0; i < t1face->len_buildchar; i++ )
1188 FT_TRACE4((
" 0" ));
1190 FT_TRACE4((
"]\n" ));
1212 t1_load_keyword( T1_Face face,
1214 const T1_Field field )
1219 FT_UInt max_objects;
1220 PS_Blend blend = face->blend;
1223 if ( blend && blend->num_designs == 0 )
1227 if ( field->type == T1_FIELD_TYPE_CALLBACK )
1229 FT_TRACE4((
" %s", field->ident ));
1231 field->reader( (FT_Face)face, loader );
1232 error = loader->parser.root.error;
1238 switch ( field->location )
1240 case T1_FIELD_LOCATION_FONT_INFO:
1241 dummy_object = &face->type1.font_info;
1242 objects = &dummy_object;
1247 objects = (
void**)blend->font_infos;
1248 max_objects = blend->num_designs;
1252 case T1_FIELD_LOCATION_FONT_EXTRA:
1253 dummy_object = &face->type1.font_extra;
1254 objects = &dummy_object;
1258 case T1_FIELD_LOCATION_PRIVATE:
1259 dummy_object = &face->type1.private_dict;
1260 objects = &dummy_object;
1265 objects = (
void**)blend->privates;
1266 max_objects = blend->num_designs;
1270 case T1_FIELD_LOCATION_BBOX:
1271 dummy_object = &face->type1.font_bbox;
1272 objects = &dummy_object;
1277 objects = (
void**)blend->bboxes;
1278 max_objects = blend->num_designs;
1282 case T1_FIELD_LOCATION_LOADER:
1283 dummy_object = loader;
1284 objects = &dummy_object;
1288 case T1_FIELD_LOCATION_FACE:
1289 dummy_object = face;
1290 objects = &dummy_object;
1294#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT
1295 case T1_FIELD_LOCATION_BLEND:
1296 dummy_object = face->blend;
1297 objects = &dummy_object;
1303 dummy_object = &face->type1;
1304 objects = &dummy_object;
1308 FT_TRACE4((
" %s", field->ident ));
1312 if ( field->type == T1_FIELD_TYPE_INTEGER_ARRAY ||
1313 field->type == T1_FIELD_TYPE_FIXED_ARRAY )
1314 error = T1_Load_Field_Table( &loader->parser, field,
1315 objects, max_objects, 0 );
1317 error = T1_Load_Field( &loader->parser, field,
1318 objects, max_objects, 0 );
1322 FT_TRACE1((
"t1_load_keyword: ignoring keyword `%s'"
1323 " which is not valid at this point\n",
1325 FT_TRACE1((
" (probably due to missing keywords)\n" ));
1329 FT_TRACE4((
"\n" ));
1337 parse_private( FT_Face face,
1340 T1_Loader loader = (T1_Loader)loader_;
1343 loader->keywords_encountered |= T1_PRIVATE;
1345 FT_TRACE4((
"\n" ));
1352 read_binary_data( T1_Parser parser,
1355 FT_Bool incremental )
1358 FT_Byte* limit = parser->root.limit;
1367 T1_Skip_Spaces( parser );
1369 cur = parser->root.cursor;
1371 if ( cur < limit && ft_isdigit( *cur ) )
1373 FT_Long s = T1_ToInt( parser );
1376 T1_Skip_PS_Token( parser );
1380 *base = parser->root.cursor + 1;
1382 if ( s >= 0 && s < limit - *base )
1384 parser->root.cursor += s + 1;
1385 *size = (FT_ULong)s;
1386 return !parser->root.error;
1392 FT_ERROR((
"read_binary_data: invalid size field\n" ));
1393 parser->root.error = FT_THROW( Invalid_File_Format );
1404 t1_parse_font_matrix( FT_Face face,
1407 T1_Face t1face = (T1_Face)face;
1408 T1_Loader loader = (T1_Loader)loader_;
1409 T1_Parser parser = &loader->parser;
1410 FT_Matrix* matrix = &t1face->type1.font_matrix;
1411 FT_Vector* offset = &t1face->type1.font_offset;
1413 FT_Fixed temp_scale;
1418 result = T1_ToFixedArray( parser, 6, temp, 3 );
1422 parser->root.error = FT_THROW( Invalid_File_Format );
1426 FT_TRACE4((
" [%f %f %f %f %f %f]\n",
1427 (
double)temp[0] / 65536 / 1000,
1428 (
double)temp[1] / 65536 / 1000,
1429 (
double)temp[2] / 65536 / 1000,
1430 (
double)temp[3] / 65536 / 1000,
1431 (
double)temp[4] / 65536 / 1000,
1432 (
double)temp[5] / 65536 / 1000 ));
1434 temp_scale = FT_ABS( temp[3] );
1436 if ( temp_scale == 0 )
1438 FT_ERROR((
"t1_parse_font_matrix: invalid font matrix\n" ));
1439 parser->root.error = FT_THROW( Invalid_File_Format );
1444 if ( temp_scale != 0x10000L )
1447 face->units_per_EM = (FT_UShort)FT_DivFix( 1000, temp_scale );
1449 temp[0] = FT_DivFix( temp[0], temp_scale );
1450 temp[1] = FT_DivFix( temp[1], temp_scale );
1451 temp[2] = FT_DivFix( temp[2], temp_scale );
1452 temp[4] = FT_DivFix( temp[4], temp_scale );
1453 temp[5] = FT_DivFix( temp[5], temp_scale );
1454 temp[3] = temp[3] < 0 ? -0x10000L : 0x10000L;
1456 matrix->xx = temp[0];
1457 matrix->yx = temp[1];
1458 matrix->xy = temp[2];
1459 matrix->yy = temp[3];
1461 if ( !FT_Matrix_Check( matrix ) )
1463 FT_ERROR((
"t1_parse_font_matrix: invalid font matrix\n" ));
1464 parser->root.error = FT_THROW( Invalid_File_Format );
1469 offset->x = temp[4] >> 16;
1470 offset->y = temp[5] >> 16;
1475 parse_encoding( FT_Face face,
1478 T1_Face t1face = (T1_Face)face;
1479 T1_Loader loader = (T1_Loader)loader_;
1480 T1_Parser parser = &loader->parser;
1482 FT_Byte* limit = parser->root.limit;
1484 PSAux_Service psaux = (PSAux_Service)t1face->psaux;
1487 T1_Skip_Spaces( parser );
1488 cur = parser->root.cursor;
1491 FT_ERROR((
"parse_encoding: out of bounds\n" ));
1492 parser->root.error = FT_THROW( Invalid_File_Format );
1498 if ( ft_isdigit( *cur ) || *cur ==
'[' )
1500 T1_Encoding encode = &t1face->type1.encoding;
1501 FT_Int count, array_size, n;
1502 PS_Table char_table = &loader->encoding_table;
1503 FT_Memory memory = parser->root.memory;
1505 FT_Bool only_immediates = 0;
1512 only_immediates = 1;
1513 parser->root.cursor++;
1516 count = (FT_Int)T1_ToInt( parser );
1521 FT_TRACE2((
"parse_encoding:"
1522 " only using first 256 encoding array entries\n" ));
1526 T1_Skip_Spaces( parser );
1527 if ( parser->root.cursor >= limit )
1531 if ( encode->char_index )
1533 FT_FREE( encode->char_index );
1534 FT_FREE( encode->char_name );
1535 T1_Release_Table( char_table );
1539 loader->num_chars = encode->num_chars = array_size;
1540 if ( FT_QNEW_ARRAY( encode->char_index, array_size ) ||
1541 FT_QNEW_ARRAY( encode->char_name, array_size ) ||
1542 FT_SET_ERROR( psaux->ps_table_funcs->init(
1543 char_table, array_size, memory ) ) )
1545 parser->root.error = error;
1550 for ( n = 0; n < array_size; n++ )
1551 (
void)T1_Add_Table( char_table, n,
".notdef", 8 );
1574 T1_Skip_Spaces( parser );
1576 while ( parser->root.cursor < limit )
1578 cur = parser->root.cursor;
1581 if ( *cur ==
'd' && cur + 3 < limit )
1583 if ( cur[1] ==
'e' &&
1585 IS_PS_DELIM( cur[3] ) )
1587 FT_TRACE6((
"encoding end\n" ));
1594 FT_TRACE6((
"encoding end\n" ));
1600 if ( ft_isdigit( *cur ) || only_immediates )
1605 if ( only_immediates )
1609 charcode = (FT_Int)T1_ToInt( parser );
1610 T1_Skip_Spaces( parser );
1613 if ( cur == parser->root.cursor )
1615 parser->root.error = FT_THROW( Unknown_File_Format );
1620 cur = parser->root.cursor;
1622 if ( cur + 2 < limit && *cur ==
'/' && n < count )
1629 parser->root.cursor = cur;
1630 T1_Skip_PS_Token( parser );
1631 if ( parser->root.cursor >= limit )
1633 if ( parser->root.error )
1636 len = (FT_UInt)( parser->root.cursor - cur );
1638 if ( n < array_size )
1640 parser->root.error = T1_Add_Table( char_table, charcode,
1642 if ( parser->root.error )
1644 char_table->elements[charcode][len] =
'\0';
1649 else if ( only_immediates )
1659 parser->root.error = FT_THROW( Unknown_File_Format );
1665 T1_Skip_PS_Token( parser );
1666 if ( parser->root.error )
1670 T1_Skip_Spaces( parser );
1673#ifdef FT_DEBUG_LEVEL_TRACE
1674 FT_TRACE4((
" [" ));
1677 FT_TRACE4((
"..." ));
1679 FT_TRACE4((
"]\n" ));
1682 t1face->type1.encoding_type = T1_ENCODING_TYPE_ARRAY;
1683 parser->root.cursor = cur;
1690 if ( cur + 17 < limit &&
1691 ft_strncmp( (
const char*)cur,
"StandardEncoding", 16 ) == 0 )
1693 t1face->type1.encoding_type = T1_ENCODING_TYPE_STANDARD;
1694 FT_TRACE4((
" StandardEncoding\n" ));
1697 else if ( cur + 15 < limit &&
1698 ft_strncmp( (
const char*)cur,
"ExpertEncoding", 14 ) == 0 )
1700 t1face->type1.encoding_type = T1_ENCODING_TYPE_EXPERT;
1701 FT_TRACE4((
" ExpertEncoding\n" ));
1704 else if ( cur + 18 < limit &&
1705 ft_strncmp( (
const char*)cur,
"ISOLatin1Encoding", 17 ) == 0 )
1707 t1face->type1.encoding_type = T1_ENCODING_TYPE_ISOLATIN1;
1708 FT_TRACE4((
" ISOLatin1Encoding\n" ));
1713 parser->root.error = FT_ERR( Ignore );
1714 FT_TRACE4((
"<unknown>\n" ));
1721 parse_subrs( FT_Face face,
1724 T1_Face t1face = (T1_Face)face;
1725 T1_Loader loader = (T1_Loader)loader_;
1726 T1_Parser parser = &loader->parser;
1727 PS_Table table = &loader->subrs;
1728 FT_Memory memory = parser->root.memory;
1733 PSAux_Service psaux = (PSAux_Service)t1face->psaux;
1736 T1_Skip_Spaces( parser );
1739 if ( parser->root.cursor < parser->root.limit &&
1740 *parser->root.cursor ==
'[' )
1742 T1_Skip_PS_Token( parser );
1743 T1_Skip_Spaces ( parser );
1744 if ( parser->root.cursor >= parser->root.limit ||
1745 *parser->root.cursor !=
']' )
1746 parser->root.error = FT_THROW( Invalid_File_Format );
1750 num_subrs = (FT_Int)T1_ToInt( parser );
1751 if ( num_subrs < 0 )
1753 parser->root.error = FT_THROW( Invalid_File_Format );
1758 if ( parser->root.limit >= parser->root.cursor &&
1759 num_subrs > ( parser->root.limit - parser->root.cursor ) >> 3 )
1776 FT_TRACE0((
"parse_subrs: adjusting number of subroutines"
1777 " (from %d to %zu)\n",
1779 ( parser->root.limit - parser->root.cursor ) >> 3 ));
1780 num_subrs = ( parser->root.limit - parser->root.cursor ) >> 3;
1782 if ( !loader->subrs_hash )
1784 if ( FT_QNEW( loader->subrs_hash ) )
1787 error = ft_hash_num_init( loader->subrs_hash, memory );
1794 T1_Skip_PS_Token( parser );
1795 if ( parser->root.error )
1797 T1_Skip_Spaces( parser );
1801 if ( !loader->num_subrs )
1803 error = psaux->ps_table_funcs->init( table, num_subrs, memory );
1812 for ( count = 0; ; count++ )
1821 if ( parser->root.cursor + 4 >= parser->root.limit ||
1822 ft_strncmp( (
char*)parser->root.cursor,
"dup", 3 ) != 0 )
1825 T1_Skip_PS_Token( parser );
1827 idx = T1_ToInt( parser );
1829 if ( !read_binary_data( parser, &size, &base, IS_INCREMENTAL ) )
1836 T1_Skip_PS_Token( parser );
1837 if ( parser->root.error )
1839 T1_Skip_Spaces ( parser );
1841 if ( parser->root.cursor + 4 < parser->root.limit &&
1842 ft_strncmp( (
char*)parser->root.cursor,
"put", 3 ) == 0 )
1844 T1_Skip_PS_Token( parser );
1845 T1_Skip_Spaces ( parser );
1850 if ( loader->subrs_hash )
1852 ft_hash_num_insert( idx, count, loader->subrs_hash, memory );
1857 if ( loader->num_subrs )
1865 if ( t1face->type1.private_dict.lenIV >= 0 )
1867 FT_Byte* temp = NULL;
1873 if ( size < (FT_ULong)t1face->type1.private_dict.lenIV )
1875 error = FT_THROW( Invalid_File_Format );
1880 if ( FT_DUP( temp, base, size ) )
1882 psaux->t1_decrypt( temp, size, 4330 );
1883 size -= (FT_ULong)t1face->type1.private_dict.lenIV;
1884 error = T1_Add_Table( table,
1886 temp + t1face->type1.private_dict.lenIV,
1891 error = T1_Add_Table( table, (FT_Int)idx, base, size );
1896 if ( !loader->num_subrs )
1897 loader->num_subrs = num_subrs;
1899#ifdef FT_DEBUG_LEVEL_TRACE
1900 FT_TRACE4((
" <" ));
1903 FT_TRACE4((
"%d elements", num_subrs ));
1905 FT_TRACE4((
">\n" ));
1911 parser->root.error = error;
1915#define TABLE_EXTEND 5
1919 parse_charstrings( FT_Face face,
1922 T1_Face t1face = (T1_Face)face;
1923 T1_Loader loader = (T1_Loader)loader_;
1924 T1_Parser parser = &loader->parser;
1925 PS_Table code_table = &loader->charstrings;
1926 PS_Table name_table = &loader->glyph_names;
1927 PS_Table swap_table = &loader->swap_table;
1928 FT_Memory memory = parser->root.memory;
1931 PSAux_Service psaux = (PSAux_Service)t1face->psaux;
1933 FT_Byte* cur = parser->root.cursor;
1934 FT_Byte* limit = parser->root.limit;
1935 FT_Int n, num_glyphs;
1936 FT_Int notdef_index = 0;
1937 FT_Byte notdef_found = 0;
1940 num_glyphs = (FT_Int)T1_ToInt( parser );
1941 if ( num_glyphs < 0 )
1943 error = FT_THROW( Invalid_File_Format );
1948 if ( num_glyphs > ( limit - cur ) >> 3 )
1950 FT_TRACE0((
"parse_charstrings: adjusting number of glyphs"
1951 " (from %d to %zu)\n",
1952 num_glyphs, ( limit - cur ) >> 3 ));
1953 num_glyphs = ( limit - cur ) >> 3;
1958 if ( num_glyphs == 0 || parser->root.error )
1968 if ( !loader->num_glyphs )
1970 error = psaux->ps_table_funcs->init(
1971 code_table, num_glyphs + 1 + TABLE_EXTEND, memory );
1975 error = psaux->ps_table_funcs->init(
1976 name_table, num_glyphs + 1 + TABLE_EXTEND, memory );
1983 error = psaux->ps_table_funcs->init( swap_table, 4, memory );
1999 T1_Skip_Spaces( parser );
2001 cur = parser->root.cursor;
2006 if ( cur + 3 < limit && IS_PS_DELIM( cur[3] ) )
2008 if ( cur[0] ==
'd' &&
2026 if ( cur[0] ==
'e' &&
2032 T1_Skip_PS_Token( parser );
2033 if ( parser->root.cursor >= limit )
2035 error = FT_THROW( Invalid_File_Format );
2038 if ( parser->root.error )
2046 if ( cur + 2 >= limit )
2048 error = FT_THROW( Invalid_File_Format );
2053 len = (FT_UInt)( parser->root.cursor - cur );
2055 if ( !read_binary_data( parser, &size, &base, IS_INCREMENTAL ) )
2061 if ( loader->num_glyphs )
2064 error = T1_Add_Table( name_table, n, cur, len + 1 );
2069 name_table->elements[n][len] =
'\0';
2073 ft_strcmp(
".notdef",
2074 (
const char*)( name_table->elements[n] ) ) == 0 )
2080 if ( t1face->type1.private_dict.lenIV >= 0 &&
2081 n < num_glyphs + TABLE_EXTEND )
2083 FT_Byte* temp = NULL;
2086 if ( size <= (FT_ULong)t1face->type1.private_dict.lenIV )
2088 error = FT_THROW( Invalid_File_Format );
2093 if ( FT_DUP( temp, base, size ) )
2095 psaux->t1_decrypt( temp, size, 4330 );
2096 size -= (FT_ULong)t1face->type1.private_dict.lenIV;
2097 error = T1_Add_Table( code_table,
2099 temp + t1face->type1.private_dict.lenIV,
2104 error = T1_Add_Table( code_table, n, base, size );
2114 error = FT_THROW( Invalid_File_Format );
2118 loader->num_glyphs = n;
2121 if ( notdef_found &&
2122 ft_strcmp(
".notdef", (
const char*)name_table->elements[0] ) )
2131 error = T1_Add_Table( swap_table, 0,
2132 name_table->elements[0],
2133 name_table->lengths [0] );
2138 error = T1_Add_Table( swap_table, 1,
2139 code_table->elements[0],
2140 code_table->lengths [0] );
2145 error = T1_Add_Table( swap_table, 2,
2146 name_table->elements[notdef_index],
2147 name_table->lengths [notdef_index] );
2152 error = T1_Add_Table( swap_table, 3,
2153 code_table->elements[notdef_index],
2154 code_table->lengths [notdef_index] );
2158 error = T1_Add_Table( name_table, notdef_index,
2159 swap_table->elements[0],
2160 swap_table->lengths [0] );
2164 error = T1_Add_Table( code_table, notdef_index,
2165 swap_table->elements[1],
2166 swap_table->lengths [1] );
2170 error = T1_Add_Table( name_table, 0,
2171 swap_table->elements[2],
2172 swap_table->lengths [2] );
2176 error = T1_Add_Table( code_table, 0,
2177 swap_table->elements[3],
2178 swap_table->lengths [3] );
2183 else if ( !notdef_found )
2191 FT_Byte notdef_glyph[] = { 0x8B, 0xF7, 0xE1, 0x0D, 0x0E };
2194 error = T1_Add_Table( swap_table, 0,
2195 name_table->elements[0],
2196 name_table->lengths [0] );
2200 error = T1_Add_Table( swap_table, 1,
2201 code_table->elements[0],
2202 code_table->lengths [0] );
2206 error = T1_Add_Table( name_table, 0,
".notdef", 8 );
2210 error = T1_Add_Table( code_table, 0, notdef_glyph, 5 );
2215 error = T1_Add_Table( name_table, n,
2216 swap_table->elements[0],
2217 swap_table->lengths [0] );
2221 error = T1_Add_Table( code_table, n,
2222 swap_table->elements[1],
2223 swap_table->lengths [1] );
2228 loader->num_glyphs += 1;
2231#ifdef FT_DEBUG_LEVEL_TRACE
2232 FT_TRACE4((
" <" ));
2235 FT_TRACE4((
"%d elements", loader->num_glyphs ));
2237 FT_TRACE4((
">\n" ));
2243 parser->root.error = error;
2256 const T1_FieldRec t1_keywords[] =
2262 T1_FIELD_CALLBACK(
"FontMatrix", t1_parse_font_matrix,
2263 T1_FIELD_DICT_FONTDICT )
2264 T1_FIELD_CALLBACK(
"Encoding", parse_encoding,
2265 T1_FIELD_DICT_FONTDICT )
2266 T1_FIELD_CALLBACK(
"Subrs", parse_subrs,
2267 T1_FIELD_DICT_PRIVATE )
2268 T1_FIELD_CALLBACK(
"CharStrings", parse_charstrings,
2269 T1_FIELD_DICT_PRIVATE )
2270 T1_FIELD_CALLBACK(
"Private", parse_private,
2271 T1_FIELD_DICT_FONTDICT )
2273#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT
2274 T1_FIELD_CALLBACK(
"BlendDesignPositions", parse_blend_design_positions,
2275 T1_FIELD_DICT_FONTDICT )
2276 T1_FIELD_CALLBACK(
"BlendDesignMap", parse_blend_design_map,
2277 T1_FIELD_DICT_FONTDICT )
2278 T1_FIELD_CALLBACK(
"BlendAxisTypes", parse_blend_axis_types,
2279 T1_FIELD_DICT_FONTDICT )
2280 T1_FIELD_CALLBACK(
"WeightVector", parse_weight_vector,
2281 T1_FIELD_DICT_FONTDICT )
2282 T1_FIELD_CALLBACK(
"BuildCharArray", parse_buildchar,
2283 T1_FIELD_DICT_PRIVATE )
2291 parse_dict( T1_Face face,
2296 T1_Parser parser = &loader->parser;
2297 FT_Byte *limit, *start_binary = NULL;
2298 FT_Bool have_integer = 0;
2301 parser->root.cursor = base;
2302 parser->root.limit = base + size;
2303 parser->root.error = FT_Err_Ok;
2305 limit = parser->root.limit;
2307 T1_Skip_Spaces( parser );
2309 while ( parser->root.cursor < limit )
2314 cur = parser->root.cursor;
2317 if ( IS_PS_TOKEN( cur, limit,
"eexec" ) )
2321 else if ( IS_PS_TOKEN( cur, limit,
"closefile" ) )
2326 else if ( IS_PS_TOKEN( cur, limit,
"FontDirectory" ) )
2328 if ( loader->keywords_encountered & T1_PRIVATE )
2329 loader->keywords_encountered |=
2330 T1_FONTDIR_AFTER_PRIVATE;
2331 parser->root.cursor += 13;
2335 else if ( ft_isdigit( *cur ) )
2338 T1_Skip_PS_Token( parser );
2339 if ( parser->root.error )
2347 else if ( *cur ==
'R' && cur + 6 < limit && *( cur + 1 ) ==
'D' &&
2354 parser->root.cursor = start_binary;
2355 if ( !read_binary_data( parser, &s, &b, IS_INCREMENTAL ) )
2356 return FT_THROW( Invalid_File_Format );
2360 else if ( *cur ==
'-' && cur + 6 < limit && *( cur + 1 ) ==
'|' &&
2367 parser->root.cursor = start_binary;
2368 if ( !read_binary_data( parser, &s, &b, IS_INCREMENTAL ) )
2369 return FT_THROW( Invalid_File_Format );
2374 else if ( *cur ==
'/' && cur + 2 < limit )
2381 parser->root.cursor = cur;
2382 T1_Skip_PS_Token( parser );
2383 if ( parser->root.error )
2386 len = (FT_UInt)( parser->root.cursor - cur );
2388 if ( len > 0 && len < 22 && parser->root.cursor < limit )
2391 T1_Field keyword = (T1_Field)t1_keywords;
2394 while ( keyword->len )
2396 FT_Byte* name = (FT_Byte*)keyword->ident;
2399 if ( keyword->len == len &&
2400 ft_memcmp( cur, name, len ) == 0 )
2429 const FT_UInt dict =
2430 ( loader->keywords_encountered & T1_PRIVATE )
2431 ? T1_FIELD_DICT_PRIVATE
2432 : T1_FIELD_DICT_FONTDICT;
2435 if ( !( dict & keyword->dict ) )
2437 FT_TRACE1((
"parse_dict: found `%s' but ignoring it"
2438 " since it is in the wrong dictionary\n",
2443 if ( !( loader->keywords_encountered &
2444 T1_FONTDIR_AFTER_PRIVATE ) ||
2445 ft_strcmp( (
const char*)name,
"CharStrings" ) == 0 )
2447 parser->root.error = t1_load_keyword( face,
2450 if ( parser->root.error )
2452 if ( FT_ERR_EQ( parser->root.error, Ignore ) )
2453 parser->root.error = FT_Err_Ok;
2455 return parser->root.error;
2469 T1_Skip_PS_Token( parser );
2470 if ( parser->root.error )
2475 T1_Skip_Spaces( parser );
2479 return parser->root.error;
2484 t1_init_loader( T1_Loader loader,
2494 t1_done_loader( T1_Loader loader )
2496 T1_Parser parser = &loader->parser;
2497 FT_Memory memory = parser->root.memory;
2501 T1_Release_Table( &loader->encoding_table );
2502 T1_Release_Table( &loader->charstrings );
2503 T1_Release_Table( &loader->glyph_names );
2504 T1_Release_Table( &loader->swap_table );
2505 T1_Release_Table( &loader->subrs );
2508 ft_hash_num_free( loader->subrs_hash, memory );
2509 FT_FREE( loader->subrs_hash );
2512 T1_Finalize_Parser( parser );
2516 FT_LOCAL_DEF( FT_Error )
2517 T1_Open_Face( T1_Face face )
2519 T1_LoaderRec loader;
2521 T1_Font type1 = &face->type1;
2522 PS_Private priv = &type1->private_dict;
2525 PSAux_Service psaux = (PSAux_Service)face->psaux;
2528 t1_init_loader( &loader, face );
2533 face->len_buildchar = 0;
2535 priv->blue_shift = 7;
2536 priv->blue_fuzz = 1;
2538 priv->expansion_factor = (FT_Fixed)( 0.06 * 0x10000L );
2539 priv->blue_scale = (FT_Fixed)( 0.039625 * 0x10000L * 1000 );
2541 parser = &loader.parser;
2542 error = T1_New_Parser( parser,
2549 FT_TRACE4((
" top dictionary:\n" ));
2550 error = parse_dict( face, &loader,
2551 parser->base_dict, parser->base_len );
2555 error = T1_Get_Private_Dict( parser, psaux );
2559 FT_TRACE4((
" private dictionary:\n" ));
2560 error = parse_dict( face, &loader,
2561 parser->private_dict, parser->private_len );
2566 priv->num_blue_values &= ~1;
2568#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT
2573 face->blend->num_designs != ( 1U << face->blend->num_axis ) )
2575 FT_ERROR((
"T1_Open_Face:"
2576 " number-of-designs != 2 ^^ number-of-axes\n" ));
2577 T1_Done_Blend( FT_FACE( face ) );
2581 face->blend->num_default_design_vector != 0 &&
2582 face->blend->num_default_design_vector != face->blend->num_axis )
2585 FT_ERROR((
"T1_Open_Face(): /DesignVector contains %u entries "
2586 "while there are %u axes.\n",
2587 face->blend->num_default_design_vector,
2588 face->blend->num_axis ));
2590 face->blend->num_default_design_vector = 0;
2596 ( !face->blend->num_designs || !face->blend->num_axis ) )
2597 T1_Done_Blend( FT_FACE( face ) );
2600 if ( face->blend && !face->blend->weight_vector )
2601 T1_Done_Blend( FT_FACE( face ) );
2604 if ( face->blend && !face->blend->design_pos[0] )
2605 T1_Done_Blend( FT_FACE( face ) );
2613 for ( i = 0; i < face->blend->num_axis; i++ )
2614 if ( !face->blend->design_map[i].num_points )
2616 T1_Done_Blend( FT_FACE( face ) );
2623 if ( face->len_buildchar > 0 )
2625 FT_Memory memory = face->root.memory;
2628 if ( FT_NEW_ARRAY( face->buildchar, face->len_buildchar ) )
2630 FT_ERROR((
"T1_Open_Face: cannot allocate BuildCharArray\n" ));
2631 face->len_buildchar = 0;
2637 face->len_buildchar = 0;
2643 type1->num_glyphs = loader.num_glyphs;
2645 if ( loader.subrs.init )
2647 type1->num_subrs = loader.num_subrs;
2648 type1->subrs_block = loader.subrs.block;
2649 type1->subrs = loader.subrs.elements;
2650 type1->subrs_len = loader.subrs.lengths;
2651 type1->subrs_hash = loader.subrs_hash;
2654 loader.subrs.init = 0;
2655 loader.subrs_hash = NULL;
2658 if ( !IS_INCREMENTAL )
2659 if ( !loader.charstrings.init )
2661 FT_ERROR((
"T1_Open_Face: no `/CharStrings' array in face\n" ));
2662 error = FT_THROW( Invalid_File_Format );
2665 loader.charstrings.init = 0;
2666 type1->charstrings_block = loader.charstrings.block;
2667 type1->charstrings = loader.charstrings.elements;
2668 type1->charstrings_len = loader.charstrings.lengths;
2672 type1->glyph_names_block = loader.glyph_names.block;
2673 type1->glyph_names = (FT_String**)loader.glyph_names.elements;
2674 loader.glyph_names.block = NULL;
2675 loader.glyph_names.elements = NULL;
2678 if ( type1->encoding_type == T1_ENCODING_TYPE_ARRAY )
2680 FT_Int charcode, idx, min_char, max_char;
2692 for ( ; charcode < loader.encoding_table.max_elems; charcode++ )
2694 const FT_String* char_name =
2695 (
const FT_String*)loader.encoding_table.elements[charcode];
2698 type1->encoding.char_index[charcode] = 0;
2699 type1->encoding.char_name [charcode] =
".notdef";
2702 for ( idx = 0; idx < type1->num_glyphs; idx++ )
2704 const FT_String* glyph_name = type1->glyph_names[idx];
2707 if ( ft_strcmp( char_name, glyph_name ) == 0 )
2709 type1->encoding.char_index[charcode] = (FT_UShort)idx;
2710 type1->encoding.char_name [charcode] = glyph_name;
2714 if ( ft_strcmp(
".notdef", glyph_name ) != 0 )
2716 if ( charcode < min_char )
2717 min_char = charcode;
2718 if ( charcode >= max_char )
2719 max_char = charcode + 1;
2726 type1->encoding.code_first = min_char;
2727 type1->encoding.code_last = max_char;
2728 type1->encoding.num_chars = loader.num_chars;
2733 if ( priv->blue_shift > 1000 || priv->blue_shift < 0 )
2735 FT_TRACE2((
"T1_Open_Face:"
2736 " setting unlikely BlueShift value %d to default (7)\n",
2737 priv->blue_shift ));
2738 priv->blue_shift = 7;
2741 if ( priv->blue_fuzz > 1000 || priv->blue_fuzz < 0 )
2743 FT_TRACE2((
"T1_Open_Face:"
2744 " setting unlikely BlueFuzz value %d to default (1)\n",
2746 priv->blue_fuzz = 1;
2750 t1_done_loader( &loader );