SkDrawPaint.cpp revision ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976e
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
18enum SkPaint_Functions {
19    SK_FUNCTION(measureText)
20};
21
22enum 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
29const 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
37const 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
67DEFINE_GET_MEMBER(SkDrawPaint);
68
69SkDrawPaint::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
80SkDrawPaint::~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
93bool 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
101SkDisplayable* 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
113bool SkDrawPaint::draw(SkAnimateMaker& maker) {
114    SkPaint* paint = maker.fPaint;
115    setupPaint(paint);
116    return false;
117}
118
119#ifdef SK_DUMP_ENABLED
120void 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
150void 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
174const SkFunctionParamType* SkDrawPaint::getFunctionsParameters() {
175    return fFunctionParameters;
176}
177
178bool 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
199bool 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
215void 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->setFilterBitmap(SkToBool(filterBitmap));
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 != (SkPaint::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 != (SkPaint::Cap) -1)
246        paint->setStrokeCap((SkPaint::Cap) strokeCap);
247    if (strokeJoin != (SkPaint::Join) -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 != (SkPaint::Align) -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 != (SkXfermode::Mode) -1)
268        paint->setXfermodeMode((SkXfermode::Mode) xfermode);
269}
270