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 } 270