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

Side by Side Diff: src/pdf/SkPDFDevice.cpp

Issue 2188303003: SkPDF: drawText makes use of SkPaint.measureText() for alignment. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 4 years, 4 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 | no next file » | 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 #include "SkAnnotationKeys.h" 9 #include "SkAnnotationKeys.h"
10 #include "SkBitmapDevice.h" 10 #include "SkBitmapDevice.h"
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
71 result.setStyle(SkPaint::kStrokeAndFill_Style); 71 result.setStyle(SkPaint::kStrokeAndFill_Style);
72 } else { 72 } else {
73 width += result.getStrokeWidth(); 73 width += result.getStrokeWidth();
74 } 74 }
75 result.setStrokeWidth(width); 75 result.setStrokeWidth(width);
76 } 76 }
77 return result; 77 return result;
78 } 78 }
79 79
80 // Stolen from measure_text in SkDraw.cpp and then tweaked. 80 // Stolen from measure_text in SkDraw.cpp and then tweaked.
81 static void align_text(SkPaint::GlyphCacheProc glyphCacheProc, const SkPaint& pa int, 81 static void align_text(const SkPaint& paint,
82 const uint16_t* glyphs, size_t len, 82 const uint16_t* glyphs, size_t len,
83 SkScalar* x, SkScalar* y) { 83 SkScalar* x, SkScalar* y) {
84 if (paint.getTextAlign() == SkPaint::kLeft_Align) { 84 if (paint.getTextAlign() == SkPaint::kLeft_Align) {
85 return; 85 return;
86 } 86 }
87 87 SkScalar advance = paint.measureText(glyphs, len * sizeof(uint16_t));
88 SkMatrix ident; 88 if (paint.getTextAlign() == SkPaint::kCenter_Align) {
89 ident.reset(); 89 advance *= 0.5f;
90 SkAutoGlyphCache autoCache(paint, nullptr, &ident);
91 SkGlyphCache* cache = autoCache.getCache();
92
93 const char* start = reinterpret_cast<const char*>(glyphs);
94 const char* stop = reinterpret_cast<const char*>(glyphs + len);
95 SkScalar xAdv = 0, yAdv = 0;
96
97 // TODO(vandebo): This probably needs to take kerning into account.
98 while (start < stop) {
99 const SkGlyph& glyph = glyphCacheProc(cache, &start);
100 xAdv += SkFloatToScalar(glyph.fAdvanceX);
101 yAdv += SkFloatToScalar(glyph.fAdvanceY);
102 };
103 if (paint.getTextAlign() == SkPaint::kLeft_Align) {
104 return;
105 } 90 }
106 91 if (paint.isVerticalText()) {
107 if (paint.getTextAlign() == SkPaint::kCenter_Align) { 92 *y -= advance;
108 xAdv = SkScalarHalf(xAdv); 93 } else {
109 yAdv = SkScalarHalf(yAdv); 94 *x -= advance;
110 } 95 }
111 *x = *x - xAdv;
112 *y = *y - yAdv;
113 } 96 }
114 97
115 static int max_glyphid_for_typeface(SkTypeface* typeface) { 98 static int max_glyphid_for_typeface(SkTypeface* typeface) {
116 SkAutoResolveDefaultTypeface autoResolve(typeface); 99 SkAutoResolveDefaultTypeface autoResolve(typeface);
117 typeface = autoResolve.get(); 100 typeface = autoResolve.get();
118 return typeface->countGlyphs() - 1; 101 return typeface->countGlyphs() - 1;
119 } 102 }
120 103
121 typedef SkAutoSTMalloc<128, uint16_t> SkGlyphStorage; 104 typedef SkAutoSTMalloc<128, uint16_t> SkGlyphStorage;
122 105
(...skipping 1084 matching lines...) Expand 10 before | Expand all | Expand 10 after
1207 ScopedContentEntry content(this, d, textPaint, true); 1190 ScopedContentEntry content(this, d, textPaint, true);
1208 if (!content.entry()) { 1191 if (!content.entry()) {
1209 return; 1192 return;
1210 } 1193 }
1211 1194
1212 SkGlyphStorage storage(0); 1195 SkGlyphStorage storage(0);
1213 const uint16_t* glyphIDs = nullptr; 1196 const uint16_t* glyphIDs = nullptr;
1214 int numGlyphs = force_glyph_encoding(paint, text, len, &storage, &glyphIDs); 1197 int numGlyphs = force_glyph_encoding(paint, text, len, &storage, &glyphIDs);
1215 textPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); 1198 textPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
1216 1199
1217 SkPaint::GlyphCacheProc glyphCacheProc = SkPaint::GetGlyphCacheProc(textPain t.getTextEncoding(), 1200 align_text(textPaint, glyphIDs, numGlyphs, &x, &y);
1218 textPain t.isDevKernText(),
1219 true);
1220 align_text(glyphCacheProc, textPaint, glyphIDs, numGlyphs, &x, &y);
1221 content.entry()->fContent.writeText("BT\n"); 1201 content.entry()->fContent.writeText("BT\n");
1222 set_text_transform(x, y, textPaint.getTextSkewX(), 1202 set_text_transform(x, y, textPaint.getTextSkewX(),
1223 &content.entry()->fContent); 1203 &content.entry()->fContent);
1224 int consumedGlyphCount = 0; 1204 int consumedGlyphCount = 0;
1225 1205
1226 SkTDArray<uint16_t> glyphIDsCopy(glyphIDs, numGlyphs); 1206 SkTDArray<uint16_t> glyphIDsCopy(glyphIDs, numGlyphs);
1227 1207
1228 SkPDFGlyphSetMap* fontGlyphUsage = fDocument->getGlyphUsage(); 1208 SkPDFGlyphSetMap* fontGlyphUsage = fDocument->getGlyphUsage();
1229 1209
1230 while (numGlyphs > consumedGlyphCount) { 1210 while (numGlyphs > consumedGlyphCount) {
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1286 ScopedContentEntry content(this, d, textPaint, true); 1266 ScopedContentEntry content(this, d, textPaint, true);
1287 if (!content.entry()) { 1267 if (!content.entry()) {
1288 return; 1268 return;
1289 } 1269 }
1290 1270
1291 SkGlyphStorage storage(0); 1271 SkGlyphStorage storage(0);
1292 const uint16_t* glyphIDs = nullptr; 1272 const uint16_t* glyphIDs = nullptr;
1293 size_t numGlyphs = force_glyph_encoding(paint, text, len, &storage, &glyphID s); 1273 size_t numGlyphs = force_glyph_encoding(paint, text, len, &storage, &glyphID s);
1294 textPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); 1274 textPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
1295 1275
1296 SkPaint::GlyphCacheProc glyphCacheProc = SkPaint::GetGlyphCacheProc(textPain t.getTextEncoding(),
1297 textPain t.isDevKernText(),
1298 true);
1299 content.entry()->fContent.writeText("BT\n"); 1276 content.entry()->fContent.writeText("BT\n");
1300 this->updateFont(textPaint, glyphIDs[0], content.entry()); 1277 this->updateFont(textPaint, glyphIDs[0], content.entry());
1301 GlyphPositioner glyphPositioner(&content.entry()->fContent, 1278 GlyphPositioner glyphPositioner(&content.entry()->fContent,
1302 textPaint.getTextSkewX(), 1279 textPaint.getTextSkewX(),
1303 content.entry()->fState.fFont->multiByteGlyp hs()); 1280 content.entry()->fState.fFont->multiByteGlyp hs());
1304 SkPDFGlyphSetMap* fontGlyphUsage = fDocument->getGlyphUsage(); 1281 SkPDFGlyphSetMap* fontGlyphUsage = fDocument->getGlyphUsage();
1305 for (size_t i = 0; i < numGlyphs; i++) { 1282 for (size_t i = 0; i < numGlyphs; i++) {
1306 SkPDFFont* font = content.entry()->fState.fFont; 1283 SkPDFFont* font = content.entry()->fState.fFont;
1307 uint16_t encodedValue = glyphIDs[i]; 1284 uint16_t encodedValue = glyphIDs[i];
1308 if (font->glyphsToPDFFontEncoding(&encodedValue, 1) != 1) { 1285 if (font->glyphsToPDFFontEncoding(&encodedValue, 1) != 1) {
1309 // The current pdf font cannot encode the current glyph. 1286 // The current pdf font cannot encode the current glyph.
1310 // Try to get a pdf font which can encode the current glyph. 1287 // Try to get a pdf font which can encode the current glyph.
1311 glyphPositioner.flush(); 1288 glyphPositioner.flush();
1312 this->updateFont(textPaint, glyphIDs[i], content.entry()); 1289 this->updateFont(textPaint, glyphIDs[i], content.entry());
1313 font = content.entry()->fState.fFont; 1290 font = content.entry()->fState.fFont;
1314 glyphPositioner.setWideChars(font->multiByteGlyphs()); 1291 glyphPositioner.setWideChars(font->multiByteGlyphs());
1315 if (font->glyphsToPDFFontEncoding(&encodedValue, 1) != 1) { 1292 if (font->glyphsToPDFFontEncoding(&encodedValue, 1) != 1) {
1316 SkDEBUGFAIL("PDF could not encode glyph."); 1293 SkDEBUGFAIL("PDF could not encode glyph.");
1317 continue; 1294 continue;
1318 } 1295 }
1319 } 1296 }
1320 1297
1321 fontGlyphUsage->noteGlyphUsage(font, &encodedValue, 1); 1298 fontGlyphUsage->noteGlyphUsage(font, &encodedValue, 1);
1322 SkScalar x = offset.x() + pos[i * scalarsPerPos]; 1299 SkScalar x = offset.x() + pos[i * scalarsPerPos];
1323 SkScalar y = offset.y() + (2 == scalarsPerPos ? pos[i * scalarsPerPos + 1] : 0); 1300 SkScalar y = offset.y() + (2 == scalarsPerPos ? pos[i * scalarsPerPos + 1] : 0);
1324 align_text(glyphCacheProc, textPaint, glyphIDs + i, 1, &x, &y); 1301 align_text(textPaint, glyphIDs + i, 1, &x, &y);
1325 1302
1326 SkScalar advanceWidth = textPaint.measureText(&encodedValue, sizeof(uint 16_t)); 1303 SkScalar advanceWidth = textPaint.measureText(&encodedValue, sizeof(uint 16_t));
1327 glyphPositioner.writeGlyph(x, y, advanceWidth, encodedValue); 1304 glyphPositioner.writeGlyph(x, y, advanceWidth, encodedValue);
1328 } 1305 }
1329 glyphPositioner.flush(); // Must flush before ending text object. 1306 glyphPositioner.flush(); // Must flush before ending text object.
1330 content.entry()->fContent.writeText("ET\n"); 1307 content.entry()->fContent.writeText("ET\n");
1331 } 1308 }
1332 1309
1333 void SkPDFDevice::drawVertices(const SkDraw& d, SkCanvas::VertexMode, 1310 void SkPDFDevice::drawVertices(const SkDraw& d, SkCanvas::VertexMode,
1334 int vertexCount, const SkPoint verts[], 1311 int vertexCount, const SkPoint verts[],
(...skipping 909 matching lines...) Expand 10 before | Expand all | Expand 10 after
2244 } 2221 }
2245 2222
2246 sk_sp<SkSpecialImage> SkPDFDevice::makeSpecial(const SkImage* image) { 2223 sk_sp<SkSpecialImage> SkPDFDevice::makeSpecial(const SkImage* image) {
2247 return SkSpecialImage::MakeFromImage(SkIRect::MakeWH(image->width(), image-> height()), 2224 return SkSpecialImage::MakeFromImage(SkIRect::MakeWH(image->width(), image-> height()),
2248 image->makeNonTextureImage()); 2225 image->makeNonTextureImage());
2249 } 2226 }
2250 2227
2251 sk_sp<SkSpecialImage> SkPDFDevice::snapSpecial() { 2228 sk_sp<SkSpecialImage> SkPDFDevice::snapSpecial() {
2252 return nullptr; 2229 return nullptr;
2253 } 2230 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698