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 | 9 |
10 #include "SkAnnotation.h" | 10 #include "SkAnnotation.h" |
(...skipping 1213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1224 SkASSERT(len <= 65535); | 1224 SkASSERT(len <= 65535); |
1225 SkString tmp(len); | 1225 SkString tmp(len); |
1226 for (size_t i = 0; i < len; i++) { | 1226 for (size_t i = 0; i < len; i++) { |
1227 SkASSERT(0 == input[i] >> 8); | 1227 SkASSERT(0 == input[i] >> 8); |
1228 tmp[i] = static_cast<uint8_t>(input[i]); | 1228 tmp[i] = static_cast<uint8_t>(input[i]); |
1229 } | 1229 } |
1230 return SkPDFUtils::FormatString(tmp.c_str(), tmp.size()); | 1230 return SkPDFUtils::FormatString(tmp.c_str(), tmp.size()); |
1231 } | 1231 } |
1232 } | 1232 } |
1233 | 1233 |
1234 static void draw_transparent_text(SkPDFDevice* device, | |
1235 const SkDraw& d, | |
1236 const void* text, size_t len, | |
1237 SkScalar x, SkScalar y, | |
1238 const SkPaint& srcPaint) { | |
1239 | |
1240 SkPaint transparent; | |
1241 // default typeface should be embeddable | |
1242 SkASSERT(SkPDFFont::CanEmbedTypeface(transparent.getTypeface(), | |
bungeman-skia
2015/10/12 19:05:29
I'm not sure it's enough to just debug assert this
hal.canary
2015/10/12 19:10:25
this:
SK_ALWAYSBREAK(SkPDFFont::CanEmbedTypef
| |
1243 device->getCanon())); | |
1244 transparent.setTextSize(srcPaint.getTextSize()); | |
1245 transparent.setColor(SK_ColorTRANSPARENT); | |
1246 switch (srcPaint.getTextEncoding()) { | |
1247 case SkPaint::kGlyphID_TextEncoding: { | |
1248 // Since a glyphId<->Unicode mapping is typeface-specific, | |
1249 // map back to Unicode first. | |
1250 size_t glyphCount = len / 2; | |
1251 SkAutoTMalloc<SkUnichar> unichars(glyphCount); | |
1252 srcPaint.glyphsToUnichars( | |
1253 (const uint16_t*)text, SkToInt(glyphCount), &unichars[0]); | |
1254 transparent.setTextEncoding(SkPaint::kUTF32_TextEncoding); | |
1255 device->drawText(d, &unichars[0], | |
1256 glyphCount * sizeof(SkUnichar), | |
1257 x, y, transparent); | |
1258 break; | |
1259 } | |
1260 case SkPaint::kUTF8_TextEncoding: | |
1261 case SkPaint::kUTF16_TextEncoding: | |
1262 case SkPaint::kUTF32_TextEncoding: | |
1263 transparent.setTextEncoding(srcPaint.getTextEncoding()); | |
1264 device->drawText(d, text, len, x, y, transparent); | |
1265 break; | |
1266 default: | |
1267 SkFAIL("unknown text encoding"); | |
1268 } | |
1269 } | |
1270 | |
1271 | |
1234 void SkPDFDevice::drawText(const SkDraw& d, const void* text, size_t len, | 1272 void SkPDFDevice::drawText(const SkDraw& d, const void* text, size_t len, |
1235 SkScalar x, SkScalar y, const SkPaint& srcPaint) { | 1273 SkScalar x, SkScalar y, const SkPaint& srcPaint) { |
1274 if (!SkPDFFont::CanEmbedTypeface(srcPaint.getTypeface(), fCanon)) { | |
1275 // http://skbug.com/3866 | |
1276 SkPath path; | |
1277 srcPaint.getTextPath(text, len, x, y, &path); | |
1278 this->drawPath(d, path, srcPaint, &SkMatrix::I(), true); | |
1279 // Draw text transparently to make it copyable/searchable/accessable. | |
1280 draw_transparent_text(this, d, text, len, x, y, srcPaint); | |
1281 return; | |
1282 } | |
1236 SkPaint paint = srcPaint; | 1283 SkPaint paint = srcPaint; |
1237 replace_srcmode_on_opaque_paint(&paint); | 1284 replace_srcmode_on_opaque_paint(&paint); |
1238 | 1285 |
1239 NOT_IMPLEMENTED(paint.getMaskFilter() != nullptr, false); | 1286 NOT_IMPLEMENTED(paint.getMaskFilter() != nullptr, false); |
1240 if (paint.getMaskFilter() != nullptr) { | 1287 if (paint.getMaskFilter() != nullptr) { |
1241 // Don't pretend we support drawing MaskFilters, it makes for artifacts | 1288 // Don't pretend we support drawing MaskFilters, it makes for artifacts |
1242 // making text unreadable (e.g. same text twice when using CSS shadows). | 1289 // making text unreadable (e.g. same text twice when using CSS shadows). |
1243 return; | 1290 return; |
1244 } | 1291 } |
1245 SkPaint textPaint = calculate_text_paint(paint); | 1292 SkPaint textPaint = calculate_text_paint(paint); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1278 content.entry()->fContent.writeText(encodedString.c_str()); | 1325 content.entry()->fContent.writeText(encodedString.c_str()); |
1279 consumedGlyphCount += availableGlyphs; | 1326 consumedGlyphCount += availableGlyphs; |
1280 content.entry()->fContent.writeText(" Tj\n"); | 1327 content.entry()->fContent.writeText(" Tj\n"); |
1281 } | 1328 } |
1282 content.entry()->fContent.writeText("ET\n"); | 1329 content.entry()->fContent.writeText("ET\n"); |
1283 } | 1330 } |
1284 | 1331 |
1285 void SkPDFDevice::drawPosText(const SkDraw& d, const void* text, size_t len, | 1332 void SkPDFDevice::drawPosText(const SkDraw& d, const void* text, size_t len, |
1286 const SkScalar pos[], int scalarsPerPos, | 1333 const SkScalar pos[], int scalarsPerPos, |
1287 const SkPoint& offset, const SkPaint& srcPaint) { | 1334 const SkPoint& offset, const SkPaint& srcPaint) { |
1335 if (!SkPDFFont::CanEmbedTypeface(srcPaint.getTypeface(), fCanon)) { | |
1336 const SkPoint* positions = reinterpret_cast<const SkPoint*>(pos); | |
1337 SkAutoTMalloc<SkPoint> positionsBuffer; | |
1338 if (2 != scalarsPerPos) { | |
1339 int glyphCount = srcPaint.textToGlyphs(text, len, NULL); | |
1340 positionsBuffer.reset(glyphCount); | |
1341 for (int i = 0; i < glyphCount; ++i) { | |
1342 positionsBuffer[i].set(pos[i], 0.0f); | |
1343 } | |
1344 positions = &positionsBuffer[0]; | |
1345 } | |
1346 SkPath path; | |
1347 srcPaint.getPosTextPath(text, len, positions, &path); | |
1348 SkMatrix matrix; | |
1349 matrix.setTranslate(offset); | |
1350 this->drawPath(d, path, srcPaint, &matrix, true); | |
1351 // Draw text transparently to make it copyable/searchable/accessable. | |
1352 draw_transparent_text( | |
1353 this, d, text, len, offset.x() + positions[0].x(), | |
1354 offset.y() + positions[0].y(), srcPaint); | |
1355 return; | |
1356 } | |
1357 | |
1288 SkPaint paint = srcPaint; | 1358 SkPaint paint = srcPaint; |
1289 replace_srcmode_on_opaque_paint(&paint); | 1359 replace_srcmode_on_opaque_paint(&paint); |
1290 | 1360 |
1291 NOT_IMPLEMENTED(paint.getMaskFilter() != nullptr, false); | 1361 NOT_IMPLEMENTED(paint.getMaskFilter() != nullptr, false); |
1292 if (paint.getMaskFilter() != nullptr) { | 1362 if (paint.getMaskFilter() != nullptr) { |
1293 // Don't pretend we support drawing MaskFilters, it makes for artifacts | 1363 // Don't pretend we support drawing MaskFilters, it makes for artifacts |
1294 // making text unreadable (e.g. same text twice when using CSS shadows). | 1364 // making text unreadable (e.g. same text twice when using CSS shadows). |
1295 return; | 1365 return; |
1296 } | 1366 } |
1297 SkASSERT(1 == scalarsPerPos || 2 == scalarsPerPos); | 1367 SkASSERT(1 == scalarsPerPos || 2 == scalarsPerPos); |
(...skipping 993 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2291 if (!pdfimage) { | 2361 if (!pdfimage) { |
2292 pdfimage.reset(SkPDFCreateBitmapObject(image)); | 2362 pdfimage.reset(SkPDFCreateBitmapObject(image)); |
2293 if (!pdfimage) { | 2363 if (!pdfimage) { |
2294 return; | 2364 return; |
2295 } | 2365 } |
2296 fCanon->addPDFBitmap(image->uniqueID(), pdfimage); | 2366 fCanon->addPDFBitmap(image->uniqueID(), pdfimage); |
2297 } | 2367 } |
2298 SkPDFUtils::DrawFormXObject(this->addXObjectResource(pdfimage.get()), | 2368 SkPDFUtils::DrawFormXObject(this->addXObjectResource(pdfimage.get()), |
2299 &content.entry()->fContent); | 2369 &content.entry()->fContent); |
2300 } | 2370 } |
OLD | NEW |