| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2006 The Android Open Source Project | 2 * Copyright 2006 The Android Open Source Project |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "SkPaint.h" | 8 #include "SkPaint.h" |
| 9 #include "SkAnnotation.h" | 9 #include "SkAnnotation.h" |
| 10 #include "SkAutoKern.h" | 10 #include "SkAutoKern.h" |
| (...skipping 16 matching lines...) Expand all Loading... |
| 27 #include "SkScalerContext.h" | 27 #include "SkScalerContext.h" |
| 28 #include "SkShader.h" | 28 #include "SkShader.h" |
| 29 #include "SkStringUtils.h" | 29 #include "SkStringUtils.h" |
| 30 #include "SkStroke.h" | 30 #include "SkStroke.h" |
| 31 #include "SkTextFormatParams.h" | 31 #include "SkTextFormatParams.h" |
| 32 #include "SkTextToPathIter.h" | 32 #include "SkTextToPathIter.h" |
| 33 #include "SkTLazy.h" | 33 #include "SkTLazy.h" |
| 34 #include "SkTypeface.h" | 34 #include "SkTypeface.h" |
| 35 #include "SkXfermode.h" | 35 #include "SkXfermode.h" |
| 36 | 36 |
| 37 enum { | |
| 38 kColor_DirtyBit = 1 << 0, | |
| 39 kTextSize_DirtyBit = 1 << 1, | |
| 40 kTextScaleX_DirtyBit = 1 << 2, | |
| 41 kTextSkewX_DirtyBit = 1 << 3, | |
| 42 kStrokeWidth_DirtyBit = 1 << 4, | |
| 43 kStrokeMiter_DirtyBit = 1 << 5, | |
| 44 | |
| 45 kPOD_DirtyBitMask = 63, | |
| 46 | |
| 47 kPathEffect_DirtyBit = 1 << 6, | |
| 48 kShader_DirtyBit = 1 << 7, | |
| 49 kXfermode_DirtyBit = 1 << 8, | |
| 50 kMaskFilter_DirtyBit = 1 << 9, | |
| 51 kColorFilter_DirtyBit = 1 << 10, | |
| 52 kRasterizer_DirtyBit = 1 << 11, | |
| 53 kLooper_DirtyBit = 1 << 12, | |
| 54 kImageFilter_DirtyBit = 1 << 13, | |
| 55 kTypeface_DirtyBit = 1 << 14, | |
| 56 kAnnotation_DirtyBit = 1 << 15, | |
| 57 }; | |
| 58 | |
| 59 // define this to get a printf for out-of-range parameter in setters | 37 // define this to get a printf for out-of-range parameter in setters |
| 60 // e.g. setTextSize(-1) | 38 // e.g. setTextSize(-1) |
| 61 //#define SK_REPORT_API_RANGE_CHECK | 39 //#define SK_REPORT_API_RANGE_CHECK |
| 62 | 40 |
| 63 #ifdef SK_BUILD_FOR_ANDROID | 41 #ifdef SK_BUILD_FOR_ANDROID |
| 64 #define GEN_ID_INC fGenerationID++ | 42 #define GEN_ID_INC fGenerationID++ |
| 65 #define GEN_ID_INC_EVAL(expression) if (expression) { fGenerationID++; } | 43 #define GEN_ID_INC_EVAL(expression) if (expression) { fGenerationID++; } |
| 66 #else | 44 #else |
| 67 #define GEN_ID_INC | 45 #define GEN_ID_INC |
| 68 #define GEN_ID_INC_EVAL(expression) | 46 #define GEN_ID_INC_EVAL(expression) |
| (...skipping 21 matching lines...) Expand all Loading... |
| 90 // Zero all bitfields, then set some non-zero defaults. | 68 // Zero all bitfields, then set some non-zero defaults. |
| 91 fBitfieldsUInt = 0; | 69 fBitfieldsUInt = 0; |
| 92 fBitfields.fFlags = SkPaintDefaults_Flags; | 70 fBitfields.fFlags = SkPaintDefaults_Flags; |
| 93 fBitfields.fCapType = kDefault_Cap; | 71 fBitfields.fCapType = kDefault_Cap; |
| 94 fBitfields.fJoinType = kDefault_Join; | 72 fBitfields.fJoinType = kDefault_Join; |
| 95 fBitfields.fTextAlign = kLeft_Align; | 73 fBitfields.fTextAlign = kLeft_Align; |
| 96 fBitfields.fStyle = kFill_Style; | 74 fBitfields.fStyle = kFill_Style; |
| 97 fBitfields.fTextEncoding = kUTF8_TextEncoding; | 75 fBitfields.fTextEncoding = kUTF8_TextEncoding; |
| 98 fBitfields.fHinting = SkPaintDefaults_Hinting; | 76 fBitfields.fHinting = SkPaintDefaults_Hinting; |
| 99 | 77 |
| 100 fDirtyBits = 0; | |
| 101 #ifdef SK_BUILD_FOR_ANDROID | 78 #ifdef SK_BUILD_FOR_ANDROID |
| 102 fGenerationID = 0; | 79 fGenerationID = 0; |
| 103 #endif | 80 #endif |
| 104 } | 81 } |
| 105 | 82 |
| 106 SkPaint::SkPaint(const SkPaint& src) { | 83 SkPaint::SkPaint(const SkPaint& src) { |
| 107 #define COPY(field) field = src.field | 84 #define COPY(field) field = src.field |
| 108 #define REF_COPY(field) field = SkSafeRef(src.field) | 85 #define REF_COPY(field) field = SkSafeRef(src.field) |
| 109 | 86 |
| 110 REF_COPY(fTypeface); | 87 REF_COPY(fTypeface); |
| 111 REF_COPY(fPathEffect); | 88 REF_COPY(fPathEffect); |
| 112 REF_COPY(fShader); | 89 REF_COPY(fShader); |
| 113 REF_COPY(fXfermode); | 90 REF_COPY(fXfermode); |
| 114 REF_COPY(fMaskFilter); | 91 REF_COPY(fMaskFilter); |
| 115 REF_COPY(fColorFilter); | 92 REF_COPY(fColorFilter); |
| 116 REF_COPY(fRasterizer); | 93 REF_COPY(fRasterizer); |
| 117 REF_COPY(fLooper); | 94 REF_COPY(fLooper); |
| 118 REF_COPY(fImageFilter); | 95 REF_COPY(fImageFilter); |
| 119 REF_COPY(fAnnotation); | 96 REF_COPY(fAnnotation); |
| 120 | 97 |
| 121 COPY(fTextSize); | 98 COPY(fTextSize); |
| 122 COPY(fTextScaleX); | 99 COPY(fTextScaleX); |
| 123 COPY(fTextSkewX); | 100 COPY(fTextSkewX); |
| 124 COPY(fColor); | 101 COPY(fColor); |
| 125 COPY(fWidth); | 102 COPY(fWidth); |
| 126 COPY(fMiterLimit); | 103 COPY(fMiterLimit); |
| 127 COPY(fBitfields); | 104 COPY(fBitfields); |
| 128 COPY(fDirtyBits); | |
| 129 | 105 |
| 130 #ifdef SK_BUILD_FOR_ANDROID | 106 #ifdef SK_BUILD_FOR_ANDROID |
| 131 COPY(fGenerationID); | 107 COPY(fGenerationID); |
| 132 #endif | 108 #endif |
| 133 | 109 |
| 134 #undef COPY | 110 #undef COPY |
| 135 #undef REF_COPY | 111 #undef REF_COPY |
| 136 } | 112 } |
| 137 | 113 |
| 138 SkPaint::~SkPaint() { | 114 SkPaint::~SkPaint() { |
| (...skipping 30 matching lines...) Expand all Loading... |
| 169 REF_COPY(fImageFilter); | 145 REF_COPY(fImageFilter); |
| 170 REF_COPY(fAnnotation); | 146 REF_COPY(fAnnotation); |
| 171 | 147 |
| 172 COPY(fTextSize); | 148 COPY(fTextSize); |
| 173 COPY(fTextScaleX); | 149 COPY(fTextScaleX); |
| 174 COPY(fTextSkewX); | 150 COPY(fTextSkewX); |
| 175 COPY(fColor); | 151 COPY(fColor); |
| 176 COPY(fWidth); | 152 COPY(fWidth); |
| 177 COPY(fMiterLimit); | 153 COPY(fMiterLimit); |
| 178 COPY(fBitfields); | 154 COPY(fBitfields); |
| 179 COPY(fDirtyBits); | |
| 180 | |
| 181 #ifdef SK_BUILD_FOR_ANDROID | 155 #ifdef SK_BUILD_FOR_ANDROID |
| 182 ++fGenerationID; | 156 ++fGenerationID; |
| 183 #endif | 157 #endif |
| 184 | 158 |
| 185 return *this; | 159 return *this; |
| 186 | 160 |
| 187 #undef COPY | 161 #undef COPY |
| 188 #undef REF_COPY | 162 #undef REF_COPY |
| 189 } | 163 } |
| 190 | 164 |
| 191 bool operator==(const SkPaint& a, const SkPaint& b) { | 165 bool operator==(const SkPaint& a, const SkPaint& b) { |
| 192 #define EQUAL(field) (a.field == b.field) | 166 #define EQUAL(field) (a.field == b.field) |
| 193 // Don't check fGenerationID, which can be different for logically equal pai
nts. | 167 // Don't check fGenerationID, which can be different for logically equal pai
nts. |
| 194 // fDirtyBits is a very quick check for non-equality, so check it first. | 168 return EQUAL(fTypeface) |
| 195 return EQUAL(fDirtyBits) | |
| 196 && EQUAL(fTypeface) | |
| 197 && EQUAL(fPathEffect) | 169 && EQUAL(fPathEffect) |
| 198 && EQUAL(fShader) | 170 && EQUAL(fShader) |
| 199 && EQUAL(fXfermode) | 171 && EQUAL(fXfermode) |
| 200 && EQUAL(fMaskFilter) | 172 && EQUAL(fMaskFilter) |
| 201 && EQUAL(fColorFilter) | 173 && EQUAL(fColorFilter) |
| 202 && EQUAL(fRasterizer) | 174 && EQUAL(fRasterizer) |
| 203 && EQUAL(fLooper) | 175 && EQUAL(fLooper) |
| 204 && EQUAL(fImageFilter) | 176 && EQUAL(fImageFilter) |
| 205 && EQUAL(fAnnotation) | 177 && EQUAL(fAnnotation) |
| 206 && EQUAL(fTextSize) | 178 && EQUAL(fTextSize) |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 310 } else { | 282 } else { |
| 311 #ifdef SK_REPORT_API_RANGE_CHECK | 283 #ifdef SK_REPORT_API_RANGE_CHECK |
| 312 SkDebugf("SkPaint::setStyle(%d) out of range\n", style); | 284 SkDebugf("SkPaint::setStyle(%d) out of range\n", style); |
| 313 #endif | 285 #endif |
| 314 } | 286 } |
| 315 } | 287 } |
| 316 | 288 |
| 317 void SkPaint::setColor(SkColor color) { | 289 void SkPaint::setColor(SkColor color) { |
| 318 GEN_ID_INC_EVAL(color != fColor); | 290 GEN_ID_INC_EVAL(color != fColor); |
| 319 fColor = color; | 291 fColor = color; |
| 320 fDirtyBits = SkSetClearMask(fDirtyBits, color != SK_ColorBLACK, kColor_Dirty
Bit); | |
| 321 } | 292 } |
| 322 | 293 |
| 323 void SkPaint::setAlpha(U8CPU a) { | 294 void SkPaint::setAlpha(U8CPU a) { |
| 324 this->setColor(SkColorSetARGB(a, SkColorGetR(fColor), | 295 this->setColor(SkColorSetARGB(a, SkColorGetR(fColor), |
| 325 SkColorGetG(fColor), SkColorGetB(fColor))); | 296 SkColorGetG(fColor), SkColorGetB(fColor))); |
| 326 } | 297 } |
| 327 | 298 |
| 328 void SkPaint::setARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) { | 299 void SkPaint::setARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) { |
| 329 this->setColor(SkColorSetARGB(a, r, g, b)); | 300 this->setColor(SkColorSetARGB(a, r, g, b)); |
| 330 } | 301 } |
| 331 | 302 |
| 332 void SkPaint::setStrokeWidth(SkScalar width) { | 303 void SkPaint::setStrokeWidth(SkScalar width) { |
| 333 if (width >= 0) { | 304 if (width >= 0) { |
| 334 GEN_ID_INC_EVAL(width != fWidth); | 305 GEN_ID_INC_EVAL(width != fWidth); |
| 335 fWidth = width; | 306 fWidth = width; |
| 336 fDirtyBits = SkSetClearMask(fDirtyBits, width != 0, kStrokeWidth_DirtyBi
t); | |
| 337 } else { | 307 } else { |
| 338 #ifdef SK_REPORT_API_RANGE_CHECK | 308 #ifdef SK_REPORT_API_RANGE_CHECK |
| 339 SkDebugf("SkPaint::setStrokeWidth() called with negative value\n"); | 309 SkDebugf("SkPaint::setStrokeWidth() called with negative value\n"); |
| 340 #endif | 310 #endif |
| 341 } | 311 } |
| 342 } | 312 } |
| 343 | 313 |
| 344 void SkPaint::setStrokeMiter(SkScalar limit) { | 314 void SkPaint::setStrokeMiter(SkScalar limit) { |
| 345 if (limit >= 0) { | 315 if (limit >= 0) { |
| 346 GEN_ID_INC_EVAL(limit != fMiterLimit); | 316 GEN_ID_INC_EVAL(limit != fMiterLimit); |
| 347 fMiterLimit = limit; | 317 fMiterLimit = limit; |
| 348 fDirtyBits = SkSetClearMask(fDirtyBits, | |
| 349 limit != SkPaintDefaults_MiterLimit, | |
| 350 kStrokeMiter_DirtyBit); | |
| 351 } else { | 318 } else { |
| 352 #ifdef SK_REPORT_API_RANGE_CHECK | 319 #ifdef SK_REPORT_API_RANGE_CHECK |
| 353 SkDebugf("SkPaint::setStrokeMiter() called with negative value\n"); | 320 SkDebugf("SkPaint::setStrokeMiter() called with negative value\n"); |
| 354 #endif | 321 #endif |
| 355 } | 322 } |
| 356 } | 323 } |
| 357 | 324 |
| 358 void SkPaint::setStrokeCap(Cap ct) { | 325 void SkPaint::setStrokeCap(Cap ct) { |
| 359 if ((unsigned)ct < kCapCount) { | 326 if ((unsigned)ct < kCapCount) { |
| 360 GEN_ID_INC_EVAL((unsigned)ct != fBitfields.fCapType); | 327 GEN_ID_INC_EVAL((unsigned)ct != fBitfields.fCapType); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 387 #ifdef SK_REPORT_API_RANGE_CHECK | 354 #ifdef SK_REPORT_API_RANGE_CHECK |
| 388 SkDebugf("SkPaint::setTextAlign(%d) out of range\n", align); | 355 SkDebugf("SkPaint::setTextAlign(%d) out of range\n", align); |
| 389 #endif | 356 #endif |
| 390 } | 357 } |
| 391 } | 358 } |
| 392 | 359 |
| 393 void SkPaint::setTextSize(SkScalar ts) { | 360 void SkPaint::setTextSize(SkScalar ts) { |
| 394 if (ts >= 0) { | 361 if (ts >= 0) { |
| 395 GEN_ID_INC_EVAL(ts != fTextSize); | 362 GEN_ID_INC_EVAL(ts != fTextSize); |
| 396 fTextSize = ts; | 363 fTextSize = ts; |
| 397 fDirtyBits = SkSetClearMask(fDirtyBits, ts != SkPaintDefaults_TextSize,
kTextSize_DirtyBit); | |
| 398 } else { | 364 } else { |
| 399 #ifdef SK_REPORT_API_RANGE_CHECK | 365 #ifdef SK_REPORT_API_RANGE_CHECK |
| 400 SkDebugf("SkPaint::setTextSize() called with negative value\n"); | 366 SkDebugf("SkPaint::setTextSize() called with negative value\n"); |
| 401 #endif | 367 #endif |
| 402 } | 368 } |
| 403 } | 369 } |
| 404 | 370 |
| 405 void SkPaint::setTextScaleX(SkScalar scaleX) { | 371 void SkPaint::setTextScaleX(SkScalar scaleX) { |
| 406 GEN_ID_INC_EVAL(scaleX != fTextScaleX); | 372 GEN_ID_INC_EVAL(scaleX != fTextScaleX); |
| 407 fTextScaleX = scaleX; | 373 fTextScaleX = scaleX; |
| 408 fDirtyBits = SkSetClearMask(fDirtyBits, scaleX != SK_Scalar1, kTextScaleX_Di
rtyBit); | |
| 409 } | 374 } |
| 410 | 375 |
| 411 void SkPaint::setTextSkewX(SkScalar skewX) { | 376 void SkPaint::setTextSkewX(SkScalar skewX) { |
| 412 GEN_ID_INC_EVAL(skewX != fTextSkewX); | 377 GEN_ID_INC_EVAL(skewX != fTextSkewX); |
| 413 fTextSkewX = skewX; | 378 fTextSkewX = skewX; |
| 414 fDirtyBits = SkSetClearMask(fDirtyBits, skewX != 0, kTextSkewX_DirtyBit); | |
| 415 } | 379 } |
| 416 | 380 |
| 417 void SkPaint::setTextEncoding(TextEncoding encoding) { | 381 void SkPaint::setTextEncoding(TextEncoding encoding) { |
| 418 if ((unsigned)encoding <= kGlyphID_TextEncoding) { | 382 if ((unsigned)encoding <= kGlyphID_TextEncoding) { |
| 419 GEN_ID_INC_EVAL((unsigned)encoding != fBitfields.fTextEncoding); | 383 GEN_ID_INC_EVAL((unsigned)encoding != fBitfields.fTextEncoding); |
| 420 fBitfields.fTextEncoding = encoding; | 384 fBitfields.fTextEncoding = encoding; |
| 421 } else { | 385 } else { |
| 422 #ifdef SK_REPORT_API_RANGE_CHECK | 386 #ifdef SK_REPORT_API_RANGE_CHECK |
| 423 SkDebugf("SkPaint::setTextEncoding(%d) out of range\n", encoding); | 387 SkDebugf("SkPaint::setTextEncoding(%d) out of range\n", encoding); |
| 424 #endif | 388 #endif |
| 425 } | 389 } |
| 426 } | 390 } |
| 427 | 391 |
| 428 /////////////////////////////////////////////////////////////////////////////// | 392 /////////////////////////////////////////////////////////////////////////////// |
| 429 | 393 |
| 430 SkTypeface* SkPaint::setTypeface(SkTypeface* font) { | 394 SkTypeface* SkPaint::setTypeface(SkTypeface* font) { |
| 431 SkRefCnt_SafeAssign(fTypeface, font); | 395 SkRefCnt_SafeAssign(fTypeface, font); |
| 432 GEN_ID_INC; | 396 GEN_ID_INC; |
| 433 fDirtyBits = SkSetClearMask(fDirtyBits, font != NULL, kTypeface_DirtyBit); | |
| 434 return font; | 397 return font; |
| 435 } | 398 } |
| 436 | 399 |
| 437 SkRasterizer* SkPaint::setRasterizer(SkRasterizer* r) { | 400 SkRasterizer* SkPaint::setRasterizer(SkRasterizer* r) { |
| 438 SkRefCnt_SafeAssign(fRasterizer, r); | 401 SkRefCnt_SafeAssign(fRasterizer, r); |
| 439 GEN_ID_INC; | 402 GEN_ID_INC; |
| 440 fDirtyBits = SkSetClearMask(fDirtyBits, r != NULL, kRasterizer_DirtyBit); | |
| 441 return r; | 403 return r; |
| 442 } | 404 } |
| 443 | 405 |
| 444 SkDrawLooper* SkPaint::setLooper(SkDrawLooper* looper) { | 406 SkDrawLooper* SkPaint::setLooper(SkDrawLooper* looper) { |
| 445 SkRefCnt_SafeAssign(fLooper, looper); | 407 SkRefCnt_SafeAssign(fLooper, looper); |
| 446 GEN_ID_INC; | 408 GEN_ID_INC; |
| 447 fDirtyBits = SkSetClearMask(fDirtyBits, looper != NULL, kLooper_DirtyBit); | |
| 448 return looper; | 409 return looper; |
| 449 } | 410 } |
| 450 | 411 |
| 451 SkImageFilter* SkPaint::setImageFilter(SkImageFilter* imageFilter) { | 412 SkImageFilter* SkPaint::setImageFilter(SkImageFilter* imageFilter) { |
| 452 SkRefCnt_SafeAssign(fImageFilter, imageFilter); | 413 SkRefCnt_SafeAssign(fImageFilter, imageFilter); |
| 453 GEN_ID_INC; | 414 GEN_ID_INC; |
| 454 fDirtyBits = SkSetClearMask(fDirtyBits, imageFilter != NULL, kImageFilter_Di
rtyBit); | |
| 455 return imageFilter; | 415 return imageFilter; |
| 456 } | 416 } |
| 457 | 417 |
| 458 SkAnnotation* SkPaint::setAnnotation(SkAnnotation* annotation) { | 418 SkAnnotation* SkPaint::setAnnotation(SkAnnotation* annotation) { |
| 459 SkRefCnt_SafeAssign(fAnnotation, annotation); | 419 SkRefCnt_SafeAssign(fAnnotation, annotation); |
| 460 GEN_ID_INC; | 420 GEN_ID_INC; |
| 461 fDirtyBits = SkSetClearMask(fDirtyBits, annotation != NULL, kAnnotation_Dirt
yBit); | |
| 462 return annotation; | 421 return annotation; |
| 463 } | 422 } |
| 464 | 423 |
| 465 /////////////////////////////////////////////////////////////////////////////// | 424 /////////////////////////////////////////////////////////////////////////////// |
| 466 | 425 |
| 467 static SkScalar mag2(SkScalar x, SkScalar y) { | 426 static SkScalar mag2(SkScalar x, SkScalar y) { |
| 468 return x * x + y * y; | 427 return x * x + y * y; |
| 469 } | 428 } |
| 470 | 429 |
| 471 static bool tooBig(const SkMatrix& m, SkScalar ma2max) { | 430 static bool tooBig(const SkMatrix& m, SkScalar ma2max) { |
| (...skipping 1726 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2198 buffer.readString(&tag); | 2157 buffer.readString(&tag); |
| 2199 buffer.readBool(); | 2158 buffer.readBool(); |
| 2200 } | 2159 } |
| 2201 } | 2160 } |
| 2202 | 2161 |
| 2203 /////////////////////////////////////////////////////////////////////////////// | 2162 /////////////////////////////////////////////////////////////////////////////// |
| 2204 | 2163 |
| 2205 SkShader* SkPaint::setShader(SkShader* shader) { | 2164 SkShader* SkPaint::setShader(SkShader* shader) { |
| 2206 GEN_ID_INC_EVAL(shader != fShader); | 2165 GEN_ID_INC_EVAL(shader != fShader); |
| 2207 SkRefCnt_SafeAssign(fShader, shader); | 2166 SkRefCnt_SafeAssign(fShader, shader); |
| 2208 fDirtyBits = SkSetClearMask(fDirtyBits, shader != NULL, kShader_DirtyBit); | |
| 2209 return shader; | 2167 return shader; |
| 2210 } | 2168 } |
| 2211 | 2169 |
| 2212 SkColorFilter* SkPaint::setColorFilter(SkColorFilter* filter) { | 2170 SkColorFilter* SkPaint::setColorFilter(SkColorFilter* filter) { |
| 2213 GEN_ID_INC_EVAL(filter != fColorFilter); | 2171 GEN_ID_INC_EVAL(filter != fColorFilter); |
| 2214 SkRefCnt_SafeAssign(fColorFilter, filter); | 2172 SkRefCnt_SafeAssign(fColorFilter, filter); |
| 2215 fDirtyBits = SkSetClearMask(fDirtyBits, filter != NULL, kColorFilter_DirtyBi
t); | |
| 2216 return filter; | 2173 return filter; |
| 2217 } | 2174 } |
| 2218 | 2175 |
| 2219 SkXfermode* SkPaint::setXfermode(SkXfermode* mode) { | 2176 SkXfermode* SkPaint::setXfermode(SkXfermode* mode) { |
| 2220 GEN_ID_INC_EVAL(mode != fXfermode); | 2177 GEN_ID_INC_EVAL(mode != fXfermode); |
| 2221 SkRefCnt_SafeAssign(fXfermode, mode); | 2178 SkRefCnt_SafeAssign(fXfermode, mode); |
| 2222 fDirtyBits = SkSetClearMask(fDirtyBits, mode != NULL, kXfermode_DirtyBit); | |
| 2223 return mode; | 2179 return mode; |
| 2224 } | 2180 } |
| 2225 | 2181 |
| 2226 SkXfermode* SkPaint::setXfermodeMode(SkXfermode::Mode mode) { | 2182 SkXfermode* SkPaint::setXfermodeMode(SkXfermode::Mode mode) { |
| 2227 SkSafeUnref(fXfermode); | 2183 SkSafeUnref(fXfermode); |
| 2228 fXfermode = SkXfermode::Create(mode); | 2184 fXfermode = SkXfermode::Create(mode); |
| 2229 GEN_ID_INC; | 2185 GEN_ID_INC; |
| 2230 fDirtyBits = SkSetClearMask(fDirtyBits, fXfermode != NULL, kXfermode_DirtyBi
t); | |
| 2231 return fXfermode; | 2186 return fXfermode; |
| 2232 } | 2187 } |
| 2233 | 2188 |
| 2234 SkPathEffect* SkPaint::setPathEffect(SkPathEffect* effect) { | 2189 SkPathEffect* SkPaint::setPathEffect(SkPathEffect* effect) { |
| 2235 GEN_ID_INC_EVAL(effect != fPathEffect); | 2190 GEN_ID_INC_EVAL(effect != fPathEffect); |
| 2236 SkRefCnt_SafeAssign(fPathEffect, effect); | 2191 SkRefCnt_SafeAssign(fPathEffect, effect); |
| 2237 fDirtyBits = SkSetClearMask(fDirtyBits, effect != NULL, kPathEffect_DirtyBit
); | |
| 2238 return effect; | 2192 return effect; |
| 2239 } | 2193 } |
| 2240 | 2194 |
| 2241 SkMaskFilter* SkPaint::setMaskFilter(SkMaskFilter* filter) { | 2195 SkMaskFilter* SkPaint::setMaskFilter(SkMaskFilter* filter) { |
| 2242 GEN_ID_INC_EVAL(filter != fMaskFilter); | 2196 GEN_ID_INC_EVAL(filter != fMaskFilter); |
| 2243 SkRefCnt_SafeAssign(fMaskFilter, filter); | 2197 SkRefCnt_SafeAssign(fMaskFilter, filter); |
| 2244 fDirtyBits = SkSetClearMask(fDirtyBits, filter != NULL, kMaskFilter_DirtyBit
); | |
| 2245 return filter; | 2198 return filter; |
| 2246 } | 2199 } |
| 2247 | 2200 |
| 2248 /////////////////////////////////////////////////////////////////////////////// | 2201 /////////////////////////////////////////////////////////////////////////////// |
| 2249 | 2202 |
| 2250 bool SkPaint::getFillPath(const SkPath& src, SkPath* dst, | 2203 bool SkPaint::getFillPath(const SkPath& src, SkPath* dst, |
| 2251 const SkRect* cullRect) const { | 2204 const SkRect* cullRect) const { |
| 2252 SkStrokeRec rec(*this); | 2205 SkStrokeRec rec(*this); |
| 2253 | 2206 |
| 2254 const SkPath* srcPtr = &src; | 2207 const SkPath* srcPtr = &src; |
| (...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2604 return 0 == this->getAlpha(); | 2557 return 0 == this->getAlpha(); |
| 2605 case SkXfermode::kDst_Mode: | 2558 case SkXfermode::kDst_Mode: |
| 2606 return true; | 2559 return true; |
| 2607 default: | 2560 default: |
| 2608 break; | 2561 break; |
| 2609 } | 2562 } |
| 2610 } | 2563 } |
| 2611 return false; | 2564 return false; |
| 2612 } | 2565 } |
| 2613 | 2566 |
| 2614 inline static unsigned popcount(uint8_t x) { | |
| 2615 // As in Hacker's delight, adapted for just 8 bits. | |
| 2616 x = (x & 0x55) + ((x >> 1) & 0x55); // a b c d w x y z -> a+b c+d w+x y+z | |
| 2617 x = (x & 0x33) + ((x >> 2) & 0x33); // a+b c+d w+x y+z -> a+b+c+d w+x+y+z | |
| 2618 x = (x & 0x0F) + ((x >> 4) & 0x0F); // a+b+c+d w+x+y+z -> a+b+c+d+w+x+y+z | |
| 2619 return x; | |
| 2620 } | |
| 2621 | |
| 2622 void SkPaint::FlatteningTraits::Flatten(SkWriteBuffer& buffer, const SkPaint& pa
int) { | |
| 2623 const uint32_t dirty = paint.fDirtyBits; | |
| 2624 | |
| 2625 // Each of the low 7 dirty bits corresponds to a 4-byte flat value, | |
| 2626 // plus one for the dirty bits and one for the bitfields | |
| 2627 const size_t flatBytes = 4 * (popcount(dirty & kPOD_DirtyBitMask) + 2); | |
| 2628 SkASSERT(flatBytes <= 32); | |
| 2629 uint32_t* u32 = buffer.reserve(flatBytes); | |
| 2630 *u32++ = dirty; | |
| 2631 *u32++ = paint.fBitfieldsUInt; | |
| 2632 if (0 == dirty) { | |
| 2633 return; | |
| 2634 } | |
| 2635 | |
| 2636 #define F(dst, field) if (dirty & k##field##_DirtyBit) *dst++ = paint.get##field
() | |
| 2637 F(u32, Color); | |
| 2638 SkScalar* f32 = reinterpret_cast<SkScalar*>(u32); | |
| 2639 F(f32, TextSize); | |
| 2640 F(f32, TextScaleX); | |
| 2641 F(f32, TextSkewX); | |
| 2642 F(f32, StrokeWidth); | |
| 2643 F(f32, StrokeMiter); | |
| 2644 #undef F | |
| 2645 #define F(field) if (dirty & k##field##_DirtyBit) buffer.writeFlattenable(paint.
get##field()) | |
| 2646 F(PathEffect); | |
| 2647 F(Shader); | |
| 2648 F(Xfermode); | |
| 2649 F(MaskFilter); | |
| 2650 F(ColorFilter); | |
| 2651 F(Rasterizer); | |
| 2652 F(Looper); | |
| 2653 F(ImageFilter); | |
| 2654 #undef F | |
| 2655 if (dirty & kTypeface_DirtyBit) buffer.writeTypeface(paint.getTypeface()); | |
| 2656 if (dirty & kAnnotation_DirtyBit) paint.getAnnotation()->writeToBuffer(buffe
r); | |
| 2657 } | |
| 2658 | |
| 2659 void SkPaint::FlatteningTraits::Unflatten(SkReadBuffer& buffer, SkPaint* paint)
{ | |
| 2660 const uint32_t dirty = buffer.readUInt(); | |
| 2661 paint->fBitfieldsUInt = buffer.readUInt(); | |
| 2662 if (dirty == 0) { | |
| 2663 return; | |
| 2664 } | |
| 2665 #define F(field, reader) if (dirty & k##field##_DirtyBit) paint->set##field(buff
er.reader()) | |
| 2666 // Same function, except it unrefs the object newly set on the paint: | |
| 2667 #define F_UNREF(field, reader) \ | |
| 2668 if (dirty & k##field##_DirtyBit) \ | |
| 2669 paint->set##field(buffer.reader())->unref() | |
| 2670 | |
| 2671 F(Color, readUInt); | |
| 2672 F(TextSize, readScalar); | |
| 2673 F(TextScaleX, readScalar); | |
| 2674 F(TextSkewX, readScalar); | |
| 2675 F(StrokeWidth, readScalar); | |
| 2676 F(StrokeMiter, readScalar); | |
| 2677 F_UNREF(PathEffect, readPathEffect); | |
| 2678 F_UNREF(Shader, readShader); | |
| 2679 F_UNREF(Xfermode, readXfermode); | |
| 2680 F_UNREF(MaskFilter, readMaskFilter); | |
| 2681 F_UNREF(ColorFilter, readColorFilter); | |
| 2682 F_UNREF(Rasterizer, readRasterizer); | |
| 2683 F_UNREF(Looper, readDrawLooper); | |
| 2684 F_UNREF(ImageFilter, readImageFilter); | |
| 2685 F(Typeface, readTypeface); | |
| 2686 #undef F | |
| 2687 #undef F_UNREF | |
| 2688 if (dirty & kAnnotation_DirtyBit) { | |
| 2689 paint->setAnnotation(SkAnnotation::Create(buffer))->unref(); | |
| 2690 } | |
| 2691 SkASSERT(dirty == paint->fDirtyBits); | |
| 2692 } | |
| OLD | NEW |