blob: 70e5e4493e0e5f3560bff5e56697e443b77f2c0d [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 "SkDrawGradient.h"
11#include "SkAnimateMaker.h"
12#include "SkAnimatorScript.h"
13#include "SkGradientShader.h"
reed@android.com8a1c16f2008-12-17 15:59:43 +000014
15#if SK_USE_CONDENSED_INFO == 0
16
rileya@google.com99547762012-07-26 21:25:09 +000017const SkMemberInfo SkDrawGradient::fInfo[] = {
reed@android.com8a1c16f2008-12-17 15:59:43 +000018 SK_MEMBER_INHERITED,
19 SK_MEMBER_ARRAY(offsets, Float),
20 SK_MEMBER(unitMapper, String)
21};
22
23#endif
24
rileya@google.com99547762012-07-26 21:25:09 +000025DEFINE_GET_MEMBER(SkDrawGradient);
reed@android.com8a1c16f2008-12-17 15:59:43 +000026
commit-bot@chromium.org83f23d82014-05-22 12:27:41 +000027SkDrawGradient::SkDrawGradient() {
reed@android.com8a1c16f2008-12-17 15:59:43 +000028}
29
rileya@google.com99547762012-07-26 21:25:09 +000030SkDrawGradient::~SkDrawGradient() {
rmistry@google.comd6176b02012-08-23 18:14:13 +000031 for (int index = 0; index < fDrawColors.count(); index++)
reed@android.com8a1c16f2008-12-17 15:59:43 +000032 delete fDrawColors[index];
reed@android.com8a1c16f2008-12-17 15:59:43 +000033}
34
tfarina@chromium.org1d3c4112012-12-03 14:38:08 +000035bool SkDrawGradient::addChild(SkAnimateMaker& , SkDisplayable* child) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000036 SkASSERT(child);
37 if (child->isColor()) {
38 SkDrawColor* color = (SkDrawColor*) child;
39 *fDrawColors.append() = color;
40 return true;
41 }
42 return false;
43}
44
rileya@google.com99547762012-07-26 21:25:09 +000045int SkDrawGradient::addPrelude() {
reed@android.com8a1c16f2008-12-17 15:59:43 +000046 int count = fDrawColors.count();
47 fColors.setCount(count);
rmistry@google.comd6176b02012-08-23 18:14:13 +000048 for (int index = 0; index < count; index++)
reed@android.com8a1c16f2008-12-17 15:59:43 +000049 fColors[index] = fDrawColors[index]->color;
50 return count;
51}
52
53#ifdef SK_DUMP_ENABLED
rileya@google.com99547762012-07-26 21:25:09 +000054void SkDrawGradient::dumpRest(SkAnimateMaker* maker) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000055 dumpAttrs(maker);
56 //can a gradient have no colors?
57 bool closedYet = false;
58 SkDisplayList::fIndent += 4;
59 for (SkDrawColor** ptr = fDrawColors.begin(); ptr < fDrawColors.end(); ptr++) {
60 if (closedYet == false) {
61 SkDebugf(">\n");
62 closedYet = true;
63 }
64 SkDrawColor* color = *ptr;
65 color->dump(maker);
66 }
rmistry@google.comd6176b02012-08-23 18:14:13 +000067 SkDisplayList::fIndent -= 4;
reed@android.com8a1c16f2008-12-17 15:59:43 +000068 dumpChildren(maker, closedYet); //dumps the matrix if it has one
69}
70#endif
71
rileya@google.com99547762012-07-26 21:25:09 +000072void SkDrawGradient::onEndElement(SkAnimateMaker& maker) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000073 if (offsets.count() != 0) {
74 if (offsets.count() != fDrawColors.count()) {
75 maker.setErrorCode(SkDisplayXMLParserError::kGradientOffsetsDontMatchColors);
76 return;
77 }
78 if (offsets[0] != 0) {
79 maker.setErrorCode(SkDisplayXMLParserError::kGradientOffsetsMustStartWithZero);
80 return;
81 }
82 if (offsets[offsets.count()-1] != SK_Scalar1) {
83 maker.setErrorCode(SkDisplayXMLParserError::kGradientOffsetsMustEndWithOne);
84 return;
85 }
86 for (int i = 1; i < offsets.count(); i++) {
87 if (offsets[i] <= offsets[i-1]) {
88 maker.setErrorCode(SkDisplayXMLParserError::kGradientOffsetsMustIncrease);
89 return;
90 }
91 if (offsets[i] > SK_Scalar1) {
92 maker.setErrorCode(SkDisplayXMLParserError::kGradientOffsetsMustBeNoMoreThanOne);
93 return;
94 }
95 }
96 }
reed@android.com8a1c16f2008-12-17 15:59:43 +000097 INHERITED::onEndElement(maker);
98}
99
100#if SK_USE_CONDENSED_INFO == 0
101
rileya@google.com99547762012-07-26 21:25:09 +0000102const SkMemberInfo SkDrawLinearGradient::fInfo[] = {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000103 SK_MEMBER_INHERITED,
104 SK_MEMBER_ARRAY(points, Float),
105};
106
107#endif
108
rileya@google.com99547762012-07-26 21:25:09 +0000109DEFINE_GET_MEMBER(SkDrawLinearGradient);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000110
rmistry@google.comd6176b02012-08-23 18:14:13 +0000111SkDrawLinearGradient::SkDrawLinearGradient() {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000112}
113
rileya@google.com99547762012-07-26 21:25:09 +0000114void SkDrawLinearGradient::onEndElement(SkAnimateMaker& maker)
reed@android.com8a1c16f2008-12-17 15:59:43 +0000115{
116 if (points.count() != 4)
117 maker.setErrorCode(SkDisplayXMLParserError::kGradientPointsLengthMustBeFour);
118 INHERITED::onEndElement(maker);
119}
120
121#ifdef SK_DUMP_ENABLED
rileya@google.com99547762012-07-26 21:25:09 +0000122void SkDrawLinearGradient::dump(SkAnimateMaker* maker) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000123 dumpBase(maker);
124 dumpRest(maker);
125 }
126#endif
127
rileya@google.com99547762012-07-26 21:25:09 +0000128SkShader* SkDrawLinearGradient::getShader() {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000129 if (addPrelude() == 0 || points.count() != 4)
130 return NULL;
131 SkShader* shader = SkGradientShader::CreateLinear((SkPoint*)points.begin(),
commit-bot@chromium.org9c9005a2014-04-28 14:55:39 +0000132 fColors.begin(), offsets.begin(), fColors.count(), (SkShader::TileMode) tileMode,
commit-bot@chromium.org83f23d82014-05-22 12:27:41 +0000133 0, getMatrix());
reed@android.com8a1c16f2008-12-17 15:59:43 +0000134 SkAutoTDelete<SkShader> autoDel(shader);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000135 (void)autoDel.detach();
136 return shader;
137}
138
139
140#if SK_USE_CONDENSED_INFO == 0
141
rileya@google.com99547762012-07-26 21:25:09 +0000142const SkMemberInfo SkDrawRadialGradient::fInfo[] = {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000143 SK_MEMBER_INHERITED,
144 SK_MEMBER(center, Point),
145 SK_MEMBER(radius, Float)
146};
147
148#endif
149
rileya@google.com99547762012-07-26 21:25:09 +0000150DEFINE_GET_MEMBER(SkDrawRadialGradient);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000151
rmistry@google.comd6176b02012-08-23 18:14:13 +0000152SkDrawRadialGradient::SkDrawRadialGradient() : radius(0) {
153 center.set(0, 0);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000154}
155
156#ifdef SK_DUMP_ENABLED
rileya@google.com99547762012-07-26 21:25:09 +0000157void SkDrawRadialGradient::dump(SkAnimateMaker* maker) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000158 dumpBase(maker);
159 dumpRest(maker);
160}
161#endif
162
rileya@google.com99547762012-07-26 21:25:09 +0000163SkShader* SkDrawRadialGradient::getShader() {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000164 if (addPrelude() == 0)
165 return NULL;
166 SkShader* shader = SkGradientShader::CreateRadial(center,
commit-bot@chromium.org9c9005a2014-04-28 14:55:39 +0000167 radius, fColors.begin(), offsets.begin(), fColors.count(), (SkShader::TileMode) tileMode,
commit-bot@chromium.org83f23d82014-05-22 12:27:41 +0000168 0, getMatrix());
reed@android.com8a1c16f2008-12-17 15:59:43 +0000169 SkAutoTDelete<SkShader> autoDel(shader);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000170 (void)autoDel.detach();
171 return shader;
172}