OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include <ctype.h> | 8 #include <ctype.h> |
9 | 9 |
10 #include "SkData.h" | 10 #include "SkData.h" |
11 #include "SkGlyphCache.h" | 11 #include "SkGlyphCache.h" |
12 #include "SkPaint.h" | 12 #include "SkPaint.h" |
13 #include "SkPDFCatalog.h" | 13 #include "SkPDFCatalog.h" |
| 14 #include "SkPDFCanon.h" |
14 #include "SkPDFDevice.h" | 15 #include "SkPDFDevice.h" |
15 #include "SkPDFFont.h" | 16 #include "SkPDFFont.h" |
16 #include "SkPDFFontImpl.h" | 17 #include "SkPDFFontImpl.h" |
17 #include "SkPDFStream.h" | 18 #include "SkPDFStream.h" |
18 #include "SkPDFTypes.h" | 19 #include "SkPDFTypes.h" |
19 #include "SkPDFUtils.h" | 20 #include "SkPDFUtils.h" |
20 #include "SkRefCnt.h" | 21 #include "SkRefCnt.h" |
21 #include "SkScalar.h" | 22 #include "SkScalar.h" |
22 #include "SkStream.h" | 23 #include "SkStream.h" |
23 #include "SkTypefacePriv.h" | 24 #include "SkTypefacePriv.h" |
(...skipping 710 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
734 * Resources are canonicalized and uniqueified by pointer so there has to be | 735 * Resources are canonicalized and uniqueified by pointer so there has to be |
735 * some additional state indicating which subset of the font is used. It | 736 * some additional state indicating which subset of the font is used. It |
736 * must be maintained at the page granularity and then combined at the document | 737 * must be maintained at the page granularity and then combined at the document |
737 * granularity. a) change SkPDFFont to fill in its state on demand, kind of | 738 * granularity. a) change SkPDFFont to fill in its state on demand, kind of |
738 * like SkPDFGraphicState. b) maintain a per font glyph usage class in each | 739 * like SkPDFGraphicState. b) maintain a per font glyph usage class in each |
739 * page/pdf device. c) in the document, retrieve the per font glyph usage | 740 * page/pdf device. c) in the document, retrieve the per font glyph usage |
740 * from each page and combine it and ask for a resource with that subset. | 741 * from each page and combine it and ask for a resource with that subset. |
741 */ | 742 */ |
742 | 743 |
743 SkPDFFont::~SkPDFFont() { | 744 SkPDFFont::~SkPDFFont() { |
744 SkAutoMutexAcquire lock(CanonicalFontsMutex()); | 745 { |
745 int index = -1; | 746 SkAutoMutexAcquire lock(SkPDFCanon::GetFontMutex()); |
746 for (int i = 0 ; i < CanonicalFonts().count() ; i++) { | 747 SkPDFCanon::GetCanon().removeFont(this); |
747 if (CanonicalFonts()[i].fFont == this) { | |
748 index = i; | |
749 } | |
750 } | |
751 | |
752 SkDEBUGCODE(int indexFound;) | |
753 SkASSERT(index == -1 || | |
754 (Find(fTypeface->uniqueID(), | |
755 fFirstGlyphID, | |
756 &indexFound) && | |
757 index == indexFound)); | |
758 if (index >= 0) { | |
759 CanonicalFonts().removeShuffle(index); | |
760 } | 748 } |
761 fResources.unrefAll(); | 749 fResources.unrefAll(); |
762 } | 750 } |
763 | 751 |
764 void SkPDFFont::getResources(const SkTSet<SkPDFObject*>& knownResourceObjects, | 752 void SkPDFFont::getResources(const SkTSet<SkPDFObject*>& knownResourceObjects, |
765 SkTSet<SkPDFObject*>* newResourceObjects) { | 753 SkTSet<SkPDFObject*>* newResourceObjects) { |
766 GetResourcesHelper(&fResources, knownResourceObjects, newResourceObjects); | 754 GetResourcesHelper(&fResources, knownResourceObjects, newResourceObjects); |
767 } | 755 } |
768 | 756 |
769 SkTypeface* SkPDFFont::typeface() { | 757 SkTypeface* SkPDFFont::typeface() { |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
810 return i; | 798 return i; |
811 } | 799 } |
812 glyphIDs[i] -= (fFirstGlyphID - 1); | 800 glyphIDs[i] -= (fFirstGlyphID - 1); |
813 } | 801 } |
814 | 802 |
815 return numGlyphs; | 803 return numGlyphs; |
816 } | 804 } |
817 | 805 |
818 // static | 806 // static |
819 SkPDFFont* SkPDFFont::GetFontResource(SkTypeface* typeface, uint16_t glyphID) { | 807 SkPDFFont* SkPDFFont::GetFontResource(SkTypeface* typeface, uint16_t glyphID) { |
820 SkAutoMutexAcquire lock(CanonicalFontsMutex()); | |
821 | |
822 SkAutoResolveDefaultTypeface autoResolve(typeface); | 808 SkAutoResolveDefaultTypeface autoResolve(typeface); |
823 typeface = autoResolve.get(); | 809 typeface = autoResolve.get(); |
| 810 const uint32_t fontID = typeface->uniqueID(); |
824 | 811 |
825 const uint32_t fontID = typeface->uniqueID(); | 812 SkAutoMutexAcquire lock(SkPDFCanon::GetFontMutex()); |
826 int relatedFontIndex; | 813 SkPDFFont* relatedFont; |
827 if (Find(fontID, glyphID, &relatedFontIndex)) { | 814 SkPDFFont* pdfFont = |
828 CanonicalFonts()[relatedFontIndex].fFont->ref(); | 815 SkPDFCanon::GetCanon().findFont(fontID, glyphID, &relatedFont); |
829 return CanonicalFonts()[relatedFontIndex].fFont; | 816 if (pdfFont) { |
| 817 return SkRef(pdfFont); |
830 } | 818 } |
831 | 819 |
832 SkAutoTUnref<const SkAdvancedTypefaceMetrics> fontMetrics; | 820 SkAutoTUnref<const SkAdvancedTypefaceMetrics> fontMetrics; |
833 SkPDFDict* relatedFontDescriptor = NULL; | 821 SkPDFDict* relatedFontDescriptor = NULL; |
834 if (relatedFontIndex >= 0) { | 822 if (relatedFont) { |
835 SkPDFFont* relatedFont = CanonicalFonts()[relatedFontIndex].fFont; | 823 fontMetrics.reset(SkSafeRef(relatedFont->fontInfo())); |
836 fontMetrics.reset(relatedFont->fontInfo()); | |
837 SkSafeRef(fontMetrics.get()); | |
838 relatedFontDescriptor = relatedFont->getFontDescriptor(); | 824 relatedFontDescriptor = relatedFont->getFontDescriptor(); |
839 | 825 |
840 // This only is to catch callers who pass invalid glyph ids. | 826 // This only is to catch callers who pass invalid glyph ids. |
841 // If glyph id is invalid, then we will create duplicate entries | 827 // If glyph id is invalid, then we will create duplicate entries |
842 // for TrueType fonts. | 828 // for TrueType fonts. |
843 SkAdvancedTypefaceMetrics::FontType fontType = | 829 SkAdvancedTypefaceMetrics::FontType fontType = |
844 fontMetrics.get() ? fontMetrics.get()->fType : | 830 fontMetrics.get() ? fontMetrics.get()->fType : |
845 SkAdvancedTypefaceMetrics::kOther_Font; | 831 SkAdvancedTypefaceMetrics::kOther_Font; |
846 | 832 |
847 if (fontType == SkAdvancedTypefaceMetrics::kType1CID_Font || | 833 if (fontType == SkAdvancedTypefaceMetrics::kType1CID_Font || |
848 fontType == SkAdvancedTypefaceMetrics::kTrueType_Font) { | 834 fontType == SkAdvancedTypefaceMetrics::kTrueType_Font) { |
849 CanonicalFonts()[relatedFontIndex].fFont->ref(); | 835 return SkRef(relatedFont); |
850 return CanonicalFonts()[relatedFontIndex].fFont; | |
851 } | 836 } |
852 } else { | 837 } else { |
853 SkAdvancedTypefaceMetrics::PerGlyphInfo info; | 838 SkAdvancedTypefaceMetrics::PerGlyphInfo info; |
854 info = SkAdvancedTypefaceMetrics::kGlyphNames_PerGlyphInfo; | 839 info = SkAdvancedTypefaceMetrics::kGlyphNames_PerGlyphInfo; |
855 info = SkTBitOr<SkAdvancedTypefaceMetrics::PerGlyphInfo>( | 840 info = SkTBitOr<SkAdvancedTypefaceMetrics::PerGlyphInfo>( |
856 info, SkAdvancedTypefaceMetrics::kToUnicode_PerGlyphInfo); | 841 info, SkAdvancedTypefaceMetrics::kToUnicode_PerGlyphInfo); |
857 #if !defined (SK_SFNTLY_SUBSETTER) | 842 #if !defined (SK_SFNTLY_SUBSETTER) |
858 info = SkTBitOr<SkAdvancedTypefaceMetrics::PerGlyphInfo>( | 843 info = SkTBitOr<SkAdvancedTypefaceMetrics::PerGlyphInfo>( |
859 info, SkAdvancedTypefaceMetrics::kHAdvance_PerGlyphInfo); | 844 info, SkAdvancedTypefaceMetrics::kHAdvance_PerGlyphInfo); |
860 #endif | 845 #endif |
861 fontMetrics.reset( | 846 fontMetrics.reset( |
862 typeface->getAdvancedTypefaceMetrics(info, NULL, 0)); | 847 typeface->getAdvancedTypefaceMetrics(info, NULL, 0)); |
863 #if defined (SK_SFNTLY_SUBSETTER) | 848 #if defined (SK_SFNTLY_SUBSETTER) |
864 if (fontMetrics.get() && | 849 if (fontMetrics.get() && |
865 fontMetrics->fType != SkAdvancedTypefaceMetrics::kTrueType_Font) { | 850 fontMetrics->fType != SkAdvancedTypefaceMetrics::kTrueType_Font) { |
866 // Font does not support subsetting, get new info with advance. | 851 // Font does not support subsetting, get new info with advance. |
867 info = SkTBitOr<SkAdvancedTypefaceMetrics::PerGlyphInfo>( | 852 info = SkTBitOr<SkAdvancedTypefaceMetrics::PerGlyphInfo>( |
868 info, SkAdvancedTypefaceMetrics::kHAdvance_PerGlyphInfo); | 853 info, SkAdvancedTypefaceMetrics::kHAdvance_PerGlyphInfo); |
869 fontMetrics.reset( | 854 fontMetrics.reset( |
870 typeface->getAdvancedTypefaceMetrics(info, NULL, 0)); | 855 typeface->getAdvancedTypefaceMetrics(info, NULL, 0)); |
871 } | 856 } |
872 #endif | 857 #endif |
873 } | 858 } |
874 | 859 |
875 SkPDFFont* font = Create(fontMetrics.get(), typeface, glyphID, | 860 SkPDFFont* font = Create(fontMetrics.get(), typeface, glyphID, |
876 relatedFontDescriptor); | 861 relatedFontDescriptor); |
877 FontRec newEntry(font, fontID, font->fFirstGlyphID); | 862 SkPDFCanon::GetCanon().addFont(font, fontID, font->fFirstGlyphID); |
878 CanonicalFonts().push(newEntry); | |
879 return font; // Return the reference new SkPDFFont() created. | 863 return font; // Return the reference new SkPDFFont() created. |
880 } | 864 } |
881 | 865 |
882 SkPDFFont* SkPDFFont::getFontSubset(const SkPDFGlyphSet*) { | 866 SkPDFFont* SkPDFFont::getFontSubset(const SkPDFGlyphSet*) { |
883 return NULL; // Default: no support. | 867 return NULL; // Default: no support. |
884 } | 868 } |
885 | 869 |
886 // static | |
887 SkTDArray<SkPDFFont::FontRec>& SkPDFFont::CanonicalFonts() { | |
888 SkPDFFont::CanonicalFontsMutex().assertHeld(); | |
889 static SkTDArray<FontRec> gCanonicalFonts; | |
890 return gCanonicalFonts; | |
891 } | |
892 | |
893 SK_DECLARE_STATIC_MUTEX(gCanonicalFontsMutex); | |
894 // static | |
895 SkBaseMutex& SkPDFFont::CanonicalFontsMutex() { | |
896 return gCanonicalFontsMutex; | |
897 } | |
898 | |
899 // static | |
900 bool SkPDFFont::Find(uint32_t fontID, uint16_t glyphID, int* index) { | |
901 // TODO(vandebo): Optimize this, do only one search? | |
902 FontRec search(NULL, fontID, glyphID); | |
903 *index = CanonicalFonts().find(search); | |
904 if (*index >= 0) { | |
905 return true; | |
906 } | |
907 search.fGlyphID = 0; | |
908 *index = CanonicalFonts().find(search); | |
909 return false; | |
910 } | |
911 | |
912 SkPDFFont::SkPDFFont(const SkAdvancedTypefaceMetrics* info, | 870 SkPDFFont::SkPDFFont(const SkAdvancedTypefaceMetrics* info, |
913 SkTypeface* typeface, | 871 SkTypeface* typeface, |
914 SkPDFDict* relatedFontDescriptor) | 872 SkPDFDict* relatedFontDescriptor) |
915 : SkPDFDict("Font"), | 873 : SkPDFDict("Font"), |
916 fTypeface(ref_or_default(typeface)), | 874 fTypeface(ref_or_default(typeface)), |
917 fFirstGlyphID(1), | 875 fFirstGlyphID(1), |
918 fLastGlyphID(info ? info->fLastGlyphID : 0), | 876 fLastGlyphID(info ? info->fLastGlyphID : 0), |
919 fFontInfo(SkSafeRef(info)), | 877 fFontInfo(SkSafeRef(info)), |
920 fDescriptor(SkSafeRef(relatedFontDescriptor)) { | 878 fDescriptor(SkSafeRef(relatedFontDescriptor)) { |
921 if (info == NULL || | 879 if (info == NULL || |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1027 } | 985 } |
1028 | 986 |
1029 void SkPDFFont::adjustGlyphRangeForSingleByteEncoding(uint16_t glyphID) { | 987 void SkPDFFont::adjustGlyphRangeForSingleByteEncoding(uint16_t glyphID) { |
1030 // Single byte glyph encoding supports a max of 255 glyphs. | 988 // Single byte glyph encoding supports a max of 255 glyphs. |
1031 fFirstGlyphID = glyphID - (glyphID - 1) % 255; | 989 fFirstGlyphID = glyphID - (glyphID - 1) % 255; |
1032 if (fLastGlyphID > fFirstGlyphID + 255 - 1) { | 990 if (fLastGlyphID > fFirstGlyphID + 255 - 1) { |
1033 fLastGlyphID = fFirstGlyphID + 255 - 1; | 991 fLastGlyphID = fFirstGlyphID + 255 - 1; |
1034 } | 992 } |
1035 } | 993 } |
1036 | 994 |
1037 bool SkPDFFont::FontRec::operator==(const SkPDFFont::FontRec& b) const { | |
1038 if (fFontID != b.fFontID) { | |
1039 return false; | |
1040 } | |
1041 if (fFont != NULL && b.fFont != NULL) { | |
1042 return fFont->fFirstGlyphID == b.fFont->fFirstGlyphID && | |
1043 fFont->fLastGlyphID == b.fFont->fLastGlyphID; | |
1044 } | |
1045 if (fGlyphID == 0 || b.fGlyphID == 0) { | |
1046 return true; | |
1047 } | |
1048 | |
1049 if (fFont != NULL) { | |
1050 return fFont->fFirstGlyphID <= b.fGlyphID && | |
1051 b.fGlyphID <= fFont->fLastGlyphID; | |
1052 } else if (b.fFont != NULL) { | |
1053 return b.fFont->fFirstGlyphID <= fGlyphID && | |
1054 fGlyphID <= b.fFont->fLastGlyphID; | |
1055 } | |
1056 return fGlyphID == b.fGlyphID; | |
1057 } | |
1058 | |
1059 SkPDFFont::FontRec::FontRec(SkPDFFont* font, uint32_t fontID, uint16_t glyphID) | |
1060 : fFont(font), | |
1061 fFontID(fontID), | |
1062 fGlyphID(glyphID) { | |
1063 } | |
1064 | |
1065 void SkPDFFont::populateToUnicodeTable(const SkPDFGlyphSet* subset) { | 995 void SkPDFFont::populateToUnicodeTable(const SkPDFGlyphSet* subset) { |
1066 if (fFontInfo == NULL || fFontInfo->fGlyphToUnicode.begin() == NULL) { | 996 if (fFontInfo == NULL || fFontInfo->fGlyphToUnicode.begin() == NULL) { |
1067 return; | 997 return; |
1068 } | 998 } |
1069 SkAutoTUnref<SkPDFStream> pdfCmap( | 999 SkAutoTUnref<SkPDFStream> pdfCmap( |
1070 generate_tounicode_cmap(fFontInfo->fGlyphToUnicode, subset, | 1000 generate_tounicode_cmap(fFontInfo->fGlyphToUnicode, subset, |
1071 multiByteGlyphs(), firstGlyphID(), | 1001 multiByteGlyphs(), firstGlyphID(), |
1072 lastGlyphID())); | 1002 lastGlyphID())); |
1073 addResource(pdfCmap.get()); | 1003 addResource(pdfCmap.get()); |
1074 insert("ToUnicode", new SkPDFObjRef(pdfCmap.get()))->unref(); | 1004 insert("ToUnicode", new SkPDFObjRef(pdfCmap.get()))->unref(); |
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1487 | 1417 |
1488 insert("FontBBox", makeFontBBox(bbox, 1000))->unref(); | 1418 insert("FontBBox", makeFontBBox(bbox, 1000))->unref(); |
1489 insertInt("FirstChar", 1); | 1419 insertInt("FirstChar", 1); |
1490 insertInt("LastChar", lastGlyphID() - firstGlyphID() + 1); | 1420 insertInt("LastChar", lastGlyphID() - firstGlyphID() + 1); |
1491 insert("Widths", widthArray.get()); | 1421 insert("Widths", widthArray.get()); |
1492 insertName("CIDToGIDMap", "Identity"); | 1422 insertName("CIDToGIDMap", "Identity"); |
1493 | 1423 |
1494 populateToUnicodeTable(NULL); | 1424 populateToUnicodeTable(NULL); |
1495 return true; | 1425 return true; |
1496 } | 1426 } |
| 1427 |
| 1428 SkPDFFont::Match SkPDFFont::IsMatch(SkPDFFont* existingFont, |
| 1429 uint32_t existingFontID, |
| 1430 uint16_t existingGlyphID, |
| 1431 uint32_t searchFontID, |
| 1432 uint16_t searchGlyphID) { |
| 1433 if (existingFontID != searchFontID) { |
| 1434 return SkPDFFont::kNot_Match; |
| 1435 } |
| 1436 if (existingGlyphID == 0 || searchGlyphID == 0) { |
| 1437 return SkPDFFont::kExact_Match; |
| 1438 } |
| 1439 if (existingFont != NULL) { |
| 1440 return (existingFont->fFirstGlyphID <= searchGlyphID && |
| 1441 searchGlyphID <= existingFont->fLastGlyphID) |
| 1442 ? SkPDFFont::kExact_Match |
| 1443 : SkPDFFont::kRelated_Match; |
| 1444 } |
| 1445 return (existingGlyphID == searchGlyphID) ? SkPDFFont::kExact_Match |
| 1446 : SkPDFFont::kRelated_Match; |
| 1447 } |
OLD | NEW |