00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063 #include <ft2build.h>
00064 #include FT_INTERNAL_DEBUG_H
00065 #include FT_CONFIG_CONFIG_H
00066 #include FT_MULTIPLE_MASTERS_H
00067 #include FT_INTERNAL_TYPE1_TYPES_H
00068 #include FT_INTERNAL_CALC_H
00069
00070 #include "t1load.h"
00071 #include "t1errors.h"
00072
00073
00074
00075
00076
00077
00078
00079
00080 #undef FT_COMPONENT
00081 #define FT_COMPONENT trace_t1load
00082
00083
00084 #ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095 static FT_Error
00096 t1_allocate_blend( T1_Face face,
00097 FT_UInt num_designs,
00098 FT_UInt num_axis )
00099 {
00100 PS_Blend blend;
00101 FT_Memory memory = face->root.memory;
00102 FT_Error error = T1_Err_Ok;
00103
00104
00105 blend = face->blend;
00106 if ( !blend )
00107 {
00108 if ( FT_NEW( blend ) )
00109 goto Exit;
00110
00111 blend->num_default_design_vector = 0;
00112
00113 face->blend = blend;
00114 }
00115
00116
00117 if ( num_designs > 0 )
00118 {
00119 if ( blend->num_designs == 0 )
00120 {
00121 FT_UInt nn;
00122
00123
00124
00125 if ( FT_NEW_ARRAY( blend->font_infos[1], num_designs ) ||
00126 FT_NEW_ARRAY( blend->privates[1], num_designs ) ||
00127 FT_NEW_ARRAY( blend->bboxes[1], num_designs ) ||
00128 FT_NEW_ARRAY( blend->weight_vector, num_designs * 2 ) )
00129 goto Exit;
00130
00131 blend->default_weight_vector = blend->weight_vector + num_designs;
00132
00133 blend->font_infos[0] = &face->type1.font_info;
00134 blend->privates [0] = &face->type1.private_dict;
00135 blend->bboxes [0] = &face->type1.font_bbox;
00136
00137 for ( nn = 2; nn <= num_designs; nn++ )
00138 {
00139 blend->privates[nn] = blend->privates [nn - 1] + 1;
00140 blend->font_infos[nn] = blend->font_infos[nn - 1] + 1;
00141 blend->bboxes[nn] = blend->bboxes [nn - 1] + 1;
00142 }
00143
00144 blend->num_designs = num_designs;
00145 }
00146 else if ( blend->num_designs != num_designs )
00147 goto Fail;
00148 }
00149
00150
00151 if ( num_axis > 0 )
00152 {
00153 if ( blend->num_axis != 0 && blend->num_axis != num_axis )
00154 goto Fail;
00155
00156 blend->num_axis = num_axis;
00157 }
00158
00159
00160 num_designs = blend->num_designs;
00161 num_axis = blend->num_axis;
00162 if ( num_designs && num_axis && blend->design_pos[0] == 0 )
00163 {
00164 FT_UInt n;
00165
00166
00167 if ( FT_NEW_ARRAY( blend->design_pos[0], num_designs * num_axis ) )
00168 goto Exit;
00169
00170 for ( n = 1; n < num_designs; n++ )
00171 blend->design_pos[n] = blend->design_pos[0] + num_axis * n;
00172 }
00173
00174 Exit:
00175 return error;
00176
00177 Fail:
00178 error = T1_Err_Invalid_File_Format;
00179 goto Exit;
00180 }
00181
00182
00183 FT_LOCAL_DEF( FT_Error )
00184 T1_Get_Multi_Master( T1_Face face,
00185 FT_Multi_Master* master )
00186 {
00187 PS_Blend blend = face->blend;
00188 FT_UInt n;
00189 FT_Error error;
00190
00191
00192 error = T1_Err_Invalid_Argument;
00193
00194 if ( blend )
00195 {
00196 master->num_axis = blend->num_axis;
00197 master->num_designs = blend->num_designs;
00198
00199 for ( n = 0; n < blend->num_axis; n++ )
00200 {
00201 FT_MM_Axis* axis = master->axis + n;
00202 PS_DesignMap map = blend->design_map + n;
00203
00204
00205 axis->name = blend->axis_names[n];
00206 axis->minimum = map->design_points[0];
00207 axis->maximum = map->design_points[map->num_points - 1];
00208 }
00209
00210 error = T1_Err_Ok;
00211 }
00212
00213 return error;
00214 }
00215
00216
00217
00218
00219
00220
00221
00222 FT_LOCAL_DEF( FT_Fixed )
00223 mm_axis_unmap( PS_DesignMap axismap,
00224 FT_Fixed ncv )
00225 {
00226 int j;
00227
00228
00229 if ( ncv <= axismap->blend_points[0] )
00230 return INT_TO_FIXED( axismap->design_points[0] );
00231
00232 for ( j = 1; j < axismap->num_points; ++j )
00233 {
00234 if ( ncv <= axismap->blend_points[j] )
00235 {
00236 FT_Fixed t = FT_MulDiv( ncv - axismap->blend_points[j - 1],
00237 0x10000L,
00238 axismap->blend_points[j] -
00239 axismap->blend_points[j - 1] );
00240
00241 return INT_TO_FIXED( axismap->design_points[j - 1] ) +
00242 FT_MulDiv( t,
00243 axismap->design_points[j] -
00244 axismap->design_points[j - 1],
00245 1L );
00246 }
00247 }
00248
00249 return INT_TO_FIXED( axismap->design_points[axismap->num_points - 1] );
00250 }
00251
00252
00253
00254
00255
00256
00257
00258 FT_LOCAL_DEF( void )
00259 mm_weights_unmap( FT_Fixed* weights,
00260 FT_Fixed* axiscoords,
00261 FT_UInt axis_count )
00262 {
00263 FT_ASSERT( axis_count <= T1_MAX_MM_AXIS );
00264
00265 if ( axis_count == 1 )
00266 axiscoords[0] = weights[1];
00267
00268 else if ( axis_count == 2 )
00269 {
00270 axiscoords[0] = weights[3] + weights[1];
00271 axiscoords[1] = weights[3] + weights[2];
00272 }
00273
00274 else if ( axis_count == 3 )
00275 {
00276 axiscoords[0] = weights[7] + weights[5] + weights[3] + weights[1];
00277 axiscoords[1] = weights[7] + weights[6] + weights[3] + weights[2];
00278 axiscoords[2] = weights[7] + weights[6] + weights[5] + weights[4];
00279 }
00280
00281 else
00282 {
00283 axiscoords[0] = weights[15] + weights[13] + weights[11] + weights[9] +
00284 weights[7] + weights[5] + weights[3] + weights[1];
00285 axiscoords[1] = weights[15] + weights[14] + weights[11] + weights[10] +
00286 weights[7] + weights[6] + weights[3] + weights[2];
00287 axiscoords[2] = weights[15] + weights[14] + weights[13] + weights[12] +
00288 weights[7] + weights[6] + weights[5] + weights[4];
00289 axiscoords[3] = weights[15] + weights[14] + weights[13] + weights[12] +
00290 weights[11] + weights[10] + weights[9] + weights[8];
00291 }
00292 }
00293
00294
00295
00296
00297
00298
00299
00300 FT_LOCAL_DEF( FT_Error )
00301 T1_Get_MM_Var( T1_Face face,
00302 FT_MM_Var* *master )
00303 {
00304 FT_Memory memory = face->root.memory;
00305 FT_MM_Var *mmvar;
00306 FT_Multi_Master mmaster;
00307 FT_Error error;
00308 FT_UInt i;
00309 FT_Fixed axiscoords[T1_MAX_MM_AXIS];
00310 PS_Blend blend = face->blend;
00311
00312
00313 error = T1_Get_Multi_Master( face, &mmaster );
00314 if ( error )
00315 goto Exit;
00316 if ( FT_ALLOC( mmvar,
00317 sizeof ( FT_MM_Var ) +
00318 mmaster.num_axis * sizeof ( FT_Var_Axis ) ) )
00319 goto Exit;
00320
00321 mmvar->num_axis = mmaster.num_axis;
00322 mmvar->num_designs = mmaster.num_designs;
00323 mmvar->num_namedstyles = (FT_UInt)-1;
00324 mmvar->axis = (FT_Var_Axis*)&mmvar[1];
00325
00326 mmvar->namedstyle = NULL;
00327
00328 for ( i = 0 ; i < mmaster.num_axis; ++i )
00329 {
00330 mmvar->axis[i].name = mmaster.axis[i].name;
00331 mmvar->axis[i].minimum = INT_TO_FIXED( mmaster.axis[i].minimum);
00332 mmvar->axis[i].maximum = INT_TO_FIXED( mmaster.axis[i].maximum);
00333 mmvar->axis[i].def = ( mmvar->axis[i].minimum +
00334 mmvar->axis[i].maximum ) / 2;
00335
00336 mmvar->axis[i].strid = (FT_UInt)-1;
00337 mmvar->axis[i].tag = (FT_ULong)-1;
00338
00339 if ( ft_strcmp( mmvar->axis[i].name, "Weight" ) == 0 )
00340 mmvar->axis[i].tag = FT_MAKE_TAG( 'w', 'g', 'h', 't' );
00341 else if ( ft_strcmp( mmvar->axis[i].name, "Width" ) == 0 )
00342 mmvar->axis[i].tag = FT_MAKE_TAG( 'w', 'd', 't', 'h' );
00343 else if ( ft_strcmp( mmvar->axis[i].name, "OpticalSize" ) == 0 )
00344 mmvar->axis[i].tag = FT_MAKE_TAG( 'o', 'p', 's', 'z' );
00345 }
00346
00347 if ( blend->num_designs == ( 1U << blend->num_axis ) )
00348 {
00349 mm_weights_unmap( blend->default_weight_vector,
00350 axiscoords,
00351 blend->num_axis );
00352
00353 for ( i = 0; i < mmaster.num_axis; ++i )
00354 mmvar->axis[i].def = mm_axis_unmap( &blend->design_map[i],
00355 axiscoords[i] );
00356 }
00357
00358 *master = mmvar;
00359
00360 Exit:
00361 return error;
00362 }
00363
00364
00365 FT_LOCAL_DEF( FT_Error )
00366 T1_Set_MM_Blend( T1_Face face,
00367 FT_UInt num_coords,
00368 FT_Fixed* coords )
00369 {
00370 PS_Blend blend = face->blend;
00371 FT_Error error;
00372 FT_UInt n, m;
00373
00374
00375 error = T1_Err_Invalid_Argument;
00376
00377 if ( blend && blend->num_axis == num_coords )
00378 {
00379
00380 error = T1_Err_Ok;
00381
00382 for ( n = 0; n < blend->num_designs; n++ )
00383 {
00384 FT_Fixed result = 0x10000L;
00385
00386
00387 for ( m = 0; m < blend->num_axis; m++ )
00388 {
00389 FT_Fixed factor;
00390
00391
00392
00393 factor = coords[m];
00394 if ( factor < 0 ) factor = 0;
00395 if ( factor > 0x10000L ) factor = 0x10000L;
00396
00397 if ( ( n & ( 1 << m ) ) == 0 )
00398 factor = 0x10000L - factor;
00399
00400 result = FT_MulFix( result, factor );
00401 }
00402 blend->weight_vector[n] = result;
00403 }
00404
00405 error = T1_Err_Ok;
00406 }
00407
00408 return error;
00409 }
00410
00411
00412 FT_LOCAL_DEF( FT_Error )
00413 T1_Set_MM_Design( T1_Face face,
00414 FT_UInt num_coords,
00415 FT_Long* coords )
00416 {
00417 PS_Blend blend = face->blend;
00418 FT_Error error;
00419 FT_UInt n, p;
00420
00421
00422 error = T1_Err_Invalid_Argument;
00423 if ( blend && blend->num_axis == num_coords )
00424 {
00425
00426 FT_Fixed final_blends[T1_MAX_MM_DESIGNS];
00427
00428
00429 for ( n = 0; n < blend->num_axis; n++ )
00430 {
00431 FT_Long design = coords[n];
00432 FT_Fixed the_blend;
00433 PS_DesignMap map = blend->design_map + n;
00434 FT_Long* designs = map->design_points;
00435 FT_Fixed* blends = map->blend_points;
00436 FT_Int before = -1, after = -1;
00437
00438
00439 for ( p = 0; p < (FT_UInt)map->num_points; p++ )
00440 {
00441 FT_Long p_design = designs[p];
00442
00443
00444
00445 if ( design == p_design )
00446 {
00447 the_blend = blends[p];
00448 goto Found;
00449 }
00450
00451 if ( design < p_design )
00452 {
00453 after = p;
00454 break;
00455 }
00456
00457 before = p;
00458 }
00459
00460
00461 if ( before < 0 )
00462 the_blend = blends[0];
00463
00464 else if ( after < 0 )
00465 the_blend = blends[map->num_points - 1];
00466
00467 else
00468 the_blend = FT_MulDiv( design - designs[before],
00469 blends [after] - blends [before],
00470 designs[after] - designs[before] );
00471
00472 Found:
00473 final_blends[n] = the_blend;
00474 }
00475
00476 error = T1_Set_MM_Blend( face, num_coords, final_blends );
00477 }
00478
00479 return error;
00480 }
00481
00482
00483
00484
00485
00486
00487
00488 FT_LOCAL_DEF( FT_Error )
00489 T1_Set_Var_Design( T1_Face face,
00490 FT_UInt num_coords,
00491 FT_Fixed* coords )
00492 {
00493 FT_Long lcoords[4];
00494 FT_UInt i;
00495 FT_Error error;
00496
00497
00498 error = T1_Err_Invalid_Argument;
00499 if ( num_coords <= 4 && num_coords > 0 )
00500 {
00501 for ( i = 0; i < num_coords; ++i )
00502 lcoords[i] = FIXED_TO_INT( coords[i] );
00503 error = T1_Set_MM_Design( face, num_coords, lcoords );
00504 }
00505
00506 return error;
00507 }
00508
00509
00510 FT_LOCAL_DEF( void )
00511 T1_Done_Blend( T1_Face face )
00512 {
00513 FT_Memory memory = face->root.memory;
00514 PS_Blend blend = face->blend;
00515
00516
00517 if ( blend )
00518 {
00519 FT_UInt num_designs = blend->num_designs;
00520 FT_UInt num_axis = blend->num_axis;
00521 FT_UInt n;
00522
00523
00524
00525 FT_FREE( blend->design_pos[0] );
00526 for ( n = 1; n < num_designs; n++ )
00527 blend->design_pos[n] = 0;
00528
00529
00530 FT_FREE( blend->privates[1] );
00531 FT_FREE( blend->font_infos[1] );
00532 FT_FREE( blend->bboxes[1] );
00533
00534 for ( n = 0; n < num_designs; n++ )
00535 {
00536 blend->privates [n] = 0;
00537 blend->font_infos[n] = 0;
00538 blend->bboxes [n] = 0;
00539 }
00540
00541
00542 FT_FREE( blend->weight_vector );
00543 blend->default_weight_vector = 0;
00544
00545
00546 for ( n = 0; n < num_axis; n++ )
00547 FT_FREE( blend->axis_names[n] );
00548
00549
00550 for ( n = 0; n < num_axis; n++ )
00551 {
00552 PS_DesignMap dmap = blend->design_map + n;
00553
00554
00555 FT_FREE( dmap->design_points );
00556 dmap->num_points = 0;
00557 }
00558
00559 FT_FREE( face->blend );
00560 }
00561 }
00562
00563
00564 static void
00565 parse_blend_axis_types( T1_Face face,
00566 T1_Loader loader )
00567 {
00568 T1_TokenRec axis_tokens[T1_MAX_MM_AXIS];
00569 FT_Int n, num_axis;
00570 FT_Error error = T1_Err_Ok;
00571 PS_Blend blend;
00572 FT_Memory memory;
00573
00574
00575
00576 T1_ToTokenArray( &loader->parser, axis_tokens,
00577 T1_MAX_MM_AXIS, &num_axis );
00578 if ( num_axis < 0 )
00579 {
00580 error = T1_Err_Ignore;
00581 goto Exit;
00582 }
00583 if ( num_axis == 0 || num_axis > T1_MAX_MM_AXIS )
00584 {
00585 FT_ERROR(( "parse_blend_axis_types: incorrect number of axes: %d\n",
00586 num_axis ));
00587 error = T1_Err_Invalid_File_Format;
00588 goto Exit;
00589 }
00590
00591
00592 error = t1_allocate_blend( face, 0, (FT_UInt)num_axis );
00593 if ( error )
00594 goto Exit;
00595
00596 blend = face->blend;
00597 memory = face->root.memory;
00598
00599
00600 for ( n = 0; n < num_axis; n++ )
00601 {
00602 T1_Token token = axis_tokens + n;
00603 FT_Byte* name;
00604 FT_PtrDist len;
00605
00606
00607
00608 if ( token->start[0] == '/' )
00609 token->start++;
00610
00611 len = token->limit - token->start;
00612 if ( len == 0 )
00613 {
00614 error = T1_Err_Invalid_File_Format;
00615 goto Exit;
00616 }
00617
00618 if ( FT_ALLOC( blend->axis_names[n], len + 1 ) )
00619 goto Exit;
00620
00621 name = (FT_Byte*)blend->axis_names[n];
00622 FT_MEM_COPY( name, token->start, len );
00623 name[len] = 0;
00624 }
00625
00626 Exit:
00627 loader->parser.root.error = error;
00628 }
00629
00630
00631 static void
00632 parse_blend_design_positions( T1_Face face,
00633 T1_Loader loader )
00634 {
00635 T1_TokenRec design_tokens[T1_MAX_MM_DESIGNS];
00636 FT_Int num_designs;
00637 FT_Int num_axis;
00638 T1_Parser parser = &loader->parser;
00639
00640 FT_Error error = T1_Err_Ok;
00641 PS_Blend blend;
00642
00643
00644
00645 T1_ToTokenArray( parser, design_tokens,
00646 T1_MAX_MM_DESIGNS, &num_designs );
00647 if ( num_designs < 0 )
00648 {
00649 error = T1_Err_Ignore;
00650 goto Exit;
00651 }
00652 if ( num_designs == 0 || num_designs > T1_MAX_MM_DESIGNS )
00653 {
00654 FT_ERROR(( "parse_blend_design_positions:"
00655 " incorrect number of designs: %d\n",
00656 num_designs ));
00657 error = T1_Err_Invalid_File_Format;
00658 goto Exit;
00659 }
00660
00661 {
00662 FT_Byte* old_cursor = parser->root.cursor;
00663 FT_Byte* old_limit = parser->root.limit;
00664 FT_Int n;
00665
00666
00667 blend = face->blend;
00668 num_axis = 0;
00669
00670 for ( n = 0; n < num_designs; n++ )
00671 {
00672 T1_TokenRec axis_tokens[T1_MAX_MM_AXIS];
00673 T1_Token token;
00674 FT_Int axis, n_axis;
00675
00676
00677
00678 token = design_tokens + n;
00679 parser->root.cursor = token->start;
00680 parser->root.limit = token->limit;
00681 T1_ToTokenArray( parser, axis_tokens, T1_MAX_MM_AXIS, &n_axis );
00682
00683 if ( n == 0 )
00684 {
00685 if ( n_axis <= 0 || n_axis > T1_MAX_MM_AXIS )
00686 {
00687 FT_ERROR(( "parse_blend_design_positions:"
00688 " invalid number of axes: %d\n",
00689 n_axis ));
00690 error = T1_Err_Invalid_File_Format;
00691 goto Exit;
00692 }
00693
00694 num_axis = n_axis;
00695 error = t1_allocate_blend( face, num_designs, num_axis );
00696 if ( error )
00697 goto Exit;
00698 blend = face->blend;
00699 }
00700 else if ( n_axis != num_axis )
00701 {
00702 FT_ERROR(( "parse_blend_design_positions: incorrect table\n" ));
00703 error = T1_Err_Invalid_File_Format;
00704 goto Exit;
00705 }
00706
00707
00708 for ( axis = 0; axis < n_axis; axis++ )
00709 {
00710 T1_Token token2 = axis_tokens + axis;
00711
00712
00713 parser->root.cursor = token2->start;
00714 parser->root.limit = token2->limit;
00715 blend->design_pos[n][axis] = T1_ToFixed( parser, 0 );
00716 }
00717 }
00718
00719 loader->parser.root.cursor = old_cursor;
00720 loader->parser.root.limit = old_limit;
00721 }
00722
00723 Exit:
00724 loader->parser.root.error = error;
00725 }
00726
00727
00728 static void
00729 parse_blend_design_map( T1_Face face,
00730 T1_Loader loader )
00731 {
00732 FT_Error error = T1_Err_Ok;
00733 T1_Parser parser = &loader->parser;
00734 PS_Blend blend;
00735 T1_TokenRec axis_tokens[T1_MAX_MM_AXIS];
00736 FT_Int n, num_axis;
00737 FT_Byte* old_cursor;
00738 FT_Byte* old_limit;
00739 FT_Memory memory = face->root.memory;
00740
00741
00742 T1_ToTokenArray( parser, axis_tokens,
00743 T1_MAX_MM_AXIS, &num_axis );
00744 if ( num_axis < 0 )
00745 {
00746 error = T1_Err_Ignore;
00747 goto Exit;
00748 }
00749 if ( num_axis == 0 || num_axis > T1_MAX_MM_AXIS )
00750 {
00751 FT_ERROR(( "parse_blend_design_map: incorrect number of axes: %d\n",
00752 num_axis ));
00753 error = T1_Err_Invalid_File_Format;
00754 goto Exit;
00755 }
00756
00757 old_cursor = parser->root.cursor;
00758 old_limit = parser->root.limit;
00759
00760 error = t1_allocate_blend( face, 0, num_axis );
00761 if ( error )
00762 goto Exit;
00763 blend = face->blend;
00764
00765
00766 for ( n = 0; n < num_axis; n++ )
00767 {
00768 PS_DesignMap map = blend->design_map + n;
00769 T1_Token axis_token;
00770 T1_TokenRec point_tokens[T1_MAX_MM_MAP_POINTS];
00771 FT_Int p, num_points;
00772
00773
00774 axis_token = axis_tokens + n;
00775
00776 parser->root.cursor = axis_token->start;
00777 parser->root.limit = axis_token->limit;
00778 T1_ToTokenArray( parser, point_tokens,
00779 T1_MAX_MM_MAP_POINTS, &num_points );
00780
00781 if ( num_points <= 0 || num_points > T1_MAX_MM_MAP_POINTS )
00782 {
00783 FT_ERROR(( "parse_blend_design_map: incorrect table\n" ));
00784 error = T1_Err_Invalid_File_Format;
00785 goto Exit;
00786 }
00787
00788
00789 if ( FT_NEW_ARRAY( map->design_points, num_points * 2 ) )
00790 goto Exit;
00791 map->blend_points = map->design_points + num_points;
00792 map->num_points = (FT_Byte)num_points;
00793
00794 for ( p = 0; p < num_points; p++ )
00795 {
00796 T1_Token point_token;
00797
00798
00799 point_token = point_tokens + p;
00800
00801
00802 parser->root.cursor = point_token->start + 1;
00803 parser->root.limit = point_token->limit - 1;
00804
00805 map->design_points[p] = T1_ToInt( parser );
00806 map->blend_points [p] = T1_ToFixed( parser, 0 );
00807 }
00808 }
00809
00810 parser->root.cursor = old_cursor;
00811 parser->root.limit = old_limit;
00812
00813 Exit:
00814 parser->root.error = error;
00815 }
00816
00817
00818 static void
00819 parse_weight_vector( T1_Face face,
00820 T1_Loader loader )
00821 {
00822 T1_TokenRec design_tokens[T1_MAX_MM_DESIGNS];
00823 FT_Int num_designs;
00824 FT_Error error = T1_Err_Ok;
00825 T1_Parser parser = &loader->parser;
00826 PS_Blend blend = face->blend;
00827 T1_Token token;
00828 FT_Int n;
00829 FT_Byte* old_cursor;
00830 FT_Byte* old_limit;
00831
00832
00833 T1_ToTokenArray( parser, design_tokens,
00834 T1_MAX_MM_DESIGNS, &num_designs );
00835 if ( num_designs < 0 )
00836 {
00837 error = T1_Err_Ignore;
00838 goto Exit;
00839 }
00840 if ( num_designs == 0 || num_designs > T1_MAX_MM_DESIGNS )
00841 {
00842 FT_ERROR(( "parse_weight_vector:"
00843 " incorrect number of designs: %d\n",
00844 num_designs ));
00845 error = T1_Err_Invalid_File_Format;
00846 goto Exit;
00847 }
00848
00849 if ( !blend || !blend->num_designs )
00850 {
00851 error = t1_allocate_blend( face, num_designs, 0 );
00852 if ( error )
00853 goto Exit;
00854 blend = face->blend;
00855 }
00856 else if ( blend->num_designs != (FT_UInt)num_designs )
00857 {
00858 FT_ERROR(( "parse_weight_vector:"
00859 " /BlendDesignPosition and /WeightVector have\n"
00860 " "
00861 " different number of elements\n" ));
00862 error = T1_Err_Invalid_File_Format;
00863 goto Exit;
00864 }
00865
00866 old_cursor = parser->root.cursor;
00867 old_limit = parser->root.limit;
00868
00869 for ( n = 0; n < num_designs; n++ )
00870 {
00871 token = design_tokens + n;
00872 parser->root.cursor = token->start;
00873 parser->root.limit = token->limit;
00874
00875 blend->default_weight_vector[n] =
00876 blend->weight_vector[n] = T1_ToFixed( parser, 0 );
00877 }
00878
00879 parser->root.cursor = old_cursor;
00880 parser->root.limit = old_limit;
00881
00882 Exit:
00883 parser->root.error = error;
00884 }
00885
00886
00887
00888
00889 static void
00890 parse_buildchar( T1_Face face,
00891 T1_Loader loader )
00892 {
00893 face->len_buildchar = T1_ToFixedArray( &loader->parser, 0, NULL, 0 );
00894
00895 return;
00896 }
00897
00898
00899 #endif
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912 static FT_Error
00913 t1_load_keyword( T1_Face face,
00914 T1_Loader loader,
00915 const T1_Field field )
00916 {
00917 FT_Error error;
00918 void* dummy_object;
00919 void** objects;
00920 FT_UInt max_objects;
00921 PS_Blend blend = face->blend;
00922
00923
00924
00925 if ( field->type == T1_FIELD_TYPE_CALLBACK )
00926 {
00927 field->reader( (FT_Face)face, loader );
00928 error = loader->parser.root.error;
00929 goto Exit;
00930 }
00931
00932
00933
00934 switch ( field->location )
00935 {
00936 case T1_FIELD_LOCATION_FONT_INFO:
00937 dummy_object = &face->type1.font_info;
00938 objects = &dummy_object;
00939 max_objects = 0;
00940
00941 if ( blend )
00942 {
00943 objects = (void**)blend->font_infos;
00944 max_objects = blend->num_designs;
00945 }
00946 break;
00947
00948 case T1_FIELD_LOCATION_FONT_EXTRA:
00949 dummy_object = &face->type1.font_extra;
00950 objects = &dummy_object;
00951 max_objects = 0;
00952 break;
00953
00954 case T1_FIELD_LOCATION_PRIVATE:
00955 dummy_object = &face->type1.private_dict;
00956 objects = &dummy_object;
00957 max_objects = 0;
00958
00959 if ( blend )
00960 {
00961 objects = (void**)blend->privates;
00962 max_objects = blend->num_designs;
00963 }
00964 break;
00965
00966 case T1_FIELD_LOCATION_BBOX:
00967 dummy_object = &face->type1.font_bbox;
00968 objects = &dummy_object;
00969 max_objects = 0;
00970
00971 if ( blend )
00972 {
00973 objects = (void**)blend->bboxes;
00974 max_objects = blend->num_designs;
00975 }
00976 break;
00977
00978 case T1_FIELD_LOCATION_LOADER:
00979 dummy_object = loader;
00980 objects = &dummy_object;
00981 max_objects = 0;
00982 break;
00983
00984 case T1_FIELD_LOCATION_FACE:
00985 dummy_object = face;
00986 objects = &dummy_object;
00987 max_objects = 0;
00988 break;
00989
00990 #ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT
00991 case T1_FIELD_LOCATION_BLEND:
00992 dummy_object = face->blend;
00993 objects = &dummy_object;
00994 max_objects = 0;
00995 break;
00996 #endif
00997
00998 default:
00999 dummy_object = &face->type1;
01000 objects = &dummy_object;
01001 max_objects = 0;
01002 }
01003
01004 if ( field->type == T1_FIELD_TYPE_INTEGER_ARRAY ||
01005 field->type == T1_FIELD_TYPE_FIXED_ARRAY )
01006 error = T1_Load_Field_Table( &loader->parser, field,
01007 objects, max_objects, 0 );
01008 else
01009 error = T1_Load_Field( &loader->parser, field,
01010 objects, max_objects, 0 );
01011
01012 Exit:
01013 return error;
01014 }
01015
01016
01017 static void
01018 parse_private( T1_Face face,
01019 T1_Loader loader )
01020 {
01021 FT_UNUSED( face );
01022
01023 loader->keywords_encountered |= T1_PRIVATE;
01024 }
01025
01026
01027 static int
01028 read_binary_data( T1_Parser parser,
01029 FT_Long* size,
01030 FT_Byte** base )
01031 {
01032 FT_Byte* cur;
01033 FT_Byte* limit = parser->root.limit;
01034
01035
01036
01037
01038
01039
01040
01041
01042 T1_Skip_Spaces( parser );
01043
01044 cur = parser->root.cursor;
01045
01046 if ( cur < limit && ft_isdigit( *cur ) )
01047 {
01048 *size = T1_ToInt( parser );
01049
01050 T1_Skip_PS_Token( parser );
01051
01052
01053
01054 *base = parser->root.cursor + 1;
01055
01056 parser->root.cursor += *size + 1;
01057 return !parser->root.error;
01058 }
01059
01060 FT_ERROR(( "read_binary_data: invalid size field\n" ));
01061 parser->root.error = T1_Err_Invalid_File_Format;
01062 return 0;
01063 }
01064
01065
01066
01067
01068
01069 static void
01070 parse_font_matrix( T1_Face face,
01071 T1_Loader loader )
01072 {
01073 T1_Parser parser = &loader->parser;
01074 FT_Matrix* matrix = &face->type1.font_matrix;
01075 FT_Vector* offset = &face->type1.font_offset;
01076 FT_Face root = (FT_Face)&face->root;
01077 FT_Fixed temp[6];
01078 FT_Fixed temp_scale;
01079 FT_Int result;
01080
01081
01082 result = T1_ToFixedArray( parser, 6, temp, 3 );
01083
01084 if ( result < 0 )
01085 {
01086 parser->root.error = T1_Err_Invalid_File_Format;
01087 return;
01088 }
01089
01090 temp_scale = FT_ABS( temp[3] );
01091
01092 if ( temp_scale == 0 )
01093 {
01094 FT_ERROR(( "parse_font_matrix: invalid font matrix\n" ));
01095 parser->root.error = T1_Err_Invalid_File_Format;
01096 return;
01097 }
01098
01099
01100
01101
01102
01103 root->units_per_EM = (FT_UShort)( FT_DivFix( 1000 * 0x10000L,
01104 temp_scale ) >> 16 );
01105
01106
01107 if ( temp_scale != 0x10000L )
01108 {
01109 temp[0] = FT_DivFix( temp[0], temp_scale );
01110 temp[1] = FT_DivFix( temp[1], temp_scale );
01111 temp[2] = FT_DivFix( temp[2], temp_scale );
01112 temp[4] = FT_DivFix( temp[4], temp_scale );
01113 temp[5] = FT_DivFix( temp[5], temp_scale );
01114 temp[3] = 0x10000L;
01115 }
01116
01117 matrix->xx = temp[0];
01118 matrix->yx = temp[1];
01119 matrix->xy = temp[2];
01120 matrix->yy = temp[3];
01121
01122
01123 offset->x = temp[4] >> 16;
01124 offset->y = temp[5] >> 16;
01125 }
01126
01127
01128 static void
01129 parse_encoding( T1_Face face,
01130 T1_Loader loader )
01131 {
01132 T1_Parser parser = &loader->parser;
01133 FT_Byte* cur;
01134 FT_Byte* limit = parser->root.limit;
01135
01136 PSAux_Service psaux = (PSAux_Service)face->psaux;
01137
01138
01139 T1_Skip_Spaces( parser );
01140 cur = parser->root.cursor;
01141 if ( cur >= limit )
01142 {
01143 FT_ERROR(( "parse_encoding: out of bounds\n" ));
01144 parser->root.error = T1_Err_Invalid_File_Format;
01145 return;
01146 }
01147
01148
01149
01150 if ( ft_isdigit( *cur ) || *cur == '[' )
01151 {
01152 T1_Encoding encode = &face->type1.encoding;
01153 FT_Int count, n;
01154 PS_Table char_table = &loader->encoding_table;
01155 FT_Memory memory = parser->root.memory;
01156 FT_Error error;
01157 FT_Bool only_immediates = 0;
01158
01159
01160
01161 if ( *cur == '[' )
01162 {
01163 count = 256;
01164 only_immediates = 1;
01165 parser->root.cursor++;
01166 }
01167 else
01168 count = (FT_Int)T1_ToInt( parser );
01169
01170 T1_Skip_Spaces( parser );
01171 if ( parser->root.cursor >= limit )
01172 return;
01173
01174
01175 loader->num_chars = encode->num_chars = count;
01176 if ( FT_NEW_ARRAY( encode->char_index, count ) ||
01177 FT_NEW_ARRAY( encode->char_name, count ) ||
01178 FT_SET_ERROR( psaux->ps_table_funcs->init(
01179 char_table, count, memory ) ) )
01180 {
01181 parser->root.error = error;
01182 return;
01183 }
01184
01185
01186 for ( n = 0; n < count; n++ )
01187 {
01188 char* notdef = (char *)".notdef";
01189
01190
01191 T1_Add_Table( char_table, n, notdef, 8 );
01192 }
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214 n = 0;
01215 T1_Skip_Spaces( parser );
01216
01217 while ( parser->root.cursor < limit )
01218 {
01219 cur = parser->root.cursor;
01220
01221
01222 if ( *cur == 'd' && cur + 3 < limit )
01223 {
01224 if ( cur[1] == 'e' &&
01225 cur[2] == 'f' &&
01226 IS_PS_DELIM( cur[3] ) )
01227 {
01228 FT_TRACE6(( "encoding end\n" ));
01229 cur += 3;
01230 break;
01231 }
01232 }
01233 if ( *cur == ']' )
01234 {
01235 FT_TRACE6(( "encoding end\n" ));
01236 cur++;
01237 break;
01238 }
01239
01240
01241 if ( ft_isdigit( *cur ) || only_immediates )
01242 {
01243 FT_Int charcode;
01244
01245
01246 if ( only_immediates )
01247 charcode = n;
01248 else
01249 {
01250 charcode = (FT_Int)T1_ToInt( parser );
01251 T1_Skip_Spaces( parser );
01252 }
01253
01254 cur = parser->root.cursor;
01255
01256 if ( *cur == '/' && cur + 2 < limit && n < count )
01257 {
01258 FT_PtrDist len;
01259
01260
01261 cur++;
01262
01263 parser->root.cursor = cur;
01264 T1_Skip_PS_Token( parser );
01265 if ( parser->root.error )
01266 return;
01267
01268 len = parser->root.cursor - cur;
01269
01270 parser->root.error = T1_Add_Table( char_table, charcode,
01271 cur, len + 1 );
01272 if ( parser->root.error )
01273 return;
01274 char_table->elements[charcode][len] = '\0';
01275
01276 n++;
01277 }
01278 else if ( only_immediates )
01279 {
01280
01281
01282
01283
01284
01285
01286
01287
01288 parser->root.error = FT_Err_Unknown_File_Format;
01289 return;
01290 }
01291 }
01292 else
01293 {
01294 T1_Skip_PS_Token( parser );
01295 if ( parser->root.error )
01296 return;
01297 }
01298
01299 T1_Skip_Spaces( parser );
01300 }
01301
01302 face->type1.encoding_type = T1_ENCODING_TYPE_ARRAY;
01303 parser->root.cursor = cur;
01304 }
01305
01306
01307
01308 else
01309 {
01310 if ( cur + 17 < limit &&
01311 ft_strncmp( (const char*)cur, "StandardEncoding", 16 ) == 0 )
01312 face->type1.encoding_type = T1_ENCODING_TYPE_STANDARD;
01313
01314 else if ( cur + 15 < limit &&
01315 ft_strncmp( (const char*)cur, "ExpertEncoding", 14 ) == 0 )
01316 face->type1.encoding_type = T1_ENCODING_TYPE_EXPERT;
01317
01318 else if ( cur + 18 < limit &&
01319 ft_strncmp( (const char*)cur, "ISOLatin1Encoding", 17 ) == 0 )
01320 face->type1.encoding_type = T1_ENCODING_TYPE_ISOLATIN1;
01321
01322 else
01323 parser->root.error = T1_Err_Ignore;
01324 }
01325 }
01326
01327
01328 static void
01329 parse_subrs( T1_Face face,
01330 T1_Loader loader )
01331 {
01332 T1_Parser parser = &loader->parser;
01333 PS_Table table = &loader->subrs;
01334 FT_Memory memory = parser->root.memory;
01335 FT_Error error;
01336 FT_Int num_subrs;
01337
01338 PSAux_Service psaux = (PSAux_Service)face->psaux;
01339
01340
01341 T1_Skip_Spaces( parser );
01342
01343
01344 if ( parser->root.cursor < parser->root.limit &&
01345 *parser->root.cursor == '[' )
01346 {
01347 T1_Skip_PS_Token( parser );
01348 T1_Skip_Spaces ( parser );
01349 if ( parser->root.cursor >= parser->root.limit ||
01350 *parser->root.cursor != ']' )
01351 parser->root.error = T1_Err_Invalid_File_Format;
01352 return;
01353 }
01354
01355 num_subrs = (FT_Int)T1_ToInt( parser );
01356
01357
01358 T1_Skip_PS_Token( parser );
01359 if ( parser->root.error )
01360 return;
01361 T1_Skip_Spaces( parser );
01362
01363
01364
01365 if ( !loader->num_subrs )
01366 {
01367 error = psaux->ps_table_funcs->init( table, num_subrs, memory );
01368 if ( error )
01369 goto Fail;
01370 }
01371
01372
01373
01374
01375
01376 for (;;)
01377 {
01378 FT_Long idx, size;
01379 FT_Byte* base;
01380
01381
01382
01383 if ( ft_strncmp( (char*)parser->root.cursor, "dup", 3 ) != 0 )
01384 break;
01385
01386 T1_Skip_PS_Token( parser );
01387
01388 idx = T1_ToInt( parser );
01389
01390 if ( !read_binary_data( parser, &size, &base ) )
01391 return;
01392
01393
01394
01395
01396
01397 T1_Skip_PS_Token( parser );
01398 if ( parser->root.error )
01399 return;
01400 T1_Skip_Spaces ( parser );
01401
01402 if ( ft_strncmp( (char*)parser->root.cursor, "put", 3 ) == 0 )
01403 {
01404 T1_Skip_PS_Token( parser );
01405 T1_Skip_Spaces ( parser );
01406 }
01407
01408
01409 if ( loader->num_subrs )
01410 continue;
01411
01412
01413
01414
01415
01416
01417 if ( face->type1.private_dict.lenIV >= 0 )
01418 {
01419 FT_Byte* temp;
01420
01421
01422
01423
01424
01425 if ( size < face->type1.private_dict.lenIV )
01426 {
01427 error = T1_Err_Invalid_File_Format;
01428 goto Fail;
01429 }
01430
01431
01432 if ( FT_ALLOC( temp, size ) )
01433 goto Fail;
01434 FT_MEM_COPY( temp, base, size );
01435 psaux->t1_decrypt( temp, size, 4330 );
01436 size -= face->type1.private_dict.lenIV;
01437 error = T1_Add_Table( table, (FT_Int)idx,
01438 temp + face->type1.private_dict.lenIV, size );
01439 FT_FREE( temp );
01440 }
01441 else
01442 error = T1_Add_Table( table, (FT_Int)idx, base, size );
01443 if ( error )
01444 goto Fail;
01445 }
01446
01447 if ( !loader->num_subrs )
01448 loader->num_subrs = num_subrs;
01449
01450 return;
01451
01452 Fail:
01453 parser->root.error = error;
01454 }
01455
01456
01457 #define TABLE_EXTEND 5
01458
01459
01460 static void
01461 parse_charstrings( T1_Face face,
01462 T1_Loader loader )
01463 {
01464 T1_Parser parser = &loader->parser;
01465 PS_Table code_table = &loader->charstrings;
01466 PS_Table name_table = &loader->glyph_names;
01467 PS_Table swap_table = &loader->swap_table;
01468 FT_Memory memory = parser->root.memory;
01469 FT_Error error;
01470
01471 PSAux_Service psaux = (PSAux_Service)face->psaux;
01472
01473 FT_Byte* cur;
01474 FT_Byte* limit = parser->root.limit;
01475 FT_Int n, num_glyphs;
01476 FT_UInt notdef_index = 0;
01477 FT_Byte notdef_found = 0;
01478
01479
01480 num_glyphs = (FT_Int)T1_ToInt( parser );
01481
01482
01483 if ( num_glyphs == 0 || parser->root.error )
01484 return;
01485
01486
01487
01488
01489
01490
01491
01492
01493 if ( !loader->num_glyphs )
01494 {
01495 error = psaux->ps_table_funcs->init(
01496 code_table, num_glyphs + 1 + TABLE_EXTEND, memory );
01497 if ( error )
01498 goto Fail;
01499
01500 error = psaux->ps_table_funcs->init(
01501 name_table, num_glyphs + 1 + TABLE_EXTEND, memory );
01502 if ( error )
01503 goto Fail;
01504
01505
01506
01507
01508 error = psaux->ps_table_funcs->init( swap_table, 4, memory );
01509 if ( error )
01510 goto Fail;
01511 }
01512
01513 n = 0;
01514
01515 for (;;)
01516 {
01517 FT_Long size;
01518 FT_Byte* base;
01519
01520
01521
01522
01523
01524 T1_Skip_Spaces( parser );
01525
01526 cur = parser->root.cursor;
01527 if ( cur >= limit )
01528 break;
01529
01530
01531 if ( cur + 3 < limit && IS_PS_DELIM( cur[3] ) )
01532 {
01533 if ( cur[0] == 'd' &&
01534 cur[1] == 'e' &&
01535 cur[2] == 'f' )
01536 {
01537
01538
01539
01540
01541
01542
01543
01544
01545
01546
01547 if ( n )
01548 break;
01549 }
01550
01551 if ( cur[0] == 'e' &&
01552 cur[1] == 'n' &&
01553 cur[2] == 'd' )
01554 break;
01555 }
01556
01557 T1_Skip_PS_Token( parser );
01558 if ( parser->root.error )
01559 return;
01560
01561 if ( *cur == '/' )
01562 {
01563 FT_PtrDist len;
01564
01565
01566 if ( cur + 1 >= limit )
01567 {
01568 error = T1_Err_Invalid_File_Format;
01569 goto Fail;
01570 }
01571
01572 cur++;
01573 len = parser->root.cursor - cur;
01574
01575 if ( !read_binary_data( parser, &size, &base ) )
01576 return;
01577
01578
01579
01580
01581 if ( loader->num_glyphs )
01582 continue;
01583
01584 error = T1_Add_Table( name_table, n, cur, len + 1 );
01585 if ( error )
01586 goto Fail;
01587
01588
01589 name_table->elements[n][len] = '\0';
01590
01591
01592 if ( *cur == '.' &&
01593 ft_strcmp( ".notdef",
01594 (const char*)(name_table->elements[n]) ) == 0 )
01595 {
01596 notdef_index = n;
01597 notdef_found = 1;
01598 }
01599
01600 if ( face->type1.private_dict.lenIV >= 0 &&
01601 n < num_glyphs + TABLE_EXTEND )
01602 {
01603 FT_Byte* temp;
01604
01605
01606 if ( size <= face->type1.private_dict.lenIV )
01607 {
01608 error = T1_Err_Invalid_File_Format;
01609 goto Fail;
01610 }
01611
01612
01613 if ( FT_ALLOC( temp, size ) )
01614 goto Fail;
01615 FT_MEM_COPY( temp, base, size );
01616 psaux->t1_decrypt( temp, size, 4330 );
01617 size -= face->type1.private_dict.lenIV;
01618 error = T1_Add_Table( code_table, n,
01619 temp + face->type1.private_dict.lenIV, size );
01620 FT_FREE( temp );
01621 }
01622 else
01623 error = T1_Add_Table( code_table, n, base, size );
01624 if ( error )
01625 goto Fail;
01626
01627 n++;
01628 }
01629 }
01630
01631 loader->num_glyphs = n;
01632
01633
01634 if ( notdef_found &&
01635 ft_strcmp( ".notdef", (const char*)name_table->elements[0] ) )
01636 {
01637
01638
01639
01640
01641
01642
01643
01644 error = T1_Add_Table( swap_table, 0,
01645 name_table->elements[0],
01646 name_table->lengths [0] );
01647 if ( error )
01648 goto Fail;
01649
01650
01651 error = T1_Add_Table( swap_table, 1,
01652 code_table->elements[0],
01653 code_table->lengths [0] );
01654 if ( error )
01655 goto Fail;
01656
01657
01658 error = T1_Add_Table( swap_table, 2,
01659 name_table->elements[notdef_index],
01660 name_table->lengths [notdef_index] );
01661 if ( error )
01662 goto Fail;
01663
01664
01665 error = T1_Add_Table( swap_table, 3,
01666 code_table->elements[notdef_index],
01667 code_table->lengths [notdef_index] );
01668 if ( error )
01669 goto Fail;
01670
01671 error = T1_Add_Table( name_table, notdef_index,
01672 swap_table->elements[0],
01673 swap_table->lengths [0] );
01674 if ( error )
01675 goto Fail;
01676
01677 error = T1_Add_Table( code_table, notdef_index,
01678 swap_table->elements[1],
01679 swap_table->lengths [1] );
01680 if ( error )
01681 goto Fail;
01682
01683 error = T1_Add_Table( name_table, 0,
01684 swap_table->elements[2],
01685 swap_table->lengths [2] );
01686 if ( error )
01687 goto Fail;
01688
01689 error = T1_Add_Table( code_table, 0,
01690 swap_table->elements[3],
01691 swap_table->lengths [3] );
01692 if ( error )
01693 goto Fail;
01694
01695 }
01696 else if ( !notdef_found )
01697 {
01698
01699
01700
01701
01702
01703
01704 FT_Byte notdef_glyph[] = { 0x8B, 0xF7, 0xE1, 0x0D, 0x0E };
01705 char* notdef_name = (char *)".notdef";
01706
01707
01708 error = T1_Add_Table( swap_table, 0,
01709 name_table->elements[0],
01710 name_table->lengths [0] );
01711 if ( error )
01712 goto Fail;
01713
01714 error = T1_Add_Table( swap_table, 1,
01715 code_table->elements[0],
01716 code_table->lengths [0] );
01717 if ( error )
01718 goto Fail;
01719
01720 error = T1_Add_Table( name_table, 0, notdef_name, 8 );
01721 if ( error )
01722 goto Fail;
01723
01724 error = T1_Add_Table( code_table, 0, notdef_glyph, 5 );
01725
01726 if ( error )
01727 goto Fail;
01728
01729 error = T1_Add_Table( name_table, n,
01730 swap_table->elements[0],
01731 swap_table->lengths [0] );
01732 if ( error )
01733 goto Fail;
01734
01735 error = T1_Add_Table( code_table, n,
01736 swap_table->elements[1],
01737 swap_table->lengths [1] );
01738 if ( error )
01739 goto Fail;
01740
01741
01742 loader->num_glyphs += 1;
01743 }
01744
01745 return;
01746
01747 Fail:
01748 parser->root.error = error;
01749 }
01750
01751
01752
01753
01754
01755
01756
01757
01758
01759
01760 static
01761 const T1_FieldRec t1_keywords[] =
01762 {
01763
01764 #include "t1tokens.h"
01765
01766
01767 T1_FIELD_CALLBACK( "FontMatrix", parse_font_matrix,
01768 T1_FIELD_DICT_FONTDICT )
01769 T1_FIELD_CALLBACK( "Encoding", parse_encoding,
01770 T1_FIELD_DICT_FONTDICT )
01771 T1_FIELD_CALLBACK( "Subrs", parse_subrs,
01772 T1_FIELD_DICT_PRIVATE )
01773 T1_FIELD_CALLBACK( "CharStrings", parse_charstrings,
01774 T1_FIELD_DICT_PRIVATE )
01775 T1_FIELD_CALLBACK( "Private", parse_private,
01776 T1_FIELD_DICT_FONTDICT )
01777
01778 #ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT
01779 T1_FIELD_CALLBACK( "BlendDesignPositions", parse_blend_design_positions,
01780 T1_FIELD_DICT_FONTDICT )
01781 T1_FIELD_CALLBACK( "BlendDesignMap", parse_blend_design_map,
01782 T1_FIELD_DICT_FONTDICT )
01783 T1_FIELD_CALLBACK( "BlendAxisTypes", parse_blend_axis_types,
01784 T1_FIELD_DICT_FONTDICT )
01785 T1_FIELD_CALLBACK( "WeightVector", parse_weight_vector,
01786 T1_FIELD_DICT_FONTDICT )
01787 T1_FIELD_CALLBACK( "BuildCharArray", parse_buildchar,
01788 T1_FIELD_DICT_PRIVATE )
01789 #endif
01790
01791 { 0, T1_FIELD_LOCATION_CID_INFO, T1_FIELD_TYPE_NONE, 0, 0, 0, 0, 0, 0 }
01792 };
01793
01794
01795 #define T1_FIELD_COUNT \
01796 ( sizeof ( t1_keywords ) / sizeof ( t1_keywords[0] ) )
01797
01798
01799 static FT_Error
01800 parse_dict( T1_Face face,
01801 T1_Loader loader,
01802 FT_Byte* base,
01803 FT_Long size )
01804 {
01805 T1_Parser parser = &loader->parser;
01806 FT_Byte *limit, *start_binary = NULL;
01807 FT_Bool have_integer = 0;
01808
01809
01810 parser->root.cursor = base;
01811 parser->root.limit = base + size;
01812 parser->root.error = T1_Err_Ok;
01813
01814 limit = parser->root.limit;
01815
01816 T1_Skip_Spaces( parser );
01817
01818 while ( parser->root.cursor < limit )
01819 {
01820 FT_Byte* cur;
01821
01822
01823 cur = parser->root.cursor;
01824
01825
01826 if ( IS_PS_TOKEN( cur, limit, "eexec" ) )
01827 break;
01828
01829
01830 else if ( IS_PS_TOKEN( cur, limit, "closefile" ) )
01831 break;
01832
01833
01834
01835 else if ( IS_PS_TOKEN( cur, limit, "FontDirectory" ) )
01836 {
01837 if ( loader->keywords_encountered & T1_PRIVATE )
01838 loader->keywords_encountered |=
01839 T1_FONTDIR_AFTER_PRIVATE;
01840 parser->root.cursor += 13;
01841 }
01842
01843
01844 else if ( ft_isdigit( *cur ) )
01845 {
01846 start_binary = cur;
01847 T1_Skip_PS_Token( parser );
01848 if ( parser->root.error )
01849 goto Exit;
01850 have_integer = 1;
01851 }
01852
01853
01854
01855
01856 else if ( *cur == 'R' && cur + 6 < limit && *(cur + 1) == 'D' &&
01857 have_integer )
01858 {
01859 FT_Long s;
01860 FT_Byte* b;
01861
01862
01863 parser->root.cursor = start_binary;
01864 if ( !read_binary_data( parser, &s, &b ) )
01865 return T1_Err_Invalid_File_Format;
01866 have_integer = 0;
01867 }
01868
01869 else if ( *cur == '-' && cur + 6 < limit && *(cur + 1) == '|' &&
01870 have_integer )
01871 {
01872 FT_Long s;
01873 FT_Byte* b;
01874
01875
01876 parser->root.cursor = start_binary;
01877 if ( !read_binary_data( parser, &s, &b ) )
01878 return T1_Err_Invalid_File_Format;
01879 have_integer = 0;
01880 }
01881
01882
01883 else if ( *cur == '/' && cur + 2 < limit )
01884 {
01885 FT_PtrDist len;
01886
01887
01888 cur++;
01889
01890 parser->root.cursor = cur;
01891 T1_Skip_PS_Token( parser );
01892 if ( parser->root.error )
01893 goto Exit;
01894
01895 len = parser->root.cursor - cur;
01896
01897 if ( len > 0 && len < 22 && parser->root.cursor < limit )
01898 {
01899
01900 T1_Field keyword = (T1_Field)t1_keywords;
01901
01902
01903 for (;;)
01904 {
01905 FT_Byte* name;
01906
01907
01908 name = (FT_Byte*)keyword->ident;
01909 if ( !name )
01910 break;
01911
01912 if ( cur[0] == name[0] &&
01913 len == (FT_PtrDist)ft_strlen( (const char *)name ) &&
01914 ft_memcmp( cur, name, len ) == 0 )
01915 {
01916
01917
01918
01919
01920
01921
01922
01923
01924
01925
01926
01927
01928
01929
01930
01931
01932
01933
01934
01935
01936
01937
01938
01939
01940
01941
01942
01943 const FT_UInt dict =
01944 ( loader->keywords_encountered & T1_PRIVATE )
01945 ? T1_FIELD_DICT_PRIVATE
01946 : T1_FIELD_DICT_FONTDICT;
01947
01948 if ( !( dict & keyword->dict ) )
01949 {
01950 FT_TRACE1(( "parse_dict: found %s but ignoring it "
01951 "since it is in the wrong dictionary\n",
01952 keyword->ident ));
01953 break;
01954 }
01955
01956 if ( !( loader->keywords_encountered &
01957 T1_FONTDIR_AFTER_PRIVATE ) ||
01958 ft_strcmp( (const char*)name, "CharStrings" ) == 0 )
01959 {
01960 parser->root.error = t1_load_keyword( face,
01961 loader,
01962 keyword );
01963 if ( parser->root.error != T1_Err_Ok )
01964 {
01965 if ( FT_ERROR_BASE( parser->root.error ) == FT_Err_Ignore )
01966 parser->root.error = T1_Err_Ok;
01967 else
01968 return parser->root.error;
01969 }
01970 }
01971 break;
01972 }
01973
01974 keyword++;
01975 }
01976 }
01977
01978 have_integer = 0;
01979 }
01980 else
01981 {
01982 T1_Skip_PS_Token( parser );
01983 if ( parser->root.error )
01984 goto Exit;
01985 have_integer = 0;
01986 }
01987
01988 T1_Skip_Spaces( parser );
01989 }
01990
01991 Exit:
01992 return parser->root.error;
01993 }
01994
01995
01996 static void
01997 t1_init_loader( T1_Loader loader,
01998 T1_Face face )
01999 {
02000 FT_UNUSED( face );
02001
02002 FT_MEM_ZERO( loader, sizeof ( *loader ) );
02003 loader->num_glyphs = 0;
02004 loader->num_chars = 0;
02005
02006
02007 loader->encoding_table.init = 0;
02008 loader->charstrings.init = 0;
02009 loader->glyph_names.init = 0;
02010 loader->subrs.init = 0;
02011 loader->swap_table.init = 0;
02012 loader->fontdata = 0;
02013 loader->keywords_encountered = 0;
02014 }
02015
02016
02017 static void
02018 t1_done_loader( T1_Loader loader )
02019 {
02020 T1_Parser parser = &loader->parser;
02021
02022
02023
02024 T1_Release_Table( &loader->encoding_table );
02025 T1_Release_Table( &loader->charstrings );
02026 T1_Release_Table( &loader->glyph_names );
02027 T1_Release_Table( &loader->swap_table );
02028 T1_Release_Table( &loader->subrs );
02029
02030
02031 T1_Finalize_Parser( parser );
02032 }
02033
02034
02035 FT_LOCAL_DEF( FT_Error )
02036 T1_Open_Face( T1_Face face )
02037 {
02038 T1_LoaderRec loader;
02039 T1_Parser parser;
02040 T1_Font type1 = &face->type1;
02041 PS_Private priv = &type1->private_dict;
02042 FT_Error error;
02043
02044 PSAux_Service psaux = (PSAux_Service)face->psaux;
02045
02046
02047 t1_init_loader( &loader, face );
02048
02049
02050 face->ndv_idx = -1;
02051 face->cdv_idx = -1;
02052 face->len_buildchar = 0;
02053
02054 priv->blue_shift = 7;
02055 priv->blue_fuzz = 1;
02056 priv->lenIV = 4;
02057 priv->expansion_factor = (FT_Fixed)( 0.06 * 0x10000L );
02058 priv->blue_scale = (FT_Fixed)( 0.039625 * 0x10000L * 1000 );
02059
02060 parser = &loader.parser;
02061 error = T1_New_Parser( parser,
02062 face->root.stream,
02063 face->root.memory,
02064 psaux );
02065 if ( error )
02066 goto Exit;
02067
02068 error = parse_dict( face, &loader,
02069 parser->base_dict, parser->base_len );
02070 if ( error )
02071 goto Exit;
02072
02073 error = T1_Get_Private_Dict( parser, psaux );
02074 if ( error )
02075 goto Exit;
02076
02077 error = parse_dict( face, &loader,
02078 parser->private_dict, parser->private_len );
02079 if ( error )
02080 goto Exit;
02081
02082
02083 priv->num_blue_values &= ~1;
02084
02085 #ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT
02086
02087 if ( face->blend &&
02088 face->blend->num_default_design_vector != 0 &&
02089 face->blend->num_default_design_vector != face->blend->num_axis )
02090 {
02091
02092 FT_ERROR(( "T1_Open_Face(): /DesignVector contains %u entries "
02093 "while there are %u axes.\n",
02094 face->blend->num_default_design_vector,
02095 face->blend->num_axis ));
02096
02097 face->blend->num_default_design_vector = 0;
02098 }
02099
02100
02101
02102 if ( face->blend &&
02103 ( !face->blend->num_designs || !face->blend->num_axis ) )
02104 T1_Done_Blend( face );
02105
02106
02107 if ( face->blend )
02108 {
02109 FT_UInt i;
02110
02111
02112 for ( i = 0; i < face->blend->num_axis; i++ )
02113 if ( !face->blend->design_map[i].num_points )
02114 {
02115 T1_Done_Blend( face );
02116 break;
02117 }
02118 }
02119
02120 if ( face->blend )
02121 {
02122 if ( face->len_buildchar > 0 )
02123 {
02124 FT_Memory memory = face->root.memory;
02125
02126
02127 if ( FT_NEW_ARRAY( face->buildchar, face->len_buildchar ) )
02128 {
02129 FT_ERROR(( "T1_Open_Face: cannot allocate BuildCharArray\n" ));
02130 face->len_buildchar = 0;
02131 goto Exit;
02132 }
02133 }
02134 }
02135
02136 #endif
02137
02138
02139
02140 type1->num_glyphs = loader.num_glyphs;
02141
02142 if ( loader.subrs.init )
02143 {
02144 loader.subrs.init = 0;
02145 type1->num_subrs = loader.num_subrs;
02146 type1->subrs_block = loader.subrs.block;
02147 type1->subrs = loader.subrs.elements;
02148 type1->subrs_len = loader.subrs.lengths;
02149 }
02150
02151 #ifdef FT_CONFIG_OPTION_INCREMENTAL
02152 if ( !face->root.internal->incremental_interface )
02153 #endif
02154 if ( !loader.charstrings.init )
02155 {
02156 FT_ERROR(( "T1_Open_Face: no `/CharStrings' array in face\n" ));
02157 error = T1_Err_Invalid_File_Format;
02158 }
02159
02160 loader.charstrings.init = 0;
02161 type1->charstrings_block = loader.charstrings.block;
02162 type1->charstrings = loader.charstrings.elements;
02163 type1->charstrings_len = loader.charstrings.lengths;
02164
02165
02166
02167 type1->glyph_names_block = loader.glyph_names.block;
02168 type1->glyph_names = (FT_String**)loader.glyph_names.elements;
02169 loader.glyph_names.block = 0;
02170 loader.glyph_names.elements = 0;
02171
02172
02173 if ( type1->encoding_type == T1_ENCODING_TYPE_ARRAY )
02174 {
02175 FT_Int charcode, idx, min_char, max_char;
02176 FT_Byte* char_name;
02177 FT_Byte* glyph_name;
02178
02179
02180
02181
02182
02183
02184
02185 min_char = 0;
02186 max_char = 0;
02187
02188 charcode = 0;
02189 for ( ; charcode < loader.encoding_table.max_elems; charcode++ )
02190 {
02191 type1->encoding.char_index[charcode] = 0;
02192 type1->encoding.char_name [charcode] = (char *)".notdef";
02193
02194 char_name = loader.encoding_table.elements[charcode];
02195 if ( char_name )
02196 for ( idx = 0; idx < type1->num_glyphs; idx++ )
02197 {
02198 glyph_name = (FT_Byte*)type1->glyph_names[idx];
02199 if ( ft_strcmp( (const char*)char_name,
02200 (const char*)glyph_name ) == 0 )
02201 {
02202 type1->encoding.char_index[charcode] = (FT_UShort)idx;
02203 type1->encoding.char_name [charcode] = (char*)glyph_name;
02204
02205
02206
02207 if ( ft_strcmp( (const char*)".notdef",
02208 (const char*)glyph_name ) != 0 )
02209 {
02210 if ( charcode < min_char )
02211 min_char = charcode;
02212 if ( charcode >= max_char )
02213 max_char = charcode + 1;
02214 }
02215 break;
02216 }
02217 }
02218 }
02219
02220 type1->encoding.code_first = min_char;
02221 type1->encoding.code_last = max_char;
02222 type1->encoding.num_chars = loader.num_chars;
02223 }
02224
02225 Exit:
02226 t1_done_loader( &loader );
02227 return error;
02228 }
02229
02230
02231