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

Side by Side Diff: experimental/svg/SkSVGDevice.cpp

Issue 899683002: [SkSVGDevice] Initial text support (Closed) Base URL: https://chromium.googlesource.com/skia.git@master
Patch Set: review comments Created 5 years, 10 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 | include/xml/SkXMLWriter.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 2015 Google Inc. 2 * Copyright 2015 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 "SkSVGDevice.h" 8 #include "SkSVGDevice.h"
9 9
10 #include "SkBitmap.h" 10 #include "SkBitmap.h"
11 #include "SkDraw.h" 11 #include "SkDraw.h"
12 #include "SkPaint.h" 12 #include "SkPaint.h"
13 #include "SkParsePath.h" 13 #include "SkParsePath.h"
14 #include "SkShader.h" 14 #include "SkShader.h"
15 #include "SkStream.h" 15 #include "SkStream.h"
16 #include "SkTypeface.h"
17 #include "SkUtils.h"
16 #include "SkXMLWriter.h" 18 #include "SkXMLWriter.h"
17 19
18 namespace { 20 namespace {
19 21
20 static SkString svg_color(SkColor color) { 22 static SkString svg_color(SkColor color) {
21 SkString colorStr; 23 SkString colorStr;
22 colorStr.printf("rgb(%u,%u,%u)", 24 colorStr.printf("rgb(%u,%u,%u)",
23 SkColorGetR(color), 25 SkColorGetR(color),
24 SkColorGetG(color), 26 SkColorGetG(color),
25 SkColorGetB(color)); 27 SkColorGetB(color));
26 return colorStr; 28 return colorStr;
27 } 29 }
28 30
29 static SkScalar svg_opacity(SkColor color) { 31 static SkScalar svg_opacity(SkColor color) {
30 return SkIntToScalar(SkColorGetA(color)) / SK_AlphaOPAQUE; 32 return SkIntToScalar(SkColorGetA(color)) / SK_AlphaOPAQUE;
31 } 33 }
32 34
35 static void append_escaped_unichar(SkUnichar c, SkString* text) {
36 switch(c) {
37 case '&':
38 text->append("&");
39 break;
40 case '"':
41 text->append(""");
42 break;
43 case '\'':
44 text->append("'");
45 break;
46 case '<':
47 text->append("&lt;");
48 break;
49 case '>':
50 text->append("&gt;");
51 break;
52 default:
53 text->appendUnichar(c);
54 break;
55 }
56 }
57
58 static SkString svg_text(const void* text, size_t byteLen, const SkPaint& paint) {
59 SkString svgText;
60 int count = paint.countText(text, byteLen);
61
62 switch(paint.getTextEncoding()) {
63 case SkPaint::kGlyphID_TextEncoding: {
64 SkASSERT(count * sizeof(uint16_t) == byteLen);
65 SkAutoSTArray<64, SkUnichar> unichars(count);
66 paint.glyphsToUnichars((const uint16_t*)text, count, unichars.get());
67 for (int i = 0; i < count; ++i) {
68 append_escaped_unichar(unichars[i], &svgText);
69 }
70 } break;
71 case SkPaint::kUTF8_TextEncoding: {
72 const char* c8 = reinterpret_cast<const char*>(text);
73 for (int i = 0; i < count; ++i) {
74 append_escaped_unichar(SkUTF8_NextUnichar(&c8), &svgText);
75 }
76 SkASSERT(reinterpret_cast<const char*>(text) + byteLen == c8);
77 } break;
78 case SkPaint::kUTF16_TextEncoding: {
79 const uint16_t* c16 = reinterpret_cast<const uint16_t*>(text);
80 for (int i = 0; i < count; ++i) {
81 append_escaped_unichar(SkUTF16_NextUnichar(&c16), &svgText);
82 }
83 SkASSERT(SkIsAlign2(byteLen));
84 SkASSERT(reinterpret_cast<const uint16_t*>(text) + (byteLen / 2) == c16) ;
85 } break;
86 case SkPaint::kUTF32_TextEncoding: {
87 SkASSERT(count * sizeof(uint32_t) == byteLen);
88 const uint32_t* c32 = reinterpret_cast<const uint32_t*>(text);
89 for (int i = 0; i < count; ++i) {
90 append_escaped_unichar(c32[i], &svgText);
91 }
92 } break;
93 default:
94 SkFAIL("unknown text encoding");
95 }
96
97 return svgText;
98 }
99
33 struct Resources { 100 struct Resources {
34 Resources(const SkPaint& paint) 101 Resources(const SkPaint& paint)
35 : fPaintServer(svg_color(paint.getColor())) {} 102 : fPaintServer(svg_color(paint.getColor())) {}
36 103
37 SkString fPaintServer; 104 SkString fPaintServer;
38 }; 105 };
39 106
40 } 107 }
41 108
42 // For now all this does is serve unique serial IDs, but it will eventually evol ve to track 109 // For now all this does is serve unique serial IDs, but it will eventually evol ve to track
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
89 } 156 }
90 157
91 void addAttribute(const char name[], int32_t val) { 158 void addAttribute(const char name[], int32_t val) {
92 fWriter->addS32Attribute(name, val); 159 fWriter->addS32Attribute(name, val);
93 } 160 }
94 161
95 void addAttribute(const char name[], SkScalar val) { 162 void addAttribute(const char name[], SkScalar val) {
96 fWriter->addScalarAttribute(name, val); 163 fWriter->addScalarAttribute(name, val);
97 } 164 }
98 165
166 void addText(const SkString& text) {
167 fWriter->addText(text);
168 }
169
170 void addFontAttributes(const SkPaint&);
171
99 private: 172 private:
100 Resources addResources(const SkPaint& paint); 173 Resources addResources(const SkPaint& paint);
101 void addResourceDefs(const SkPaint& paint, Resources* resources); 174 void addResourceDefs(const SkPaint& paint, Resources* resources);
102 175
103 void addPaint(const SkPaint& paint, const Resources& resources); 176 void addPaint(const SkPaint& paint, const Resources& resources);
104 void addTransform(const SkMatrix& transform, const char name[] = "transform" ); 177 void addTransform(const SkMatrix& transform, const char name[] = "transform" );
105 178
106 SkString addLinearGradientDef(const SkShader::GradientInfo& info, const SkSh ader* shader); 179 SkString addLinearGradientDef(const SkShader::GradientInfo& info, const SkSh ader* shader);
107 180
108 SkXMLWriter* fWriter; 181 SkXMLWriter* fWriter;
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
227 if (SK_AlphaOPAQUE != SkColorGetA(color)) { 300 if (SK_AlphaOPAQUE != SkColorGetA(color)) {
228 stop.addAttribute("stop-opacity", svg_opacity(color)); 301 stop.addAttribute("stop-opacity", svg_opacity(color));
229 } 302 }
230 } 303 }
231 } 304 }
232 } 305 }
233 306
234 return id; 307 return id;
235 } 308 }
236 309
310 void SkSVGDevice::AutoElement::addFontAttributes(const SkPaint& paint) {
311 this->addAttribute("font-size", paint.getTextSize());
312
313 SkTypeface::Style style = paint.getTypeface()->style();
314 if (style & SkTypeface::kItalic) {
315 this->addAttribute("font-style", "italic");
316 }
317 if (style & SkTypeface::kBold) {
318 this->addAttribute("font-weight", "bold");
319 }
320
321 SkAutoTUnref<const SkTypeface> tface(paint.getTypeface() ?
322 SkRef(paint.getTypeface()) : SkTypeface::RefDefault(style));
323 SkString familyName;
324 tface->getFamilyName(&familyName);
325 if (!familyName.isEmpty()) {
326 this->addAttribute("font-family", familyName);
327 }
328 }
329
237 SkBaseDevice* SkSVGDevice::Create(const SkISize& size, SkWStream* wstream) { 330 SkBaseDevice* SkSVGDevice::Create(const SkISize& size, SkWStream* wstream) {
238 if (!SkToBool(wstream)) { 331 if (!SkToBool(wstream)) {
239 return NULL; 332 return NULL;
240 } 333 }
241 334
242 return SkNEW_ARGS(SkSVGDevice, (size, wstream)); 335 return SkNEW_ARGS(SkSVGDevice, (size, wstream));
243 } 336 }
244 337
245 SkSVGDevice::SkSVGDevice(const SkISize& size, SkWStream* wstream) 338 SkSVGDevice::SkSVGDevice(const SkISize& size, SkWStream* wstream)
246 : fWriter(SkNEW_ARGS(SkXMLStreamWriter, (wstream))) 339 : fWriter(SkNEW_ARGS(SkXMLStreamWriter, (wstream)))
(...skipping 27 matching lines...) Expand all
274 AutoElement rect("rect", fWriter, fResourceBucket, draw, paint); 367 AutoElement rect("rect", fWriter, fResourceBucket, draw, paint);
275 rect.addAttribute("x", 0); 368 rect.addAttribute("x", 0);
276 rect.addAttribute("y", 0); 369 rect.addAttribute("y", 0);
277 rect.addAttribute("width", this->width()); 370 rect.addAttribute("width", this->width());
278 rect.addAttribute("height", this->height()); 371 rect.addAttribute("height", this->height());
279 } 372 }
280 373
281 void SkSVGDevice::drawPoints(const SkDraw&, SkCanvas::PointMode mode, size_t cou nt, 374 void SkSVGDevice::drawPoints(const SkDraw&, SkCanvas::PointMode mode, size_t cou nt,
282 const SkPoint[], const SkPaint& paint) { 375 const SkPoint[], const SkPaint& paint) {
283 // todo 376 // todo
284 SkDebugf("unsupported operation: drawPoints()"); 377 SkDebugf("unsupported operation: drawPoints()\n");
285 } 378 }
286 379
287 void SkSVGDevice::drawRect(const SkDraw& draw, const SkRect& r, const SkPaint& p aint) { 380 void SkSVGDevice::drawRect(const SkDraw& draw, const SkRect& r, const SkPaint& p aint) {
288 AutoElement rect("rect", fWriter, fResourceBucket, draw, paint); 381 AutoElement rect("rect", fWriter, fResourceBucket, draw, paint);
289 rect.addAttribute("x", r.fLeft); 382 rect.addAttribute("x", r.fLeft);
290 rect.addAttribute("y", r.fTop); 383 rect.addAttribute("y", r.fTop);
291 rect.addAttribute("width", r.width()); 384 rect.addAttribute("width", r.width());
292 rect.addAttribute("height", r.height()); 385 rect.addAttribute("height", r.height());
293 } 386 }
294 387
295 void SkSVGDevice::drawOval(const SkDraw& draw, const SkRect& oval, const SkPaint & paint) { 388 void SkSVGDevice::drawOval(const SkDraw& draw, const SkRect& oval, const SkPaint & paint) {
296 AutoElement ellipse("ellipse", fWriter, fResourceBucket, draw, paint); 389 AutoElement ellipse("ellipse", fWriter, fResourceBucket, draw, paint);
297 ellipse.addAttribute("cx", oval.centerX()); 390 ellipse.addAttribute("cx", oval.centerX());
298 ellipse.addAttribute("cy", oval.centerY()); 391 ellipse.addAttribute("cy", oval.centerY());
299 ellipse.addAttribute("rx", oval.width() / 2); 392 ellipse.addAttribute("rx", oval.width() / 2);
300 ellipse.addAttribute("ry", oval.height() / 2); 393 ellipse.addAttribute("ry", oval.height() / 2);
301 } 394 }
302 395
303 void SkSVGDevice::drawRRect(const SkDraw&, const SkRRect& rr, const SkPaint& pai nt) { 396 void SkSVGDevice::drawRRect(const SkDraw&, const SkRRect& rr, const SkPaint& pai nt) {
304 // todo 397 // todo
305 SkDebugf("unsupported operation: drawRRect()"); 398 SkDebugf("unsupported operation: drawRRect()\n");
306 } 399 }
307 400
308 void SkSVGDevice::drawPath(const SkDraw& draw, const SkPath& path, const SkPaint & paint, 401 void SkSVGDevice::drawPath(const SkDraw& draw, const SkPath& path, const SkPaint & paint,
309 const SkMatrix* prePathMatrix, bool pathIsMutable) { 402 const SkMatrix* prePathMatrix, bool pathIsMutable) {
310 AutoElement elem("path", fWriter, fResourceBucket, draw, paint); 403 AutoElement elem("path", fWriter, fResourceBucket, draw, paint);
311 404
312 SkString pathStr; 405 SkString pathStr;
313 SkParsePath::ToSVGString(path, &pathStr); 406 SkParsePath::ToSVGString(path, &pathStr);
314 elem.addAttribute("d", pathStr.c_str()); 407 elem.addAttribute("d", pathStr.c_str());
315 } 408 }
316 409
317 void SkSVGDevice::drawBitmap(const SkDraw&, const SkBitmap& bitmap, 410 void SkSVGDevice::drawBitmap(const SkDraw&, const SkBitmap& bitmap,
318 const SkMatrix& matrix, const SkPaint& paint) { 411 const SkMatrix& matrix, const SkPaint& paint) {
319 // todo 412 // todo
320 SkDebugf("unsupported operation: drawBitmap()"); 413 SkDebugf("unsupported operation: drawBitmap()\n");
321 } 414 }
322 415
323 void SkSVGDevice::drawSprite(const SkDraw&, const SkBitmap& bitmap, 416 void SkSVGDevice::drawSprite(const SkDraw&, const SkBitmap& bitmap,
324 int x, int y, const SkPaint& paint) { 417 int x, int y, const SkPaint& paint) {
325 // todo 418 // todo
326 SkDebugf("unsupported operation: drawSprite()"); 419 SkDebugf("unsupported operation: drawSprite()\n");
327 } 420 }
328 421
329 void SkSVGDevice::drawBitmapRect(const SkDraw&, const SkBitmap&, const SkRect* s rcOrNull, 422 void SkSVGDevice::drawBitmapRect(const SkDraw&, const SkBitmap&, const SkRect* s rcOrNull,
330 const SkRect& dst, const SkPaint& paint, 423 const SkRect& dst, const SkPaint& paint,
331 SkCanvas::DrawBitmapRectFlags flags) { 424 SkCanvas::DrawBitmapRectFlags flags) {
332 // todo 425 // todo
333 SkDebugf("unsupported operation: drawBitmapRect()"); 426 SkDebugf("unsupported operation: drawBitmapRect()\n");
334 } 427 }
335 428
336 void SkSVGDevice::drawText(const SkDraw&, const void* text, size_t len, 429 void SkSVGDevice::drawText(const SkDraw& draw, const void* text, size_t len,
337 SkScalar x, SkScalar y, const SkPaint& paint) { 430 SkScalar x, SkScalar y, const SkPaint& paint) {
338 // todo 431 AutoElement elem("text", fWriter, fResourceBucket, draw, paint);
339 SkDebugf("unsupported operation: drawText()"); 432 elem.addFontAttributes(paint);
433 elem.addAttribute("x", x);
434 elem.addAttribute("y", y);
435 elem.addText(svg_text(text, len, paint));
340 } 436 }
341 437
342 void SkSVGDevice::drawPosText(const SkDraw&, const void* text, size_t len,const SkScalar pos[], 438 void SkSVGDevice::drawPosText(const SkDraw& draw, const void* text, size_t len,
343 int scalarsPerPos, const SkPoint& offset, const Sk Paint& paint) { 439 const SkScalar pos[], int scalarsPerPos, const SkP oint& offset,
344 // todo 440 const SkPaint& paint) {
345 SkDebugf("unsupported operation: drawPosText()"); 441 AutoElement elem("text", fWriter, fResourceBucket, draw, paint);
442 elem.addFontAttributes(paint);
443
444 SkString xStr;
445 SkString yStr;
446 for (int i = 0; i < paint.countText(text, len); ++i) {
447 xStr.appendf("%.8g, ", offset.x() + pos[i * scalarsPerPos]);
448
449 if (scalarsPerPos == 2) {
450 yStr.appendf("%.8g, ", offset.y() + pos[i * scalarsPerPos + 1]);
451 }
452 }
453
mtklein 2015/02/03 23:56:08 SkASSERT(scalarsPerPos == 1 || scalarsPerPos == 2)
f(malita) 2015/02/04 00:46:13 Done.
454 if (scalarsPerPos != 2) {
455 yStr.appendScalar(offset.y());
456 }
457
458 elem.addAttribute("x", xStr);
459 elem.addAttribute("y", yStr);
460 elem.addText(svg_text(text, len, paint));
346 } 461 }
347 462
348 void SkSVGDevice::drawTextOnPath(const SkDraw&, const void* text, size_t len, co nst SkPath& path, 463 void SkSVGDevice::drawTextOnPath(const SkDraw&, const void* text, size_t len, co nst SkPath& path,
349 const SkMatrix* matrix, const SkPaint& paint) { 464 const SkMatrix* matrix, const SkPaint& paint) {
350 // todo 465 // todo
351 SkDebugf("unsupported operation: drawTextOnPath()"); 466 SkDebugf("unsupported operation: drawTextOnPath()\n");
352 } 467 }
353 468
354 void SkSVGDevice::drawVertices(const SkDraw&, SkCanvas::VertexMode, int vertexCo unt, 469 void SkSVGDevice::drawVertices(const SkDraw&, SkCanvas::VertexMode, int vertexCo unt,
355 const SkPoint verts[], const SkPoint texs[], 470 const SkPoint verts[], const SkPoint texs[],
356 const SkColor colors[], SkXfermode* xmode, 471 const SkColor colors[], SkXfermode* xmode,
357 const uint16_t indices[], int indexCount, 472 const uint16_t indices[], int indexCount,
358 const SkPaint& paint) { 473 const SkPaint& paint) {
359 // todo 474 // todo
360 SkDebugf("unsupported operation: drawVertices()"); 475 SkDebugf("unsupported operation: drawVertices()\n");
361 } 476 }
362 477
363 void SkSVGDevice::drawDevice(const SkDraw&, SkBaseDevice*, int x, int y, 478 void SkSVGDevice::drawDevice(const SkDraw&, SkBaseDevice*, int x, int y,
364 const SkPaint&) { 479 const SkPaint&) {
365 // todo 480 // todo
366 SkDebugf("unsupported operation: drawDevice()"); 481 SkDebugf("unsupported operation: drawDevice()\n");
367 } 482 }
OLDNEW
« no previous file with comments | « no previous file | include/xml/SkXMLWriter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698