00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <ft2build.h>
00020 #include FT_INTERNAL_DEBUG_H
00021 #include FT_INTERNAL_OBJECTS_H
00022 #include FT_INTERNAL_STREAM_H
00023 #include FT_SERVICE_POSTSCRIPT_CMAPS_H
00024 #include FT_TRUETYPE_TAGS_H
00025 #include FT_TYPE1_TABLES_H
00026
00027 #include "cffload.h"
00028 #include "cffparse.h"
00029
00030 #include "cfferrs.h"
00031
00032
00033 #if 1
00034
00035 static const FT_UShort cff_isoadobe_charset[229] =
00036 {
00037 0, 1, 2, 3, 4, 5, 6, 7,
00038 8, 9, 10, 11, 12, 13, 14, 15,
00039 16, 17, 18, 19, 20, 21, 22, 23,
00040 24, 25, 26, 27, 28, 29, 30, 31,
00041 32, 33, 34, 35, 36, 37, 38, 39,
00042 40, 41, 42, 43, 44, 45, 46, 47,
00043 48, 49, 50, 51, 52, 53, 54, 55,
00044 56, 57, 58, 59, 60, 61, 62, 63,
00045 64, 65, 66, 67, 68, 69, 70, 71,
00046 72, 73, 74, 75, 76, 77, 78, 79,
00047 80, 81, 82, 83, 84, 85, 86, 87,
00048 88, 89, 90, 91, 92, 93, 94, 95,
00049 96, 97, 98, 99, 100, 101, 102, 103,
00050 104, 105, 106, 107, 108, 109, 110, 111,
00051 112, 113, 114, 115, 116, 117, 118, 119,
00052 120, 121, 122, 123, 124, 125, 126, 127,
00053 128, 129, 130, 131, 132, 133, 134, 135,
00054 136, 137, 138, 139, 140, 141, 142, 143,
00055 144, 145, 146, 147, 148, 149, 150, 151,
00056 152, 153, 154, 155, 156, 157, 158, 159,
00057 160, 161, 162, 163, 164, 165, 166, 167,
00058 168, 169, 170, 171, 172, 173, 174, 175,
00059 176, 177, 178, 179, 180, 181, 182, 183,
00060 184, 185, 186, 187, 188, 189, 190, 191,
00061 192, 193, 194, 195, 196, 197, 198, 199,
00062 200, 201, 202, 203, 204, 205, 206, 207,
00063 208, 209, 210, 211, 212, 213, 214, 215,
00064 216, 217, 218, 219, 220, 221, 222, 223,
00065 224, 225, 226, 227, 228
00066 };
00067
00068 static const FT_UShort cff_expert_charset[166] =
00069 {
00070 0, 1, 229, 230, 231, 232, 233, 234,
00071 235, 236, 237, 238, 13, 14, 15, 99,
00072 239, 240, 241, 242, 243, 244, 245, 246,
00073 247, 248, 27, 28, 249, 250, 251, 252,
00074 253, 254, 255, 256, 257, 258, 259, 260,
00075 261, 262, 263, 264, 265, 266, 109, 110,
00076 267, 268, 269, 270, 271, 272, 273, 274,
00077 275, 276, 277, 278, 279, 280, 281, 282,
00078 283, 284, 285, 286, 287, 288, 289, 290,
00079 291, 292, 293, 294, 295, 296, 297, 298,
00080 299, 300, 301, 302, 303, 304, 305, 306,
00081 307, 308, 309, 310, 311, 312, 313, 314,
00082 315, 316, 317, 318, 158, 155, 163, 319,
00083 320, 321, 322, 323, 324, 325, 326, 150,
00084 164, 169, 327, 328, 329, 330, 331, 332,
00085 333, 334, 335, 336, 337, 338, 339, 340,
00086 341, 342, 343, 344, 345, 346, 347, 348,
00087 349, 350, 351, 352, 353, 354, 355, 356,
00088 357, 358, 359, 360, 361, 362, 363, 364,
00089 365, 366, 367, 368, 369, 370, 371, 372,
00090 373, 374, 375, 376, 377, 378
00091 };
00092
00093 static const FT_UShort cff_expertsubset_charset[87] =
00094 {
00095 0, 1, 231, 232, 235, 236, 237, 238,
00096 13, 14, 15, 99, 239, 240, 241, 242,
00097 243, 244, 245, 246, 247, 248, 27, 28,
00098 249, 250, 251, 253, 254, 255, 256, 257,
00099 258, 259, 260, 261, 262, 263, 264, 265,
00100 266, 109, 110, 267, 268, 269, 270, 272,
00101 300, 301, 302, 305, 314, 315, 158, 155,
00102 163, 320, 321, 322, 323, 324, 325, 326,
00103 150, 164, 169, 327, 328, 329, 330, 331,
00104 332, 333, 334, 335, 336, 337, 338, 339,
00105 340, 341, 342, 343, 344, 345, 346
00106 };
00107
00108 static const FT_UShort cff_standard_encoding[256] =
00109 {
00110 0, 0, 0, 0, 0, 0, 0, 0,
00111 0, 0, 0, 0, 0, 0, 0, 0,
00112 0, 0, 0, 0, 0, 0, 0, 0,
00113 0, 0, 0, 0, 0, 0, 0, 0,
00114 1, 2, 3, 4, 5, 6, 7, 8,
00115 9, 10, 11, 12, 13, 14, 15, 16,
00116 17, 18, 19, 20, 21, 22, 23, 24,
00117 25, 26, 27, 28, 29, 30, 31, 32,
00118 33, 34, 35, 36, 37, 38, 39, 40,
00119 41, 42, 43, 44, 45, 46, 47, 48,
00120 49, 50, 51, 52, 53, 54, 55, 56,
00121 57, 58, 59, 60, 61, 62, 63, 64,
00122 65, 66, 67, 68, 69, 70, 71, 72,
00123 73, 74, 75, 76, 77, 78, 79, 80,
00124 81, 82, 83, 84, 85, 86, 87, 88,
00125 89, 90, 91, 92, 93, 94, 95, 0,
00126 0, 0, 0, 0, 0, 0, 0, 0,
00127 0, 0, 0, 0, 0, 0, 0, 0,
00128 0, 0, 0, 0, 0, 0, 0, 0,
00129 0, 0, 0, 0, 0, 0, 0, 0,
00130 0, 96, 97, 98, 99, 100, 101, 102,
00131 103, 104, 105, 106, 107, 108, 109, 110,
00132 0, 111, 112, 113, 114, 0, 115, 116,
00133 117, 118, 119, 120, 121, 122, 0, 123,
00134 0, 124, 125, 126, 127, 128, 129, 130,
00135 131, 0, 132, 133, 0, 134, 135, 136,
00136 137, 0, 0, 0, 0, 0, 0, 0,
00137 0, 0, 0, 0, 0, 0, 0, 0,
00138 0, 138, 0, 139, 0, 0, 0, 0,
00139 140, 141, 142, 143, 0, 0, 0, 0,
00140 0, 144, 0, 0, 0, 145, 0, 0,
00141 146, 147, 148, 149, 0, 0, 0, 0
00142 };
00143
00144 static const FT_UShort cff_expert_encoding[256] =
00145 {
00146 0, 0, 0, 0, 0, 0, 0, 0,
00147 0, 0, 0, 0, 0, 0, 0, 0,
00148 0, 0, 0, 0, 0, 0, 0, 0,
00149 0, 0, 0, 0, 0, 0, 0, 0,
00150 1, 229, 230, 0, 231, 232, 233, 234,
00151 235, 236, 237, 238, 13, 14, 15, 99,
00152 239, 240, 241, 242, 243, 244, 245, 246,
00153 247, 248, 27, 28, 249, 250, 251, 252,
00154 0, 253, 254, 255, 256, 257, 0, 0,
00155 0, 258, 0, 0, 259, 260, 261, 262,
00156 0, 0, 263, 264, 265, 0, 266, 109,
00157 110, 267, 268, 269, 0, 270, 271, 272,
00158 273, 274, 275, 276, 277, 278, 279, 280,
00159 281, 282, 283, 284, 285, 286, 287, 288,
00160 289, 290, 291, 292, 293, 294, 295, 296,
00161 297, 298, 299, 300, 301, 302, 303, 0,
00162 0, 0, 0, 0, 0, 0, 0, 0,
00163 0, 0, 0, 0, 0, 0, 0, 0,
00164 0, 0, 0, 0, 0, 0, 0, 0,
00165 0, 0, 0, 0, 0, 0, 0, 0,
00166 0, 304, 305, 306, 0, 0, 307, 308,
00167 309, 310, 311, 0, 312, 0, 0, 312,
00168 0, 0, 314, 315, 0, 0, 316, 317,
00169 318, 0, 0, 0, 158, 155, 163, 319,
00170 320, 321, 322, 323, 324, 325, 0, 0,
00171 326, 150, 164, 169, 327, 328, 329, 330,
00172 331, 332, 333, 334, 335, 336, 337, 338,
00173 339, 340, 341, 342, 343, 344, 345, 346,
00174 347, 348, 349, 350, 351, 352, 353, 354,
00175 355, 356, 357, 358, 359, 360, 361, 362,
00176 363, 364, 365, 366, 367, 368, 369, 370,
00177 371, 372, 373, 374, 375, 376, 377, 378
00178 };
00179
00180 #endif
00181
00182
00183 FT_LOCAL_DEF( FT_UShort )
00184 cff_get_standard_encoding( FT_UInt charcode )
00185 {
00186 return (FT_UShort)( charcode < 256 ? cff_standard_encoding[charcode]
00187 : 0 );
00188 }
00189
00190
00191
00192
00193
00194
00195
00196
00197 #undef FT_COMPONENT
00198 #define FT_COMPONENT trace_cffload
00199
00200
00201
00202 static FT_ULong
00203 cff_index_read_offset( CFF_Index idx,
00204 FT_Error *errorp )
00205 {
00206 FT_Error error;
00207 FT_Stream stream = idx->stream;
00208 FT_Byte tmp[4];
00209 FT_ULong result = 0;
00210
00211
00212 if ( !FT_STREAM_READ( tmp, idx->off_size ) )
00213 {
00214 FT_Int nn;
00215
00216
00217 for ( nn = 0; nn < idx->off_size; nn++ )
00218 result = ( result << 8 ) | tmp[nn];
00219 }
00220
00221 *errorp = error;
00222 return result;
00223 }
00224
00225
00226 static FT_Error
00227 cff_index_init( CFF_Index idx,
00228 FT_Stream stream,
00229 FT_Bool load )
00230 {
00231 FT_Error error;
00232 FT_Memory memory = stream->memory;
00233 FT_UShort count;
00234
00235
00236 FT_MEM_ZERO( idx, sizeof ( *idx ) );
00237
00238 idx->stream = stream;
00239 idx->start = FT_STREAM_POS();
00240 if ( !FT_READ_USHORT( count ) &&
00241 count > 0 )
00242 {
00243 FT_Byte offsize;
00244 FT_ULong size;
00245
00246
00247
00248
00249 if ( FT_READ_BYTE( offsize ) )
00250 goto Exit;
00251
00252 if ( offsize < 1 || offsize > 4 )
00253 {
00254 error = FT_Err_Invalid_Table;
00255 goto Exit;
00256 }
00257
00258 idx->count = count;
00259 idx->off_size = offsize;
00260 size = (FT_ULong)( count + 1 ) * offsize;
00261
00262 idx->data_offset = idx->start + 3 + size;
00263
00264 if ( FT_STREAM_SKIP( size - offsize ) )
00265 goto Exit;
00266
00267 size = cff_index_read_offset( idx, &error );
00268 if ( error )
00269 goto Exit;
00270
00271 if ( size == 0 )
00272 {
00273 error = CFF_Err_Invalid_Table;
00274 goto Exit;
00275 }
00276
00277 idx->data_size = --size;
00278
00279 if ( load )
00280 {
00281
00282 if ( FT_FRAME_EXTRACT( size, idx->bytes ) )
00283 goto Exit;
00284 }
00285 else
00286 {
00287
00288 if ( FT_STREAM_SKIP( size ) )
00289 goto Exit;
00290 }
00291 }
00292
00293 Exit:
00294 if ( error )
00295 FT_FREE( idx->offsets );
00296
00297 return error;
00298 }
00299
00300
00301 static void
00302 cff_index_done( CFF_Index idx )
00303 {
00304 if ( idx->stream )
00305 {
00306 FT_Stream stream = idx->stream;
00307 FT_Memory memory = stream->memory;
00308
00309
00310 if ( idx->bytes )
00311 FT_FRAME_RELEASE( idx->bytes );
00312
00313 FT_FREE( idx->offsets );
00314 FT_MEM_ZERO( idx, sizeof ( *idx ) );
00315 }
00316 }
00317
00318
00319 static FT_Error
00320 cff_index_load_offsets( CFF_Index idx )
00321 {
00322 FT_Error error = CFF_Err_Ok;
00323 FT_Stream stream = idx->stream;
00324 FT_Memory memory = stream->memory;
00325
00326
00327 if ( idx->count > 0 && idx->offsets == NULL )
00328 {
00329 FT_Byte offsize = idx->off_size;
00330 FT_ULong data_size;
00331 FT_Byte* p;
00332 FT_Byte* p_end;
00333 FT_ULong* poff;
00334
00335
00336 data_size = (FT_ULong)( idx->count + 1 ) * offsize;
00337
00338 if ( FT_NEW_ARRAY( idx->offsets, idx->count + 1 ) ||
00339 FT_STREAM_SEEK( idx->start + 3 ) ||
00340 FT_FRAME_ENTER( data_size ) )
00341 goto Exit;
00342
00343 poff = idx->offsets;
00344 p = (FT_Byte*)stream->cursor;
00345 p_end = p + data_size;
00346
00347 switch ( offsize )
00348 {
00349 case 1:
00350 for ( ; p < p_end; p++, poff++ )
00351 poff[0] = p[0];
00352 break;
00353
00354 case 2:
00355 for ( ; p < p_end; p += 2, poff++ )
00356 poff[0] = FT_PEEK_USHORT( p );
00357 break;
00358
00359 case 3:
00360 for ( ; p < p_end; p += 3, poff++ )
00361 poff[0] = FT_PEEK_OFF3( p );
00362 break;
00363
00364 default:
00365 for ( ; p < p_end; p += 4, poff++ )
00366 poff[0] = FT_PEEK_ULONG( p );
00367 }
00368
00369 FT_FRAME_EXIT();
00370 }
00371
00372 Exit:
00373 if ( error )
00374 FT_FREE( idx->offsets );
00375
00376 return error;
00377 }
00378
00379
00380
00381 static FT_Error
00382 cff_index_get_pointers( CFF_Index idx,
00383 FT_Byte*** table )
00384 {
00385 FT_Error error = CFF_Err_Ok;
00386 FT_Memory memory = idx->stream->memory;
00387 FT_ULong n, offset, old_offset;
00388 FT_Byte** t;
00389
00390
00391 *table = 0;
00392
00393 if ( idx->offsets == NULL )
00394 {
00395 error = cff_index_load_offsets( idx );
00396 if ( error )
00397 goto Exit;
00398 }
00399
00400 if ( idx->count > 0 && !FT_NEW_ARRAY( t, idx->count + 1 ) )
00401 {
00402 old_offset = 1;
00403 for ( n = 0; n <= idx->count; n++ )
00404 {
00405
00406 offset = idx->offsets[n];
00407 if ( !offset )
00408 offset = old_offset;
00409
00410
00411 else if ( offset < old_offset )
00412 offset = old_offset;
00413
00414 else if ( offset - 1 >= idx->data_size && n < idx->count )
00415 offset = old_offset;
00416
00417 t[n] = idx->bytes + offset - 1;
00418
00419 old_offset = offset;
00420 }
00421 *table = t;
00422 }
00423
00424 Exit:
00425 return error;
00426 }
00427
00428
00429 FT_LOCAL_DEF( FT_Error )
00430 cff_index_access_element( CFF_Index idx,
00431 FT_UInt element,
00432 FT_Byte** pbytes,
00433 FT_ULong* pbyte_len )
00434 {
00435 FT_Error error = CFF_Err_Ok;
00436
00437
00438 if ( idx && idx->count > element )
00439 {
00440
00441 FT_Stream stream = idx->stream;
00442 FT_ULong off1, off2 = 0;
00443
00444
00445
00446 if ( !idx->offsets )
00447 {
00448 FT_ULong pos = element * idx->off_size;
00449
00450
00451 if ( FT_STREAM_SEEK( idx->start + 3 + pos ) )
00452 goto Exit;
00453
00454 off1 = cff_index_read_offset( idx, &error );
00455 if ( error )
00456 goto Exit;
00457
00458 if ( off1 != 0 )
00459 {
00460 do
00461 {
00462 element++;
00463 off2 = cff_index_read_offset( idx, &error );
00464 }
00465 while ( off2 == 0 && element < idx->count );
00466 }
00467 }
00468 else
00469 {
00470 off1 = idx->offsets[element];
00471 if ( off1 )
00472 {
00473 do
00474 {
00475 element++;
00476 off2 = idx->offsets[element];
00477
00478 } while ( off2 == 0 && element < idx->count );
00479 }
00480 }
00481
00482
00483 if ( off1 && off2 > off1 )
00484 {
00485 *pbyte_len = off2 - off1;
00486
00487 if ( idx->bytes )
00488 {
00489
00490 *pbytes = idx->bytes + off1 - 1;
00491 }
00492 else
00493 {
00494
00495 if ( FT_STREAM_SEEK( idx->data_offset + off1 - 1 ) ||
00496 FT_FRAME_EXTRACT( off2 - off1, *pbytes ) )
00497 goto Exit;
00498 }
00499 }
00500 else
00501 {
00502
00503 *pbytes = 0;
00504 *pbyte_len = 0;
00505 }
00506 }
00507 else
00508 error = CFF_Err_Invalid_Argument;
00509
00510 Exit:
00511 return error;
00512 }
00513
00514
00515 FT_LOCAL_DEF( void )
00516 cff_index_forget_element( CFF_Index idx,
00517 FT_Byte** pbytes )
00518 {
00519 if ( idx->bytes == 0 )
00520 {
00521 FT_Stream stream = idx->stream;
00522
00523
00524 FT_FRAME_RELEASE( *pbytes );
00525 }
00526 }
00527
00528
00529 FT_LOCAL_DEF( FT_String* )
00530 cff_index_get_name( CFF_Index idx,
00531 FT_UInt element )
00532 {
00533 FT_Memory memory = idx->stream->memory;
00534 FT_Byte* bytes;
00535 FT_ULong byte_len;
00536 FT_Error error;
00537 FT_String* name = 0;
00538
00539
00540 error = cff_index_access_element( idx, element, &bytes, &byte_len );
00541 if ( error )
00542 goto Exit;
00543
00544 if ( !FT_ALLOC( name, byte_len + 1 ) )
00545 {
00546 FT_MEM_COPY( name, bytes, byte_len );
00547 name[byte_len] = 0;
00548 }
00549 cff_index_forget_element( idx, &bytes );
00550
00551 Exit:
00552 return name;
00553 }
00554
00555
00556 FT_LOCAL_DEF( FT_String* )
00557 cff_index_get_sid_string( CFF_Index idx,
00558 FT_UInt sid,
00559 FT_Service_PsCMaps psnames )
00560 {
00561
00562 if ( sid == 0xFFFFU )
00563 return 0;
00564
00565
00566 if ( sid > 390 )
00567 return cff_index_get_name( idx, sid - 391 );
00568
00569
00570 if ( !psnames )
00571 return 0;
00572
00573
00574 {
00575 FT_String* name = 0;
00576 const char* adobe_name = psnames->adobe_std_strings( sid );
00577
00578
00579 if ( adobe_name )
00580 {
00581 FT_Memory memory = idx->stream->memory;
00582 FT_Error error;
00583
00584
00585 (void)FT_STRDUP( name, adobe_name );
00586
00587 FT_UNUSED( error );
00588 }
00589
00590 return name;
00591 }
00592 }
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604 static void
00605 CFF_Done_FD_Select( CFF_FDSelect fdselect,
00606 FT_Stream stream )
00607 {
00608 if ( fdselect->data )
00609 FT_FRAME_RELEASE( fdselect->data );
00610
00611 fdselect->data_size = 0;
00612 fdselect->format = 0;
00613 fdselect->range_count = 0;
00614 }
00615
00616
00617 static FT_Error
00618 CFF_Load_FD_Select( CFF_FDSelect fdselect,
00619 FT_UInt num_glyphs,
00620 FT_Stream stream,
00621 FT_ULong offset )
00622 {
00623 FT_Error error;
00624 FT_Byte format;
00625 FT_UInt num_ranges;
00626
00627
00628
00629 if ( FT_STREAM_SEEK( offset ) || FT_READ_BYTE( format ) )
00630 goto Exit;
00631
00632 fdselect->format = format;
00633 fdselect->cache_count = 0;
00634
00635 switch ( format )
00636 {
00637 case 0:
00638 fdselect->data_size = num_glyphs;
00639 goto Load_Data;
00640
00641 case 3:
00642 if ( FT_READ_USHORT( num_ranges ) )
00643 goto Exit;
00644
00645 fdselect->data_size = num_ranges * 3 + 2;
00646
00647 Load_Data:
00648 if ( FT_FRAME_EXTRACT( fdselect->data_size, fdselect->data ) )
00649 goto Exit;
00650 break;
00651
00652 default:
00653 error = CFF_Err_Invalid_File_Format;
00654 }
00655
00656 Exit:
00657 return error;
00658 }
00659
00660
00661 FT_LOCAL_DEF( FT_Byte )
00662 cff_fd_select_get( CFF_FDSelect fdselect,
00663 FT_UInt glyph_index )
00664 {
00665 FT_Byte fd = 0;
00666
00667
00668 switch ( fdselect->format )
00669 {
00670 case 0:
00671 fd = fdselect->data[glyph_index];
00672 break;
00673
00674 case 3:
00675
00676 if ( (FT_UInt)( glyph_index - fdselect->cache_first ) <
00677 fdselect->cache_count )
00678 {
00679 fd = fdselect->cache_fd;
00680 break;
00681 }
00682
00683
00684 {
00685 FT_Byte* p = fdselect->data;
00686 FT_Byte* p_limit = p + fdselect->data_size;
00687 FT_Byte fd2;
00688 FT_UInt first, limit;
00689
00690
00691 first = FT_NEXT_USHORT( p );
00692 do
00693 {
00694 if ( glyph_index < first )
00695 break;
00696
00697 fd2 = *p++;
00698 limit = FT_NEXT_USHORT( p );
00699
00700 if ( glyph_index < limit )
00701 {
00702 fd = fd2;
00703
00704
00705 fdselect->cache_first = first;
00706 fdselect->cache_count = limit-first;
00707 fdselect->cache_fd = fd2;
00708 break;
00709 }
00710 first = limit;
00711
00712 } while ( p < p_limit );
00713 }
00714 break;
00715
00716 default:
00717 ;
00718 }
00719
00720 return fd;
00721 }
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732 static FT_Error
00733 cff_charset_compute_cids( CFF_Charset charset,
00734 FT_UInt num_glyphs,
00735 FT_Memory memory )
00736 {
00737 FT_Error error = FT_Err_Ok;
00738 FT_UInt i;
00739 FT_Long j;
00740 FT_UShort max_cid = 0;
00741
00742
00743 if ( charset->max_cid > 0 )
00744 goto Exit;
00745
00746 for ( i = 0; i < num_glyphs; i++ )
00747 if ( charset->sids[i] > max_cid )
00748 max_cid = charset->sids[i];
00749 max_cid++;
00750
00751 if ( FT_NEW_ARRAY( charset->cids, max_cid ) )
00752 goto Exit;
00753
00754
00755
00756
00757 for ( j = num_glyphs - 1; j >= 0 ; j-- )
00758 charset->cids[charset->sids[j]] = (FT_UShort)j;
00759
00760 charset->max_cid = max_cid;
00761 charset->num_glyphs = num_glyphs;
00762
00763 Exit:
00764 return error;
00765 }
00766
00767
00768 FT_LOCAL_DEF( FT_UInt )
00769 cff_charset_cid_to_gindex( CFF_Charset charset,
00770 FT_UInt cid )
00771 {
00772 FT_UInt result = 0;
00773
00774
00775 if ( cid < charset->max_cid )
00776 result = charset->cids[cid];
00777
00778 return result;
00779 }
00780
00781
00782 static void
00783 cff_charset_free_cids( CFF_Charset charset,
00784 FT_Memory memory )
00785 {
00786 FT_FREE( charset->cids );
00787 charset->max_cid = 0;
00788 }
00789
00790
00791 static void
00792 cff_charset_done( CFF_Charset charset,
00793 FT_Stream stream )
00794 {
00795 FT_Memory memory = stream->memory;
00796
00797
00798 cff_charset_free_cids( charset, memory );
00799
00800 FT_FREE( charset->sids );
00801 charset->format = 0;
00802 charset->offset = 0;
00803 }
00804
00805
00806 static FT_Error
00807 cff_charset_load( CFF_Charset charset,
00808 FT_UInt num_glyphs,
00809 FT_Stream stream,
00810 FT_ULong base_offset,
00811 FT_ULong offset,
00812 FT_Bool invert )
00813 {
00814 FT_Memory memory = stream->memory;
00815 FT_Error error = CFF_Err_Ok;
00816 FT_UShort glyph_sid;
00817
00818
00819
00820
00821 if ( offset > 2 )
00822 {
00823 FT_UInt j;
00824
00825
00826 charset->offset = base_offset + offset;
00827
00828
00829 if ( FT_STREAM_SEEK( charset->offset ) ||
00830 FT_READ_BYTE( charset->format ) )
00831 goto Exit;
00832
00833
00834 if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
00835 goto Exit;
00836
00837
00838 charset->sids[0] = 0;
00839
00840 switch ( charset->format )
00841 {
00842 case 0:
00843 if ( num_glyphs > 0 )
00844 {
00845 if ( FT_FRAME_ENTER( ( num_glyphs - 1 ) * 2 ) )
00846 goto Exit;
00847
00848 for ( j = 1; j < num_glyphs; j++ )
00849 {
00850 FT_UShort sid = FT_GET_USHORT();
00851
00852
00853
00854 if ( sid < 65000L )
00855 charset->sids[j] = sid;
00856 else
00857 {
00858 FT_TRACE0(( "cff_charset_load:"
00859 " invalid SID value %d set to zero\n", sid ));
00860 charset->sids[j] = 0;
00861 }
00862 }
00863
00864 FT_FRAME_EXIT();
00865 }
00866 break;
00867
00868 case 1:
00869 case 2:
00870 {
00871 FT_UInt nleft;
00872 FT_UInt i;
00873
00874
00875 j = 1;
00876
00877 while ( j < num_glyphs )
00878 {
00879
00880 if ( FT_READ_USHORT( glyph_sid ) )
00881 goto Exit;
00882
00883
00884 if ( charset->format == 2 )
00885 {
00886 if ( FT_READ_USHORT( nleft ) )
00887 goto Exit;
00888 }
00889 else
00890 {
00891 if ( FT_READ_BYTE( nleft ) )
00892 goto Exit;
00893 }
00894
00895
00896
00897 if ( glyph_sid >= 65000L ) {
00898 FT_ERROR(( "cff_charset_load: invalid SID range\n" ));
00899 error = CFF_Err_Invalid_File_Format;
00900 goto Exit;
00901 }
00902
00903
00904 if ( nleft > 65000L - 1L || glyph_sid >= 65000L - nleft ) {
00905 FT_ERROR(( "cff_charset_load: invalid SID range trimmed\n" ));
00906 nleft = ( FT_UInt )( 65000L - 1L - glyph_sid );
00907 }
00908
00909
00910 for ( i = 0; j < num_glyphs && i <= nleft; i++, j++, glyph_sid++ )
00911 charset->sids[j] = glyph_sid;
00912 }
00913 }
00914 break;
00915
00916 default:
00917 FT_ERROR(( "cff_charset_load: invalid table format\n" ));
00918 error = CFF_Err_Invalid_File_Format;
00919 goto Exit;
00920 }
00921 }
00922 else
00923 {
00924
00925
00926
00927
00928
00929
00930
00931
00932 charset->offset = offset;
00933
00934 switch ( (FT_UInt)offset )
00935 {
00936 case 0:
00937 if ( num_glyphs > 229 )
00938 {
00939 FT_ERROR(( "cff_charset_load: implicit charset larger than\n"
00940 "predefined charset (Adobe ISO-Latin)\n" ));
00941 error = CFF_Err_Invalid_File_Format;
00942 goto Exit;
00943 }
00944
00945
00946 if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
00947 goto Exit;
00948
00949
00950 FT_ARRAY_COPY( charset->sids, cff_isoadobe_charset, num_glyphs );
00951
00952 break;
00953
00954 case 1:
00955 if ( num_glyphs > 166 )
00956 {
00957 FT_ERROR(( "cff_charset_load: implicit charset larger than\n"
00958 "predefined charset (Adobe Expert)\n" ));
00959 error = CFF_Err_Invalid_File_Format;
00960 goto Exit;
00961 }
00962
00963
00964 if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
00965 goto Exit;
00966
00967
00968 FT_ARRAY_COPY( charset->sids, cff_expert_charset, num_glyphs );
00969
00970 break;
00971
00972 case 2:
00973 if ( num_glyphs > 87 )
00974 {
00975 FT_ERROR(( "cff_charset_load: implicit charset larger than\n"
00976 "predefined charset (Adobe Expert Subset)\n" ));
00977 error = CFF_Err_Invalid_File_Format;
00978 goto Exit;
00979 }
00980
00981
00982 if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
00983 goto Exit;
00984
00985
00986 FT_ARRAY_COPY( charset->sids, cff_expertsubset_charset, num_glyphs );
00987
00988 break;
00989
00990 default:
00991 error = CFF_Err_Invalid_File_Format;
00992 goto Exit;
00993 }
00994 }
00995
00996
00997 if ( invert )
00998 error = cff_charset_compute_cids( charset, num_glyphs, memory );
00999
01000 Exit:
01001
01002 if ( error )
01003 {
01004 FT_FREE( charset->sids );
01005 FT_FREE( charset->cids );
01006 charset->format = 0;
01007 charset->offset = 0;
01008 charset->sids = 0;
01009 }
01010
01011 return error;
01012 }
01013
01014
01015 static void
01016 cff_encoding_done( CFF_Encoding encoding )
01017 {
01018 encoding->format = 0;
01019 encoding->offset = 0;
01020 encoding->count = 0;
01021 }
01022
01023
01024 static FT_Error
01025 cff_encoding_load( CFF_Encoding encoding,
01026 CFF_Charset charset,
01027 FT_UInt num_glyphs,
01028 FT_Stream stream,
01029 FT_ULong base_offset,
01030 FT_ULong offset )
01031 {
01032 FT_Error error = CFF_Err_Ok;
01033 FT_UInt count;
01034 FT_UInt j;
01035 FT_UShort glyph_sid;
01036 FT_UInt glyph_code;
01037
01038
01039
01040 if ( !charset->sids )
01041 {
01042 error = CFF_Err_Invalid_File_Format;
01043 goto Exit;
01044 }
01045
01046
01047 for ( j = 0; j < 256; j++ )
01048 {
01049 encoding->sids [j] = 0;
01050 encoding->codes[j] = 0;
01051 }
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065 if ( offset > 1 )
01066 {
01067 encoding->offset = base_offset + offset;
01068
01069
01070 if ( FT_STREAM_SEEK( encoding->offset ) ||
01071 FT_READ_BYTE( encoding->format ) ||
01072 FT_READ_BYTE( count ) )
01073 goto Exit;
01074
01075 switch ( encoding->format & 0x7F )
01076 {
01077 case 0:
01078 {
01079 FT_Byte* p;
01080
01081
01082
01083
01084
01085
01086 encoding->count = count + 1;
01087
01088 if ( FT_FRAME_ENTER( count ) )
01089 goto Exit;
01090
01091 p = (FT_Byte*)stream->cursor;
01092
01093 for ( j = 1; j <= count; j++ )
01094 {
01095 glyph_code = *p++;
01096
01097
01098 if ( j < num_glyphs )
01099 {
01100
01101 encoding->codes[glyph_code] = (FT_UShort)j;
01102
01103
01104 encoding->sids[glyph_code] = charset->sids[j];
01105 }
01106 }
01107
01108 FT_FRAME_EXIT();
01109 }
01110 break;
01111
01112 case 1:
01113 {
01114 FT_UInt nleft;
01115 FT_UInt i = 1;
01116 FT_UInt k;
01117
01118
01119 encoding->count = 0;
01120
01121
01122 for ( j = 0; j < count; j++, i += nleft )
01123 {
01124
01125 if ( FT_READ_BYTE( glyph_code ) )
01126 goto Exit;
01127
01128
01129 if ( FT_READ_BYTE( nleft ) )
01130 goto Exit;
01131
01132
01133 nleft++;
01134
01135
01136 if ( (FT_UInt)nleft > encoding->count )
01137 encoding->count = nleft;
01138
01139
01140 for ( k = i; k < nleft + i; k++, glyph_code++ )
01141 {
01142
01143 if ( k < num_glyphs && glyph_code < 256 )
01144 {
01145
01146 encoding->codes[glyph_code] = (FT_UShort)k;
01147
01148
01149 encoding->sids[glyph_code] = charset->sids[k];
01150 }
01151 }
01152 }
01153
01154
01155 if ( encoding->count > 256 )
01156 encoding->count = 256;
01157 }
01158 break;
01159
01160 default:
01161 FT_ERROR(( "cff_encoding_load: invalid table format\n" ));
01162 error = CFF_Err_Invalid_File_Format;
01163 goto Exit;
01164 }
01165
01166
01167 if ( encoding->format & 0x80 )
01168 {
01169 FT_UInt gindex;
01170
01171
01172
01173 if ( FT_READ_BYTE( count ) )
01174 goto Exit;
01175
01176 for ( j = 0; j < count; j++ )
01177 {
01178
01179 if ( FT_READ_BYTE( glyph_code ) )
01180 goto Exit;
01181
01182
01183 if ( FT_READ_USHORT( glyph_sid ) )
01184 goto Exit;
01185
01186
01187 encoding->sids[glyph_code] = glyph_sid;
01188
01189
01190
01191 for ( gindex = 0; gindex < num_glyphs; gindex++ )
01192 {
01193 if ( charset->sids[gindex] == glyph_sid )
01194 {
01195 encoding->codes[glyph_code] = (FT_UShort)gindex;
01196 break;
01197 }
01198 }
01199 }
01200 }
01201 }
01202 else
01203 {
01204
01205
01206
01207
01208
01209 switch ( (FT_UInt)offset )
01210 {
01211 case 0:
01212
01213 FT_ARRAY_COPY( encoding->sids, cff_standard_encoding, 256 );
01214 goto Populate;
01215
01216 case 1:
01217
01218 FT_ARRAY_COPY( encoding->sids, cff_expert_encoding, 256 );
01219
01220 Populate:
01221
01222
01223
01224 encoding->count = 0;
01225
01226 error = cff_charset_compute_cids( charset, num_glyphs,
01227 stream->memory );
01228 if ( error )
01229 goto Exit;
01230
01231 for ( j = 0; j < 256; j++ )
01232 {
01233 FT_UInt sid = encoding->sids[j];
01234 FT_UInt gid = 0;
01235
01236
01237 if ( sid )
01238 gid = cff_charset_cid_to_gindex( charset, sid );
01239
01240 if ( gid != 0 )
01241 {
01242 encoding->codes[j] = (FT_UShort)gid;
01243
01244 if ( encoding->count < j + 1 )
01245 encoding->count = j + 1;
01246 }
01247 else
01248 {
01249 encoding->codes[j] = 0;
01250 encoding->sids [j] = 0;
01251 }
01252 }
01253 break;
01254
01255 default:
01256 FT_ERROR(( "cff_encoding_load: invalid table format\n" ));
01257 error = CFF_Err_Invalid_File_Format;
01258 goto Exit;
01259 }
01260 }
01261
01262 Exit:
01263
01264
01265 return error;
01266 }
01267
01268
01269 static FT_Error
01270 cff_subfont_load( CFF_SubFont font,
01271 CFF_Index idx,
01272 FT_UInt font_index,
01273 FT_Stream stream,
01274 FT_ULong base_offset,
01275 FT_Library library )
01276 {
01277 FT_Error error;
01278 CFF_ParserRec parser;
01279 FT_Byte* dict = NULL;
01280 FT_ULong dict_len;
01281 CFF_FontRecDict top = &font->font_dict;
01282 CFF_Private priv = &font->private_dict;
01283
01284
01285 cff_parser_init( &parser, CFF_CODE_TOPDICT, &font->font_dict, library );
01286
01287
01288 FT_MEM_ZERO( top, sizeof ( *top ) );
01289
01290 top->underline_position = -100L << 16;
01291 top->underline_thickness = 50L << 16;
01292 top->charstring_type = 2;
01293 top->font_matrix.xx = 0x10000L;
01294 top->font_matrix.yy = 0x10000L;
01295 top->cid_count = 8720;
01296
01297
01298
01299 top->version = 0xFFFFU;
01300 top->notice = 0xFFFFU;
01301 top->copyright = 0xFFFFU;
01302 top->full_name = 0xFFFFU;
01303 top->family_name = 0xFFFFU;
01304 top->weight = 0xFFFFU;
01305 top->embedded_postscript = 0xFFFFU;
01306
01307 top->cid_registry = 0xFFFFU;
01308 top->cid_ordering = 0xFFFFU;
01309 top->cid_font_name = 0xFFFFU;
01310
01311 error = cff_index_access_element( idx, font_index, &dict, &dict_len );
01312 if ( !error )
01313 error = cff_parser_run( &parser, dict, dict + dict_len );
01314
01315 cff_index_forget_element( idx, &dict );
01316
01317 if ( error )
01318 goto Exit;
01319
01320
01321 if ( top->cid_registry != 0xFFFFU )
01322 goto Exit;
01323
01324
01325 if ( top->private_offset && top->private_size )
01326 {
01327
01328 FT_MEM_ZERO( priv, sizeof ( *priv ) );
01329
01330 priv->blue_shift = 7;
01331 priv->blue_fuzz = 1;
01332 priv->lenIV = -1;
01333 priv->expansion_factor = (FT_Fixed)( 0.06 * 0x10000L );
01334 priv->blue_scale = (FT_Fixed)( 0.039625 * 0x10000L * 1000 );
01335
01336 cff_parser_init( &parser, CFF_CODE_PRIVATE, priv, library );
01337
01338 if ( FT_STREAM_SEEK( base_offset + font->font_dict.private_offset ) ||
01339 FT_FRAME_ENTER( font->font_dict.private_size ) )
01340 goto Exit;
01341
01342 error = cff_parser_run( &parser,
01343 (FT_Byte*)stream->cursor,
01344 (FT_Byte*)stream->limit );
01345 FT_FRAME_EXIT();
01346 if ( error )
01347 goto Exit;
01348
01349
01350 priv->num_blue_values &= ~1;
01351 }
01352
01353
01354 if ( priv->local_subrs_offset )
01355 {
01356 if ( FT_STREAM_SEEK( base_offset + top->private_offset +
01357 priv->local_subrs_offset ) )
01358 goto Exit;
01359
01360 error = cff_index_init( &font->local_subrs_index, stream, 1 );
01361 if ( error )
01362 goto Exit;
01363
01364 font->num_local_subrs = font->local_subrs_index.count;
01365 error = cff_index_get_pointers( &font->local_subrs_index,
01366 &font->local_subrs );
01367 if ( error )
01368 goto Exit;
01369 }
01370
01371 Exit:
01372 return error;
01373 }
01374
01375
01376 static void
01377 cff_subfont_done( FT_Memory memory,
01378 CFF_SubFont subfont )
01379 {
01380 if ( subfont )
01381 {
01382 cff_index_done( &subfont->local_subrs_index );
01383 FT_FREE( subfont->local_subrs );
01384 }
01385 }
01386
01387
01388 FT_LOCAL_DEF( FT_Error )
01389 cff_font_load( FT_Library library,
01390 FT_Stream stream,
01391 FT_Int face_index,
01392 CFF_Font font,
01393 FT_Bool pure_cff )
01394 {
01395 static const FT_Frame_Field cff_header_fields[] =
01396 {
01397 #undef FT_STRUCTURE
01398 #define FT_STRUCTURE CFF_FontRec
01399
01400 FT_FRAME_START( 4 ),
01401 FT_FRAME_BYTE( version_major ),
01402 FT_FRAME_BYTE( version_minor ),
01403 FT_FRAME_BYTE( header_size ),
01404 FT_FRAME_BYTE( absolute_offsize ),
01405 FT_FRAME_END
01406 };
01407
01408 FT_Error error;
01409 FT_Memory memory = stream->memory;
01410 FT_ULong base_offset;
01411 CFF_FontRecDict dict;
01412
01413
01414 FT_ZERO( font );
01415
01416 font->stream = stream;
01417 font->memory = memory;
01418 dict = &font->top_font.font_dict;
01419 base_offset = FT_STREAM_POS();
01420
01421
01422 if ( FT_STREAM_READ_FIELDS( cff_header_fields, font ) )
01423 goto Exit;
01424
01425
01426 if ( font->version_major != 1 ||
01427 font->header_size < 4 ||
01428 font->absolute_offsize > 4 )
01429 {
01430 FT_TRACE2(( "[not a CFF font header]\n" ));
01431 error = CFF_Err_Unknown_File_Format;
01432 goto Exit;
01433 }
01434
01435
01436 if ( FT_STREAM_SKIP( font->header_size - 4 ) )
01437 goto Exit;
01438
01439
01440 if ( FT_SET_ERROR( cff_index_init( &font->name_index,
01441 stream, 0 ) ) ||
01442 FT_SET_ERROR( cff_index_init( &font->font_dict_index,
01443 stream, 0 ) ) ||
01444 FT_SET_ERROR( cff_index_init( &font->string_index,
01445 stream, 0 ) ) ||
01446 FT_SET_ERROR( cff_index_init( &font->global_subrs_index,
01447 stream, 1 ) ) )
01448 goto Exit;
01449
01450
01451 font->num_faces = font->name_index.count;
01452 if ( face_index >= (FT_Int)font->num_faces )
01453 {
01454 FT_ERROR(( "cff_font_load: incorrect face index = %d\n",
01455 face_index ));
01456 error = CFF_Err_Invalid_Argument;
01457 }
01458
01459
01460 if ( face_index < 0 )
01461 goto Exit;
01462
01463
01464 error = cff_subfont_load( &font->top_font,
01465 &font->font_dict_index,
01466 face_index,
01467 stream,
01468 base_offset,
01469 library );
01470 if ( error )
01471 goto Exit;
01472
01473 if ( FT_STREAM_SEEK( base_offset + dict->charstrings_offset ) )
01474 goto Exit;
01475
01476 error = cff_index_init( &font->charstrings_index, stream, 0 );
01477 if ( error )
01478 goto Exit;
01479
01480
01481 if ( dict->cid_registry != 0xFFFFU )
01482 {
01483 CFF_IndexRec fd_index;
01484 CFF_SubFont sub;
01485 FT_UInt idx;
01486
01487
01488
01489
01490 if ( FT_STREAM_SEEK( base_offset + dict->cid_fd_array_offset ) )
01491 goto Exit;
01492
01493 error = cff_index_init( &fd_index, stream, 0 );
01494 if ( error )
01495 goto Exit;
01496
01497 if ( fd_index.count > CFF_MAX_CID_FONTS )
01498 {
01499 FT_TRACE0(( "cff_font_load: FD array too large in CID font\n" ));
01500 goto Fail_CID;
01501 }
01502
01503
01504 font->num_subfonts = fd_index.count;
01505 if ( FT_NEW_ARRAY( sub, fd_index.count ) )
01506 goto Fail_CID;
01507
01508
01509 for ( idx = 0; idx < fd_index.count; idx++ )
01510 font->subfonts[idx] = sub + idx;
01511
01512
01513 for ( idx = 0; idx < fd_index.count; idx++ )
01514 {
01515 sub = font->subfonts[idx];
01516 error = cff_subfont_load( sub, &fd_index, idx,
01517 stream, base_offset, library );
01518 if ( error )
01519 goto Fail_CID;
01520 }
01521
01522
01523 error = CFF_Load_FD_Select( &font->fd_select,
01524 font->charstrings_index.count,
01525 stream,
01526 base_offset + dict->cid_fd_select_offset );
01527
01528 Fail_CID:
01529 cff_index_done( &fd_index );
01530
01531 if ( error )
01532 goto Exit;
01533 }
01534 else
01535 font->num_subfonts = 0;
01536
01537
01538 if ( dict->charstrings_offset == 0 )
01539 {
01540 FT_ERROR(( "cff_font_load: no charstrings offset\n" ));
01541 error = CFF_Err_Unknown_File_Format;
01542 goto Exit;
01543 }
01544
01545
01546 font->num_global_subrs = font->global_subrs_index.count;
01547 font->num_glyphs = font->charstrings_index.count;
01548
01549 error = cff_index_get_pointers( &font->global_subrs_index,
01550 &font->global_subrs ) ;
01551
01552 if ( error )
01553 goto Exit;
01554
01555
01556 if ( font->num_glyphs > 0 )
01557 {
01558 FT_Bool invert = FT_BOOL( dict->cid_registry != 0xFFFFU && pure_cff );
01559
01560
01561 error = cff_charset_load( &font->charset, font->num_glyphs, stream,
01562 base_offset, dict->charset_offset, invert );
01563 if ( error )
01564 goto Exit;
01565
01566
01567 if ( dict->cid_registry == 0xFFFFU )
01568 {
01569 error = cff_encoding_load( &font->encoding,
01570 &font->charset,
01571 font->num_glyphs,
01572 stream,
01573 base_offset,
01574 dict->encoding_offset );
01575 if ( error )
01576 goto Exit;
01577 }
01578 }
01579
01580
01581
01582 font->font_name = cff_index_get_name( &font->name_index, face_index );
01583
01584 Exit:
01585 return error;
01586 }
01587
01588
01589 FT_LOCAL_DEF( void )
01590 cff_font_done( CFF_Font font )
01591 {
01592 FT_Memory memory = font->memory;
01593 FT_UInt idx;
01594
01595
01596 cff_index_done( &font->global_subrs_index );
01597 cff_index_done( &font->string_index );
01598 cff_index_done( &font->font_dict_index );
01599 cff_index_done( &font->name_index );
01600 cff_index_done( &font->charstrings_index );
01601
01602
01603
01604 if ( font->num_subfonts > 0 )
01605 {
01606 for ( idx = 0; idx < font->num_subfonts; idx++ )
01607 cff_subfont_done( memory, font->subfonts[idx] );
01608
01609
01610 FT_FREE( font->subfonts[0] );
01611 }
01612
01613 cff_encoding_done( &font->encoding );
01614 cff_charset_done( &font->charset, font->stream );
01615
01616 cff_subfont_done( memory, &font->top_font );
01617
01618 CFF_Done_FD_Select( &font->fd_select, font->stream );
01619
01620 if (font->font_info != NULL)
01621 {
01622 FT_FREE( font->font_info->version );
01623 FT_FREE( font->font_info->notice );
01624 FT_FREE( font->font_info->full_name );
01625 FT_FREE( font->font_info->family_name );
01626 FT_FREE( font->font_info->weight );
01627 FT_FREE( font->font_info );
01628 }
01629
01630 FT_FREE( font->registry );
01631 FT_FREE( font->ordering );
01632
01633 FT_FREE( font->global_subrs );
01634 FT_FREE( font->font_name );
01635 }
01636
01637
01638