OLD | NEW |
1 | |
2 /* | 1 /* |
3 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
4 * | 3 * |
5 * 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 |
6 * found in the LICENSE file. | 5 * found in the LICENSE file. |
7 */ | 6 */ |
8 | 7 |
9 | |
10 #include <ctype.h> | 8 #include <ctype.h> |
11 | 9 |
12 #include "SkData.h" | 10 #include "SkData.h" |
13 #include "SkFontHost.h" | 11 #include "SkFontHost.h" |
14 #include "SkGlyphCache.h" | 12 #include "SkGlyphCache.h" |
15 #include "SkPaint.h" | 13 #include "SkPaint.h" |
16 #include "SkPDFCatalog.h" | 14 #include "SkPDFCatalog.h" |
17 #include "SkPDFDevice.h" | 15 #include "SkPDFDevice.h" |
18 #include "SkPDFFont.h" | 16 #include "SkPDFFont.h" |
19 #include "SkPDFFontImpl.h" | 17 #include "SkPDFFontImpl.h" |
20 #include "SkPDFStream.h" | 18 #include "SkPDFStream.h" |
21 #include "SkPDFTypes.h" | 19 #include "SkPDFTypes.h" |
22 #include "SkPDFUtils.h" | 20 #include "SkPDFUtils.h" |
23 #include "SkRefCnt.h" | 21 #include "SkRefCnt.h" |
24 #include "SkScalar.h" | 22 #include "SkScalar.h" |
25 #include "SkStream.h" | 23 #include "SkStream.h" |
26 #include "SkTypeface.h" | 24 #include "SkTypefacePriv.h" |
27 #include "SkTypes.h" | 25 #include "SkTypes.h" |
28 #include "SkUtils.h" | 26 #include "SkUtils.h" |
29 | 27 |
30 #if defined (SK_SFNTLY_SUBSETTER) | 28 #if defined (SK_SFNTLY_SUBSETTER) |
31 #include SK_SFNTLY_SUBSETTER | 29 #include SK_SFNTLY_SUBSETTER |
32 #endif | 30 #endif |
33 | 31 |
34 // PDF's notion of symbolic vs non-symbolic is related to the character set, not | 32 // PDF's notion of symbolic vs non-symbolic is related to the character set, not |
35 // symbols vs. characters. Rarely is a font the right character set to call it | 33 // symbols vs. characters. Rarely is a font the right character set to call it |
36 // non-symbolic, so always call it symbolic. (PDF 1.4 spec, section 5.7.1) | 34 // non-symbolic, so always call it symbolic. (PDF 1.4 spec, section 5.7.1) |
(...skipping 505 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
542 static void sk_delete_array(const void* ptr, size_t, void*) { | 540 static void sk_delete_array(const void* ptr, size_t, void*) { |
543 // Use C-style cast to cast away const and cast type simultaneously. | 541 // Use C-style cast to cast away const and cast type simultaneously. |
544 delete[] (unsigned char*)ptr; | 542 delete[] (unsigned char*)ptr; |
545 } | 543 } |
546 #endif | 544 #endif |
547 | 545 |
548 static int get_subset_font_stream(const char* fontName, | 546 static int get_subset_font_stream(const char* fontName, |
549 const SkTypeface* typeface, | 547 const SkTypeface* typeface, |
550 const SkTDArray<uint32_t>& subset, | 548 const SkTDArray<uint32_t>& subset, |
551 SkPDFStream** fontStream) { | 549 SkPDFStream** fontStream) { |
552 SkAutoTUnref<SkStream> fontData( | 550 int ttcIndex; |
553 SkFontHost::OpenStream(SkTypeface::UniqueID(typeface))); | 551 SkAutoTUnref<SkStream> fontData(typeface->openStream(&ttcIndex)); |
554 | 552 |
555 int fontSize = fontData->getLength(); | 553 int fontSize = fontData->getLength(); |
556 | 554 |
557 #if defined (SK_SFNTLY_SUBSETTER) | 555 #if defined (SK_SFNTLY_SUBSETTER) |
558 // Read font into buffer. | 556 // Read font into buffer. |
559 SkPDFStream* subsetFontStream = NULL; | 557 SkPDFStream* subsetFontStream = NULL; |
560 SkTDArray<unsigned char> originalFont; | 558 SkTDArray<unsigned char> originalFont; |
561 originalFont.setCount(fontSize); | 559 originalFont.setCount(fontSize); |
562 if (fontData->read(originalFont.begin(), fontSize) == (size_t)fontSize) { | 560 if (fontData->read(originalFont.begin(), fontSize) == (size_t)fontSize) { |
563 unsigned char* subsetFont = NULL; | 561 unsigned char* subsetFont = NULL; |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
707 SkAutoMutexAcquire lock(CanonicalFontsMutex()); | 705 SkAutoMutexAcquire lock(CanonicalFontsMutex()); |
708 int index = -1; | 706 int index = -1; |
709 for (int i = 0 ; i < CanonicalFonts().count() ; i++) { | 707 for (int i = 0 ; i < CanonicalFonts().count() ; i++) { |
710 if (CanonicalFonts()[i].fFont == this) { | 708 if (CanonicalFonts()[i].fFont == this) { |
711 index = i; | 709 index = i; |
712 } | 710 } |
713 } | 711 } |
714 | 712 |
715 SkDEBUGCODE(int indexFound;) | 713 SkDEBUGCODE(int indexFound;) |
716 SkASSERT(index == -1 || | 714 SkASSERT(index == -1 || |
717 (Find(SkTypeface::UniqueID(fTypeface.get()), | 715 (Find(fTypeface->uniqueID(), |
718 fFirstGlyphID, | 716 fFirstGlyphID, |
719 &indexFound) && | 717 &indexFound) && |
720 index == indexFound)); | 718 index == indexFound)); |
721 if (index >= 0) { | 719 if (index >= 0) { |
722 CanonicalFonts().removeShuffle(index); | 720 CanonicalFonts().removeShuffle(index); |
723 } | 721 } |
724 fResources.unrefAll(); | 722 fResources.unrefAll(); |
725 } | 723 } |
726 | 724 |
727 void SkPDFFont::getResources(SkTDArray<SkPDFObject*>* resourceList) { | 725 void SkPDFFont::getResources(SkTDArray<SkPDFObject*>* resourceList) { |
(...skipping 28 matching lines...) Expand all Loading... |
756 } | 754 } |
757 glyphIDs[i] -= (fFirstGlyphID - 1); | 755 glyphIDs[i] -= (fFirstGlyphID - 1); |
758 } | 756 } |
759 | 757 |
760 return numGlyphs; | 758 return numGlyphs; |
761 } | 759 } |
762 | 760 |
763 // static | 761 // static |
764 SkPDFFont* SkPDFFont::GetFontResource(SkTypeface* typeface, uint16_t glyphID) { | 762 SkPDFFont* SkPDFFont::GetFontResource(SkTypeface* typeface, uint16_t glyphID) { |
765 SkAutoMutexAcquire lock(CanonicalFontsMutex()); | 763 SkAutoMutexAcquire lock(CanonicalFontsMutex()); |
766 const uint32_t fontID = SkTypeface::UniqueID(typeface); | 764 |
| 765 SkAutoResolveDefaultTypeface autoResolve(typeface); |
| 766 typeface = autoResolve.get(); |
| 767 |
| 768 const uint32_t fontID = typeface->uniqueID(); |
767 int relatedFontIndex; | 769 int relatedFontIndex; |
768 if (Find(fontID, glyphID, &relatedFontIndex)) { | 770 if (Find(fontID, glyphID, &relatedFontIndex)) { |
769 CanonicalFonts()[relatedFontIndex].fFont->ref(); | 771 CanonicalFonts()[relatedFontIndex].fFont->ref(); |
770 return CanonicalFonts()[relatedFontIndex].fFont; | 772 return CanonicalFonts()[relatedFontIndex].fFont; |
771 } | 773 } |
772 | 774 |
773 SkAutoTUnref<SkAdvancedTypefaceMetrics> fontMetrics; | 775 SkAutoTUnref<SkAdvancedTypefaceMetrics> fontMetrics; |
774 SkPDFDict* relatedFontDescriptor = NULL; | 776 SkPDFDict* relatedFontDescriptor = NULL; |
775 if (relatedFontIndex >= 0) { | 777 if (relatedFontIndex >= 0) { |
776 SkPDFFont* relatedFont = CanonicalFonts()[relatedFontIndex].fFont; | 778 SkPDFFont* relatedFont = CanonicalFonts()[relatedFontIndex].fFont; |
(...skipping 16 matching lines...) Expand all Loading... |
793 } else { | 795 } else { |
794 SkAdvancedTypefaceMetrics::PerGlyphInfo info; | 796 SkAdvancedTypefaceMetrics::PerGlyphInfo info; |
795 info = SkAdvancedTypefaceMetrics::kGlyphNames_PerGlyphInfo; | 797 info = SkAdvancedTypefaceMetrics::kGlyphNames_PerGlyphInfo; |
796 info = SkTBitOr<SkAdvancedTypefaceMetrics::PerGlyphInfo>( | 798 info = SkTBitOr<SkAdvancedTypefaceMetrics::PerGlyphInfo>( |
797 info, SkAdvancedTypefaceMetrics::kToUnicode_PerGlyphInfo); | 799 info, SkAdvancedTypefaceMetrics::kToUnicode_PerGlyphInfo); |
798 #if !defined (SK_SFNTLY_SUBSETTER) | 800 #if !defined (SK_SFNTLY_SUBSETTER) |
799 info = SkTBitOr<SkAdvancedTypefaceMetrics::PerGlyphInfo>( | 801 info = SkTBitOr<SkAdvancedTypefaceMetrics::PerGlyphInfo>( |
800 info, SkAdvancedTypefaceMetrics::kHAdvance_PerGlyphInfo); | 802 info, SkAdvancedTypefaceMetrics::kHAdvance_PerGlyphInfo); |
801 #endif | 803 #endif |
802 fontMetrics.reset( | 804 fontMetrics.reset( |
803 SkFontHost::GetAdvancedTypefaceMetrics(fontID, info, NULL, 0)); | 805 typeface->getAdvancedTypefaceMetrics(info, NULL, 0)); |
804 #if defined (SK_SFNTLY_SUBSETTER) | 806 #if defined (SK_SFNTLY_SUBSETTER) |
805 if (fontMetrics.get() && | 807 if (fontMetrics.get() && |
806 fontMetrics->fType != SkAdvancedTypefaceMetrics::kTrueType_Font) { | 808 fontMetrics->fType != SkAdvancedTypefaceMetrics::kTrueType_Font) { |
807 // Font does not support subsetting, get new info with advance. | 809 // Font does not support subsetting, get new info with advance. |
808 info = SkTBitOr<SkAdvancedTypefaceMetrics::PerGlyphInfo>( | 810 info = SkTBitOr<SkAdvancedTypefaceMetrics::PerGlyphInfo>( |
809 info, SkAdvancedTypefaceMetrics::kHAdvance_PerGlyphInfo); | 811 info, SkAdvancedTypefaceMetrics::kHAdvance_PerGlyphInfo); |
810 fontMetrics.reset( | 812 fontMetrics.reset( |
811 SkFontHost::GetAdvancedTypefaceMetrics(fontID, info, NULL, 0)); | 813 typeface->getAdvancedTypefaceMetrics(info, NULL, 0)); |
812 } | 814 } |
813 #endif | 815 #endif |
814 } | 816 } |
815 | 817 |
816 SkPDFFont* font = Create(fontMetrics.get(), typeface, glyphID, | 818 SkPDFFont* font = Create(fontMetrics.get(), typeface, glyphID, |
817 relatedFontDescriptor); | 819 relatedFontDescriptor); |
818 FontRec newEntry(font, fontID, font->fFirstGlyphID); | 820 FontRec newEntry(font, fontID, font->fFirstGlyphID); |
819 CanonicalFonts().push(newEntry); | 821 CanonicalFonts().push(newEntry); |
820 return font; // Return the reference new SkPDFFont() created. | 822 return font; // Return the reference new SkPDFFont() created. |
821 } | 823 } |
(...skipping 26 matching lines...) Expand all Loading... |
848 return true; | 850 return true; |
849 } | 851 } |
850 search.fGlyphID = 0; | 852 search.fGlyphID = 0; |
851 *index = CanonicalFonts().find(search); | 853 *index = CanonicalFonts().find(search); |
852 return false; | 854 return false; |
853 } | 855 } |
854 | 856 |
855 SkPDFFont::SkPDFFont(SkAdvancedTypefaceMetrics* info, SkTypeface* typeface, | 857 SkPDFFont::SkPDFFont(SkAdvancedTypefaceMetrics* info, SkTypeface* typeface, |
856 SkPDFDict* relatedFontDescriptor) | 858 SkPDFDict* relatedFontDescriptor) |
857 : SkPDFDict("Font"), | 859 : SkPDFDict("Font"), |
858 fTypeface(typeface), | 860 fTypeface(ref_or_default(typeface)), |
859 fFirstGlyphID(1), | 861 fFirstGlyphID(1), |
860 fLastGlyphID(info ? info->fLastGlyphID : 0), | 862 fLastGlyphID(info ? info->fLastGlyphID : 0), |
861 fFontInfo(info), | 863 fFontInfo(info), |
862 fDescriptor(relatedFontDescriptor) { | 864 fDescriptor(relatedFontDescriptor) { |
863 SkSafeRef(typeface); | 865 SkSafeRef(typeface); |
864 SkSafeRef(info); | 866 SkSafeRef(info); |
865 if (info == NULL) { | 867 if (info == NULL) { |
866 fFontType = SkAdvancedTypefaceMetrics::kNotEmbeddable_Font; | 868 fFontType = SkAdvancedTypefaceMetrics::kNotEmbeddable_Font; |
867 } else if (info->fMultiMaster) { | 869 } else if (info->fMultiMaster) { |
868 fFontType = SkAdvancedTypefaceMetrics::kOther_Font; | 870 fFontType = SkAdvancedTypefaceMetrics::kOther_Font; |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1092 SkAutoTUnref<SkPDFStream> fontStream(rawStream); | 1094 SkAutoTUnref<SkPDFStream> fontStream(rawStream); |
1093 addResource(fontStream.get()); | 1095 addResource(fontStream.get()); |
1094 | 1096 |
1095 fontStream->insertInt("Length1", fontSize); | 1097 fontStream->insertInt("Length1", fontSize); |
1096 descriptor->insert("FontFile2", | 1098 descriptor->insert("FontFile2", |
1097 new SkPDFObjRef(fontStream.get()))->unref(); | 1099 new SkPDFObjRef(fontStream.get()))->unref(); |
1098 break; | 1100 break; |
1099 } | 1101 } |
1100 case SkAdvancedTypefaceMetrics::kCFF_Font: | 1102 case SkAdvancedTypefaceMetrics::kCFF_Font: |
1101 case SkAdvancedTypefaceMetrics::kType1CID_Font: { | 1103 case SkAdvancedTypefaceMetrics::kType1CID_Font: { |
1102 SkAutoTUnref<SkStream> fontData( | 1104 int ttcIndex; |
1103 SkFontHost::OpenStream(SkTypeface::UniqueID(typeface()))); | 1105 SkAutoTUnref<SkStream> fontData(typeface()->openStream(&ttcIndex)); |
1104 SkAutoTUnref<SkPDFStream> fontStream( | 1106 SkAutoTUnref<SkPDFStream> fontStream( |
1105 new SkPDFStream(fontData.get())); | 1107 new SkPDFStream(fontData.get())); |
1106 addResource(fontStream.get()); | 1108 addResource(fontStream.get()); |
1107 | 1109 |
1108 if (getType() == SkAdvancedTypefaceMetrics::kCFF_Font) { | 1110 if (getType() == SkAdvancedTypefaceMetrics::kCFF_Font) { |
1109 fontStream->insertName("Subtype", "Type1C"); | 1111 fontStream->insertName("Subtype", "Type1C"); |
1110 } else { | 1112 } else { |
1111 fontStream->insertName("Subtype", "CIDFontType0c"); | 1113 fontStream->insertName("Subtype", "CIDFontType0c"); |
1112 } | 1114 } |
1113 descriptor->insert("FontFile3", | 1115 descriptor->insert("FontFile3", |
(...skipping 18 matching lines...) Expand all Loading... |
1132 subset->exportTo(&glyphIDs); | 1134 subset->exportTo(&glyphIDs); |
1133 } | 1135 } |
1134 | 1136 |
1135 SkAdvancedTypefaceMetrics::PerGlyphInfo info; | 1137 SkAdvancedTypefaceMetrics::PerGlyphInfo info; |
1136 info = SkAdvancedTypefaceMetrics::kGlyphNames_PerGlyphInfo; | 1138 info = SkAdvancedTypefaceMetrics::kGlyphNames_PerGlyphInfo; |
1137 info = SkTBitOr<SkAdvancedTypefaceMetrics::PerGlyphInfo>( | 1139 info = SkTBitOr<SkAdvancedTypefaceMetrics::PerGlyphInfo>( |
1138 info, SkAdvancedTypefaceMetrics::kHAdvance_PerGlyphInfo); | 1140 info, SkAdvancedTypefaceMetrics::kHAdvance_PerGlyphInfo); |
1139 uint32_t* glyphs = (glyphIDs.count() == 1) ? NULL : glyphIDs.begin(); | 1141 uint32_t* glyphs = (glyphIDs.count() == 1) ? NULL : glyphIDs.begin(); |
1140 uint32_t glyphsCount = glyphs ? glyphIDs.count() : 0; | 1142 uint32_t glyphsCount = glyphs ? glyphIDs.count() : 0; |
1141 SkAutoTUnref<SkAdvancedTypefaceMetrics> fontMetrics( | 1143 SkAutoTUnref<SkAdvancedTypefaceMetrics> fontMetrics( |
1142 SkFontHost::GetAdvancedTypefaceMetrics( | 1144 typeface()->getAdvancedTypefaceMetrics(info, glyphs, glyphsCount)); |
1143 SkTypeface::UniqueID(typeface()), | |
1144 info, | |
1145 glyphs, | |
1146 glyphsCount)); | |
1147 setFontInfo(fontMetrics.get()); | 1145 setFontInfo(fontMetrics.get()); |
1148 addFontDescriptor(0, &glyphIDs); | 1146 addFontDescriptor(0, &glyphIDs); |
1149 } else { | 1147 } else { |
1150 // Other CID fonts | 1148 // Other CID fonts |
1151 addFontDescriptor(0, NULL); | 1149 addFontDescriptor(0, NULL); |
1152 } | 1150 } |
1153 | 1151 |
1154 insertName("BaseFont", fontInfo()->fFontName); | 1152 insertName("BaseFont", fontInfo()->fFontName); |
1155 | 1153 |
1156 if (getType() == SkAdvancedTypefaceMetrics::kType1CID_Font) { | 1154 if (getType() == SkAdvancedTypefaceMetrics::kType1CID_Font) { |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1222 if (getFontDescriptor() != NULL) { | 1220 if (getFontDescriptor() != NULL) { |
1223 SkPDFDict* descriptor = getFontDescriptor(); | 1221 SkPDFDict* descriptor = getFontDescriptor(); |
1224 addResource(descriptor); | 1222 addResource(descriptor); |
1225 insert("FontDescriptor", new SkPDFObjRef(descriptor))->unref(); | 1223 insert("FontDescriptor", new SkPDFObjRef(descriptor))->unref(); |
1226 return true; | 1224 return true; |
1227 } | 1225 } |
1228 | 1226 |
1229 SkAutoTUnref<SkPDFDict> descriptor(new SkPDFDict("FontDescriptor")); | 1227 SkAutoTUnref<SkPDFDict> descriptor(new SkPDFDict("FontDescriptor")); |
1230 setFontDescriptor(descriptor.get()); | 1228 setFontDescriptor(descriptor.get()); |
1231 | 1229 |
| 1230 int ttcIndex; |
1232 size_t header SK_INIT_TO_AVOID_WARNING; | 1231 size_t header SK_INIT_TO_AVOID_WARNING; |
1233 size_t data SK_INIT_TO_AVOID_WARNING; | 1232 size_t data SK_INIT_TO_AVOID_WARNING; |
1234 size_t trailer SK_INIT_TO_AVOID_WARNING; | 1233 size_t trailer SK_INIT_TO_AVOID_WARNING; |
1235 SkAutoTUnref<SkStream> rawFontData( | 1234 SkAutoTUnref<SkStream> rawFontData(typeface()->openStream(&ttcIndex)); |
1236 SkFontHost::OpenStream(SkTypeface::UniqueID(typeface()))); | |
1237 SkStream* fontData = handleType1Stream(rawFontData.get(), &header, &data, | 1235 SkStream* fontData = handleType1Stream(rawFontData.get(), &header, &data, |
1238 &trailer); | 1236 &trailer); |
1239 if (fontData == NULL) { | 1237 if (fontData == NULL) { |
1240 return false; | 1238 return false; |
1241 } | 1239 } |
1242 SkAutoTUnref<SkPDFStream> fontStream(new SkPDFStream(fontData)); | 1240 SkAutoTUnref<SkPDFStream> fontStream(new SkPDFStream(fontData)); |
1243 addResource(fontStream.get()); | 1241 addResource(fontStream.get()); |
1244 fontStream->insertInt("Length1", header); | 1242 fontStream->insertInt("Length1", header); |
1245 fontStream->insertInt("Length2", data); | 1243 fontStream->insertInt("Length2", data); |
1246 fontStream->insertInt("Length3", trailer); | 1244 fontStream->insertInt("Length3", trailer); |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1409 | 1407 |
1410 insert("FontBBox", makeFontBBox(bbox, 1000))->unref(); | 1408 insert("FontBBox", makeFontBBox(bbox, 1000))->unref(); |
1411 insertInt("FirstChar", firstGlyphID()); | 1409 insertInt("FirstChar", firstGlyphID()); |
1412 insertInt("LastChar", lastGlyphID()); | 1410 insertInt("LastChar", lastGlyphID()); |
1413 insert("Widths", widthArray.get()); | 1411 insert("Widths", widthArray.get()); |
1414 insertName("CIDToGIDMap", "Identity"); | 1412 insertName("CIDToGIDMap", "Identity"); |
1415 | 1413 |
1416 populateToUnicodeTable(NULL); | 1414 populateToUnicodeTable(NULL); |
1417 return true; | 1415 return true; |
1418 } | 1416 } |
OLD | NEW |