Index: src/pdf/SkPDFDevice.cpp |
diff --git a/src/pdf/SkPDFDevice.cpp b/src/pdf/SkPDFDevice.cpp |
index 7ca6c2200e9a021ff1c2881e080bd82b141b65d9..cf7e7fb02e8343ec0edd47f96f0092ecb17b6636 100644 |
--- a/src/pdf/SkPDFDevice.cpp |
+++ b/src/pdf/SkPDFDevice.cpp |
@@ -1129,8 +1129,54 @@ static SkString format_wide_string(const uint16_t* input, |
} |
} |
+static void draw_transparent_text(SkPDFDevice* device, |
+ const SkDraw& d, |
+ const void* text, size_t len, |
+ SkScalar x, SkScalar y, |
+ const SkPaint& srcPaint) { |
+ |
+ SkPaint transparent; |
+ // default typeface should be embeddable |
+ SkASSERT(SkPDFFont::CanEmbedTypeface(transparent.getTypeface())); |
+ transparent.setTextSize(srcPaint.getTextSize()); |
+ transparent.setColor(SK_ColorTRANSPARENT); |
+ switch (srcPaint.getTextEncoding()) { |
+ case SkPaint::kGlyphID_TextEncoding: { |
+ // Since a glyphId<->Unicode mapping is typeface-specific, |
+ // map back to Unicode first. |
+ size_t glyphCount = len / 2; |
+ SkAutoTMalloc<SkUnichar> unichars(glyphCount); |
+ srcPaint.glyphsToUnichars( |
+ (const uint16_t*)text, SkToInt(glyphCount), &unichars[0]); |
+ transparent.setTextEncoding(SkPaint::kUTF32_TextEncoding); |
+ device->drawText(d, &unichars[0], |
+ glyphCount * sizeof(SkUnichar), |
+ x, y, transparent); |
+ break; |
+ } |
+ case SkPaint::kUTF8_TextEncoding: |
+ case SkPaint::kUTF16_TextEncoding: |
+ case SkPaint::kUTF32_TextEncoding: |
+ transparent.setTextEncoding(srcPaint.getTextEncoding()); |
+ device->drawText(d, text, len, x, y, transparent); |
+ break; |
+ default: |
+ SkFAIL("unknown text encoding"); |
+ } |
+} |
+ |
+ |
void SkPDFDevice::drawText(const SkDraw& d, const void* text, size_t len, |
SkScalar x, SkScalar y, const SkPaint& srcPaint) { |
+ if (!SkPDFFont::CanEmbedTypeface(srcPaint.getTypeface())) { |
+ // http://skbug.com/3866 |
+ SkPath path; |
+ srcPaint.getTextPath(text, len, x, y, &path); |
+ this->drawPath(d, path, srcPaint, &SkMatrix::I(), true); |
+ // Draw text transparently to make it copyable/searchable/accessable. |
+ draw_transparent_text(this, d, text, len, x, y, srcPaint); |
+ return; |
+ } |
SkPaint paint = srcPaint; |
replace_srcmode_on_opaque_paint(&paint); |
@@ -1183,6 +1229,29 @@ void SkPDFDevice::drawText(const SkDraw& d, const void* text, size_t len, |
void SkPDFDevice::drawPosText(const SkDraw& d, const void* text, size_t len, |
const SkScalar pos[], int scalarsPerPos, |
const SkPoint& offset, const SkPaint& srcPaint) { |
+ if (!SkPDFFont::CanEmbedTypeface(srcPaint.getTypeface())) { |
+ const SkPoint* positions = reinterpret_cast<const SkPoint*>(pos); |
+ SkAutoTMalloc<SkPoint> positionsBuffer; |
+ if (2 != scalarsPerPos) { |
+ int glyphCount = srcPaint.textToGlyphs(text, len, NULL); |
+ positionsBuffer.reset(glyphCount); |
+ for (int i = 0; i < glyphCount; ++i) { |
+ positionsBuffer[i].set(pos[i], 0.0f); |
+ } |
+ positions = &positionsBuffer[0]; |
+ } |
+ SkPath path; |
+ srcPaint.getPosTextPath(text, len, positions, &path); |
+ SkMatrix matrix; |
+ matrix.setTranslate(offset); |
+ this->drawPath(d, path, srcPaint, &matrix, true); |
+ // Draw text transparently to make it copyable/searchable/accessable. |
+ draw_transparent_text( |
+ this, d, text, len, offset.x() + positions[0].x(), |
+ offset.y() + positions[0].y(), srcPaint); |
+ return; |
+ } |
+ |
SkPaint paint = srcPaint; |
replace_srcmode_on_opaque_paint(&paint); |