OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2006 The Android Open Source Project | 3 * Copyright 2006 The Android Open Source Project |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 #include "SkPaint.h" | 9 #include "SkPaint.h" |
10 #include "SkAnnotation.h" | 10 #include "SkAnnotation.h" |
(...skipping 17 matching lines...) Expand all Loading... |
28 #include "SkScalerContext.h" | 28 #include "SkScalerContext.h" |
29 #include "SkShader.h" | 29 #include "SkShader.h" |
30 #include "SkStringUtils.h" | 30 #include "SkStringUtils.h" |
31 #include "SkStroke.h" | 31 #include "SkStroke.h" |
32 #include "SkTextFormatParams.h" | 32 #include "SkTextFormatParams.h" |
33 #include "SkTextToPathIter.h" | 33 #include "SkTextToPathIter.h" |
34 #include "SkTLazy.h" | 34 #include "SkTLazy.h" |
35 #include "SkTypeface.h" | 35 #include "SkTypeface.h" |
36 #include "SkXfermode.h" | 36 #include "SkXfermode.h" |
37 | 37 |
| 38 enum { |
| 39 kColor_DirtyBit = 1 << 0, |
| 40 kBitfields_DirtyBit = 1 << 1, |
| 41 kTextSize_DirtyBit = 1 << 2, |
| 42 kTextScaleX_DirtyBit = 1 << 3, |
| 43 kTextSkewX_DirtyBit = 1 << 4, |
| 44 kStrokeWidth_DirtyBit = 1 << 5, |
| 45 kStrokeMiter_DirtyBit = 1 << 6, |
| 46 kPathEffect_DirtyBit = 1 << 7, |
| 47 kShader_DirtyBit = 1 << 8, |
| 48 kXfermode_DirtyBit = 1 << 9, |
| 49 kMaskFilter_DirtyBit = 1 << 10, |
| 50 kColorFilter_DirtyBit = 1 << 11, |
| 51 kRasterizer_DirtyBit = 1 << 12, |
| 52 kLooper_DirtyBit = 1 << 13, |
| 53 kImageFilter_DirtyBit = 1 << 14, |
| 54 kTypeface_DirtyBit = 1 << 15, |
| 55 kAnnotation_DirtyBit = 1 << 16, |
| 56 kPaintOptionsAndroid_DirtyBit = 1 << 17, |
| 57 }; |
38 | 58 |
39 // define this to get a printf for out-of-range parameter in setters | 59 // define this to get a printf for out-of-range parameter in setters |
40 // e.g. setTextSize(-1) | 60 // e.g. setTextSize(-1) |
41 //#define SK_REPORT_API_RANGE_CHECK | 61 //#define SK_REPORT_API_RANGE_CHECK |
42 | 62 |
43 #ifdef SK_BUILD_FOR_ANDROID | 63 #ifdef SK_BUILD_FOR_ANDROID |
44 #define GEN_ID_INC fGenerationID++ | 64 #define GEN_ID_INC fGenerationID++ |
45 #define GEN_ID_INC_EVAL(expression) if (expression) { fGenerationID++; } | 65 #define GEN_ID_INC_EVAL(expression) if (expression) { fGenerationID++; } |
46 #else | 66 #else |
47 #define GEN_ID_INC | 67 #define GEN_ID_INC |
48 #define GEN_ID_INC_EVAL(expression) | 68 #define GEN_ID_INC_EVAL(expression) |
49 #endif | 69 #endif |
50 | 70 |
51 SkPaint::SkPaint() { | 71 SkPaint::SkPaint() { |
52 // since we may have padding, we zero everything so that our memcmp() call | 72 // since we may have padding, we zero everything so that our memcmp() call |
53 // in operator== will work correctly. | 73 // in operator== will work correctly. |
54 // with this, we can skip 0 and null individual initializations | 74 // with this, we can skip 0 and null individual initializations |
55 sk_bzero(this, sizeof(*this)); | 75 sk_bzero(this, sizeof(*this)); |
56 | 76 |
57 #if 0 // not needed with the bzero call above | 77 #if 0 // not needed with the bzero call above |
58 fTypeface = NULL; | 78 fTypeface = NULL; |
59 fTextSkewX = 0; | 79 fTextSkewX = 0; |
60 fPathEffect = NULL; | 80 fPathEffect = NULL; |
61 fShader = NULL; | 81 fShader = NULL; |
62 fXfermode = NULL; | 82 fXfermode = NULL; |
63 fMaskFilter = NULL; | 83 fMaskFilter = NULL; |
64 fColorFilter = NULL; | 84 fColorFilter = NULL; |
65 fRasterizer = NULL; | 85 fRasterizer = NULL; |
66 fLooper = NULL; | 86 fLooper = NULL; |
67 fImageFilter = NULL; | 87 fImageFilter = NULL; |
68 fAnnotation = NULL; | 88 fAnnotation = NULL; |
69 fWidth = 0; | 89 fWidth = 0; |
| 90 fDirtyBits = 0; |
70 #endif | 91 #endif |
71 | 92 |
72 fTextSize = SkPaintDefaults_TextSize; | 93 fTextSize = SkPaintDefaults_TextSize; |
73 fTextScaleX = SK_Scalar1; | 94 fTextScaleX = SK_Scalar1; |
74 fColor = SK_ColorBLACK; | 95 fColor = SK_ColorBLACK; |
75 fMiterLimit = SkPaintDefaults_MiterLimit; | 96 fMiterLimit = SkPaintDefaults_MiterLimit; |
76 fFlags = SkPaintDefaults_Flags; | 97 fFlags = SkPaintDefaults_Flags; |
77 fCapType = kDefault_Cap; | 98 fCapType = kDefault_Cap; |
78 fJoinType = kDefault_Join; | 99 fJoinType = kDefault_Join; |
79 fTextAlign = kLeft_Align; | 100 fTextAlign = kLeft_Align; |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
191 unsigned SkPaint::getBaseGlyphCount(SkUnichar text) const { | 212 unsigned SkPaint::getBaseGlyphCount(SkUnichar text) const { |
192 SkAutoGlyphCache autoCache(*this, NULL, NULL); | 213 SkAutoGlyphCache autoCache(*this, NULL, NULL); |
193 SkGlyphCache* cache = autoCache.getCache(); | 214 SkGlyphCache* cache = autoCache.getCache(); |
194 return cache->getBaseGlyphCount(text); | 215 return cache->getBaseGlyphCount(text); |
195 } | 216 } |
196 | 217 |
197 void SkPaint::setPaintOptionsAndroid(const SkPaintOptionsAndroid& options) { | 218 void SkPaint::setPaintOptionsAndroid(const SkPaintOptionsAndroid& options) { |
198 if (options != fPaintOptionsAndroid) { | 219 if (options != fPaintOptionsAndroid) { |
199 fPaintOptionsAndroid = options; | 220 fPaintOptionsAndroid = options; |
200 GEN_ID_INC; | 221 GEN_ID_INC; |
| 222 fDirtyBits |= kPaintOptionsAndroid_DirtyBit; |
201 } | 223 } |
202 } | 224 } |
203 #endif | 225 #endif |
204 | 226 |
205 SkPaint::FilterLevel SkPaint::getFilterLevel() const { | 227 SkPaint::FilterLevel SkPaint::getFilterLevel() const { |
206 int level = 0; | 228 int level = 0; |
207 if (fFlags & kFilterBitmap_Flag) { | 229 if (fFlags & kFilterBitmap_Flag) { |
208 level |= 1; | 230 level |= 1; |
209 } | 231 } |
210 if (fFlags & kHighQualityFilterBitmap_Flag) { | 232 if (fFlags & kHighQualityFilterBitmap_Flag) { |
(...skipping 10 matching lines...) Expand all Loading... |
221 } | 243 } |
222 if (level & 2) { | 244 if (level & 2) { |
223 flags |= kHighQualityFilterBitmap_Flag; | 245 flags |= kHighQualityFilterBitmap_Flag; |
224 } | 246 } |
225 this->setFlags((fFlags & ~mask) | flags); | 247 this->setFlags((fFlags & ~mask) | flags); |
226 } | 248 } |
227 | 249 |
228 void SkPaint::setHinting(Hinting hintingLevel) { | 250 void SkPaint::setHinting(Hinting hintingLevel) { |
229 GEN_ID_INC_EVAL((unsigned) hintingLevel != fHinting); | 251 GEN_ID_INC_EVAL((unsigned) hintingLevel != fHinting); |
230 fHinting = hintingLevel; | 252 fHinting = hintingLevel; |
| 253 fDirtyBits |= kBitfields_DirtyBit; |
231 } | 254 } |
232 | 255 |
233 void SkPaint::setFlags(uint32_t flags) { | 256 void SkPaint::setFlags(uint32_t flags) { |
234 GEN_ID_INC_EVAL(fFlags != flags); | 257 GEN_ID_INC_EVAL(fFlags != flags); |
235 fFlags = flags; | 258 fFlags = flags; |
| 259 fDirtyBits |= kBitfields_DirtyBit; |
236 } | 260 } |
237 | 261 |
238 void SkPaint::setAntiAlias(bool doAA) { | 262 void SkPaint::setAntiAlias(bool doAA) { |
239 this->setFlags(SkSetClearMask(fFlags, doAA, kAntiAlias_Flag)); | 263 this->setFlags(SkSetClearMask(fFlags, doAA, kAntiAlias_Flag)); |
240 } | 264 } |
241 | 265 |
242 void SkPaint::setDither(bool doDither) { | 266 void SkPaint::setDither(bool doDither) { |
243 this->setFlags(SkSetClearMask(fFlags, doDither, kDither_Flag)); | 267 this->setFlags(SkSetClearMask(fFlags, doDither, kDither_Flag)); |
244 } | 268 } |
245 | 269 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
280 } | 304 } |
281 | 305 |
282 void SkPaint::setDevKernText(bool doDevKern) { | 306 void SkPaint::setDevKernText(bool doDevKern) { |
283 this->setFlags(SkSetClearMask(fFlags, doDevKern, kDevKernText_Flag)); | 307 this->setFlags(SkSetClearMask(fFlags, doDevKern, kDevKernText_Flag)); |
284 } | 308 } |
285 | 309 |
286 void SkPaint::setStyle(Style style) { | 310 void SkPaint::setStyle(Style style) { |
287 if ((unsigned)style < kStyleCount) { | 311 if ((unsigned)style < kStyleCount) { |
288 GEN_ID_INC_EVAL((unsigned)style != fStyle); | 312 GEN_ID_INC_EVAL((unsigned)style != fStyle); |
289 fStyle = style; | 313 fStyle = style; |
| 314 fDirtyBits |= kBitfields_DirtyBit; |
290 } else { | 315 } else { |
291 #ifdef SK_REPORT_API_RANGE_CHECK | 316 #ifdef SK_REPORT_API_RANGE_CHECK |
292 SkDebugf("SkPaint::setStyle(%d) out of range\n", style); | 317 SkDebugf("SkPaint::setStyle(%d) out of range\n", style); |
293 #endif | 318 #endif |
294 } | 319 } |
295 } | 320 } |
296 | 321 |
297 void SkPaint::setColor(SkColor color) { | 322 void SkPaint::setColor(SkColor color) { |
298 GEN_ID_INC_EVAL(color != fColor); | 323 GEN_ID_INC_EVAL(color != fColor); |
299 fColor = color; | 324 fColor = color; |
| 325 fDirtyBits |= kColor_DirtyBit; |
300 } | 326 } |
301 | 327 |
302 void SkPaint::setAlpha(U8CPU a) { | 328 void SkPaint::setAlpha(U8CPU a) { |
303 this->setColor(SkColorSetARGB(a, SkColorGetR(fColor), | 329 this->setColor(SkColorSetARGB(a, SkColorGetR(fColor), |
304 SkColorGetG(fColor), SkColorGetB(fColor))); | 330 SkColorGetG(fColor), SkColorGetB(fColor))); |
305 } | 331 } |
306 | 332 |
307 void SkPaint::setARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) { | 333 void SkPaint::setARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) { |
308 this->setColor(SkColorSetARGB(a, r, g, b)); | 334 this->setColor(SkColorSetARGB(a, r, g, b)); |
309 } | 335 } |
310 | 336 |
311 void SkPaint::setStrokeWidth(SkScalar width) { | 337 void SkPaint::setStrokeWidth(SkScalar width) { |
312 if (width >= 0) { | 338 if (width >= 0) { |
313 GEN_ID_INC_EVAL(width != fWidth); | 339 GEN_ID_INC_EVAL(width != fWidth); |
314 fWidth = width; | 340 fWidth = width; |
| 341 fDirtyBits |= kStrokeWidth_DirtyBit; |
315 } else { | 342 } else { |
316 #ifdef SK_REPORT_API_RANGE_CHECK | 343 #ifdef SK_REPORT_API_RANGE_CHECK |
317 SkDebugf("SkPaint::setStrokeWidth() called with negative value\n"); | 344 SkDebugf("SkPaint::setStrokeWidth() called with negative value\n"); |
318 #endif | 345 #endif |
319 } | 346 } |
320 } | 347 } |
321 | 348 |
322 void SkPaint::setStrokeMiter(SkScalar limit) { | 349 void SkPaint::setStrokeMiter(SkScalar limit) { |
323 if (limit >= 0) { | 350 if (limit >= 0) { |
324 GEN_ID_INC_EVAL(limit != fMiterLimit); | 351 GEN_ID_INC_EVAL(limit != fMiterLimit); |
325 fMiterLimit = limit; | 352 fMiterLimit = limit; |
| 353 fDirtyBits |= kStrokeMiter_DirtyBit; |
326 } else { | 354 } else { |
327 #ifdef SK_REPORT_API_RANGE_CHECK | 355 #ifdef SK_REPORT_API_RANGE_CHECK |
328 SkDebugf("SkPaint::setStrokeMiter() called with negative value\n"); | 356 SkDebugf("SkPaint::setStrokeMiter() called with negative value\n"); |
329 #endif | 357 #endif |
330 } | 358 } |
331 } | 359 } |
332 | 360 |
333 void SkPaint::setStrokeCap(Cap ct) { | 361 void SkPaint::setStrokeCap(Cap ct) { |
334 if ((unsigned)ct < kCapCount) { | 362 if ((unsigned)ct < kCapCount) { |
335 GEN_ID_INC_EVAL((unsigned)ct != fCapType); | 363 GEN_ID_INC_EVAL((unsigned)ct != fCapType); |
336 fCapType = SkToU8(ct); | 364 fCapType = SkToU8(ct); |
| 365 fDirtyBits |= kBitfields_DirtyBit; |
337 } else { | 366 } else { |
338 #ifdef SK_REPORT_API_RANGE_CHECK | 367 #ifdef SK_REPORT_API_RANGE_CHECK |
339 SkDebugf("SkPaint::setStrokeCap(%d) out of range\n", ct); | 368 SkDebugf("SkPaint::setStrokeCap(%d) out of range\n", ct); |
340 #endif | 369 #endif |
341 } | 370 } |
342 } | 371 } |
343 | 372 |
344 void SkPaint::setStrokeJoin(Join jt) { | 373 void SkPaint::setStrokeJoin(Join jt) { |
345 if ((unsigned)jt < kJoinCount) { | 374 if ((unsigned)jt < kJoinCount) { |
346 GEN_ID_INC_EVAL((unsigned)jt != fJoinType); | 375 GEN_ID_INC_EVAL((unsigned)jt != fJoinType); |
347 fJoinType = SkToU8(jt); | 376 fJoinType = SkToU8(jt); |
| 377 fDirtyBits |= kBitfields_DirtyBit; |
348 } else { | 378 } else { |
349 #ifdef SK_REPORT_API_RANGE_CHECK | 379 #ifdef SK_REPORT_API_RANGE_CHECK |
350 SkDebugf("SkPaint::setStrokeJoin(%d) out of range\n", jt); | 380 SkDebugf("SkPaint::setStrokeJoin(%d) out of range\n", jt); |
351 #endif | 381 #endif |
352 } | 382 } |
353 } | 383 } |
354 | 384 |
355 /////////////////////////////////////////////////////////////////////////////// | 385 /////////////////////////////////////////////////////////////////////////////// |
356 | 386 |
357 void SkPaint::setTextAlign(Align align) { | 387 void SkPaint::setTextAlign(Align align) { |
358 if ((unsigned)align < kAlignCount) { | 388 if ((unsigned)align < kAlignCount) { |
359 GEN_ID_INC_EVAL((unsigned)align != fTextAlign); | 389 GEN_ID_INC_EVAL((unsigned)align != fTextAlign); |
360 fTextAlign = SkToU8(align); | 390 fTextAlign = SkToU8(align); |
| 391 fDirtyBits |= kBitfields_DirtyBit; |
361 } else { | 392 } else { |
362 #ifdef SK_REPORT_API_RANGE_CHECK | 393 #ifdef SK_REPORT_API_RANGE_CHECK |
363 SkDebugf("SkPaint::setTextAlign(%d) out of range\n", align); | 394 SkDebugf("SkPaint::setTextAlign(%d) out of range\n", align); |
364 #endif | 395 #endif |
365 } | 396 } |
366 } | 397 } |
367 | 398 |
368 void SkPaint::setTextSize(SkScalar ts) { | 399 void SkPaint::setTextSize(SkScalar ts) { |
369 if (ts >= 0) { | 400 if (ts >= 0) { |
370 GEN_ID_INC_EVAL(ts != fTextSize); | 401 GEN_ID_INC_EVAL(ts != fTextSize); |
371 fTextSize = ts; | 402 fTextSize = ts; |
| 403 fDirtyBits |= kTextSize_DirtyBit; |
372 } else { | 404 } else { |
373 #ifdef SK_REPORT_API_RANGE_CHECK | 405 #ifdef SK_REPORT_API_RANGE_CHECK |
374 SkDebugf("SkPaint::setTextSize() called with negative value\n"); | 406 SkDebugf("SkPaint::setTextSize() called with negative value\n"); |
375 #endif | 407 #endif |
376 } | 408 } |
377 } | 409 } |
378 | 410 |
379 void SkPaint::setTextScaleX(SkScalar scaleX) { | 411 void SkPaint::setTextScaleX(SkScalar scaleX) { |
380 GEN_ID_INC_EVAL(scaleX != fTextScaleX); | 412 GEN_ID_INC_EVAL(scaleX != fTextScaleX); |
381 fTextScaleX = scaleX; | 413 fTextScaleX = scaleX; |
| 414 fDirtyBits |= kTextScaleX_DirtyBit; |
382 } | 415 } |
383 | 416 |
384 void SkPaint::setTextSkewX(SkScalar skewX) { | 417 void SkPaint::setTextSkewX(SkScalar skewX) { |
385 GEN_ID_INC_EVAL(skewX != fTextSkewX); | 418 GEN_ID_INC_EVAL(skewX != fTextSkewX); |
386 fTextSkewX = skewX; | 419 fTextSkewX = skewX; |
| 420 fDirtyBits |= kTextSkewX_DirtyBit; |
387 } | 421 } |
388 | 422 |
389 void SkPaint::setTextEncoding(TextEncoding encoding) { | 423 void SkPaint::setTextEncoding(TextEncoding encoding) { |
390 if ((unsigned)encoding <= kGlyphID_TextEncoding) { | 424 if ((unsigned)encoding <= kGlyphID_TextEncoding) { |
391 GEN_ID_INC_EVAL((unsigned)encoding != fTextEncoding); | 425 GEN_ID_INC_EVAL((unsigned)encoding != fTextEncoding); |
392 fTextEncoding = encoding; | 426 fTextEncoding = encoding; |
| 427 fDirtyBits |= kBitfields_DirtyBit; |
393 } else { | 428 } else { |
394 #ifdef SK_REPORT_API_RANGE_CHECK | 429 #ifdef SK_REPORT_API_RANGE_CHECK |
395 SkDebugf("SkPaint::setTextEncoding(%d) out of range\n", encoding); | 430 SkDebugf("SkPaint::setTextEncoding(%d) out of range\n", encoding); |
396 #endif | 431 #endif |
397 } | 432 } |
398 } | 433 } |
399 | 434 |
400 /////////////////////////////////////////////////////////////////////////////// | 435 /////////////////////////////////////////////////////////////////////////////// |
401 | 436 |
| 437 // Returns dst with the given bitmask enabled or disabled, depending on value. |
| 438 inline static uint32_t set_mask(uint32_t dst, uint32_t bitmask, bool value) { |
| 439 return value ? (dst | bitmask) : (dst & ~bitmask); |
| 440 } |
| 441 |
402 SkTypeface* SkPaint::setTypeface(SkTypeface* font) { | 442 SkTypeface* SkPaint::setTypeface(SkTypeface* font) { |
403 SkRefCnt_SafeAssign(fTypeface, font); | 443 SkRefCnt_SafeAssign(fTypeface, font); |
404 GEN_ID_INC; | 444 GEN_ID_INC; |
| 445 fDirtyBits = set_mask(fDirtyBits, kTypeface_DirtyBit, font != NULL); |
405 return font; | 446 return font; |
406 } | 447 } |
407 | 448 |
408 SkRasterizer* SkPaint::setRasterizer(SkRasterizer* r) { | 449 SkRasterizer* SkPaint::setRasterizer(SkRasterizer* r) { |
409 SkRefCnt_SafeAssign(fRasterizer, r); | 450 SkRefCnt_SafeAssign(fRasterizer, r); |
410 GEN_ID_INC; | 451 GEN_ID_INC; |
| 452 fDirtyBits = set_mask(fDirtyBits, kRasterizer_DirtyBit, r != NULL); |
411 return r; | 453 return r; |
412 } | 454 } |
413 | 455 |
414 SkDrawLooper* SkPaint::setLooper(SkDrawLooper* looper) { | 456 SkDrawLooper* SkPaint::setLooper(SkDrawLooper* looper) { |
415 SkRefCnt_SafeAssign(fLooper, looper); | 457 SkRefCnt_SafeAssign(fLooper, looper); |
416 GEN_ID_INC; | 458 GEN_ID_INC; |
| 459 fDirtyBits = set_mask(fDirtyBits, kLooper_DirtyBit, looper != NULL); |
417 return looper; | 460 return looper; |
418 } | 461 } |
419 | 462 |
420 SkImageFilter* SkPaint::setImageFilter(SkImageFilter* imageFilter) { | 463 SkImageFilter* SkPaint::setImageFilter(SkImageFilter* imageFilter) { |
421 SkRefCnt_SafeAssign(fImageFilter, imageFilter); | 464 SkRefCnt_SafeAssign(fImageFilter, imageFilter); |
422 GEN_ID_INC; | 465 GEN_ID_INC; |
| 466 fDirtyBits = set_mask(fDirtyBits, kImageFilter_DirtyBit, imageFilter != NULL
); |
423 return imageFilter; | 467 return imageFilter; |
424 } | 468 } |
425 | 469 |
426 SkAnnotation* SkPaint::setAnnotation(SkAnnotation* annotation) { | 470 SkAnnotation* SkPaint::setAnnotation(SkAnnotation* annotation) { |
427 SkRefCnt_SafeAssign(fAnnotation, annotation); | 471 SkRefCnt_SafeAssign(fAnnotation, annotation); |
428 GEN_ID_INC; | 472 GEN_ID_INC; |
| 473 fDirtyBits = set_mask(fDirtyBits, kAnnotation_DirtyBit, annotation != NULL); |
429 return annotation; | 474 return annotation; |
430 } | 475 } |
431 | 476 |
432 /////////////////////////////////////////////////////////////////////////////// | 477 /////////////////////////////////////////////////////////////////////////////// |
433 | 478 |
434 static SkScalar mag2(SkScalar x, SkScalar y) { | 479 static SkScalar mag2(SkScalar x, SkScalar y) { |
435 return x * x + y * y; | 480 return x * x + y * y; |
436 } | 481 } |
437 | 482 |
438 static bool tooBig(const SkMatrix& m, SkScalar ma2max) { | 483 static bool tooBig(const SkMatrix& m, SkScalar ma2max) { |
(...skipping 1703 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2142 this->setPaintOptionsAndroid(options); | 2187 this->setPaintOptionsAndroid(options); |
2143 #endif | 2188 #endif |
2144 } | 2189 } |
2145 } | 2190 } |
2146 | 2191 |
2147 /////////////////////////////////////////////////////////////////////////////// | 2192 /////////////////////////////////////////////////////////////////////////////// |
2148 | 2193 |
2149 SkShader* SkPaint::setShader(SkShader* shader) { | 2194 SkShader* SkPaint::setShader(SkShader* shader) { |
2150 GEN_ID_INC_EVAL(shader != fShader); | 2195 GEN_ID_INC_EVAL(shader != fShader); |
2151 SkRefCnt_SafeAssign(fShader, shader); | 2196 SkRefCnt_SafeAssign(fShader, shader); |
| 2197 fDirtyBits = set_mask(fDirtyBits, kShader_DirtyBit, shader != NULL); |
2152 return shader; | 2198 return shader; |
2153 } | 2199 } |
2154 | 2200 |
2155 SkColorFilter* SkPaint::setColorFilter(SkColorFilter* filter) { | 2201 SkColorFilter* SkPaint::setColorFilter(SkColorFilter* filter) { |
2156 GEN_ID_INC_EVAL(filter != fColorFilter); | 2202 GEN_ID_INC_EVAL(filter != fColorFilter); |
2157 SkRefCnt_SafeAssign(fColorFilter, filter); | 2203 SkRefCnt_SafeAssign(fColorFilter, filter); |
| 2204 fDirtyBits = set_mask(fDirtyBits, kColorFilter_DirtyBit, filter != NULL); |
2158 return filter; | 2205 return filter; |
2159 } | 2206 } |
2160 | 2207 |
2161 SkXfermode* SkPaint::setXfermode(SkXfermode* mode) { | 2208 SkXfermode* SkPaint::setXfermode(SkXfermode* mode) { |
2162 GEN_ID_INC_EVAL(mode != fXfermode); | 2209 GEN_ID_INC_EVAL(mode != fXfermode); |
2163 SkRefCnt_SafeAssign(fXfermode, mode); | 2210 SkRefCnt_SafeAssign(fXfermode, mode); |
| 2211 fDirtyBits = set_mask(fDirtyBits, kXfermode_DirtyBit, mode != NULL); |
2164 return mode; | 2212 return mode; |
2165 } | 2213 } |
2166 | 2214 |
2167 SkXfermode* SkPaint::setXfermodeMode(SkXfermode::Mode mode) { | 2215 SkXfermode* SkPaint::setXfermodeMode(SkXfermode::Mode mode) { |
2168 SkSafeUnref(fXfermode); | 2216 SkSafeUnref(fXfermode); |
2169 fXfermode = SkXfermode::Create(mode); | 2217 fXfermode = SkXfermode::Create(mode); |
2170 GEN_ID_INC; | 2218 GEN_ID_INC; |
| 2219 fDirtyBits = set_mask(fDirtyBits, kXfermode_DirtyBit, fXfermode != NULL); |
2171 return fXfermode; | 2220 return fXfermode; |
2172 } | 2221 } |
2173 | 2222 |
2174 SkPathEffect* SkPaint::setPathEffect(SkPathEffect* effect) { | 2223 SkPathEffect* SkPaint::setPathEffect(SkPathEffect* effect) { |
2175 GEN_ID_INC_EVAL(effect != fPathEffect); | 2224 GEN_ID_INC_EVAL(effect != fPathEffect); |
2176 SkRefCnt_SafeAssign(fPathEffect, effect); | 2225 SkRefCnt_SafeAssign(fPathEffect, effect); |
| 2226 fDirtyBits = set_mask(fDirtyBits, kPathEffect_DirtyBit, effect != NULL); |
2177 return effect; | 2227 return effect; |
2178 } | 2228 } |
2179 | 2229 |
2180 SkMaskFilter* SkPaint::setMaskFilter(SkMaskFilter* filter) { | 2230 SkMaskFilter* SkPaint::setMaskFilter(SkMaskFilter* filter) { |
2181 GEN_ID_INC_EVAL(filter != fMaskFilter); | 2231 GEN_ID_INC_EVAL(filter != fMaskFilter); |
2182 SkRefCnt_SafeAssign(fMaskFilter, filter); | 2232 SkRefCnt_SafeAssign(fMaskFilter, filter); |
| 2233 fDirtyBits = set_mask(fDirtyBits, kMaskFilter_DirtyBit, filter != NULL); |
2183 return filter; | 2234 return filter; |
2184 } | 2235 } |
2185 | 2236 |
2186 /////////////////////////////////////////////////////////////////////////////// | 2237 /////////////////////////////////////////////////////////////////////////////// |
2187 | 2238 |
2188 bool SkPaint::getFillPath(const SkPath& src, SkPath* dst, | 2239 bool SkPaint::getFillPath(const SkPath& src, SkPath* dst, |
2189 const SkRect* cullRect) const { | 2240 const SkRect* cullRect) const { |
2190 SkStrokeRec rec(*this); | 2241 SkStrokeRec rec(*this); |
2191 | 2242 |
2192 const SkPath* srcPtr = &src; | 2243 const SkPath* srcPtr = &src; |
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2543 case SkXfermode::kPlus_Mode: | 2594 case SkXfermode::kPlus_Mode: |
2544 return 0 == this->getAlpha(); | 2595 return 0 == this->getAlpha(); |
2545 case SkXfermode::kDst_Mode: | 2596 case SkXfermode::kDst_Mode: |
2546 return true; | 2597 return true; |
2547 default: | 2598 default: |
2548 break; | 2599 break; |
2549 } | 2600 } |
2550 } | 2601 } |
2551 return false; | 2602 return false; |
2552 } | 2603 } |
| 2604 |
| 2605 void SkPaint::setBitfields(uint32_t bitfields) { |
| 2606 fBitfields = bitfields; |
| 2607 fDirtyBits |= kBitfields_DirtyBit; |
| 2608 } |
| 2609 |
| 2610 inline static unsigned popcount(uint8_t x) { |
| 2611 // As in Hacker's delight, adapted for just 8 bits. |
| 2612 x = (x & 0x55) + ((x >> 1) & 0x55); // a b c d w x y z -> a+b c+d w+x y+z |
| 2613 x = (x & 0x33) + ((x >> 2) & 0x33); // a+b c+d w+x y+z -> a+b+c+d w+x+y+z |
| 2614 x = (x & 0x0F) + ((x >> 4) & 0x0F); // a+b+c+d w+x+y+z -> a+b+c+d+w+x+y+z |
| 2615 return x; |
| 2616 } |
| 2617 |
| 2618 void SkPaint::FlatteningTraits::Flatten(SkWriteBuffer& buffer, const SkPaint& pa
int) { |
| 2619 const uint32_t dirty = paint.fDirtyBits; |
| 2620 |
| 2621 // Each of the low 7 dirty bits corresponds to a 4-byte flat value, plus one
for the dirty bits. |
| 2622 const size_t flatBytes = 4 * (popcount(dirty & 127) + 1); |
| 2623 SkASSERT(flatBytes <= 32); |
| 2624 uint32_t* u32 = buffer.reserve(flatBytes); |
| 2625 *u32++ = dirty; |
| 2626 if (dirty == 0) { |
| 2627 return; |
| 2628 } |
| 2629 |
| 2630 #define F(dst, field) if (dirty & k##field##_DirtyBit) *dst++ = paint.get##field
() |
| 2631 F(u32, Color); |
| 2632 F(u32, Bitfields); |
| 2633 SkScalar* f32 = reinterpret_cast<SkScalar*>(u32); |
| 2634 F(f32, TextSize); |
| 2635 F(f32, TextScaleX); |
| 2636 F(f32, TextSkewX); |
| 2637 F(f32, StrokeWidth); |
| 2638 F(f32, StrokeMiter); |
| 2639 #undef F |
| 2640 #define F(field) if (dirty & k##field##_DirtyBit) buffer.writeFlattenable(paint.
get##field()) |
| 2641 F(PathEffect); |
| 2642 F(Shader); |
| 2643 F(Xfermode); |
| 2644 F(MaskFilter); |
| 2645 F(ColorFilter); |
| 2646 F(Rasterizer); |
| 2647 F(Looper); |
| 2648 F(ImageFilter); |
| 2649 #undef F |
| 2650 if (dirty & kTypeface_DirtyBit) buffer.writeTypeface(paint.getTypeface()); |
| 2651 if (dirty & kAnnotation_DirtyBit) paint.getAnnotation()->writeToBuffer(buffe
r); |
| 2652 #ifdef SK_BUILD_FOR_ANDROID |
| 2653 if (dirty & kPaintOptionsAndroid_DirtyBit) paint.getPaintOptionsAndroid().fl
atten(buffer); |
| 2654 #endif |
| 2655 } |
| 2656 |
| 2657 void SkPaint::FlatteningTraits::Unflatten(SkReadBuffer& buffer, SkPaint* paint)
{ |
| 2658 const uint32_t dirty = buffer.readUInt(); |
| 2659 if (dirty == 0) { |
| 2660 return; |
| 2661 } |
| 2662 #define F(field, reader) if (dirty & k##field##_DirtyBit) paint->set##field(buff
er.reader()) |
| 2663 // Same function, except it unrefs the object newly set on the paint: |
| 2664 #define F_UNREF(field, reader) \ |
| 2665 if (dirty & k##field##_DirtyBit) \ |
| 2666 paint->set##field(buffer.reader())->unref() |
| 2667 |
| 2668 F(Color, readUInt); |
| 2669 F(Bitfields, readUInt); |
| 2670 F(TextSize, readScalar); |
| 2671 F(TextScaleX, readScalar); |
| 2672 F(TextSkewX, readScalar); |
| 2673 F(StrokeWidth, readScalar); |
| 2674 F(StrokeMiter, readScalar); |
| 2675 F_UNREF(PathEffect, readPathEffect); |
| 2676 F_UNREF(Shader, readShader); |
| 2677 F_UNREF(Xfermode, readXfermode); |
| 2678 F_UNREF(MaskFilter, readMaskFilter); |
| 2679 F_UNREF(ColorFilter, readColorFilter); |
| 2680 F_UNREF(Rasterizer, readRasterizer); |
| 2681 F_UNREF(Looper, readDrawLooper); |
| 2682 F_UNREF(ImageFilter, readImageFilter); |
| 2683 F(Typeface, readTypeface); |
| 2684 #undef F |
| 2685 #undef F_UNREF |
| 2686 if (dirty & kAnnotation_DirtyBit) { |
| 2687 paint->setAnnotation(SkNEW_ARGS(SkAnnotation, (buffer)))->unref(); |
| 2688 } |
| 2689 #ifdef SK_BUILD_FOR_ANDROID |
| 2690 if (dirty & kPaintOptionsAndroid_DirtyBit) { |
| 2691 SkPaintOptionsAndroid options; |
| 2692 options.unflatten(buffer); |
| 2693 paint->setPaintOptionsAndroid(options); |
| 2694 } |
| 2695 #endif |
| 2696 SkASSERT(dirty == paint->fDirtyBits); |
| 2697 } |
OLD | NEW |