| 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" |
| (...skipping 728 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 739 * 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 |
| 740 * 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 |
| 741 * 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. |
| 742 */ | 742 */ |
| 743 | 743 |
| 744 SkPDFFont::~SkPDFFont() { | 744 SkPDFFont::~SkPDFFont() { |
| 745 { | 745 { |
| 746 SkAutoMutexAcquire lock(SkPDFCanon::GetFontMutex()); | 746 SkAutoMutexAcquire lock(SkPDFCanon::GetFontMutex()); |
| 747 SkPDFCanon::GetCanon().removeFont(this); | 747 SkPDFCanon::GetCanon().removeFont(this); |
| 748 } | 748 } |
| 749 fResources.unrefAll(); | |
| 750 } | |
| 751 | |
| 752 void SkPDFFont::getResources(const SkTSet<SkPDFObject*>& knownResourceObjects, | |
| 753 SkTSet<SkPDFObject*>* newResourceObjects) { | |
| 754 GetResourcesHelper(&fResources, knownResourceObjects, newResourceObjects); | |
| 755 } | 749 } |
| 756 | 750 |
| 757 SkTypeface* SkPDFFont::typeface() { | 751 SkTypeface* SkPDFFont::typeface() { |
| 758 return fTypeface.get(); | 752 return fTypeface.get(); |
| 759 } | 753 } |
| 760 | 754 |
| 761 SkAdvancedTypefaceMetrics::FontType SkPDFFont::getType() { | 755 SkAdvancedTypefaceMetrics::FontType SkPDFFont::getType() { |
| 762 return fFontType; | 756 return fFontType; |
| 763 } | 757 } |
| 764 | 758 |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 933 } | 927 } |
| 934 | 928 |
| 935 uint16_t SkPDFFont::lastGlyphID() const { | 929 uint16_t SkPDFFont::lastGlyphID() const { |
| 936 return fLastGlyphID; | 930 return fLastGlyphID; |
| 937 } | 931 } |
| 938 | 932 |
| 939 void SkPDFFont::setLastGlyphID(uint16_t glyphID) { | 933 void SkPDFFont::setLastGlyphID(uint16_t glyphID) { |
| 940 fLastGlyphID = glyphID; | 934 fLastGlyphID = glyphID; |
| 941 } | 935 } |
| 942 | 936 |
| 943 void SkPDFFont::addResource(SkPDFObject* object) { | |
| 944 SkASSERT(object != NULL); | |
| 945 fResources.push(object); | |
| 946 object->ref(); | |
| 947 } | |
| 948 | |
| 949 SkPDFDict* SkPDFFont::getFontDescriptor() { | 937 SkPDFDict* SkPDFFont::getFontDescriptor() { |
| 950 return fDescriptor.get(); | 938 return fDescriptor.get(); |
| 951 } | 939 } |
| 952 | 940 |
| 953 void SkPDFFont::setFontDescriptor(SkPDFDict* descriptor) { | 941 void SkPDFFont::setFontDescriptor(SkPDFDict* descriptor) { |
| 954 fDescriptor.reset(descriptor); | 942 fDescriptor.reset(descriptor); |
| 955 SkSafeRef(descriptor); | 943 SkSafeRef(descriptor); |
| 956 } | 944 } |
| 957 | 945 |
| 958 bool SkPDFFont::addCommonFontDescriptorEntries(int16_t defaultWidth) { | 946 bool SkPDFFont::addCommonFontDescriptorEntries(int16_t defaultWidth) { |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 993 } | 981 } |
| 994 | 982 |
| 995 void SkPDFFont::populateToUnicodeTable(const SkPDFGlyphSet* subset) { | 983 void SkPDFFont::populateToUnicodeTable(const SkPDFGlyphSet* subset) { |
| 996 if (fFontInfo == NULL || fFontInfo->fGlyphToUnicode.begin() == NULL) { | 984 if (fFontInfo == NULL || fFontInfo->fGlyphToUnicode.begin() == NULL) { |
| 997 return; | 985 return; |
| 998 } | 986 } |
| 999 SkAutoTUnref<SkPDFStream> pdfCmap( | 987 SkAutoTUnref<SkPDFStream> pdfCmap( |
| 1000 generate_tounicode_cmap(fFontInfo->fGlyphToUnicode, subset, | 988 generate_tounicode_cmap(fFontInfo->fGlyphToUnicode, subset, |
| 1001 multiByteGlyphs(), firstGlyphID(), | 989 multiByteGlyphs(), firstGlyphID(), |
| 1002 lastGlyphID())); | 990 lastGlyphID())); |
| 1003 addResource(pdfCmap.get()); | |
| 1004 insert("ToUnicode", new SkPDFObjRef(pdfCmap.get()))->unref(); | 991 insert("ToUnicode", new SkPDFObjRef(pdfCmap.get()))->unref(); |
| 1005 } | 992 } |
| 1006 | 993 |
| 1007 /////////////////////////////////////////////////////////////////////////////// | 994 /////////////////////////////////////////////////////////////////////////////// |
| 1008 // class SkPDFType0Font | 995 // class SkPDFType0Font |
| 1009 /////////////////////////////////////////////////////////////////////////////// | 996 /////////////////////////////////////////////////////////////////////////////// |
| 1010 | 997 |
| 1011 SkPDFType0Font::SkPDFType0Font(const SkAdvancedTypefaceMetrics* info, | 998 SkPDFType0Font::SkPDFType0Font(const SkAdvancedTypefaceMetrics* info, |
| 1012 SkTypeface* typeface) | 999 SkTypeface* typeface) |
| 1013 : SkPDFFont(info, typeface, NULL) { | 1000 : SkPDFFont(info, typeface, NULL) { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1035 } | 1022 } |
| 1036 #endif | 1023 #endif |
| 1037 | 1024 |
| 1038 bool SkPDFType0Font::populate(const SkPDFGlyphSet* subset) { | 1025 bool SkPDFType0Font::populate(const SkPDFGlyphSet* subset) { |
| 1039 insertName("Subtype", "Type0"); | 1026 insertName("Subtype", "Type0"); |
| 1040 insertName("BaseFont", fontInfo()->fFontName); | 1027 insertName("BaseFont", fontInfo()->fFontName); |
| 1041 insertName("Encoding", "Identity-H"); | 1028 insertName("Encoding", "Identity-H"); |
| 1042 | 1029 |
| 1043 SkAutoTUnref<SkPDFCIDFont> newCIDFont( | 1030 SkAutoTUnref<SkPDFCIDFont> newCIDFont( |
| 1044 new SkPDFCIDFont(fontInfo(), typeface(), subset)); | 1031 new SkPDFCIDFont(fontInfo(), typeface(), subset)); |
| 1045 addResource(newCIDFont.get()); | |
| 1046 SkAutoTUnref<SkPDFArray> descendantFonts(new SkPDFArray()); | 1032 SkAutoTUnref<SkPDFArray> descendantFonts(new SkPDFArray()); |
| 1047 descendantFonts->append(new SkPDFObjRef(newCIDFont.get()))->unref(); | 1033 descendantFonts->append(new SkPDFObjRef(newCIDFont.get()))->unref(); |
| 1048 insert("DescendantFonts", descendantFonts.get()); | 1034 insert("DescendantFonts", descendantFonts.get()); |
| 1049 | 1035 |
| 1050 populateToUnicodeTable(subset); | 1036 populateToUnicodeTable(subset); |
| 1051 | 1037 |
| 1052 SkDEBUGCODE(fPopulated = true); | 1038 SkDEBUGCODE(fPopulated = true); |
| 1053 return true; | 1039 return true; |
| 1054 } | 1040 } |
| 1055 | 1041 |
| 1056 /////////////////////////////////////////////////////////////////////////////// | 1042 /////////////////////////////////////////////////////////////////////////////// |
| 1057 // class SkPDFCIDFont | 1043 // class SkPDFCIDFont |
| 1058 /////////////////////////////////////////////////////////////////////////////// | 1044 /////////////////////////////////////////////////////////////////////////////// |
| 1059 | 1045 |
| 1060 SkPDFCIDFont::SkPDFCIDFont(const SkAdvancedTypefaceMetrics* info, | 1046 SkPDFCIDFont::SkPDFCIDFont(const SkAdvancedTypefaceMetrics* info, |
| 1061 SkTypeface* typeface, const SkPDFGlyphSet* subset) | 1047 SkTypeface* typeface, const SkPDFGlyphSet* subset) |
| 1062 : SkPDFFont(info, typeface, NULL) { | 1048 : SkPDFFont(info, typeface, NULL) { |
| 1063 populate(subset); | 1049 populate(subset); |
| 1064 } | 1050 } |
| 1065 | 1051 |
| 1066 SkPDFCIDFont::~SkPDFCIDFont() {} | 1052 SkPDFCIDFont::~SkPDFCIDFont() {} |
| 1067 | 1053 |
| 1068 bool SkPDFCIDFont::addFontDescriptor(int16_t defaultWidth, | 1054 bool SkPDFCIDFont::addFontDescriptor(int16_t defaultWidth, |
| 1069 const SkTDArray<uint32_t>* subset) { | 1055 const SkTDArray<uint32_t>* subset) { |
| 1070 SkAutoTUnref<SkPDFDict> descriptor(new SkPDFDict("FontDescriptor")); | 1056 SkAutoTUnref<SkPDFDict> descriptor(new SkPDFDict("FontDescriptor")); |
| 1071 setFontDescriptor(descriptor.get()); | 1057 setFontDescriptor(descriptor.get()); |
| 1072 addResource(descriptor.get()); | |
| 1073 insert("FontDescriptor", new SkPDFObjRef(descriptor.get()))->unref(); | 1058 insert("FontDescriptor", new SkPDFObjRef(descriptor.get()))->unref(); |
| 1074 if (!addCommonFontDescriptorEntries(defaultWidth)) { | 1059 if (!addCommonFontDescriptorEntries(defaultWidth)) { |
| 1075 return false; | 1060 return false; |
| 1076 } | 1061 } |
| 1077 if (!canEmbed()) { | 1062 if (!canEmbed()) { |
| 1078 return true; | 1063 return true; |
| 1079 } | 1064 } |
| 1080 | 1065 |
| 1081 switch (getType()) { | 1066 switch (getType()) { |
| 1082 case SkAdvancedTypefaceMetrics::kTrueType_Font: { | 1067 case SkAdvancedTypefaceMetrics::kTrueType_Font: { |
| 1083 SkAutoTUnref<SkPDFStream> fontStream; | 1068 SkAutoTUnref<SkPDFStream> fontStream; |
| 1084 size_t fontSize = 0; | 1069 size_t fontSize = 0; |
| 1085 if (canSubset()) { | 1070 if (canSubset()) { |
| 1086 SkPDFStream* rawStream = NULL; | 1071 SkPDFStream* rawStream = NULL; |
| 1087 fontSize = get_subset_font_stream(fontInfo()->fFontName.c_str(), | 1072 fontSize = get_subset_font_stream(fontInfo()->fFontName.c_str(), |
| 1088 typeface(), | 1073 typeface(), |
| 1089 *subset, | 1074 *subset, |
| 1090 &rawStream); | 1075 &rawStream); |
| 1091 fontStream.reset(rawStream); | 1076 fontStream.reset(rawStream); |
| 1092 } else { | 1077 } else { |
| 1093 int ttcIndex; | 1078 int ttcIndex; |
| 1094 SkAutoTDelete<SkStream> fontData( | 1079 SkAutoTDelete<SkStream> fontData( |
| 1095 typeface()->openStream(&ttcIndex)); | 1080 typeface()->openStream(&ttcIndex)); |
| 1096 fontStream.reset(new SkPDFStream(fontData.get())); | 1081 fontStream.reset(new SkPDFStream(fontData.get())); |
| 1097 fontSize = fontData->getLength(); | 1082 fontSize = fontData->getLength(); |
| 1098 } | 1083 } |
| 1099 SkASSERT(fontSize); | 1084 SkASSERT(fontSize); |
| 1100 SkASSERT(fontStream.get()); | 1085 SkASSERT(fontStream.get()); |
| 1101 addResource(fontStream.get()); | |
| 1102 | 1086 |
| 1103 fontStream->insertInt("Length1", fontSize); | 1087 fontStream->insertInt("Length1", fontSize); |
| 1104 descriptor->insert("FontFile2", | 1088 descriptor->insert("FontFile2", |
| 1105 new SkPDFObjRef(fontStream.get()))->unref(); | 1089 new SkPDFObjRef(fontStream.get()))->unref(); |
| 1106 break; | 1090 break; |
| 1107 } | 1091 } |
| 1108 case SkAdvancedTypefaceMetrics::kCFF_Font: | 1092 case SkAdvancedTypefaceMetrics::kCFF_Font: |
| 1109 case SkAdvancedTypefaceMetrics::kType1CID_Font: { | 1093 case SkAdvancedTypefaceMetrics::kType1CID_Font: { |
| 1110 int ttcIndex; | 1094 int ttcIndex; |
| 1111 SkAutoTDelete<SkStream> fontData(typeface()->openStream(&ttcIndex)); | 1095 SkAutoTDelete<SkStream> fontData(typeface()->openStream(&ttcIndex)); |
| 1112 SkAutoTUnref<SkPDFStream> fontStream( | 1096 SkAutoTUnref<SkPDFStream> fontStream( |
| 1113 new SkPDFStream(fontData.get())); | 1097 new SkPDFStream(fontData.get())); |
| 1114 addResource(fontStream.get()); | |
| 1115 | 1098 |
| 1116 if (getType() == SkAdvancedTypefaceMetrics::kCFF_Font) { | 1099 if (getType() == SkAdvancedTypefaceMetrics::kCFF_Font) { |
| 1117 fontStream->insertName("Subtype", "Type1C"); | 1100 fontStream->insertName("Subtype", "Type1C"); |
| 1118 } else { | 1101 } else { |
| 1119 fontStream->insertName("Subtype", "CIDFontType0c"); | 1102 fontStream->insertName("Subtype", "CIDFontType0c"); |
| 1120 } | 1103 } |
| 1121 descriptor->insert("FontFile3", | 1104 descriptor->insert("FontFile3", |
| 1122 new SkPDFObjRef(fontStream.get()))->unref(); | 1105 new SkPDFObjRef(fontStream.get()))->unref(); |
| 1123 break; | 1106 break; |
| 1124 } | 1107 } |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1219 SkPDFDict* relatedFontDescriptor) | 1202 SkPDFDict* relatedFontDescriptor) |
| 1220 : SkPDFFont(info, typeface, relatedFontDescriptor) { | 1203 : SkPDFFont(info, typeface, relatedFontDescriptor) { |
| 1221 populate(glyphID); | 1204 populate(glyphID); |
| 1222 } | 1205 } |
| 1223 | 1206 |
| 1224 SkPDFType1Font::~SkPDFType1Font() {} | 1207 SkPDFType1Font::~SkPDFType1Font() {} |
| 1225 | 1208 |
| 1226 bool SkPDFType1Font::addFontDescriptor(int16_t defaultWidth) { | 1209 bool SkPDFType1Font::addFontDescriptor(int16_t defaultWidth) { |
| 1227 if (getFontDescriptor() != NULL) { | 1210 if (getFontDescriptor() != NULL) { |
| 1228 SkPDFDict* descriptor = getFontDescriptor(); | 1211 SkPDFDict* descriptor = getFontDescriptor(); |
| 1229 addResource(descriptor); | |
| 1230 insert("FontDescriptor", new SkPDFObjRef(descriptor))->unref(); | 1212 insert("FontDescriptor", new SkPDFObjRef(descriptor))->unref(); |
| 1231 return true; | 1213 return true; |
| 1232 } | 1214 } |
| 1233 | 1215 |
| 1234 SkAutoTUnref<SkPDFDict> descriptor(new SkPDFDict("FontDescriptor")); | 1216 SkAutoTUnref<SkPDFDict> descriptor(new SkPDFDict("FontDescriptor")); |
| 1235 setFontDescriptor(descriptor.get()); | 1217 setFontDescriptor(descriptor.get()); |
| 1236 | 1218 |
| 1237 int ttcIndex; | 1219 int ttcIndex; |
| 1238 size_t header SK_INIT_TO_AVOID_WARNING; | 1220 size_t header SK_INIT_TO_AVOID_WARNING; |
| 1239 size_t data SK_INIT_TO_AVOID_WARNING; | 1221 size_t data SK_INIT_TO_AVOID_WARNING; |
| 1240 size_t trailer SK_INIT_TO_AVOID_WARNING; | 1222 size_t trailer SK_INIT_TO_AVOID_WARNING; |
| 1241 SkAutoTDelete<SkStream> rawFontData(typeface()->openStream(&ttcIndex)); | 1223 SkAutoTDelete<SkStream> rawFontData(typeface()->openStream(&ttcIndex)); |
| 1242 SkAutoTUnref<SkData> fontData(handle_type1_stream(rawFontData.get(), &header
, | 1224 SkAutoTUnref<SkData> fontData(handle_type1_stream(rawFontData.get(), &header
, |
| 1243 &data, &trailer)); | 1225 &data, &trailer)); |
| 1244 if (fontData.get() == NULL) { | 1226 if (fontData.get() == NULL) { |
| 1245 return false; | 1227 return false; |
| 1246 } | 1228 } |
| 1247 if (canEmbed()) { | 1229 if (canEmbed()) { |
| 1248 SkAutoTUnref<SkPDFStream> fontStream(new SkPDFStream(fontData.get())); | 1230 SkAutoTUnref<SkPDFStream> fontStream(new SkPDFStream(fontData.get())); |
| 1249 addResource(fontStream.get()); | |
| 1250 fontStream->insertInt("Length1", header); | 1231 fontStream->insertInt("Length1", header); |
| 1251 fontStream->insertInt("Length2", data); | 1232 fontStream->insertInt("Length2", data); |
| 1252 fontStream->insertInt("Length3", trailer); | 1233 fontStream->insertInt("Length3", trailer); |
| 1253 descriptor->insert("FontFile", | 1234 descriptor->insert("FontFile", |
| 1254 new SkPDFObjRef(fontStream.get()))->unref(); | 1235 new SkPDFObjRef(fontStream.get()))->unref(); |
| 1255 } | 1236 } |
| 1256 | 1237 |
| 1257 addResource(descriptor.get()); | |
| 1258 insert("FontDescriptor", new SkPDFObjRef(descriptor.get()))->unref(); | 1238 insert("FontDescriptor", new SkPDFObjRef(descriptor.get()))->unref(); |
| 1259 | 1239 |
| 1260 return addCommonFontDescriptorEntries(defaultWidth); | 1240 return addCommonFontDescriptorEntries(defaultWidth); |
| 1261 } | 1241 } |
| 1262 | 1242 |
| 1263 bool SkPDFType1Font::populate(int16_t glyphID) { | 1243 bool SkPDFType1Font::populate(int16_t glyphID) { |
| 1264 SkASSERT(!fontInfo()->fVerticalMetrics.get()); | 1244 SkASSERT(!fontInfo()->fVerticalMetrics.get()); |
| 1265 SkASSERT(fontInfo()->fGlyphWidths.get()); | 1245 SkASSERT(fontInfo()->fGlyphWidths.get()); |
| 1266 | 1246 |
| 1267 adjustGlyphRangeForSingleByteEncoding(glyphID); | 1247 adjustGlyphRangeForSingleByteEncoding(glyphID); |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1403 if (path) { | 1383 if (path) { |
| 1404 SkPDFUtils::EmitPath(*path, paint.getStyle(), &content); | 1384 SkPDFUtils::EmitPath(*path, paint.getStyle(), &content); |
| 1405 SkPDFUtils::PaintPath(paint.getStyle(), path->getFillType(), | 1385 SkPDFUtils::PaintPath(paint.getStyle(), path->getFillType(), |
| 1406 &content); | 1386 &content); |
| 1407 } | 1387 } |
| 1408 SkAutoTDelete<SkMemoryStream> glyphStream(new SkMemoryStream()); | 1388 SkAutoTDelete<SkMemoryStream> glyphStream(new SkMemoryStream()); |
| 1409 glyphStream->setData(content.copyToData())->unref(); | 1389 glyphStream->setData(content.copyToData())->unref(); |
| 1410 | 1390 |
| 1411 SkAutoTUnref<SkPDFStream> glyphDescription( | 1391 SkAutoTUnref<SkPDFStream> glyphDescription( |
| 1412 new SkPDFStream(glyphStream.get())); | 1392 new SkPDFStream(glyphStream.get())); |
| 1413 addResource(glyphDescription.get()); | |
| 1414 charProcs->insert(characterName.c_str(), | 1393 charProcs->insert(characterName.c_str(), |
| 1415 new SkPDFObjRef(glyphDescription.get()))->unref(); | 1394 new SkPDFObjRef(glyphDescription.get()))->unref(); |
| 1416 } | 1395 } |
| 1417 | 1396 |
| 1418 insert("FontBBox", makeFontBBox(bbox, 1000))->unref(); | 1397 insert("FontBBox", makeFontBBox(bbox, 1000))->unref(); |
| 1419 insertInt("FirstChar", 1); | 1398 insertInt("FirstChar", 1); |
| 1420 insertInt("LastChar", lastGlyphID() - firstGlyphID() + 1); | 1399 insertInt("LastChar", lastGlyphID() - firstGlyphID() + 1); |
| 1421 insert("Widths", widthArray.get()); | 1400 insert("Widths", widthArray.get()); |
| 1422 insertName("CIDToGIDMap", "Identity"); | 1401 insertName("CIDToGIDMap", "Identity"); |
| 1423 | 1402 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1438 } | 1417 } |
| 1439 if (existingFont != NULL) { | 1418 if (existingFont != NULL) { |
| 1440 return (existingFont->fFirstGlyphID <= searchGlyphID && | 1419 return (existingFont->fFirstGlyphID <= searchGlyphID && |
| 1441 searchGlyphID <= existingFont->fLastGlyphID) | 1420 searchGlyphID <= existingFont->fLastGlyphID) |
| 1442 ? SkPDFFont::kExact_Match | 1421 ? SkPDFFont::kExact_Match |
| 1443 : SkPDFFont::kRelated_Match; | 1422 : SkPDFFont::kRelated_Match; |
| 1444 } | 1423 } |
| 1445 return (existingGlyphID == searchGlyphID) ? SkPDFFont::kExact_Match | 1424 return (existingGlyphID == searchGlyphID) ? SkPDFFont::kExact_Match |
| 1446 : SkPDFFont::kRelated_Match; | 1425 : SkPDFFont::kRelated_Match; |
| 1447 } | 1426 } |
| OLD | NEW |