Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(748)

Unified Diff: src/pdf/SkPDFDevice.cpp

Issue 2150393002: SkPDF: Join Positioned Text (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: 2016-07-15 (Friday) 16:11:07 EDT Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | src/pdf/SkPDFUtils.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/pdf/SkPDFDevice.cpp
diff --git a/src/pdf/SkPDFDevice.cpp b/src/pdf/SkPDFDevice.cpp
index 8e417b1f529dbf9e4b41909175a9cf7107aeb940..8e76c442befaabe89e492455c631285d141fdeab 100644
--- a/src/pdf/SkPDFDevice.cpp
+++ b/src/pdf/SkPDFDevice.cpp
@@ -1079,6 +1079,72 @@ static void write_wide_string(SkDynamicMemoryWStream* wStream,
}
}
+namespace {
+class GlyphPositioner {
+public:
+ GlyphPositioner(SkDynamicMemoryWStream* content,
+ SkScalar textSkewX,
+ bool wideChars)
+ : fContent(content)
+ , fCurrentMatrixX(0.0f)
+ , fCurrentMatrixY(0.0f)
+ , fXAdvance(0.0f)
+ , fWideChars(wideChars)
+ , fInText(false) {
+ set_text_transform(0.0f, 0.0f, textSkewX, fContent);
+ }
+ ~GlyphPositioner() { SkASSERT(!fInText); /* flush first */ }
+ void flush() {
+ if (fInText) {
+ fContent->writeText("> Tj\n");
+ fInText = false;
+ }
+ }
+ void setWideChars(bool wideChars) {
+ if (fWideChars != wideChars) {
+ SkASSERT(!fInText);
+ fWideChars = wideChars;
+ }
+ }
+ void writeGlyph(SkScalar x,
+ SkScalar y,
+ SkScalar advanceWidth,
+ uint16_t glyph) {
+ SkScalar xPosition = x - fCurrentMatrixX;
+ SkScalar yPosition = y - fCurrentMatrixY;
+ if (xPosition != fXAdvance || yPosition != 0) {
+ this->flush();
+ SkPDFUtils::AppendScalar(xPosition, fContent);
+ fContent->writeText(" ");
+ SkPDFUtils::AppendScalar(-yPosition, fContent);
+ fContent->writeText(" Td ");
+ fCurrentMatrixX = x;
+ fCurrentMatrixY = y;
+ fXAdvance = 0;
+ }
+ if (!fInText) {
+ fContent->writeText("<");
+ fInText = true;
+ }
+ if (fWideChars) {
+ SkPDFUtils::WriteUInt16BE(fContent, glyph);
+ } else {
+ SkASSERT(0 == glyph >> 8);
+ SkPDFUtils::WriteUInt8(fContent, static_cast<uint8_t>(glyph));
+ }
+ fXAdvance += advanceWidth;
+ }
+
+private:
+ SkDynamicMemoryWStream* fContent;
+ SkScalar fCurrentMatrixX;
+ SkScalar fCurrentMatrixY;
+ SkScalar fXAdvance;
+ bool fWideChars;
+ bool fInText;
+};
+} // namespace
+
static void draw_transparent_text(SkPDFDevice* device,
const SkDraw& d,
const void* text, size_t len,
@@ -1230,6 +1296,9 @@ void SkPDFDevice::drawPosText(const SkDraw& d, const void* text, size_t len,
SkPaint::GlyphCacheProc glyphCacheProc = textPaint.getGlyphCacheProc(true);
content.entry()->fContent.writeText("BT\n");
this->updateFont(textPaint, glyphIDs[0], content.entry());
+ GlyphPositioner glyphPositioner(&content.entry()->fContent,
+ textPaint.getTextSkewX(),
+ content.entry()->fState.fFont->multiByteGlyphs());
SkPDFGlyphSetMap* fontGlyphUsage = fDocument->getGlyphUsage();
for (size_t i = 0; i < numGlyphs; i++) {
SkPDFFont* font = content.entry()->fState.fFont;
@@ -1237,8 +1306,10 @@ void SkPDFDevice::drawPosText(const SkDraw& d, const void* text, size_t len,
if (font->glyphsToPDFFontEncoding(&encodedValue, 1) != 1) {
// The current pdf font cannot encode the current glyph.
// Try to get a pdf font which can encode the current glyph.
+ glyphPositioner.flush();
this->updateFont(textPaint, glyphIDs[i], content.entry());
font = content.entry()->fState.fFont;
+ glyphPositioner.setWideChars(font->multiByteGlyphs());
if (font->glyphsToPDFFontEncoding(&encodedValue, 1) != 1) {
SkDEBUGFAIL("PDF could not encode glyph.");
continue;
@@ -1248,13 +1319,12 @@ void SkPDFDevice::drawPosText(const SkDraw& d, const void* text, size_t len,
fontGlyphUsage->noteGlyphUsage(font, &encodedValue, 1);
SkScalar x = offset.x() + pos[i * scalarsPerPos];
SkScalar y = offset.y() + (2 == scalarsPerPos ? pos[i * scalarsPerPos + 1] : 0);
-
align_text(glyphCacheProc, textPaint, glyphIDs + i, 1, &x, &y);
- set_text_transform(x, y, textPaint.getTextSkewX(), &content.entry()->fContent);
- write_wide_string(&content.entry()->fContent, &encodedValue, 1,
- font->multiByteGlyphs());
- content.entry()->fContent.writeText(" Tj\n");
+
+ SkScalar advanceWidth = textPaint.measureText(&encodedValue, sizeof(uint16_t));
+ glyphPositioner.writeGlyph(x, y, advanceWidth, encodedValue);
}
+ glyphPositioner.flush(); // Must flush before ending text object.
content.entry()->fContent.writeText("ET\n");
}
« no previous file with comments | « no previous file | src/pdf/SkPDFUtils.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698