| 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 |