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

Side by Side 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 unified diff | Download patch
« no previous file with comments | « no previous file | src/pdf/SkPDFUtils.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "SkAnnotationKeys.h" 10 #include "SkAnnotationKeys.h"
(...skipping 1061 matching lines...) Expand 10 before | Expand all | Expand 10 after
1072 SkAutoMalloc buffer(len); // Remove every other byte. 1072 SkAutoMalloc buffer(len); // Remove every other byte.
1073 uint8_t* ptr = (uint8_t*)buffer.get(); 1073 uint8_t* ptr = (uint8_t*)buffer.get();
1074 for (size_t i = 0; i < len; i++) { 1074 for (size_t i = 0; i < len; i++) {
1075 SkASSERT(0 == input[i] >> 8); 1075 SkASSERT(0 == input[i] >> 8);
1076 ptr[i] = static_cast<uint8_t>(input[i]); 1076 ptr[i] = static_cast<uint8_t>(input[i]);
1077 } 1077 }
1078 SkPDFUtils::WriteString(wStream, (char*)buffer.get(), len); 1078 SkPDFUtils::WriteString(wStream, (char*)buffer.get(), len);
1079 } 1079 }
1080 } 1080 }
1081 1081
1082 namespace {
1083 class GlyphPositioner {
1084 public:
1085 GlyphPositioner(SkDynamicMemoryWStream* content,
1086 SkScalar textSkewX,
1087 bool wideChars)
1088 : fContent(content)
1089 , fCurrentMatrixX(0.0f)
1090 , fCurrentMatrixY(0.0f)
1091 , fXAdvance(0.0f)
1092 , fWideChars(wideChars)
1093 , fInText(false) {
1094 set_text_transform(0.0f, 0.0f, textSkewX, fContent);
1095 }
1096 ~GlyphPositioner() { SkASSERT(!fInText); /* flush first */ }
1097 void flush() {
1098 if (fInText) {
1099 fContent->writeText("> Tj\n");
1100 fInText = false;
1101 }
1102 }
1103 void setWideChars(bool wideChars) {
1104 if (fWideChars != wideChars) {
1105 SkASSERT(!fInText);
1106 fWideChars = wideChars;
1107 }
1108 }
1109 void writeGlyph(SkScalar x,
1110 SkScalar y,
1111 SkScalar advanceWidth,
1112 uint16_t glyph) {
1113 SkScalar xPosition = x - fCurrentMatrixX;
1114 SkScalar yPosition = y - fCurrentMatrixY;
1115 if (xPosition != fXAdvance || yPosition != 0) {
1116 this->flush();
1117 SkPDFUtils::AppendScalar(xPosition, fContent);
1118 fContent->writeText(" ");
1119 SkPDFUtils::AppendScalar(-yPosition, fContent);
1120 fContent->writeText(" Td ");
1121 fCurrentMatrixX = x;
1122 fCurrentMatrixY = y;
1123 fXAdvance = 0;
1124 }
1125 if (!fInText) {
1126 fContent->writeText("<");
1127 fInText = true;
1128 }
1129 if (fWideChars) {
1130 SkPDFUtils::WriteUInt16BE(fContent, glyph);
1131 } else {
1132 SkASSERT(0 == glyph >> 8);
1133 SkPDFUtils::WriteUInt8(fContent, static_cast<uint8_t>(glyph));
1134 }
1135 fXAdvance += advanceWidth;
1136 }
1137
1138 private:
1139 SkDynamicMemoryWStream* fContent;
1140 SkScalar fCurrentMatrixX;
1141 SkScalar fCurrentMatrixY;
1142 SkScalar fXAdvance;
1143 bool fWideChars;
1144 bool fInText;
1145 };
1146 } // namespace
1147
1082 static void draw_transparent_text(SkPDFDevice* device, 1148 static void draw_transparent_text(SkPDFDevice* device,
1083 const SkDraw& d, 1149 const SkDraw& d,
1084 const void* text, size_t len, 1150 const void* text, size_t len,
1085 SkScalar x, SkScalar y, 1151 SkScalar x, SkScalar y,
1086 const SkPaint& srcPaint) { 1152 const SkPaint& srcPaint) {
1087 1153
1088 SkPaint transparent; 1154 SkPaint transparent;
1089 if (!SkPDFFont::CanEmbedTypeface(transparent.getTypeface(), 1155 if (!SkPDFFont::CanEmbedTypeface(transparent.getTypeface(),
1090 device->getCanon())) { 1156 device->getCanon())) {
1091 SkDEBUGFAIL("default typeface should be embeddable"); 1157 SkDEBUGFAIL("default typeface should be embeddable");
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
1223 } 1289 }
1224 1290
1225 SkGlyphStorage storage(0); 1291 SkGlyphStorage storage(0);
1226 const uint16_t* glyphIDs = nullptr; 1292 const uint16_t* glyphIDs = nullptr;
1227 size_t numGlyphs = force_glyph_encoding(paint, text, len, &storage, &glyphID s); 1293 size_t numGlyphs = force_glyph_encoding(paint, text, len, &storage, &glyphID s);
1228 textPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); 1294 textPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
1229 1295
1230 SkPaint::GlyphCacheProc glyphCacheProc = textPaint.getGlyphCacheProc(true); 1296 SkPaint::GlyphCacheProc glyphCacheProc = textPaint.getGlyphCacheProc(true);
1231 content.entry()->fContent.writeText("BT\n"); 1297 content.entry()->fContent.writeText("BT\n");
1232 this->updateFont(textPaint, glyphIDs[0], content.entry()); 1298 this->updateFont(textPaint, glyphIDs[0], content.entry());
1299 GlyphPositioner glyphPositioner(&content.entry()->fContent,
1300 textPaint.getTextSkewX(),
1301 content.entry()->fState.fFont->multiByteGlyp hs());
1233 SkPDFGlyphSetMap* fontGlyphUsage = fDocument->getGlyphUsage(); 1302 SkPDFGlyphSetMap* fontGlyphUsage = fDocument->getGlyphUsage();
1234 for (size_t i = 0; i < numGlyphs; i++) { 1303 for (size_t i = 0; i < numGlyphs; i++) {
1235 SkPDFFont* font = content.entry()->fState.fFont; 1304 SkPDFFont* font = content.entry()->fState.fFont;
1236 uint16_t encodedValue = glyphIDs[i]; 1305 uint16_t encodedValue = glyphIDs[i];
1237 if (font->glyphsToPDFFontEncoding(&encodedValue, 1) != 1) { 1306 if (font->glyphsToPDFFontEncoding(&encodedValue, 1) != 1) {
1238 // The current pdf font cannot encode the current glyph. 1307 // The current pdf font cannot encode the current glyph.
1239 // Try to get a pdf font which can encode the current glyph. 1308 // Try to get a pdf font which can encode the current glyph.
1309 glyphPositioner.flush();
1240 this->updateFont(textPaint, glyphIDs[i], content.entry()); 1310 this->updateFont(textPaint, glyphIDs[i], content.entry());
1241 font = content.entry()->fState.fFont; 1311 font = content.entry()->fState.fFont;
1312 glyphPositioner.setWideChars(font->multiByteGlyphs());
1242 if (font->glyphsToPDFFontEncoding(&encodedValue, 1) != 1) { 1313 if (font->glyphsToPDFFontEncoding(&encodedValue, 1) != 1) {
1243 SkDEBUGFAIL("PDF could not encode glyph."); 1314 SkDEBUGFAIL("PDF could not encode glyph.");
1244 continue; 1315 continue;
1245 } 1316 }
1246 } 1317 }
1247 1318
1248 fontGlyphUsage->noteGlyphUsage(font, &encodedValue, 1); 1319 fontGlyphUsage->noteGlyphUsage(font, &encodedValue, 1);
1249 SkScalar x = offset.x() + pos[i * scalarsPerPos]; 1320 SkScalar x = offset.x() + pos[i * scalarsPerPos];
1250 SkScalar y = offset.y() + (2 == scalarsPerPos ? pos[i * scalarsPerPos + 1] : 0); 1321 SkScalar y = offset.y() + (2 == scalarsPerPos ? pos[i * scalarsPerPos + 1] : 0);
1322 align_text(glyphCacheProc, textPaint, glyphIDs + i, 1, &x, &y);
1251 1323
1252 align_text(glyphCacheProc, textPaint, glyphIDs + i, 1, &x, &y); 1324 SkScalar advanceWidth = textPaint.measureText(&encodedValue, sizeof(uint 16_t));
1253 set_text_transform(x, y, textPaint.getTextSkewX(), &content.entry()->fCo ntent); 1325 glyphPositioner.writeGlyph(x, y, advanceWidth, encodedValue);
1254 write_wide_string(&content.entry()->fContent, &encodedValue, 1,
1255 font->multiByteGlyphs());
1256 content.entry()->fContent.writeText(" Tj\n");
1257 } 1326 }
1327 glyphPositioner.flush(); // Must flush before ending text object.
1258 content.entry()->fContent.writeText("ET\n"); 1328 content.entry()->fContent.writeText("ET\n");
1259 } 1329 }
1260 1330
1261 void SkPDFDevice::drawVertices(const SkDraw& d, SkCanvas::VertexMode, 1331 void SkPDFDevice::drawVertices(const SkDraw& d, SkCanvas::VertexMode,
1262 int vertexCount, const SkPoint verts[], 1332 int vertexCount, const SkPoint verts[],
1263 const SkPoint texs[], const SkColor colors[], 1333 const SkPoint texs[], const SkColor colors[],
1264 SkXfermode* xmode, const uint16_t indices[], 1334 SkXfermode* xmode, const uint16_t indices[],
1265 int indexCount, const SkPaint& paint) { 1335 int indexCount, const SkPaint& paint) {
1266 if (d.fRC->isEmpty()) { 1336 if (d.fRC->isEmpty()) {
1267 return; 1337 return;
(...skipping 853 matching lines...) Expand 10 before | Expand all | Expand 10 after
2121 if (!pdfimage) { 2191 if (!pdfimage) {
2122 return; 2192 return;
2123 } 2193 }
2124 fDocument->serialize(pdfimage); // serialize images early. 2194 fDocument->serialize(pdfimage); // serialize images early.
2125 fDocument->canon()->addPDFBitmap(key, pdfimage); 2195 fDocument->canon()->addPDFBitmap(key, pdfimage);
2126 } 2196 }
2127 // TODO(halcanary): addXObjectResource() should take a sk_sp<SkPDFObject> 2197 // TODO(halcanary): addXObjectResource() should take a sk_sp<SkPDFObject>
2128 SkPDFUtils::DrawFormXObject(this->addXObjectResource(pdfimage.get()), 2198 SkPDFUtils::DrawFormXObject(this->addXObjectResource(pdfimage.get()),
2129 &content.entry()->fContent); 2199 &content.entry()->fContent);
2130 } 2200 }
OLDNEW
« 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