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 "SkPDFDevice.h" | 8 #include "SkPDFDevice.h" |
9 #include "SkAnnotationKeys.h" | 9 #include "SkAnnotationKeys.h" |
10 #include "SkBitmapDevice.h" | 10 #include "SkBitmapDevice.h" |
(...skipping 1188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1199 content.entry()->fContent.writeText("BT\n"); | 1199 content.entry()->fContent.writeText("BT\n"); |
1200 set_text_transform(x, y, textPaint.getTextSkewX(), | 1200 set_text_transform(x, y, textPaint.getTextSkewX(), |
1201 &content.entry()->fContent); | 1201 &content.entry()->fContent); |
1202 int consumedGlyphCount = 0; | 1202 int consumedGlyphCount = 0; |
1203 | 1203 |
1204 SkTDArray<uint16_t> glyphIDsCopy(glyphIDs, numGlyphs); | 1204 SkTDArray<uint16_t> glyphIDsCopy(glyphIDs, numGlyphs); |
1205 | 1205 |
1206 SkPDFGlyphSetMap* fontGlyphUsage = fDocument->getGlyphUsage(); | 1206 SkPDFGlyphSetMap* fontGlyphUsage = fDocument->getGlyphUsage(); |
1207 | 1207 |
1208 while (numGlyphs > consumedGlyphCount) { | 1208 while (numGlyphs > consumedGlyphCount) { |
1209 this->updateFont(textPaint, glyphIDs[consumedGlyphCount], content.entry(
)); | 1209 if (!this->updateFont(textPaint, glyphIDs[consumedGlyphCount], content.e
ntry())) { |
| 1210 SkDebugf("SkPDF: Font error."); |
| 1211 content.entry()->fContent.writeText("ET\n%SkPDF: Font error.\n"); |
| 1212 return; |
| 1213 } |
1210 SkPDFFont* font = content.entry()->fState.fFont; | 1214 SkPDFFont* font = content.entry()->fState.fFont; |
1211 | 1215 |
1212 int availableGlyphs = font->glyphsToPDFFontEncoding( | 1216 int availableGlyphs = font->glyphsToPDFFontEncoding( |
1213 glyphIDsCopy.begin() + consumedGlyphCount, | 1217 glyphIDsCopy.begin() + consumedGlyphCount, |
1214 numGlyphs - consumedGlyphCount); | 1218 numGlyphs - consumedGlyphCount); |
1215 fontGlyphUsage->noteGlyphUsage( | 1219 fontGlyphUsage->noteGlyphUsage( |
1216 font, glyphIDsCopy.begin() + consumedGlyphCount, | 1220 font, glyphIDsCopy.begin() + consumedGlyphCount, |
1217 availableGlyphs); | 1221 availableGlyphs); |
1218 write_wide_string(&content.entry()->fContent, | 1222 write_wide_string(&content.entry()->fContent, |
1219 glyphIDsCopy.begin() + consumedGlyphCount, | 1223 glyphIDsCopy.begin() + consumedGlyphCount, |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1266 return; | 1270 return; |
1267 } | 1271 } |
1268 | 1272 |
1269 SkGlyphStorage storage(0); | 1273 SkGlyphStorage storage(0); |
1270 const uint16_t* glyphIDs = nullptr; | 1274 const uint16_t* glyphIDs = nullptr; |
1271 size_t numGlyphs = force_glyph_encoding(paint, text, len, &storage, &glyphID
s); | 1275 size_t numGlyphs = force_glyph_encoding(paint, text, len, &storage, &glyphID
s); |
1272 textPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); | 1276 textPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); |
1273 SkAutoGlyphCache autoGlyphCache(textPaint, nullptr, nullptr); | 1277 SkAutoGlyphCache autoGlyphCache(textPaint, nullptr, nullptr); |
1274 | 1278 |
1275 content.entry()->fContent.writeText("BT\n"); | 1279 content.entry()->fContent.writeText("BT\n"); |
1276 this->updateFont(textPaint, glyphIDs[0], content.entry()); | 1280 if (!this->updateFont(textPaint, glyphIDs[0], content.entry())) { |
| 1281 SkDebugf("SkPDF: Font error."); |
| 1282 content.entry()->fContent.writeText("ET\n%SkPDF: Font error.\n"); |
| 1283 return; |
| 1284 } |
1277 GlyphPositioner glyphPositioner(&content.entry()->fContent, | 1285 GlyphPositioner glyphPositioner(&content.entry()->fContent, |
1278 textPaint.getTextSkewX(), | 1286 textPaint.getTextSkewX(), |
1279 content.entry()->fState.fFont->multiByteGlyp
hs()); | 1287 content.entry()->fState.fFont->multiByteGlyp
hs()); |
1280 SkPDFGlyphSetMap* fontGlyphUsage = fDocument->getGlyphUsage(); | 1288 SkPDFGlyphSetMap* fontGlyphUsage = fDocument->getGlyphUsage(); |
1281 for (size_t i = 0; i < numGlyphs; i++) { | 1289 for (size_t i = 0; i < numGlyphs; i++) { |
1282 SkPDFFont* font = content.entry()->fState.fFont; | 1290 SkPDFFont* font = content.entry()->fState.fFont; |
1283 uint16_t encodedValue = glyphIDs[i]; | 1291 uint16_t encodedValue = glyphIDs[i]; |
1284 SkScalar advanceWidth = autoGlyphCache->getGlyphIDAdvance(encodedValue).
fAdvanceX; | 1292 SkScalar advanceWidth = autoGlyphCache->getGlyphIDAdvance(encodedValue).
fAdvanceX; |
1285 if (font->glyphsToPDFFontEncoding(&encodedValue, 1) != 1) { | 1293 if (font->glyphsToPDFFontEncoding(&encodedValue, 1) != 1) { |
1286 // The current pdf font cannot encode the current glyph. | 1294 // The current pdf font cannot encode the current glyph. |
1287 // Try to get a pdf font which can encode the current glyph. | 1295 // Try to get a pdf font which can encode the current glyph. |
1288 glyphPositioner.flush(); | 1296 glyphPositioner.flush(); |
1289 this->updateFont(textPaint, glyphIDs[i], content.entry()); | 1297 if (!this->updateFont(textPaint, glyphIDs[i], content.entry())) { |
| 1298 SkDebugf("SkPDF: Font error."); |
| 1299 content.entry()->fContent.writeText("ET\n%SkPDF: Font error.\n")
; |
| 1300 return; |
| 1301 } |
1290 font = content.entry()->fState.fFont; | 1302 font = content.entry()->fState.fFont; |
1291 glyphPositioner.setWideChars(font->multiByteGlyphs()); | 1303 glyphPositioner.setWideChars(font->multiByteGlyphs()); |
1292 if (font->glyphsToPDFFontEncoding(&encodedValue, 1) != 1) { | 1304 if (font->glyphsToPDFFontEncoding(&encodedValue, 1) != 1) { |
1293 SkDEBUGFAIL("PDF could not encode glyph."); | 1305 SkDEBUGFAIL("PDF could not encode glyph."); |
1294 continue; | 1306 continue; |
1295 } | 1307 } |
1296 } | 1308 } |
1297 fontGlyphUsage->noteGlyphUsage(font, &encodedValue, 1); | 1309 fontGlyphUsage->noteGlyphUsage(font, &encodedValue, 1); |
1298 SkScalar x = offset.x() + pos[i * scalarsPerPos]; | 1310 SkScalar x = offset.x() + pos[i * scalarsPerPos]; |
1299 SkScalar y = offset.y() + (2 == scalarsPerPos ? pos[i * scalarsPerPos +
1] : 0); | 1311 SkScalar y = offset.y() + (2 == scalarsPerPos ? pos[i * scalarsPerPos +
1] : 0); |
(...skipping 690 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1990 // Assumes that xobject has been canonicalized (so we can directly compare | 2002 // Assumes that xobject has been canonicalized (so we can directly compare |
1991 // pointers). | 2003 // pointers). |
1992 int result = fXObjectResources.find(xObject); | 2004 int result = fXObjectResources.find(xObject); |
1993 if (result < 0) { | 2005 if (result < 0) { |
1994 result = fXObjectResources.count(); | 2006 result = fXObjectResources.count(); |
1995 fXObjectResources.push(SkRef(xObject)); | 2007 fXObjectResources.push(SkRef(xObject)); |
1996 } | 2008 } |
1997 return result; | 2009 return result; |
1998 } | 2010 } |
1999 | 2011 |
2000 void SkPDFDevice::updateFont(const SkPaint& paint, uint16_t glyphID, | 2012 bool SkPDFDevice::updateFont(const SkPaint& paint, uint16_t glyphID, |
2001 SkPDFDevice::ContentEntry* contentEntry) { | 2013 SkPDFDevice::ContentEntry* contentEntry) { |
2002 SkTypeface* typeface = paint.getTypeface(); | 2014 SkTypeface* typeface = paint.getTypeface(); |
2003 if (contentEntry->fState.fFont == nullptr || | 2015 if (contentEntry->fState.fFont == nullptr || |
2004 contentEntry->fState.fTextSize != paint.getTextSize() || | 2016 contentEntry->fState.fTextSize != paint.getTextSize() || |
2005 !contentEntry->fState.fFont->hasGlyph(glyphID)) { | 2017 !contentEntry->fState.fFont->hasGlyph(glyphID)) { |
2006 int fontIndex = getFontResourceIndex(typeface, glyphID); | 2018 int fontIndex = getFontResourceIndex(typeface, glyphID); |
| 2019 if (fontIndex < 0) { |
| 2020 return false; |
| 2021 } |
2007 contentEntry->fContent.writeText("/"); | 2022 contentEntry->fContent.writeText("/"); |
2008 contentEntry->fContent.writeText(SkPDFResourceDict::getResourceName( | 2023 contentEntry->fContent.writeText(SkPDFResourceDict::getResourceName( |
2009 SkPDFResourceDict::kFont_ResourceType, | 2024 SkPDFResourceDict::kFont_ResourceType, |
2010 fontIndex).c_str()); | 2025 fontIndex).c_str()); |
2011 contentEntry->fContent.writeText(" "); | 2026 contentEntry->fContent.writeText(" "); |
2012 SkPDFUtils::AppendScalar(paint.getTextSize(), &contentEntry->fContent); | 2027 SkPDFUtils::AppendScalar(paint.getTextSize(), &contentEntry->fContent); |
2013 contentEntry->fContent.writeText(" Tf\n"); | 2028 contentEntry->fContent.writeText(" Tf\n"); |
2014 contentEntry->fState.fFont = fFontResources[fontIndex]; | 2029 contentEntry->fState.fFont = fFontResources[fontIndex]; |
2015 } | 2030 } |
| 2031 return true; |
2016 } | 2032 } |
2017 | 2033 |
2018 int SkPDFDevice::getFontResourceIndex(SkTypeface* typeface, uint16_t glyphID) { | 2034 int SkPDFDevice::getFontResourceIndex(SkTypeface* typeface, uint16_t glyphID) { |
2019 sk_sp<SkPDFFont> newFont( | 2035 sk_sp<SkPDFFont> newFont( |
2020 SkPDFFont::GetFontResource(fDocument->canon(), typeface, glyphID)); | 2036 SkPDFFont::GetFontResource(fDocument->canon(), typeface, glyphID)); |
| 2037 if (!newFont) { |
| 2038 return -1; |
| 2039 } |
2021 int resourceIndex = fFontResources.find(newFont.get()); | 2040 int resourceIndex = fFontResources.find(newFont.get()); |
2022 if (resourceIndex < 0) { | 2041 if (resourceIndex < 0) { |
2023 resourceIndex = fFontResources.count(); | 2042 resourceIndex = fFontResources.count(); |
2024 fFontResources.push(newFont.get()); | 2043 fFontResources.push(newFont.get()); |
2025 newFont.get()->ref(); | 2044 newFont.get()->ref(); |
2026 } | 2045 } |
2027 return resourceIndex; | 2046 return resourceIndex; |
2028 } | 2047 } |
2029 | 2048 |
2030 static SkSize rect_to_size(const SkRect& r) { | 2049 static SkSize rect_to_size(const SkRect& r) { |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2232 } | 2251 } |
2233 | 2252 |
2234 sk_sp<SkSpecialImage> SkPDFDevice::makeSpecial(const SkImage* image) { | 2253 sk_sp<SkSpecialImage> SkPDFDevice::makeSpecial(const SkImage* image) { |
2235 return SkSpecialImage::MakeFromImage(SkIRect::MakeWH(image->width(), image->
height()), | 2254 return SkSpecialImage::MakeFromImage(SkIRect::MakeWH(image->width(), image->
height()), |
2236 image->makeNonTextureImage()); | 2255 image->makeNonTextureImage()); |
2237 } | 2256 } |
2238 | 2257 |
2239 sk_sp<SkSpecialImage> SkPDFDevice::snapSpecial() { | 2258 sk_sp<SkSpecialImage> SkPDFDevice::snapSpecial() { |
2240 return nullptr; | 2259 return nullptr; |
2241 } | 2260 } |
OLD | NEW |