blob: bbcca18f398a59f4ce49f47818cfc29364bf2a97 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
2/*
3 * Copyright 2006 The Android Open Source Project
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
reed@android.com8a1c16f2008-12-17 15:59:43 +00009
10#include "SkSVGGradient.h"
11#include "SkSVGParser.h"
12#include "SkSVGStop.h"
13
14SkSVGGradient::SkSVGGradient() {
15}
16
17SkSVGElement* SkSVGGradient::getGradient() {
18 return this;
19}
20
21bool SkSVGGradient::isDef() {
22 return true;
23}
24
25bool SkSVGGradient::isNotDef() {
26 return false;
27}
28
29void SkSVGGradient::translate(SkSVGParser& parser, bool defState) {
30 INHERITED::translate(parser, defState);
31 // !!! no support for 'objectBoundingBox' yet
32 bool first = true;
33 bool addedFirst = false;
34 bool addedLast = false;
35 SkString offsets("[");
36 SkString* lastOffset = NULL;
37 for (SkSVGElement** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) {
38 SkASSERT((*ptr)->getType() == SkSVGType_Stop);
39 SkSVGStop* stop = (SkSVGStop*) *ptr;
40 if (first && stop->f_offset.equals("0") == false) {
41 addedFirst = true;
42 offsets.append("0,");
43 }
44 SkString* thisOffset = &stop->f_offset;
45 if (lastOffset && thisOffset->equals(*lastOffset)) {
46 if (thisOffset->equals("1")) {
47 offsets.remove(offsets.size() - 2, 2);
48 offsets.append(".999,");
49 } else {
50 SkASSERT(0); // !!! need to write this case
51 }
52 }
53 offsets.append(*thisOffset);
54 if (ptr == fChildren.end() - 1) { // last
55 if (stop->f_offset.equals("1") == false) {
56 offsets.append(",1");
57 addedLast = true;
58 }
59 } else
60 offsets.appendUnichar(',');
61 first = false;
62 lastOffset = thisOffset;
63 }
64 offsets.appendUnichar(']');
65 parser._addAttribute("offsets", offsets);
66 if (addedFirst)
67 parser.translate(*fChildren.begin(), defState);
68 for (SkSVGElement** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++)
69 parser.translate(*ptr, defState);
70 if (addedLast)
71 parser.translate(*(fChildren.end() - 1), defState);
72}
73
74void SkSVGGradient::translateGradientUnits(SkString& units) {
75 // !!! no support for 'objectBoundingBox' yet
76 SkASSERT(strcmp(units.c_str(), "userSpaceOnUse") == 0);
77}
78
79void SkSVGGradient::write(SkSVGParser& parser, SkString& baseColor) {
80 if (baseColor.c_str()[0] != '#')
81 return;
82 SkSVGPaint* saveHead = parser.fHead;
83 parser.fHead = &fPaintState;
84 parser.fSuppressPaint = true;
85 SkString originalID(f_id);
86 f_id.set("mask"); // write out gradient named given name + color (less initial #)
rmistry@google.comd6176b02012-08-23 18:14:13 +000087 f_id.append(baseColor.c_str() + 1);
reed@android.com8a1c16f2008-12-17 15:59:43 +000088 SkString originalColors;
89 for (SkSVGElement** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) {
90 SkSVGStop* colorElement = (SkSVGStop*) *ptr;
91 SkString& color = colorElement->fPaintState.f_stopColor;
92 originalColors.append(color);
93 originalColors.appendUnichar(',');
94 SkASSERT(color.c_str()[0] == '#');
95 SkString replacement;
96 replacement.set("0x");
97 replacement.append(color.c_str() + 1, 2); // add stop colors using given color, turning existing stop color into alpha
98 SkASSERT(baseColor.c_str()[0] == '#');
99 SkASSERT(baseColor.size() == 7);
100 replacement.append(baseColor.c_str() + 1);
101 color.set(replacement);
102 }
103 translate(parser, true);
104 const char* originalPtr = originalColors.c_str(); // restore original gradient values
105 for (SkSVGElement** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) {
106 SkSVGStop* color = (SkSVGStop*) *ptr;
107 const char* originalEnd = strchr(originalPtr, ',');
108 color->fPaintState.f_stopColor.set(originalPtr, originalEnd - originalPtr);
109 originalPtr = originalEnd + 1;
110 }
111 f_id.set(originalID);
112 parser.fSuppressPaint = false;
113 parser.fHead = saveHead;
114}