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 #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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |