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