Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(226)

Side by Side Diff: third_party/freetype/src/sfnt/sfobjs.c

Issue 815103002: Update freetype to 2.5.4. (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: Adjust GYP and GN Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/freetype/src/sfnt/sfobjs.h ('k') | third_party/freetype/src/sfnt/ttbdf.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /***************************************************************************/ 1 /***************************************************************************/
2 /* */ 2 /* */
3 /* sfobjs.c */ 3 /* sfobjs.c */
4 /* */ 4 /* */
5 /* SFNT object management (base). */ 5 /* SFNT object management (base). */
6 /* */ 6 /* */
7 /* Copyright 1996-2008, 2010-2013 by */ 7 /* Copyright 1996-2008, 2010-2014 by */
8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */ 8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */
9 /* */ 9 /* */
10 /* This file is part of the FreeType project, and may only be used, */ 10 /* This file is part of the FreeType project, and may only be used, */
11 /* modified, and distributed under the terms of the FreeType project */ 11 /* modified, and distributed under the terms of the FreeType project */
12 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 12 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */
13 /* this file you indicate that you have read the license and */ 13 /* this file you indicate that you have read the license and */
14 /* understand and accept it fully. */ 14 /* understand and accept it fully. */
15 /* */ 15 /* */
16 /***************************************************************************/ 16 /***************************************************************************/
17 17
18 18
19 #include "../../include/ft2build.h" 19 #include <ft2build.h>
20 #include "sfobjs.h" 20 #include "sfobjs.h"
21 #include "ttload.h" 21 #include "ttload.h"
22 #include "ttcmap.h" 22 #include "ttcmap.h"
23 #include "ttkern.h" 23 #include "ttkern.h"
24 #include "../../include/freetype/internal/sfnt.h" 24 #include FT_INTERNAL_SFNT_H
25 #include "../../include/freetype/internal/ftdebug.h" 25 #include FT_INTERNAL_DEBUG_H
26 #include "../../include/freetype/ttnameid.h" 26 #include FT_TRUETYPE_IDS_H
27 #include "../../include/freetype/tttags.h" 27 #include FT_TRUETYPE_TAGS_H
28 #include "../../include/freetype/internal/services/svpscmap.h" 28 #include FT_SERVICE_POSTSCRIPT_CMAPS_H
29 #include "../../include/freetype/ftsnames.h" 29 #include FT_SFNT_NAMES_H
30 #include FT_GZIP_H
30 #include "sferrors.h" 31 #include "sferrors.h"
31 32
32 #ifdef TT_CONFIG_OPTION_BDF 33 #ifdef TT_CONFIG_OPTION_BDF
33 #include "ttbdf.h" 34 #include "ttbdf.h"
34 #endif 35 #endif
35 36
36 37
37 /*************************************************************************/ 38 /*************************************************************************/
38 /* */ 39 /* */
39 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 40 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
(...skipping 21 matching lines...) Expand all
61 if ( FT_NEW_ARRAY( string, len + 1 ) ) 62 if ( FT_NEW_ARRAY( string, len + 1 ) )
62 return NULL; 63 return NULL;
63 64
64 for ( n = 0; n < len; n++ ) 65 for ( n = 0; n < len; n++ )
65 { 66 {
66 code = FT_NEXT_USHORT( read ); 67 code = FT_NEXT_USHORT( read );
67 68
68 if ( code == 0 ) 69 if ( code == 0 )
69 break; 70 break;
70 71
71 if (code > 255) /*Johnson 2010-10-09, #TESTDOC:0000042_QUT20005_5.pdf.*/ 72 if ( code < 32 || code > 127 )
72 » » code = code>>8&0x00ff;
73 » if ( code < 32 || code > 127 )
74 code = '?'; 73 code = '?';
75 74
76 string[n] = (char)code; 75 string[n] = (char)code;
77 } 76 }
78 77
79 string[n] = 0; 78 string[n] = 0;
80 79
81 return string; 80 return string;
82 } 81 }
83 82
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after
342 if ( cur->encoding_id == encoding_id || 341 if ( cur->encoding_id == encoding_id ||
343 cur->encoding_id == -1 ) 342 cur->encoding_id == -1 )
344 return cur->encoding; 343 return cur->encoding;
345 } 344 }
346 } 345 }
347 346
348 return FT_ENCODING_NONE; 347 return FT_ENCODING_NONE;
349 } 348 }
350 349
351 350
351 #define WRITE_USHORT( p, v ) \
352 do \
353 { \
354 *(p)++ = (FT_Byte)( (v) >> 8 ); \
355 *(p)++ = (FT_Byte)( (v) >> 0 ); \
356 \
357 } while ( 0 )
358
359 #define WRITE_ULONG( p, v ) \
360 do \
361 { \
362 *(p)++ = (FT_Byte)( (v) >> 24 ); \
363 *(p)++ = (FT_Byte)( (v) >> 16 ); \
364 *(p)++ = (FT_Byte)( (v) >> 8 ); \
365 *(p)++ = (FT_Byte)( (v) >> 0 ); \
366 \
367 } while ( 0 )
368
369
370 static void
371 sfnt_stream_close( FT_Stream stream )
372 {
373 FT_Memory memory = stream->memory;
374
375
376 FT_FREE( stream->base );
377
378 stream->size = 0;
379 stream->base = 0;
380 stream->close = 0;
381 }
382
383
384 FT_CALLBACK_DEF( int )
385 compare_offsets( const void* a,
386 const void* b )
387 {
388 WOFF_Table table1 = *(WOFF_Table*)a;
389 WOFF_Table table2 = *(WOFF_Table*)b;
390
391 FT_ULong offset1 = table1->Offset;
392 FT_ULong offset2 = table2->Offset;
393
394
395 if ( offset1 > offset2 )
396 return 1;
397 else if ( offset1 < offset2 )
398 return -1;
399 else
400 return 0;
401 }
402
403
404 /* Replace `face->root.stream' with a stream containing the extracted */
405 /* SFNT of a WOFF font. */
406
407 static FT_Error
408 woff_open_font( FT_Stream stream,
409 TT_Face face )
410 {
411 FT_Memory memory = stream->memory;
412 FT_Error error = FT_Err_Ok;
413
414 WOFF_HeaderRec woff;
415 WOFF_Table tables = NULL;
416 WOFF_Table* indices = NULL;
417
418 FT_ULong woff_offset;
419
420 FT_Byte* sfnt = NULL;
421 FT_Stream sfnt_stream = NULL;
422
423 FT_Byte* sfnt_header;
424 FT_ULong sfnt_offset;
425
426 FT_Int nn;
427 FT_ULong old_tag = 0;
428
429 static const FT_Frame_Field woff_header_fields[] =
430 {
431 #undef FT_STRUCTURE
432 #define FT_STRUCTURE WOFF_HeaderRec
433
434 FT_FRAME_START( 44 ),
435 FT_FRAME_ULONG ( signature ),
436 FT_FRAME_ULONG ( flavor ),
437 FT_FRAME_ULONG ( length ),
438 FT_FRAME_USHORT( num_tables ),
439 FT_FRAME_USHORT( reserved ),
440 FT_FRAME_ULONG ( totalSfntSize ),
441 FT_FRAME_USHORT( majorVersion ),
442 FT_FRAME_USHORT( minorVersion ),
443 FT_FRAME_ULONG ( metaOffset ),
444 FT_FRAME_ULONG ( metaLength ),
445 FT_FRAME_ULONG ( metaOrigLength ),
446 FT_FRAME_ULONG ( privOffset ),
447 FT_FRAME_ULONG ( privLength ),
448 FT_FRAME_END
449 };
450
451
452 FT_ASSERT( stream == face->root.stream );
453 FT_ASSERT( FT_STREAM_POS() == 0 );
454
455 if ( FT_STREAM_READ_FIELDS( woff_header_fields, &woff ) )
456 return error;
457
458 /* Make sure we don't recurse back here or hit TTC code. */
459 if ( woff.flavor == TTAG_wOFF || woff.flavor == TTAG_ttcf )
460 return FT_THROW( Invalid_Table );
461
462 /* Miscellaneous checks. */
463 if ( woff.length != stream->size ||
464 woff.num_tables == 0 ||
465 44 + woff.num_tables * 20UL >= woff.length ||
466 12 + woff.num_tables * 16UL >= woff.totalSfntSize ||
467 ( woff.totalSfntSize & 3 ) != 0 ||
468 ( woff.metaOffset == 0 && ( woff.metaLength != 0 ||
469 woff.metaOrigLength != 0 ) ) ||
470 ( woff.metaLength != 0 && woff.metaOrigLength == 0 ) ||
471 ( woff.privOffset == 0 && woff.privLength != 0 ) )
472 return FT_THROW( Invalid_Table );
473
474 if ( FT_ALLOC( sfnt, woff.totalSfntSize ) ||
475 FT_NEW( sfnt_stream ) )
476 goto Exit;
477
478 sfnt_header = sfnt;
479
480 /* Write sfnt header. */
481 {
482 FT_UInt searchRange, entrySelector, rangeShift, x;
483
484
485 x = woff.num_tables;
486 entrySelector = 0;
487 while ( x )
488 {
489 x >>= 1;
490 entrySelector += 1;
491 }
492 entrySelector--;
493
494 searchRange = ( 1 << entrySelector ) * 16;
495 rangeShift = woff.num_tables * 16 - searchRange;
496
497 WRITE_ULONG ( sfnt_header, woff.flavor );
498 WRITE_USHORT( sfnt_header, woff.num_tables );
499 WRITE_USHORT( sfnt_header, searchRange );
500 WRITE_USHORT( sfnt_header, entrySelector );
501 WRITE_USHORT( sfnt_header, rangeShift );
502 }
503
504 /* While the entries in the sfnt header must be sorted by the */
505 /* tag value, the tables themselves are not. We thus have to */
506 /* sort them by offset and check that they don't overlap. */
507
508 if ( FT_NEW_ARRAY( tables, woff.num_tables ) ||
509 FT_NEW_ARRAY( indices, woff.num_tables ) )
510 goto Exit;
511
512 FT_TRACE2(( "\n"
513 " tag offset compLen origLen checksum\n"
514 " -------------------------------------------\n" ));
515
516 if ( FT_FRAME_ENTER( 20L * woff.num_tables ) )
517 goto Exit;
518
519 for ( nn = 0; nn < woff.num_tables; nn++ )
520 {
521 WOFF_Table table = tables + nn;
522
523 table->Tag = FT_GET_TAG4();
524 table->Offset = FT_GET_ULONG();
525 table->CompLength = FT_GET_ULONG();
526 table->OrigLength = FT_GET_ULONG();
527 table->CheckSum = FT_GET_ULONG();
528
529 FT_TRACE2(( " %c%c%c%c %08lx %08lx %08lx %08lx\n",
530 (FT_Char)( table->Tag >> 24 ),
531 (FT_Char)( table->Tag >> 16 ),
532 (FT_Char)( table->Tag >> 8 ),
533 (FT_Char)( table->Tag ),
534 table->Offset,
535 table->CompLength,
536 table->OrigLength,
537 table->CheckSum ));
538
539 if ( table->Tag <= old_tag )
540 {
541 FT_FRAME_EXIT();
542 error = FT_THROW( Invalid_Table );
543 goto Exit;
544 }
545
546 old_tag = table->Tag;
547 indices[nn] = table;
548 }
549
550 FT_FRAME_EXIT();
551
552 /* Sort by offset. */
553
554 ft_qsort( indices,
555 woff.num_tables,
556 sizeof ( WOFF_Table ),
557 compare_offsets );
558
559 /* Check offsets and lengths. */
560
561 woff_offset = 44 + woff.num_tables * 20L;
562 sfnt_offset = 12 + woff.num_tables * 16L;
563
564 for ( nn = 0; nn < woff.num_tables; nn++ )
565 {
566 WOFF_Table table = indices[nn];
567
568
569 if ( table->Offset != woff_offset ||
570 table->CompLength > woff.length ||
571 table->Offset > woff.length - table->CompLength ||
572 table->OrigLength > woff.totalSfntSize ||
573 sfnt_offset > woff.totalSfntSize - table->OrigLength ||
574 table->CompLength > table->OrigLength )
575 {
576 error = FT_THROW( Invalid_Table );
577 goto Exit;
578 }
579
580 table->OrigOffset = sfnt_offset;
581
582 /* The offsets must be multiples of 4. */
583 woff_offset += ( table->CompLength + 3 ) & ~3;
584 sfnt_offset += ( table->OrigLength + 3 ) & ~3;
585 }
586
587 /*
588 * Final checks!
589 *
590 * We don't decode and check the metadata block.
591 * We don't check table checksums either.
592 * But other than those, I think we implement all
593 * `MUST' checks from the spec.
594 */
595
596 if ( woff.metaOffset )
597 {
598 if ( woff.metaOffset != woff_offset ||
599 woff.metaOffset + woff.metaLength > woff.length )
600 {
601 error = FT_THROW( Invalid_Table );
602 goto Exit;
603 }
604
605 /* We have padding only ... */
606 woff_offset += woff.metaLength;
607 }
608
609 if ( woff.privOffset )
610 {
611 /* ... if it isn't the last block. */
612 woff_offset = ( woff_offset + 3 ) & ~3;
613
614 if ( woff.privOffset != woff_offset ||
615 woff.privOffset + woff.privLength > woff.length )
616 {
617 error = FT_THROW( Invalid_Table );
618 goto Exit;
619 }
620
621 /* No padding for the last block. */
622 woff_offset += woff.privLength;
623 }
624
625 if ( sfnt_offset != woff.totalSfntSize ||
626 woff_offset != woff.length )
627 {
628 error = FT_THROW( Invalid_Table );
629 goto Exit;
630 }
631
632 /* Write the tables. */
633
634 for ( nn = 0; nn < woff.num_tables; nn++ )
635 {
636 WOFF_Table table = tables + nn;
637
638
639 /* Write SFNT table entry. */
640 WRITE_ULONG( sfnt_header, table->Tag );
641 WRITE_ULONG( sfnt_header, table->CheckSum );
642 WRITE_ULONG( sfnt_header, table->OrigOffset );
643 WRITE_ULONG( sfnt_header, table->OrigLength );
644
645 /* Write table data. */
646 if ( FT_STREAM_SEEK( table->Offset ) ||
647 FT_FRAME_ENTER( table->CompLength ) )
648 goto Exit;
649
650 if ( table->CompLength == table->OrigLength )
651 {
652 /* Uncompressed data; just copy. */
653 ft_memcpy( sfnt + table->OrigOffset,
654 stream->cursor,
655 table->OrigLength );
656 }
657 else
658 {
659 #ifdef FT_CONFIG_OPTION_USE_ZLIB
660
661 /* Uncompress with zlib. */
662 FT_ULong output_len = table->OrigLength;
663
664
665 error = FT_Gzip_Uncompress( memory,
666 sfnt + table->OrigOffset, &output_len,
667 stream->cursor, table->CompLength );
668 if ( error )
669 goto Exit;
670 if ( output_len != table->OrigLength )
671 {
672 error = FT_THROW( Invalid_Table );
673 goto Exit;
674 }
675
676 #else /* !FT_CONFIG_OPTION_USE_ZLIB */
677
678 error = FT_THROW( Unimplemented_Feature );
679 goto Exit;
680
681 #endif /* !FT_CONFIG_OPTION_USE_ZLIB */
682 }
683
684 FT_FRAME_EXIT();
685
686 /* We don't check whether the padding bytes in the WOFF file are */
687 /* actually '\0'. For the output, however, we do set them properly. */
688 sfnt_offset = table->OrigOffset + table->OrigLength;
689 while ( sfnt_offset & 3 )
690 {
691 sfnt[sfnt_offset] = '\0';
692 sfnt_offset++;
693 }
694 }
695
696 /* Ok! Finally ready. Swap out stream and return. */
697 FT_Stream_OpenMemory( sfnt_stream, sfnt, woff.totalSfntSize );
698 sfnt_stream->memory = stream->memory;
699 sfnt_stream->close = sfnt_stream_close;
700
701 FT_Stream_Free(
702 face->root.stream,
703 ( face->root.face_flags & FT_FACE_FLAG_EXTERNAL_STREAM ) != 0 );
704
705 face->root.stream = sfnt_stream;
706
707 face->root.face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM;
708
709 Exit:
710 FT_FREE( tables );
711 FT_FREE( indices );
712
713 if ( error )
714 {
715 FT_FREE( sfnt );
716 FT_Stream_Close( sfnt_stream );
717 FT_FREE( sfnt_stream );
718 }
719
720 return error;
721 }
722
723
724 #undef WRITE_USHORT
725 #undef WRITE_ULONG
726
727
352 /* Fill in face->ttc_header. If the font is not a TTC, it is */ 728 /* Fill in face->ttc_header. If the font is not a TTC, it is */
353 /* synthesized into a TTC with one offset table. */ 729 /* synthesized into a TTC with one offset table. */
354 static FT_Error 730 static FT_Error
355 sfnt_open_font( FT_Stream stream, 731 sfnt_open_font( FT_Stream stream,
356 TT_Face face ) 732 TT_Face face )
357 { 733 {
358 FT_Memory memory = stream->memory; 734 FT_Memory memory = stream->memory;
359 FT_Error error; 735 FT_Error error;
360 FT_ULong tag, offset; 736 FT_ULong tag, offset;
361 737
362 static const FT_Frame_Field ttc_header_fields[] = 738 static const FT_Frame_Field ttc_header_fields[] =
363 { 739 {
364 #undef FT_STRUCTURE 740 #undef FT_STRUCTURE
365 #define FT_STRUCTURE TTC_HeaderRec 741 #define FT_STRUCTURE TTC_HeaderRec
366 742
367 FT_FRAME_START( 8 ), 743 FT_FRAME_START( 8 ),
368 FT_FRAME_LONG( version ), 744 FT_FRAME_LONG( version ),
369 FT_FRAME_LONG( count ), /* this is ULong in the specs */ 745 FT_FRAME_LONG( count ), /* this is ULong in the specs */
370 FT_FRAME_END 746 FT_FRAME_END
371 }; 747 };
372 748
373 749
374 face->ttc_header.tag = 0; 750 face->ttc_header.tag = 0;
375 face->ttc_header.version = 0; 751 face->ttc_header.version = 0;
376 face->ttc_header.count = 0; 752 face->ttc_header.count = 0;
377 753
754 retry:
378 offset = FT_STREAM_POS(); 755 offset = FT_STREAM_POS();
379 756
380 if ( FT_READ_ULONG( tag ) ) 757 if ( FT_READ_ULONG( tag ) )
381 return error; 758 return error;
382 759
760 if ( tag == TTAG_wOFF )
761 {
762 FT_TRACE2(( "sfnt_open_font: file is a WOFF; synthesizing SFNT\n" ));
763
764 if ( FT_STREAM_SEEK( offset ) )
765 return error;
766
767 error = woff_open_font( stream, face );
768 if ( error )
769 return error;
770
771 /* Swap out stream and retry! */
772 stream = face->root.stream;
773 goto retry;
774 }
775
383 if ( tag != 0x00010000UL && 776 if ( tag != 0x00010000UL &&
384 tag != TTAG_ttcf && 777 tag != TTAG_ttcf &&
385 tag != TTAG_OTTO && 778 tag != TTAG_OTTO &&
386 tag != TTAG_true && 779 tag != TTAG_true &&
387 tag != TTAG_typ1 && 780 tag != TTAG_typ1 &&
388 tag != 0x00020000UL ) 781 tag != 0x00020000UL )
389 { 782 {
390 FT_TRACE2(( " not a font using the SFNT container format\n" )); 783 FT_TRACE2(( " not a font using the SFNT container format\n" ));
391 return FT_THROW( Unknown_File_Format ); 784 return FT_THROW( Unknown_File_Format );
392 } 785 }
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
475 } 868 }
476 869
477 FT_FACE_FIND_GLOBAL_SERVICE( face, face->psnames, POSTSCRIPT_CMAPS ); 870 FT_FACE_FIND_GLOBAL_SERVICE( face, face->psnames, POSTSCRIPT_CMAPS );
478 871
479 FT_TRACE2(( "SFNT driver\n" )); 872 FT_TRACE2(( "SFNT driver\n" ));
480 873
481 error = sfnt_open_font( stream, face ); 874 error = sfnt_open_font( stream, face );
482 if ( error ) 875 if ( error )
483 return error; 876 return error;
484 877
878 /* Stream may have changed in sfnt_open_font. */
879 stream = face->root.stream;
880
485 FT_TRACE2(( "sfnt_init_face: %08p, %ld\n", face, face_index )); 881 FT_TRACE2(( "sfnt_init_face: %08p, %ld\n", face, face_index ));
486 882
487 if ( face_index < 0 ) 883 if ( face_index < 0 )
488 face_index = 0; 884 face_index = 0;
489 885
490 if ( face_index >= face->ttc_header.count ) 886 if ( face_index >= face->ttc_header.count )
491 return FT_THROW( Invalid_Argument ); 887 return FT_THROW( Invalid_Argument );
492 888
493 if ( FT_STREAM_SEEK( face->ttc_header.offsets[face_index] ) ) 889 if ( FT_STREAM_SEEK( face->ttc_header.offsets[face_index] ) )
494 return error; 890 return error;
495 891
496 /* check that we have a valid TrueType file */ 892 /* check that we have a valid TrueType file */
497 error = sfnt->load_font_dir( face, stream ); 893 error = sfnt->load_font_dir( face, stream );
498 if ( error ) 894 if ( error )
499 return error; 895 return error;
500 896
501 face->root.num_faces = face->ttc_header.count; 897 face->root.num_faces = face->ttc_header.count;
502 face->root.face_index = face_index; 898 face->root.face_index = face_index;
503 899
504 return error; 900 return error;
505 } 901 }
506 902
507 903
508 #define LOAD_( x ) \ 904 #define LOAD_( x ) \
509 do { \ 905 do \
906 { \
510 FT_TRACE2(( "`" #x "' " )); \ 907 FT_TRACE2(( "`" #x "' " )); \
511 FT_TRACE3(( "-->\n" )); \ 908 FT_TRACE3(( "-->\n" )); \
512 \ 909 \
513 error = sfnt->load_ ## x( face, stream ); \ 910 error = sfnt->load_ ## x( face, stream ); \
514 \ 911 \
515 FT_TRACE2(( "%s\n", ( !error ) \ 912 FT_TRACE2(( "%s\n", ( !error ) \
516 ? "loaded" \ 913 ? "loaded" \
517 : FT_ERR_EQ( error, Table_Missing ) \ 914 : FT_ERR_EQ( error, Table_Missing ) \
518 ? "missing" \ 915 ? "missing" \
519 : "failed to load" )); \ 916 : "failed to load" )); \
520 FT_TRACE3(( "\n" )); \ 917 FT_TRACE3(( "\n" )); \
521 } while ( 0 ) 918 } while ( 0 )
522 919
523 #define LOADM_( x, vertical ) \ 920 #define LOADM_( x, vertical ) \
524 do { \ 921 do \
922 { \
525 FT_TRACE2(( "`%s" #x "' ", \ 923 FT_TRACE2(( "`%s" #x "' ", \
526 vertical ? "vertical " : "" )); \ 924 vertical ? "vertical " : "" )); \
527 FT_TRACE3(( "-->\n" )); \ 925 FT_TRACE3(( "-->\n" )); \
528 \ 926 \
529 error = sfnt->load_ ## x( face, stream, vertical ); \ 927 error = sfnt->load_ ## x( face, stream, vertical ); \
530 \ 928 \
531 FT_TRACE2(( "%s\n", ( !error ) \ 929 FT_TRACE2(( "%s\n", ( !error ) \
532 ? "loaded" \ 930 ? "loaded" \
533 : FT_ERR_EQ( error, Table_Missing ) \ 931 : FT_ERR_EQ( error, Table_Missing ) \
534 ? "missing" \ 932 ? "missing" \
535 : "failed to load" )); \ 933 : "failed to load" )); \
536 FT_TRACE3(( "\n" )); \ 934 FT_TRACE3(( "\n" )); \
537 } while ( 0 ) 935 } while ( 0 )
538 936
539 #define GET_NAME( id, field ) \ 937 #define GET_NAME( id, field ) \
540 do { \ 938 do \
939 { \
541 error = tt_face_get_name( face, TT_NAME_ID_ ## id, field ); \ 940 error = tt_face_get_name( face, TT_NAME_ID_ ## id, field ); \
542 if ( error ) \ 941 if ( error ) \
543 goto Exit; \ 942 goto Exit; \
544 } while ( 0 ) 943 } while ( 0 )
545 944
546 945
547 FT_LOCAL_DEF( FT_Error ) 946 FT_LOCAL_DEF( FT_Error )
548 sfnt_load_face( FT_Stream stream, 947 sfnt_load_face( FT_Stream stream,
549 TT_Face face, 948 TT_Face face,
550 FT_Int face_index, 949 FT_Int face_index,
551 FT_Int num_params, 950 FT_Int num_params,
552 FT_Parameter* params ) 951 FT_Parameter* params )
553 { 952 {
554 FT_Error error; 953 FT_Error error;
555 #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES 954 #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
556 FT_Error psnames_error; 955 FT_Error psnames_error;
557 #endif 956 #endif
558 FT_Bool has_outline; 957 FT_Bool has_outline;
559 FT_Bool is_apple_sbit; 958 FT_Bool is_apple_sbit;
959 FT_Bool is_apple_sbix;
560 FT_Bool ignore_preferred_family = FALSE; 960 FT_Bool ignore_preferred_family = FALSE;
561 FT_Bool ignore_preferred_subfamily = FALSE; 961 FT_Bool ignore_preferred_subfamily = FALSE;
562 962
563 SFNT_Service sfnt = (SFNT_Service)face->sfnt; 963 SFNT_Service sfnt = (SFNT_Service)face->sfnt;
564 964
565 FT_UNUSED( face_index ); 965 FT_UNUSED( face_index );
566 966
567 967
568 /* Check parameters */ 968 /* Check parameters */
569 969
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
603 #ifdef FT_CONFIG_OPTION_INCREMENTAL 1003 #ifdef FT_CONFIG_OPTION_INCREMENTAL
604 has_outline = FT_BOOL( face->root.internal->incremental_interface != 0 || 1004 has_outline = FT_BOOL( face->root.internal->incremental_interface != 0 ||
605 tt_face_lookup_table( face, TTAG_glyf ) != 0 || 1005 tt_face_lookup_table( face, TTAG_glyf ) != 0 ||
606 tt_face_lookup_table( face, TTAG_CFF ) != 0 ); 1006 tt_face_lookup_table( face, TTAG_CFF ) != 0 );
607 #else 1007 #else
608 has_outline = FT_BOOL( tt_face_lookup_table( face, TTAG_glyf ) != 0 || 1008 has_outline = FT_BOOL( tt_face_lookup_table( face, TTAG_glyf ) != 0 ||
609 tt_face_lookup_table( face, TTAG_CFF ) != 0 ); 1009 tt_face_lookup_table( face, TTAG_CFF ) != 0 );
610 #endif 1010 #endif
611 1011
612 is_apple_sbit = 0; 1012 is_apple_sbit = 0;
1013 is_apple_sbix = !face->goto_table( face, TTAG_sbix, stream, 0 );
1014
1015 /* Apple 'sbix' color bitmaps are rendered scaled and then the 'glyf'
1016 * outline rendered on top. We don't support that yet, so just ignore
1017 * the 'glyf' outline and advertise it as a bitmap-only font. */
1018 if ( is_apple_sbix )
1019 has_outline = FALSE;
613 1020
614 /* if this font doesn't contain outlines, we try to load */ 1021 /* if this font doesn't contain outlines, we try to load */
615 /* a `bhed' table */ 1022 /* a `bhed' table */
616 if ( !has_outline && sfnt->load_bhed ) 1023 if ( !has_outline && sfnt->load_bhed )
617 { 1024 {
618 LOAD_( bhed ); 1025 LOAD_( bhed );
619 is_apple_sbit = FT_BOOL( !error ); 1026 is_apple_sbit = FT_BOOL( !error );
620 } 1027 }
621 1028
622 /* load the font header (`head' table) if this isn't an Apple */ 1029 /* load the font header (`head' table) if this isn't an Apple */
623 /* sbit font file */ 1030 /* sbit font file */
624 if ( !is_apple_sbit ) 1031 if ( !is_apple_sbit || is_apple_sbix )
625 { 1032 {
626 LOAD_( head ); 1033 LOAD_( head );
627 if ( error ) 1034 if ( error )
628 goto Exit; 1035 goto Exit;
629 } 1036 }
630 1037
631 if ( face->header.Units_Per_EM == 0 ) 1038 if ( face->header.Units_Per_EM == 0 )
632 { 1039 {
633 error = FT_THROW( Invalid_Table ); 1040 error = FT_THROW( Invalid_Table );
634 1041
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
698 { 1105 {
699 face->horizontal.number_Of_HMetrics = 0; 1106 face->horizontal.number_Of_HMetrics = 0;
700 error = FT_Err_Ok; 1107 error = FT_Err_Ok;
701 } 1108 }
702 #endif 1109 #endif
703 1110
704 } 1111 }
705 } 1112 }
706 1113
707 if ( error ) 1114 if ( error )
708 goto Exit; 1115 goto Exit;
709 1116
710 /* try to load the `vhea' and `vmtx' tables */ 1117 /* try to load the `vhea' and `vmtx' tables */
711 LOADM_( hhea, 1 ); 1118 LOADM_( hhea, 1 );
712 if ( !error ) 1119 if ( !error )
713 { 1120 {
714 LOADM_( hmtx, 1 ); 1121 LOADM_( hmtx, 1 );
715 if ( !error ) 1122 if ( !error )
716 face->vertical_info = 1; 1123 face->vertical_info = 1;
717 } 1124 }
718 1125
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
798 /* now set up root fields */ 1205 /* now set up root fields */
799 { 1206 {
800 FT_Face root = &face->root; 1207 FT_Face root = &face->root;
801 FT_Long flags = root->face_flags; 1208 FT_Long flags = root->face_flags;
802 1209
803 1210
804 /*********************************************************************/ 1211 /*********************************************************************/
805 /* */ 1212 /* */
806 /* Compute face flags. */ 1213 /* Compute face flags. */
807 /* */ 1214 /* */
1215 if ( face->sbit_table_type == TT_SBIT_TABLE_TYPE_CBLC ||
1216 face->sbit_table_type == TT_SBIT_TABLE_TYPE_SBIX )
1217 flags |= FT_FACE_FLAG_COLOR; /* color glyphs */
1218
808 if ( has_outline == TRUE ) 1219 if ( has_outline == TRUE )
809 flags |= FT_FACE_FLAG_SCALABLE; /* scalable outlines */ 1220 flags |= FT_FACE_FLAG_SCALABLE; /* scalable outlines */
810 1221
811 /* The sfnt driver only supports bitmap fonts natively, thus we */ 1222 /* The sfnt driver only supports bitmap fonts natively, thus we */
812 /* don't set FT_FACE_FLAG_HINTER. */ 1223 /* don't set FT_FACE_FLAG_HINTER. */
813 flags |= FT_FACE_FLAG_SFNT | /* SFNT file format */ 1224 flags |= FT_FACE_FLAG_SFNT | /* SFNT file format */
814 FT_FACE_FLAG_HORIZONTAL; /* horizontal data */ 1225 FT_FACE_FLAG_HORIZONTAL; /* horizontal data */
815 1226
816 #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES 1227 #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
817 if ( !psnames_error && 1228 if ( !psnames_error &&
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
926 if ( count > 0 ) 1337 if ( count > 0 )
927 { 1338 {
928 FT_Memory memory = face->root.stream->memory; 1339 FT_Memory memory = face->root.stream->memory;
929 FT_UShort em_size = face->header.Units_Per_EM; 1340 FT_UShort em_size = face->header.Units_Per_EM;
930 FT_Short avgwidth = face->os2.xAvgCharWidth; 1341 FT_Short avgwidth = face->os2.xAvgCharWidth;
931 FT_Size_Metrics metrics; 1342 FT_Size_Metrics metrics;
932 1343
933 1344
934 if ( em_size == 0 || face->os2.version == 0xFFFFU ) 1345 if ( em_size == 0 || face->os2.version == 0xFFFFU )
935 { 1346 {
936 avgwidth = 0; 1347 avgwidth = 1;
937 em_size = 1; 1348 em_size = 1;
938 } 1349 }
939 1350
940 if ( FT_NEW_ARRAY( root->available_sizes, count ) ) 1351 if ( FT_NEW_ARRAY( root->available_sizes, count ) )
941 goto Exit; 1352 goto Exit;
942 1353
943 for ( i = 0; i < count; i++ ) 1354 for ( i = 0; i < count; i++ )
944 { 1355 {
945 FT_Bitmap_Size* bsize = root->available_sizes + i; 1356 FT_Bitmap_Size* bsize = root->available_sizes + i;
946 1357
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
1156 FT_FREE( face->root.available_sizes ); 1567 FT_FREE( face->root.available_sizes );
1157 face->root.num_fixed_sizes = 0; 1568 face->root.num_fixed_sizes = 0;
1158 1569
1159 FT_FREE( face->postscript_name ); 1570 FT_FREE( face->postscript_name );
1160 1571
1161 face->sfnt = 0; 1572 face->sfnt = 0;
1162 } 1573 }
1163 1574
1164 1575
1165 /* END */ 1576 /* END */
OLDNEW
« no previous file with comments | « third_party/freetype/src/sfnt/sfobjs.h ('k') | third_party/freetype/src/sfnt/ttbdf.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698