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

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: 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 | « experimental/svg/SkSVGDevice.h ('k') | 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
mtklein 2015/02/03 20:51:08 Worth asserting byteLen alignment for each of thes
f(malita) 2015/02/03 22:51:25 We can probably be even more opinionated and asser
62 switch(paint.getTextEncoding()) {
63 case SkPaint::kGlyphID_TextEncoding: {
64 SkAutoSTArray<64, SkUnichar> unichars(count);
65 paint.glyphsToUnichars((const uint16_t*)text, count, unichars.get());
66 for (int i = 0; i < count; ++i) {
67 append_escaped_unichar(unichars[i], &svgText);
68 }
69 } break;
70 case SkPaint::kUTF8_TextEncoding: {
71 const char* c8 = reinterpret_cast<const char*>(text);
72 for (int i = 0; i < count; ++i) {
73 append_escaped_unichar(SkUTF8_NextUnichar(&c8), &svgText);
74 }
75 } break;
76 case SkPaint::kUTF16_TextEncoding: {
77 const uint16_t* c16 = reinterpret_cast<const uint16_t*>(text);
78 for (int i = 0; i < count; ++i) {
79 append_escaped_unichar(SkUTF16_NextUnichar(&c16), &svgText);
80 }
81 } break;
82 case SkPaint::kUTF32_TextEncoding: {
83 const uint32_t* c32 = reinterpret_cast<const uint32_t*>(text);
84 for (int i = 0; i < count; ++i) {
85 append_escaped_unichar(c32[i], &svgText);
86 }
87 } break;
88 default:
89 SkFAIL("unknown text encoding");
90 }
91
92 return svgText;
93 }
94
33 struct Resources { 95 struct Resources {
34 Resources(const SkPaint& paint) 96 Resources(const SkPaint& paint)
35 : fPaintServer(svg_color(paint.getColor())) {} 97 : fPaintServer(svg_color(paint.getColor())) {}
36 98
37 SkString fPaintServer; 99 SkString fPaintServer;
38 }; 100 };
39 101
40 } 102 }
41 103
42 // For now all this does is serve unique serial IDs, but it will eventually evol ve to track 104 // 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 } 151 }
90 152
91 void addAttribute(const char name[], int32_t val) { 153 void addAttribute(const char name[], int32_t val) {
92 fWriter->addS32Attribute(name, val); 154 fWriter->addS32Attribute(name, val);
93 } 155 }
94 156
95 void addAttribute(const char name[], SkScalar val) { 157 void addAttribute(const char name[], SkScalar val) {
96 fWriter->addScalarAttribute(name, val); 158 fWriter->addScalarAttribute(name, val);
97 } 159 }
98 160
161 void addText(const SkString& text) {
162 fWriter->addText(text);
163 }
164
99 private: 165 private:
100 Resources addResources(const SkPaint& paint); 166 Resources addResources(const SkPaint& paint);
101 void addResourceDefs(const SkPaint& paint, Resources* resources); 167 void addResourceDefs(const SkPaint& paint, Resources* resources);
102 168
103 void addPaint(const SkPaint& paint, const Resources& resources); 169 void addPaint(const SkPaint& paint, const Resources& resources);
104 void addTransform(const SkMatrix& transform, const char name[] = "transform" ); 170 void addTransform(const SkMatrix& transform, const char name[] = "transform" );
105 171
106 SkString addLinearGradientDef(const SkShader::GradientInfo& info, const SkSh ader* shader); 172 SkString addLinearGradientDef(const SkShader::GradientInfo& info, const SkSh ader* shader);
107 173
108 SkXMLWriter* fWriter; 174 SkXMLWriter* fWriter;
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
326 SkDebugf("unsupported operation: drawSprite()"); 392 SkDebugf("unsupported operation: drawSprite()");
327 } 393 }
328 394
329 void SkSVGDevice::drawBitmapRect(const SkDraw&, const SkBitmap&, const SkRect* s rcOrNull, 395 void SkSVGDevice::drawBitmapRect(const SkDraw&, const SkBitmap&, const SkRect* s rcOrNull,
330 const SkRect& dst, const SkPaint& paint, 396 const SkRect& dst, const SkPaint& paint,
331 SkCanvas::DrawBitmapRectFlags flags) { 397 SkCanvas::DrawBitmapRectFlags flags) {
332 // todo 398 // todo
333 SkDebugf("unsupported operation: drawBitmapRect()"); 399 SkDebugf("unsupported operation: drawBitmapRect()");
334 } 400 }
335 401
336 void SkSVGDevice::drawText(const SkDraw&, const void* text, size_t len, 402 void SkSVGDevice::AddFontAttributes(const SkPaint& paint, AutoElement* elem) {
mtklein 2015/02/03 20:51:08 void AutoElement::addFontAttributes(const SkPaint&
f(malita) 2015/02/03 22:51:25 Done.
337 SkScalar x, SkScalar y, const SkPaint& paint) { 403 elem->addAttribute("font-size", paint.getTextSize());
338 // todo 404
339 SkDebugf("unsupported operation: drawText()"); 405 SkTypeface::Style style = paint.getTypeface()->style();
406 if (style & SkTypeface::kItalic) {
407 elem->addAttribute("font-style", "italic");
408 }
409 if (style & SkTypeface::kBold) {
410 elem->addAttribute("font-weight", "bold");
411 }
412
413 SkAutoTUnref<const SkTypeface> tface(paint.getTypeface() ?
414 SkRef(paint.getTypeface()) : SkTypeface::RefDefault(style));
415 SkString familyName;
416 tface->getFamilyName(&familyName);
417 if (!familyName.isEmpty()) {
418 elem->addAttribute("font-family", familyName);
419 }
340 } 420 }
341 421
342 void SkSVGDevice::drawPosText(const SkDraw&, const void* text, size_t len,const SkScalar pos[], 422 void SkSVGDevice::drawText(const SkDraw& draw, const void* text, size_t len,
343 int scalarsPerPos, const SkPoint& offset, const Sk Paint& paint) { 423 SkScalar x, SkScalar y, const SkPaint& paint) {
344 // todo 424 AutoElement elem("text", fWriter, fResourceBucket, draw, paint);
345 SkDebugf("unsupported operation: drawPosText()"); 425 AddFontAttributes(paint, &elem);
426 elem.addAttribute("x", x);
427 elem.addAttribute("y", y);
428 elem.addText(svg_text(text, len, paint));
429 }
430
431 void SkSVGDevice::drawPosText(const SkDraw& draw, const void* text, size_t len,
432 const SkScalar pos[], int scalarsPerPos, const SkP oint& offset,
433 const SkPaint& paint) {
434 AutoElement elem("text", fWriter, fResourceBucket, draw, paint);
435 AddFontAttributes(paint, &elem);
436
437 SkString xStr;
438 SkString yStr;
439 for (int i = 0; i < paint.countText(text, len); ++i) {
440 SkScalar x = offset.x() + pos[i * scalarsPerPos];
mtklein 2015/02/03 20:51:08 Are offset.x() and offset.y() "dx" and "dy"? If s
f(malita) 2015/02/03 22:51:25 The syntactic rules are quirky though and this wou
441 SkScalar y = offset.y() + (scalarsPerPos > 1 ? pos[i * scalarsPerPos + 1 ] : 0);
mtklein 2015/02/03 20:51:08 When scalarsPerPos == 1, can we just use a single
f(malita) 2015/02/03 22:51:25 Yeah, I think that will work. Done.
442
443 if (i > 0) {
444 xStr.append(", ");
445 yStr.append(", ");
446 }
447 xStr.appendScalar(x);
448 yStr.appendScalar(y);
449 }
450
451 elem.addAttribute("x", xStr);
452 elem.addAttribute("y", yStr);
453 elem.addText(svg_text(text, len, paint));
346 } 454 }
347 455
348 void SkSVGDevice::drawTextOnPath(const SkDraw&, const void* text, size_t len, co nst SkPath& path, 456 void SkSVGDevice::drawTextOnPath(const SkDraw&, const void* text, size_t len, co nst SkPath& path,
349 const SkMatrix* matrix, const SkPaint& paint) { 457 const SkMatrix* matrix, const SkPaint& paint) {
350 // todo 458 // todo
351 SkDebugf("unsupported operation: drawTextOnPath()"); 459 SkDebugf("unsupported operation: drawTextOnPath()");
352 } 460 }
353 461
354 void SkSVGDevice::drawVertices(const SkDraw&, SkCanvas::VertexMode, int vertexCo unt, 462 void SkSVGDevice::drawVertices(const SkDraw&, SkCanvas::VertexMode, int vertexCo unt,
355 const SkPoint verts[], const SkPoint texs[], 463 const SkPoint verts[], const SkPoint texs[],
356 const SkColor colors[], SkXfermode* xmode, 464 const SkColor colors[], SkXfermode* xmode,
357 const uint16_t indices[], int indexCount, 465 const uint16_t indices[], int indexCount,
358 const SkPaint& paint) { 466 const SkPaint& paint) {
359 // todo 467 // todo
360 SkDebugf("unsupported operation: drawVertices()"); 468 SkDebugf("unsupported operation: drawVertices()");
361 } 469 }
362 470
363 void SkSVGDevice::drawDevice(const SkDraw&, SkBaseDevice*, int x, int y, 471 void SkSVGDevice::drawDevice(const SkDraw&, SkBaseDevice*, int x, int y,
364 const SkPaint&) { 472 const SkPaint&) {
365 // todo 473 // todo
366 SkDebugf("unsupported operation: drawDevice()"); 474 SkDebugf("unsupported operation: drawDevice()");
367 } 475 }
OLDNEW
« no previous file with comments | « experimental/svg/SkSVGDevice.h ('k') | include/xml/SkXMLWriter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698