|
1 |
|
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 |
|
9 |
|
10 #include "SkDrawPaint.h" |
|
11 #include "SkAnimateMaker.h" |
|
12 #include "SkDrawColor.h" |
|
13 #include "SkDrawShader.h" |
|
14 #include "SkMaskFilter.h" |
|
15 #include "SkPaintParts.h" |
|
16 #include "SkPathEffect.h" |
|
17 |
|
18 enum SkPaint_Functions { |
|
19 SK_FUNCTION(measureText) |
|
20 }; |
|
21 |
|
22 enum SkPaint_Properties { |
|
23 SK_PROPERTY(ascent), |
|
24 SK_PROPERTY(descent) |
|
25 }; |
|
26 |
|
27 // !!! in the future, this could be compiled by build-condensed-info into an array of parameters |
|
28 // with a lookup table to find the first parameter -- for now, it is iteratively searched through |
|
29 const SkFunctionParamType SkDrawPaint::fFunctionParameters[] = { |
|
30 (SkFunctionParamType) SkType_String, |
|
31 (SkFunctionParamType) 0 // terminator for parameter list (there may be multiple parameter lists) |
|
32 }; |
|
33 |
|
34 |
|
35 #if SK_USE_CONDENSED_INFO == 0 |
|
36 |
|
37 const SkMemberInfo SkDrawPaint::fInfo[] = { |
|
38 SK_MEMBER(antiAlias, Boolean), |
|
39 SK_MEMBER_PROPERTY(ascent, Float), |
|
40 SK_MEMBER(color, Color), |
|
41 SK_MEMBER_PROPERTY(descent, Float), |
|
42 SK_MEMBER(fakeBold, Boolean), |
|
43 SK_MEMBER(filterBitmap, Boolean), |
|
44 SK_MEMBER(linearText, Boolean), |
|
45 SK_MEMBER(maskFilter, MaskFilter), |
|
46 SK_MEMBER_FUNCTION(measureText, Float), |
|
47 SK_MEMBER(pathEffect, PathEffect), |
|
48 SK_MEMBER(shader, Shader), |
|
49 SK_MEMBER(strikeThru, Boolean), |
|
50 SK_MEMBER(stroke, Boolean), |
|
51 SK_MEMBER(strokeCap, Cap), |
|
52 SK_MEMBER(strokeJoin, Join), |
|
53 SK_MEMBER(strokeMiter, Float), |
|
54 SK_MEMBER(strokeWidth, Float), |
|
55 SK_MEMBER(style, Style), |
|
56 SK_MEMBER(textAlign, Align), |
|
57 SK_MEMBER(textScaleX, Float), |
|
58 SK_MEMBER(textSize, Float), |
|
59 SK_MEMBER(textSkewX, Float), |
|
60 SK_MEMBER(typeface, Typeface), |
|
61 SK_MEMBER(underline, Boolean), |
|
62 SK_MEMBER(xfermode, Xfermode) |
|
63 }; |
|
64 |
|
65 #endif |
|
66 |
|
67 DEFINE_GET_MEMBER(SkDrawPaint); |
|
68 |
|
69 SkDrawPaint::SkDrawPaint() : antiAlias(-1), color(NULL), fakeBold(-1), filterBitmap(-1), |
|
70 linearText(-1), maskFilter((SkDrawMaskFilter*) -1), pathEffect((SkDrawPathEffect*) -1), |
|
71 shader((SkDrawShader*) -1), strikeThru(-1), stroke(-1), |
|
72 strokeCap((SkPaint::Cap) -1), strokeJoin((SkPaint::Join) -1), strokeMiter(SK_ScalarNaN), |
|
73 strokeWidth(SK_ScalarNaN), style((SkPaint::Style) -1), |
|
74 textAlign((SkPaint::Align) -1), textScaleX(SK_ScalarNaN), textSize(SK_ScalarNaN), |
|
75 textSkewX(SK_ScalarNaN), typeface((SkDrawTypeface*) -1), |
|
76 underline(-1), xfermode((SkXfermode::Mode) -1), fOwnsColor(false), fOwnsMaskFilter(false), |
|
77 fOwnsPathEffect(false), fOwnsShader(false), fOwnsTypeface(false) { |
|
78 } |
|
79 |
|
80 SkDrawPaint::~SkDrawPaint() { |
|
81 if (fOwnsColor) |
|
82 delete color; |
|
83 if (fOwnsMaskFilter) |
|
84 delete maskFilter; |
|
85 if (fOwnsPathEffect) |
|
86 delete pathEffect; |
|
87 if (fOwnsShader) |
|
88 delete shader; |
|
89 if (fOwnsTypeface) |
|
90 delete typeface; |
|
91 } |
|
92 |
|
93 bool SkDrawPaint::add(SkAnimateMaker* maker, SkDisplayable* child) { |
|
94 SkASSERT(child && child->isPaintPart()); |
|
95 SkPaintPart* part = (SkPaintPart*) child; |
|
96 if (part->add() && maker) |
|
97 maker->setErrorCode(SkDisplayXMLParserError::kErrorAddingToPaint); |
|
98 return true; |
|
99 } |
|
100 |
|
101 SkDisplayable* SkDrawPaint::deepCopy(SkAnimateMaker* maker) { |
|
102 SkDrawColor* tempColor = color; |
|
103 color = NULL; |
|
104 SkDrawPaint* copy = (SkDrawPaint*) INHERITED::deepCopy(maker); |
|
105 color = tempColor; |
|
106 tempColor = (SkDrawColor*) color->deepCopy(maker); |
|
107 tempColor->setParent(copy); |
|
108 tempColor->add(); |
|
109 copy->fOwnsColor = true; |
|
110 return copy; |
|
111 } |
|
112 |
|
113 bool SkDrawPaint::draw(SkAnimateMaker& maker) { |
|
114 SkPaint* paint = maker.fPaint; |
|
115 setupPaint(paint); |
|
116 return false; |
|
117 } |
|
118 |
|
119 #ifdef SK_DUMP_ENABLED |
|
120 void SkDrawPaint::dump(SkAnimateMaker* maker) { |
|
121 dumpBase(maker); |
|
122 dumpAttrs(maker); |
|
123 bool closedYet = false; |
|
124 SkDisplayList::fIndent +=4; |
|
125 //should i say if (maskFilter && ...? |
|
126 if (maskFilter != (SkDrawMaskFilter*)-1) { |
|
127 SkDebugf(">\n"); |
|
128 maskFilter->dump(maker); |
|
129 closedYet = true; |
|
130 } |
|
131 if (pathEffect != (SkDrawPathEffect*) -1) { |
|
132 if (closedYet == false) { |
|
133 SkDebugf(">\n"); |
|
134 closedYet = true; |
|
135 } |
|
136 pathEffect->dump(maker); |
|
137 } |
|
138 if (fOwnsTypeface) { |
|
139 if (closedYet == false) { |
|
140 SkDebugf(">\n"); |
|
141 closedYet = true; |
|
142 } |
|
143 typeface->dump(maker); |
|
144 } |
|
145 SkDisplayList::fIndent -= 4; |
|
146 dumpChildren(maker, closedYet); |
|
147 } |
|
148 #endif |
|
149 |
|
150 void SkDrawPaint::executeFunction(SkDisplayable* target, int index, |
|
151 SkTDArray<SkScriptValue>& parameters, SkDisplayTypes type, |
|
152 SkScriptValue* scriptValue) { |
|
153 if (scriptValue == NULL) |
|
154 return; |
|
155 SkASSERT(target == this); |
|
156 switch (index) { |
|
157 case SK_FUNCTION(measureText): { |
|
158 SkASSERT(parameters.count() == 1); |
|
159 SkASSERT(type == SkType_Float); |
|
160 SkPaint paint; |
|
161 setupPaint(&paint); |
|
162 scriptValue->fType = SkType_Float; |
|
163 SkASSERT(parameters[0].fType == SkType_String); |
|
164 scriptValue->fOperand.fScalar = paint.measureText(parameters[0].fOperand.fString->c_str(), |
|
165 parameters[0].fOperand.fString->size()); |
|
166 // SkDebugf("measureText: %s = %g\n", parameters[0].fOperand.fString->c_str(), |
|
167 // scriptValue->fOperand.fScalar / 65536.0f); |
|
168 } break; |
|
169 default: |
|
170 SkASSERT(0); |
|
171 } |
|
172 } |
|
173 |
|
174 const SkFunctionParamType* SkDrawPaint::getFunctionsParameters() { |
|
175 return fFunctionParameters; |
|
176 } |
|
177 |
|
178 bool SkDrawPaint::getProperty(int index, SkScriptValue* value) const { |
|
179 SkPaint::FontMetrics metrics; |
|
180 SkPaint paint; |
|
181 setupPaint(&paint); |
|
182 paint.getFontMetrics(&metrics); |
|
183 switch (index) { |
|
184 case SK_PROPERTY(ascent): |
|
185 value->fOperand.fScalar = metrics.fAscent; |
|
186 break; |
|
187 case SK_PROPERTY(descent): |
|
188 value->fOperand.fScalar = metrics.fDescent; |
|
189 break; |
|
190 // should consider returning fLeading as well (or roll it into ascent/descent somehow |
|
191 default: |
|
192 SkASSERT(0); |
|
193 return false; |
|
194 } |
|
195 value->fType = SkType_Float; |
|
196 return true; |
|
197 } |
|
198 |
|
199 bool SkDrawPaint::resolveIDs(SkAnimateMaker& maker, SkDisplayable* origDisp, SkApply* ) { |
|
200 SkASSERT(origDisp->isPaint()); |
|
201 SkDrawPaint* original = (SkDrawPaint*) origDisp; |
|
202 if (fOwnsColor && maker.resolveID(color, original->color) == false) |
|
203 return true; |
|
204 if (fOwnsMaskFilter && maker.resolveID(maskFilter, original->maskFilter) == false) |
|
205 return true; |
|
206 if (fOwnsPathEffect && maker.resolveID(pathEffect, original->pathEffect) == false) |
|
207 return true; |
|
208 if (fOwnsShader && maker.resolveID(shader, original->shader) == false) |
|
209 return true; |
|
210 if (fOwnsTypeface && maker.resolveID(typeface, original->typeface) == false) |
|
211 return true; |
|
212 return false; // succeeded |
|
213 } |
|
214 |
|
215 void SkDrawPaint::setupPaint(SkPaint* paint) const { |
|
216 if (antiAlias != -1) |
|
217 paint->setAntiAlias(SkToBool(antiAlias)); |
|
218 if (color != NULL) |
|
219 paint->setColor(color->getColor()); |
|
220 if (fakeBold != -1) |
|
221 paint->setFakeBoldText(SkToBool(fakeBold)); |
|
222 if (filterBitmap != -1) |
|
223 paint->setFilterLevel(filterBitmap ? SkPaint::kLow_FilterLevel : SkPaint::kNone_FilterLevel); |
|
224 // stroke is legacy; style setting if present overrides stroke |
|
225 if (stroke != -1) |
|
226 paint->setStyle(SkToBool(stroke) ? SkPaint::kStroke_Style : SkPaint::kFill_Style); |
|
227 if (style != -1) |
|
228 paint->setStyle((SkPaint::Style) style); |
|
229 if (linearText != -1) |
|
230 paint->setLinearText(SkToBool(linearText)); |
|
231 if (maskFilter == NULL) |
|
232 paint->setMaskFilter(NULL); |
|
233 else if (maskFilter != (SkDrawMaskFilter*) -1) |
|
234 SkSafeUnref(paint->setMaskFilter(maskFilter->getMaskFilter())); |
|
235 if (pathEffect == NULL) |
|
236 paint->setPathEffect(NULL); |
|
237 else if (pathEffect != (SkDrawPathEffect*) -1) |
|
238 SkSafeUnref(paint->setPathEffect(pathEffect->getPathEffect())); |
|
239 if (shader == NULL) |
|
240 paint->setShader(NULL); |
|
241 else if (shader != (SkDrawShader*) -1) |
|
242 SkSafeUnref(paint->setShader(shader->getShader())); |
|
243 if (strikeThru != -1) |
|
244 paint->setStrikeThruText(SkToBool(strikeThru)); |
|
245 if (strokeCap != -1) |
|
246 paint->setStrokeCap((SkPaint::Cap) strokeCap); |
|
247 if (strokeJoin != -1) |
|
248 paint->setStrokeJoin((SkPaint::Join) strokeJoin); |
|
249 if (SkScalarIsNaN(strokeMiter) == false) |
|
250 paint->setStrokeMiter(strokeMiter); |
|
251 if (SkScalarIsNaN(strokeWidth) == false) |
|
252 paint->setStrokeWidth(strokeWidth); |
|
253 if (textAlign != -1) |
|
254 paint->setTextAlign((SkPaint::Align) textAlign); |
|
255 if (SkScalarIsNaN(textScaleX) == false) |
|
256 paint->setTextScaleX(textScaleX); |
|
257 if (SkScalarIsNaN(textSize) == false) |
|
258 paint->setTextSize(textSize); |
|
259 if (SkScalarIsNaN(textSkewX) == false) |
|
260 paint->setTextSkewX(textSkewX); |
|
261 if (typeface == NULL) |
|
262 paint->setTypeface(NULL); |
|
263 else if (typeface != (SkDrawTypeface*) -1) |
|
264 SkSafeUnref(paint->setTypeface(typeface->getTypeface())); |
|
265 if (underline != -1) |
|
266 paint->setUnderlineText(SkToBool(underline)); |
|
267 if (xfermode != -1) |
|
268 paint->setXfermodeMode((SkXfermode::Mode) xfermode); |
|
269 } |