OLD | NEW |
1 /***************************************************************************/ | 1 /***************************************************************************/ |
2 /* */ | 2 /* */ |
3 /* cffobjs.c */ | 3 /* cffobjs.c */ |
4 /* */ | 4 /* */ |
5 /* OpenType objects manager (body). */ | 5 /* OpenType objects manager (body). */ |
6 /* */ | 6 /* */ |
7 /* Copyright 1996-2011 by */ | 7 /* Copyright 1996-2012 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 |
(...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
396 /* Strip all subset prefixes of the form `ABCDEF+'. Usually, there */ | 396 /* Strip all subset prefixes of the form `ABCDEF+'. Usually, there */ |
397 /* is only one, but font names like `APCOOG+JFABTD+FuturaBQ-Bold' */ | 397 /* is only one, but font names like `APCOOG+JFABTD+FuturaBQ-Bold' */ |
398 /* have been seen in the wild. */ | 398 /* have been seen in the wild. */ |
399 | 399 |
400 static void | 400 static void |
401 remove_subset_prefix( FT_String* name ) | 401 remove_subset_prefix( FT_String* name ) |
402 { | 402 { |
403 FT_Int32 idx = 0; | 403 FT_Int32 idx = 0; |
404 FT_Int32 length = strlen( name ) + 1; | 404 FT_Int32 length = strlen( name ) + 1; |
405 FT_Bool continue_search = 1; | 405 FT_Bool continue_search = 1; |
406 | 406 |
407 | 407 |
408 while ( continue_search ) | 408 while ( continue_search ) |
409 { | 409 { |
410 if ( length >= 7 && name[6] == '+' ) | 410 if ( length >= 7 && name[6] == '+' ) |
411 { | 411 { |
412 for ( idx = 0; idx < 6; idx++ ) | 412 for ( idx = 0; idx < 6; idx++ ) |
413 { | 413 { |
414 /* ASCII uppercase letters */ | 414 /* ASCII uppercase letters */ |
415 if ( !( 'A' <= name[idx] && name[idx] <= 'Z' ) ) | 415 if ( !( 'A' <= name[idx] && name[idx] <= 'Z' ) ) |
416 continue_search = 0; | 416 continue_search = 0; |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
487 FT_Service_PsCMaps psnames; | 487 FT_Service_PsCMaps psnames; |
488 PSHinter_Service pshinter; | 488 PSHinter_Service pshinter; |
489 FT_Bool pure_cff = 1; | 489 FT_Bool pure_cff = 1; |
490 FT_Bool sfnt_format = 0; | 490 FT_Bool sfnt_format = 0; |
491 FT_Library library = cffface->driver->root.library; | 491 FT_Library library = cffface->driver->root.library; |
492 | 492 |
493 | 493 |
494 sfnt = (SFNT_Service)FT_Get_Module_Interface( | 494 sfnt = (SFNT_Service)FT_Get_Module_Interface( |
495 library, "sfnt" ); | 495 library, "sfnt" ); |
496 if ( !sfnt ) | 496 if ( !sfnt ) |
497 goto Bad_Format; | 497 { |
| 498 FT_ERROR(( "cff_face_init: cannot access `sfnt' module\n" )); |
| 499 error = CFF_Err_Missing_Module; |
| 500 goto Exit; |
| 501 } |
498 | 502 |
499 FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS ); | 503 FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS ); |
500 | 504 |
501 pshinter = (PSHinter_Service)FT_Get_Module_Interface( | 505 pshinter = (PSHinter_Service)FT_Get_Module_Interface( |
502 library, "pshinter" ); | 506 library, "pshinter" ); |
503 | 507 |
| 508 FT_TRACE2(( "CFF driver\n" )); |
| 509 |
504 /* create input stream from resource */ | 510 /* create input stream from resource */ |
505 if ( FT_STREAM_SEEK( 0 ) ) | 511 if ( FT_STREAM_SEEK( 0 ) ) |
506 goto Exit; | 512 goto Exit; |
507 | 513 |
508 /* check whether we have a valid OpenType file */ | 514 /* check whether we have a valid OpenType file */ |
509 error = sfnt->init_face( stream, face, face_index, num_params, params ); | 515 error = sfnt->init_face( stream, face, face_index, num_params, params ); |
510 if ( !error ) | 516 if ( !error ) |
511 { | 517 { |
512 if ( face->format_tag != TTAG_OTTO ) /* `OTTO'; OpenType/CFF font */ | 518 if ( face->format_tag != TTAG_OTTO ) /* `OTTO'; OpenType/CFF font */ |
513 { | 519 { |
514 FT_TRACE2(( "[not a valid OpenType/CFF font]\n" )); | 520 FT_TRACE2(( " not an OpenType/CFF font\n" )); |
515 goto Bad_Format; | 521 error = CFF_Err_Unknown_File_Format; |
| 522 goto Exit; |
516 } | 523 } |
517 | 524 |
518 /* if we are performing a simple font format check, exit immediately */ | 525 /* if we are performing a simple font format check, exit immediately */ |
519 if ( face_index < 0 ) | 526 if ( face_index < 0 ) |
520 return CFF_Err_Ok; | 527 return CFF_Err_Ok; |
521 | 528 |
522 /* UNDOCUMENTED! A CFF in an SFNT can have only a single font. */ | 529 /* UNDOCUMENTED! A CFF in an SFNT can have only a single font. */ |
523 if ( face_index > 0 ) | 530 if ( face_index > 0 ) |
524 { | 531 { |
525 FT_ERROR(( "cff_face_init: invalid face index\n" )); | 532 FT_ERROR(( "cff_face_init: invalid face index\n" )); |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
597 dict = &cff->top_font.font_dict; | 604 dict = &cff->top_font.font_dict; |
598 | 605 |
599 /* we need the `PSNames' module for CFF and CEF formats */ | 606 /* we need the `PSNames' module for CFF and CEF formats */ |
600 /* which aren't CID-keyed */ | 607 /* which aren't CID-keyed */ |
601 if ( dict->cid_registry == 0xFFFFU && !psnames ) | 608 if ( dict->cid_registry == 0xFFFFU && !psnames ) |
602 { | 609 { |
603 FT_ERROR(( "cff_face_init:" | 610 FT_ERROR(( "cff_face_init:" |
604 " cannot open CFF & CEF fonts\n" | 611 " cannot open CFF & CEF fonts\n" |
605 " " | 612 " " |
606 " without the `PSNames' module\n" )); | 613 " without the `PSNames' module\n" )); |
607 goto Bad_Format; | 614 error = CFF_Err_Missing_Module; |
| 615 goto Exit; |
608 } | 616 } |
609 | 617 |
610 if ( !dict->units_per_em ) | 618 #ifdef FT_DEBUG_LEVEL_TRACE |
| 619 { |
| 620 FT_UInt idx; |
| 621 FT_String* s; |
| 622 |
| 623 |
| 624 FT_TRACE4(( "SIDs\n" )); |
| 625 |
| 626 /* dump string index, including default strings for convenience */ |
| 627 for ( idx = 0; idx < cff->num_strings + 390; idx++ ) |
| 628 { |
| 629 s = cff_index_get_sid_string( cff, idx ); |
| 630 if ( s ) |
| 631 FT_TRACE4((" %5d %s\n", idx, s )); |
| 632 } |
| 633 } |
| 634 #endif /* FT_DEBUG_LEVEL_TRACE */ |
| 635 |
| 636 if ( !dict->has_font_matrix ) |
611 dict->units_per_em = pure_cff ? 1000 : face->root.units_per_EM; | 637 dict->units_per_em = pure_cff ? 1000 : face->root.units_per_EM; |
612 | 638 |
613 /* Normalize the font matrix so that `matrix->xx' is 1; the */ | 639 /* Normalize the font matrix so that `matrix->xx' is 1; the */ |
614 /* scaling is done with `units_per_em' then (at this point, */ | 640 /* scaling is done with `units_per_em' then (at this point, */ |
615 /* it already contains the scaling factor, but without */ | 641 /* it already contains the scaling factor, but without */ |
616 /* normalization of the matrix). */ | 642 /* normalization of the matrix). */ |
617 /* */ | 643 /* */ |
618 /* Note that the offsets must be expressed in integer font */ | 644 /* Note that the offsets must be expressed in integer font */ |
619 /* units. */ | 645 /* units. */ |
620 | 646 |
(...skipping 24 matching lines...) Expand all Loading... |
645 { | 671 { |
646 CFF_FontRecDict sub = &cff->subfonts[i - 1]->font_dict; | 672 CFF_FontRecDict sub = &cff->subfonts[i - 1]->font_dict; |
647 CFF_FontRecDict top = &cff->top_font.font_dict; | 673 CFF_FontRecDict top = &cff->top_font.font_dict; |
648 | 674 |
649 FT_Matrix* matrix; | 675 FT_Matrix* matrix; |
650 FT_Vector* offset; | 676 FT_Vector* offset; |
651 FT_ULong* upm; | 677 FT_ULong* upm; |
652 FT_Fixed temp; | 678 FT_Fixed temp; |
653 | 679 |
654 | 680 |
655 if ( sub->units_per_em ) | 681 if ( sub->has_font_matrix ) |
656 { | 682 { |
657 FT_Long scaling; | 683 FT_Long scaling; |
658 | 684 |
659 | 685 |
660 if ( top->units_per_em > 1 && sub->units_per_em > 1 ) | 686 /* if we have a top-level matrix, */ |
661 scaling = FT_MIN( top->units_per_em, sub->units_per_em ); | 687 /* concatenate the subfont matrix */ |
662 else | |
663 scaling = 1; | |
664 | 688 |
665 FT_Matrix_Multiply_Scaled( &top->font_matrix, | 689 if ( top->has_font_matrix ) |
666 &sub->font_matrix, | 690 { |
667 scaling ); | 691 if ( top->units_per_em > 1 && sub->units_per_em > 1 ) |
668 FT_Vector_Transform_Scaled( &sub->font_offset, | 692 scaling = FT_MIN( top->units_per_em, sub->units_per_em ); |
669 &top->font_matrix, | 693 else |
670 scaling ); | 694 scaling = 1; |
671 | 695 |
672 sub->units_per_em = FT_MulDiv( sub->units_per_em, | 696 FT_Matrix_Multiply_Scaled( &top->font_matrix, |
673 top->units_per_em, | 697 &sub->font_matrix, |
674 scaling ); | 698 scaling ); |
| 699 FT_Vector_Transform_Scaled( &sub->font_offset, |
| 700 &top->font_matrix, |
| 701 scaling ); |
| 702 |
| 703 sub->units_per_em = FT_MulDiv( sub->units_per_em, |
| 704 top->units_per_em, |
| 705 scaling ); |
| 706 } |
675 } | 707 } |
676 else | 708 else |
677 { | 709 { |
678 sub->font_matrix = top->font_matrix; | 710 sub->font_matrix = top->font_matrix; |
679 sub->font_offset = top->font_offset; | 711 sub->font_offset = top->font_offset; |
680 | 712 |
681 sub->units_per_em = top->units_per_em; | 713 sub->units_per_em = top->units_per_em; |
682 } | 714 } |
683 | 715 |
684 matrix = &sub->font_matrix; | 716 matrix = &sub->font_matrix; |
685 offset = &sub->font_offset; | 717 offset = &sub->font_offset; |
686 upm = &sub->units_per_em; | 718 upm = &sub->units_per_em; |
687 temp = FT_ABS( matrix->yy ); | 719 temp = FT_ABS( matrix->yy ); |
688 | 720 |
689 if ( temp != 0x10000L ) | 721 if ( temp != 0x10000L ) |
690 { | 722 { |
691 *upm = FT_DivFix( *upm, temp ); | 723 *upm = FT_DivFix( *upm, temp ); |
692 | 724 |
693 /* if *upm is larger than 100*1000 we divide by 1000 -- */ | |
694 /* this can happen if e.g. there is no top-font FontMatrix */ | |
695 /* and the subfont FontMatrix already contains the complete */ | |
696 /* scaling for the subfont (see section 5.11 of the PLRM) */ | |
697 | |
698 /* 100 is a heuristic value */ | |
699 | |
700 if ( *upm > 100L * 1000L ) | |
701 *upm = ( *upm + 500 ) / 1000; | |
702 | |
703 matrix->xx = FT_DivFix( matrix->xx, temp ); | 725 matrix->xx = FT_DivFix( matrix->xx, temp ); |
704 matrix->yx = FT_DivFix( matrix->yx, temp ); | 726 matrix->yx = FT_DivFix( matrix->yx, temp ); |
705 matrix->xy = FT_DivFix( matrix->xy, temp ); | 727 matrix->xy = FT_DivFix( matrix->xy, temp ); |
706 matrix->yy = FT_DivFix( matrix->yy, temp ); | 728 matrix->yy = FT_DivFix( matrix->yy, temp ); |
707 offset->x = FT_DivFix( offset->x, temp ); | 729 offset->x = FT_DivFix( offset->x, temp ); |
708 offset->y = FT_DivFix( offset->y, temp ); | 730 offset->y = FT_DivFix( offset->y, temp ); |
709 } | 731 } |
710 | 732 |
711 offset->x >>= 16; | 733 offset->x >>= 16; |
712 offset->y >>= 16; | 734 offset->y >>= 16; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
751 cffface->family_name = cff_index_get_name( cff, face_index ); | 773 cffface->family_name = cff_index_get_name( cff, face_index ); |
752 if ( cffface->family_name ) | 774 if ( cffface->family_name ) |
753 { | 775 { |
754 char* full = cff_index_get_sid_string( cff, | 776 char* full = cff_index_get_sid_string( cff, |
755 dict->full_name ); | 777 dict->full_name ); |
756 char* fullp = full; | 778 char* fullp = full; |
757 char* family = cffface->family_name; | 779 char* family = cffface->family_name; |
758 char* family_name = NULL; | 780 char* family_name = NULL; |
759 | 781 |
760 | 782 |
761 remove_subset_prefix( cffface->family_name ); | 783 remove_subset_prefix( cffface->family_name ); |
762 | 784 |
763 if ( dict->family_name ) | 785 if ( dict->family_name ) |
764 { | 786 { |
765 family_name = cff_index_get_sid_string( cff, | 787 family_name = cff_index_get_sid_string( cff, |
766 dict->family_name ); | 788 dict->family_name ); |
767 if ( family_name ) | 789 if ( family_name ) |
768 family = family_name; | 790 family = family_name; |
769 } | 791 } |
770 | 792 |
771 /* We try to extract the style name from the full name. */ | 793 /* We try to extract the style name from the full name. */ |
(...skipping 26 matching lines...) Expand all Loading... |
798 | 820 |
799 if ( !*family && *fullp ) | 821 if ( !*family && *fullp ) |
800 { | 822 { |
801 /* The full name begins with the same characters as the */ | 823 /* The full name begins with the same characters as the */ |
802 /* family name, with spaces and dashes removed. In this */ | 824 /* family name, with spaces and dashes removed. In this */ |
803 /* case, the remaining string in `fullp' will be used as */ | 825 /* case, the remaining string in `fullp' will be used as */ |
804 /* the style name. */ | 826 /* the style name. */ |
805 style_name = cff_strcpy( memory, fullp ); | 827 style_name = cff_strcpy( memory, fullp ); |
806 | 828 |
807 /* remove the style part from the family name (if present) */ | 829 /* remove the style part from the family name (if present) */ |
808 remove_style( cffface->family_name, style_name ); | 830 remove_style( cffface->family_name, style_name ); |
809 } | 831 } |
810 break; | 832 break; |
811 } | 833 } |
812 } | 834 } |
813 } | 835 } |
814 else | 836 else |
815 { | 837 { |
816 char *cid_font_name = | 838 char *cid_font_name = |
817 cff_index_get_sid_string( cff, | 839 cff_index_get_sid_string( cff, |
818 dict->cid_font_name ); | 840 dict->cid_font_name ); |
819 | 841 |
820 | 842 |
821 /* do we have a `/FontName' for a CID-keyed font? */ | 843 /* do we have a `/FontName' for a CID-keyed font? */ |
822 if ( cid_font_name ) | 844 if ( cid_font_name ) |
823 cffface->family_name = cff_strcpy( memory, cid_font_name ); | 845 cffface->family_name = cff_strcpy( memory, cid_font_name ); |
824 } | 846 } |
825 | 847 |
826 if ( style_name ) | 848 if ( style_name ) |
827 cffface->style_name = style_name; | 849 cffface->style_name = style_name; |
828 else | 850 else |
829 /* assume "Regular" style if we don't know better */ | 851 /* assume "Regular" style if we don't know better */ |
830 cffface->style_name = cff_strcpy( memory, (char *)"Regular" ); | 852 cffface->style_name = cff_strcpy( memory, (char *)"Regular" ); |
831 | 853 |
832 /*******************************************************************/ | 854 /*******************************************************************/ |
833 /* */ | 855 /* */ |
834 /* Compute face flags. */ | 856 /* Compute face flags. */ |
835 /* */ | 857 /* */ |
836 flags = (FT_UInt32)( FT_FACE_FLAG_SCALABLE | /* scalable outlines */ | 858 flags = FT_FACE_FLAG_SCALABLE | /* scalable outlines */ |
837 FT_FACE_FLAG_HORIZONTAL | /* horizontal data */ | 859 FT_FACE_FLAG_HORIZONTAL | /* horizontal data */ |
838 FT_FACE_FLAG_HINTER ); /* has native hinter */ | 860 FT_FACE_FLAG_HINTER; /* has native hinter */ |
839 | 861 |
840 if ( sfnt_format ) | 862 if ( sfnt_format ) |
841 flags |= (FT_UInt32)FT_FACE_FLAG_SFNT; | 863 flags |= FT_FACE_FLAG_SFNT; |
842 | 864 |
843 /* fixed width font? */ | 865 /* fixed width font? */ |
844 if ( dict->is_fixed_pitch ) | 866 if ( dict->is_fixed_pitch ) |
845 flags |= (FT_UInt32)FT_FACE_FLAG_FIXED_WIDTH; | 867 flags |= FT_FACE_FLAG_FIXED_WIDTH; |
846 | 868 |
847 /* XXX: WE DO NOT SUPPORT KERNING METRICS IN THE GPOS TABLE FOR NOW */ | 869 /* XXX: WE DO NOT SUPPORT KERNING METRICS IN THE GPOS TABLE FOR NOW */ |
848 #if 0 | 870 #if 0 |
849 /* kerning available? */ | 871 /* kerning available? */ |
850 if ( face->kern_pairs ) | 872 if ( face->kern_pairs ) |
851 flags |= (FT_UInt32)FT_FACE_FLAG_KERNING; | 873 flags |= FT_FACE_FLAG_KERNING; |
852 #endif | 874 #endif |
853 | 875 |
854 cffface->face_flags = flags; | 876 cffface->face_flags = flags; |
855 | 877 |
856 /*******************************************************************/ | 878 /*******************************************************************/ |
857 /* */ | 879 /* */ |
858 /* Compute style flags. */ | 880 /* Compute style flags. */ |
859 /* */ | 881 /* */ |
860 flags = 0; | 882 flags = 0; |
861 | 883 |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
993 clazz = &FT_CFF_CMAP_ENCODING_CLASS_REC_GET; | 1015 clazz = &FT_CFF_CMAP_ENCODING_CLASS_REC_GET; |
994 } | 1016 } |
995 | 1017 |
996 error = FT_CMap_New( clazz, NULL, &cmaprec, NULL ); | 1018 error = FT_CMap_New( clazz, NULL, &cmaprec, NULL ); |
997 } | 1019 } |
998 } | 1020 } |
999 } | 1021 } |
1000 | 1022 |
1001 Exit: | 1023 Exit: |
1002 return error; | 1024 return error; |
1003 | |
1004 Bad_Format: | |
1005 error = CFF_Err_Unknown_File_Format; | |
1006 goto Exit; | |
1007 } | 1025 } |
1008 | 1026 |
1009 | 1027 |
1010 FT_LOCAL_DEF( void ) | 1028 FT_LOCAL_DEF( void ) |
1011 cff_face_done( FT_Face cffface ) /* CFF_Face */ | 1029 cff_face_done( FT_Face cffface ) /* CFF_Face */ |
1012 { | 1030 { |
1013 CFF_Face face = (CFF_Face)cffface; | 1031 CFF_Face face = (CFF_Face)cffface; |
1014 FT_Memory memory; | 1032 FT_Memory memory; |
1015 SFNT_Service sfnt; | 1033 SFNT_Service sfnt; |
1016 | 1034 |
(...skipping 30 matching lines...) Expand all Loading... |
1047 | 1065 |
1048 | 1066 |
1049 FT_LOCAL_DEF( void ) | 1067 FT_LOCAL_DEF( void ) |
1050 cff_driver_done( FT_Module module ) | 1068 cff_driver_done( FT_Module module ) |
1051 { | 1069 { |
1052 FT_UNUSED( module ); | 1070 FT_UNUSED( module ); |
1053 } | 1071 } |
1054 | 1072 |
1055 | 1073 |
1056 /* END */ | 1074 /* END */ |
OLD | NEW |