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 18 matching lines...) Expand all Loading... | |
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 { | 38 enum { |
39 kColor_DirtyBit = 1 << 0, | 39 kColor_DirtyBit = 1 << 0, |
robertphillips
2014/04/16 15:39:33
Just delete?
mtklein
2014/04/16 15:53:23
Or // Bit 1 is safe to reuse.
mtklein
2014/04/16 15:54:43
Actually. Hold on. Let's just shift everyone dow
| |
40 kBitfields_DirtyBit = 1 << 1, | 40 // kBitfields_DirtyBit = 1 << 1, |
41 kTextSize_DirtyBit = 1 << 2, | 41 kTextSize_DirtyBit = 1 << 2, |
42 kTextScaleX_DirtyBit = 1 << 3, | 42 kTextScaleX_DirtyBit = 1 << 3, |
43 kTextSkewX_DirtyBit = 1 << 4, | 43 kTextSkewX_DirtyBit = 1 << 4, |
44 kStrokeWidth_DirtyBit = 1 << 5, | 44 kStrokeWidth_DirtyBit = 1 << 5, |
45 kStrokeMiter_DirtyBit = 1 << 6, | 45 kStrokeMiter_DirtyBit = 1 << 6, |
46 kPathEffect_DirtyBit = 1 << 7, | 46 kPathEffect_DirtyBit = 1 << 7, |
47 kShader_DirtyBit = 1 << 8, | 47 kShader_DirtyBit = 1 << 8, |
48 kXfermode_DirtyBit = 1 << 9, | 48 kXfermode_DirtyBit = 1 << 9, |
49 kMaskFilter_DirtyBit = 1 << 10, | 49 kMaskFilter_DirtyBit = 1 << 10, |
50 kColorFilter_DirtyBit = 1 << 11, | 50 kColorFilter_DirtyBit = 1 << 11, |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
247 fPaintOptionsAndroid = options; | 247 fPaintOptionsAndroid = options; |
248 GEN_ID_INC; | 248 GEN_ID_INC; |
249 fDirtyBits |= kPaintOptionsAndroid_DirtyBit; | 249 fDirtyBits |= kPaintOptionsAndroid_DirtyBit; |
250 } | 250 } |
251 } | 251 } |
252 #endif | 252 #endif |
253 | 253 |
254 void SkPaint::setFilterLevel(FilterLevel level) { | 254 void SkPaint::setFilterLevel(FilterLevel level) { |
255 GEN_ID_INC_EVAL((unsigned) level != fFilterLevel); | 255 GEN_ID_INC_EVAL((unsigned) level != fFilterLevel); |
256 fFilterLevel = level; | 256 fFilterLevel = level; |
257 fDirtyBits |= kBitfields_DirtyBit; | |
258 } | 257 } |
259 | 258 |
260 void SkPaint::setHinting(Hinting hintingLevel) { | 259 void SkPaint::setHinting(Hinting hintingLevel) { |
261 GEN_ID_INC_EVAL((unsigned) hintingLevel != fHinting); | 260 GEN_ID_INC_EVAL((unsigned) hintingLevel != fHinting); |
262 fHinting = hintingLevel; | 261 fHinting = hintingLevel; |
263 fDirtyBits |= kBitfields_DirtyBit; | |
264 } | 262 } |
265 | 263 |
266 void SkPaint::setFlags(uint32_t flags) { | 264 void SkPaint::setFlags(uint32_t flags) { |
267 GEN_ID_INC_EVAL(fFlags != flags); | 265 GEN_ID_INC_EVAL(fFlags != flags); |
268 fFlags = flags; | 266 fFlags = flags; |
269 fDirtyBits |= kBitfields_DirtyBit; | |
270 } | 267 } |
271 | 268 |
272 void SkPaint::setAntiAlias(bool doAA) { | 269 void SkPaint::setAntiAlias(bool doAA) { |
273 this->setFlags(SkSetClearMask(fFlags, doAA, kAntiAlias_Flag)); | 270 this->setFlags(SkSetClearMask(fFlags, doAA, kAntiAlias_Flag)); |
274 } | 271 } |
275 | 272 |
276 void SkPaint::setDither(bool doDither) { | 273 void SkPaint::setDither(bool doDither) { |
277 this->setFlags(SkSetClearMask(fFlags, doDither, kDither_Flag)); | 274 this->setFlags(SkSetClearMask(fFlags, doDither, kDither_Flag)); |
278 } | 275 } |
279 | 276 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
318 } | 315 } |
319 | 316 |
320 void SkPaint::setDistanceFieldTextTEMP(bool doDistanceFieldText) { | 317 void SkPaint::setDistanceFieldTextTEMP(bool doDistanceFieldText) { |
321 this->setFlags(SkSetClearMask(fFlags, doDistanceFieldText, kDistanceFieldTex tTEMP_Flag)); | 318 this->setFlags(SkSetClearMask(fFlags, doDistanceFieldText, kDistanceFieldTex tTEMP_Flag)); |
322 } | 319 } |
323 | 320 |
324 void SkPaint::setStyle(Style style) { | 321 void SkPaint::setStyle(Style style) { |
325 if ((unsigned)style < kStyleCount) { | 322 if ((unsigned)style < kStyleCount) { |
326 GEN_ID_INC_EVAL((unsigned)style != fStyle); | 323 GEN_ID_INC_EVAL((unsigned)style != fStyle); |
327 fStyle = style; | 324 fStyle = style; |
328 fDirtyBits |= kBitfields_DirtyBit; | |
329 } else { | 325 } else { |
330 #ifdef SK_REPORT_API_RANGE_CHECK | 326 #ifdef SK_REPORT_API_RANGE_CHECK |
331 SkDebugf("SkPaint::setStyle(%d) out of range\n", style); | 327 SkDebugf("SkPaint::setStyle(%d) out of range\n", style); |
332 #endif | 328 #endif |
333 } | 329 } |
334 } | 330 } |
335 | 331 |
336 void SkPaint::setColor(SkColor color) { | 332 void SkPaint::setColor(SkColor color) { |
337 GEN_ID_INC_EVAL(color != fColor); | 333 GEN_ID_INC_EVAL(color != fColor); |
338 fColor = color; | 334 fColor = color; |
(...skipping 30 matching lines...) Expand all Loading... | |
369 #ifdef SK_REPORT_API_RANGE_CHECK | 365 #ifdef SK_REPORT_API_RANGE_CHECK |
370 SkDebugf("SkPaint::setStrokeMiter() called with negative value\n"); | 366 SkDebugf("SkPaint::setStrokeMiter() called with negative value\n"); |
371 #endif | 367 #endif |
372 } | 368 } |
373 } | 369 } |
374 | 370 |
375 void SkPaint::setStrokeCap(Cap ct) { | 371 void SkPaint::setStrokeCap(Cap ct) { |
376 if ((unsigned)ct < kCapCount) { | 372 if ((unsigned)ct < kCapCount) { |
377 GEN_ID_INC_EVAL((unsigned)ct != fCapType); | 373 GEN_ID_INC_EVAL((unsigned)ct != fCapType); |
378 fCapType = SkToU8(ct); | 374 fCapType = SkToU8(ct); |
379 fDirtyBits |= kBitfields_DirtyBit; | |
380 } else { | 375 } else { |
381 #ifdef SK_REPORT_API_RANGE_CHECK | 376 #ifdef SK_REPORT_API_RANGE_CHECK |
382 SkDebugf("SkPaint::setStrokeCap(%d) out of range\n", ct); | 377 SkDebugf("SkPaint::setStrokeCap(%d) out of range\n", ct); |
383 #endif | 378 #endif |
384 } | 379 } |
385 } | 380 } |
386 | 381 |
387 void SkPaint::setStrokeJoin(Join jt) { | 382 void SkPaint::setStrokeJoin(Join jt) { |
388 if ((unsigned)jt < kJoinCount) { | 383 if ((unsigned)jt < kJoinCount) { |
389 GEN_ID_INC_EVAL((unsigned)jt != fJoinType); | 384 GEN_ID_INC_EVAL((unsigned)jt != fJoinType); |
390 fJoinType = SkToU8(jt); | 385 fJoinType = SkToU8(jt); |
391 fDirtyBits |= kBitfields_DirtyBit; | |
392 } else { | 386 } else { |
393 #ifdef SK_REPORT_API_RANGE_CHECK | 387 #ifdef SK_REPORT_API_RANGE_CHECK |
394 SkDebugf("SkPaint::setStrokeJoin(%d) out of range\n", jt); | 388 SkDebugf("SkPaint::setStrokeJoin(%d) out of range\n", jt); |
395 #endif | 389 #endif |
396 } | 390 } |
397 } | 391 } |
398 | 392 |
399 /////////////////////////////////////////////////////////////////////////////// | 393 /////////////////////////////////////////////////////////////////////////////// |
400 | 394 |
401 void SkPaint::setTextAlign(Align align) { | 395 void SkPaint::setTextAlign(Align align) { |
402 if ((unsigned)align < kAlignCount) { | 396 if ((unsigned)align < kAlignCount) { |
403 GEN_ID_INC_EVAL((unsigned)align != fTextAlign); | 397 GEN_ID_INC_EVAL((unsigned)align != fTextAlign); |
404 fTextAlign = SkToU8(align); | 398 fTextAlign = SkToU8(align); |
405 fDirtyBits |= kBitfields_DirtyBit; | |
406 } else { | 399 } else { |
407 #ifdef SK_REPORT_API_RANGE_CHECK | 400 #ifdef SK_REPORT_API_RANGE_CHECK |
408 SkDebugf("SkPaint::setTextAlign(%d) out of range\n", align); | 401 SkDebugf("SkPaint::setTextAlign(%d) out of range\n", align); |
409 #endif | 402 #endif |
410 } | 403 } |
411 } | 404 } |
412 | 405 |
413 void SkPaint::setTextSize(SkScalar ts) { | 406 void SkPaint::setTextSize(SkScalar ts) { |
414 if (ts >= 0) { | 407 if (ts >= 0) { |
415 GEN_ID_INC_EVAL(ts != fTextSize); | 408 GEN_ID_INC_EVAL(ts != fTextSize); |
(...skipping 15 matching lines...) Expand all Loading... | |
431 void SkPaint::setTextSkewX(SkScalar skewX) { | 424 void SkPaint::setTextSkewX(SkScalar skewX) { |
432 GEN_ID_INC_EVAL(skewX != fTextSkewX); | 425 GEN_ID_INC_EVAL(skewX != fTextSkewX); |
433 fTextSkewX = skewX; | 426 fTextSkewX = skewX; |
434 fDirtyBits |= kTextSkewX_DirtyBit; | 427 fDirtyBits |= kTextSkewX_DirtyBit; |
435 } | 428 } |
436 | 429 |
437 void SkPaint::setTextEncoding(TextEncoding encoding) { | 430 void SkPaint::setTextEncoding(TextEncoding encoding) { |
438 if ((unsigned)encoding <= kGlyphID_TextEncoding) { | 431 if ((unsigned)encoding <= kGlyphID_TextEncoding) { |
439 GEN_ID_INC_EVAL((unsigned)encoding != fTextEncoding); | 432 GEN_ID_INC_EVAL((unsigned)encoding != fTextEncoding); |
440 fTextEncoding = encoding; | 433 fTextEncoding = encoding; |
441 fDirtyBits |= kBitfields_DirtyBit; | |
442 } else { | 434 } else { |
443 #ifdef SK_REPORT_API_RANGE_CHECK | 435 #ifdef SK_REPORT_API_RANGE_CHECK |
444 SkDebugf("SkPaint::setTextEncoding(%d) out of range\n", encoding); | 436 SkDebugf("SkPaint::setTextEncoding(%d) out of range\n", encoding); |
445 #endif | 437 #endif |
446 } | 438 } |
447 } | 439 } |
448 | 440 |
449 /////////////////////////////////////////////////////////////////////////////// | 441 /////////////////////////////////////////////////////////////////////////////// |
450 | 442 |
451 // Returns dst with the given bitmask enabled or disabled, depending on value. | 443 // Returns dst with the given bitmask enabled or disabled, depending on value. |
(...skipping 2191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2643 return true; | 2635 return true; |
2644 default: | 2636 default: |
2645 break; | 2637 break; |
2646 } | 2638 } |
2647 } | 2639 } |
2648 return false; | 2640 return false; |
2649 } | 2641 } |
2650 | 2642 |
2651 void SkPaint::setBitfields(uint32_t bitfields) { | 2643 void SkPaint::setBitfields(uint32_t bitfields) { |
2652 fBitfields = bitfields; | 2644 fBitfields = bitfields; |
2653 fDirtyBits |= kBitfields_DirtyBit; | |
2654 } | 2645 } |
2655 | 2646 |
2656 inline static unsigned popcount(uint8_t x) { | 2647 inline static unsigned popcount(uint8_t x) { |
2657 // As in Hacker's delight, adapted for just 8 bits. | 2648 // As in Hacker's delight, adapted for just 8 bits. |
2658 x = (x & 0x55) + ((x >> 1) & 0x55); // a b c d w x y z -> a+b c+d w+x y+z | 2649 x = (x & 0x55) + ((x >> 1) & 0x55); // a b c d w x y z -> a+b c+d w+x y+z |
2659 x = (x & 0x33) + ((x >> 2) & 0x33); // a+b c+d w+x y+z -> a+b+c+d w+x+y+z | 2650 x = (x & 0x33) + ((x >> 2) & 0x33); // a+b c+d w+x y+z -> a+b+c+d w+x+y+z |
2660 x = (x & 0x0F) + ((x >> 4) & 0x0F); // a+b+c+d w+x+y+z -> a+b+c+d+w+x+y+z | 2651 x = (x & 0x0F) + ((x >> 4) & 0x0F); // a+b+c+d w+x+y+z -> a+b+c+d+w+x+y+z |
2661 return x; | 2652 return x; |
2662 } | 2653 } |
2663 | 2654 |
2664 void SkPaint::FlatteningTraits::Flatten(SkWriteBuffer& buffer, const SkPaint& pa int) { | 2655 void SkPaint::FlatteningTraits::Flatten(SkWriteBuffer& buffer, const SkPaint& pa int) { |
2665 const uint32_t dirty = paint.fDirtyBits; | 2656 const uint32_t dirty = paint.fDirtyBits; |
2666 | 2657 |
2667 // Each of the low 7 dirty bits corresponds to a 4-byte flat value, plus one for the dirty bits. | 2658 // Each of the low 7 dirty bits corresponds to a 4-byte flat value, |
mtklein
2014/04/16 15:53:23
// Each of bits 0,2,3,4,5, and 6 corresponds to a
| |
2668 const size_t flatBytes = 4 * (popcount(dirty & 127) + 1); | 2659 // plus one for the dirty bits and one for the bitfields |
2660 const size_t flatBytes = 4 * (popcount(dirty & 127) + 2); | |
2669 SkASSERT(flatBytes <= 32); | 2661 SkASSERT(flatBytes <= 32); |
2670 uint32_t* u32 = buffer.reserve(flatBytes); | 2662 uint32_t* u32 = buffer.reserve(flatBytes); |
2671 *u32++ = dirty; | 2663 *u32++ = dirty; |
robertphillips
2014/04/16 15:39:33
This is minor but, would it make more sense to rea
| |
2672 if (dirty == 0) { | 2664 *u32++ = paint.getBitfields(); |
2665 if (0 == dirty) { | |
2673 return; | 2666 return; |
2674 } | 2667 } |
2675 | 2668 |
2676 #define F(dst, field) if (dirty & k##field##_DirtyBit) *dst++ = paint.get##field () | 2669 #define F(dst, field) if (dirty & k##field##_DirtyBit) *dst++ = paint.get##field () |
2677 F(u32, Color); | 2670 F(u32, Color); |
2678 F(u32, Bitfields); | |
2679 SkScalar* f32 = reinterpret_cast<SkScalar*>(u32); | 2671 SkScalar* f32 = reinterpret_cast<SkScalar*>(u32); |
2680 F(f32, TextSize); | 2672 F(f32, TextSize); |
2681 F(f32, TextScaleX); | 2673 F(f32, TextScaleX); |
2682 F(f32, TextSkewX); | 2674 F(f32, TextSkewX); |
2683 F(f32, StrokeWidth); | 2675 F(f32, StrokeWidth); |
2684 F(f32, StrokeMiter); | 2676 F(f32, StrokeMiter); |
2685 #undef F | 2677 #undef F |
2686 #define F(field) if (dirty & k##field##_DirtyBit) buffer.writeFlattenable(paint. get##field()) | 2678 #define F(field) if (dirty & k##field##_DirtyBit) buffer.writeFlattenable(paint. get##field()) |
2687 F(PathEffect); | 2679 F(PathEffect); |
2688 F(Shader); | 2680 F(Shader); |
2689 F(Xfermode); | 2681 F(Xfermode); |
2690 F(MaskFilter); | 2682 F(MaskFilter); |
2691 F(ColorFilter); | 2683 F(ColorFilter); |
2692 F(Rasterizer); | 2684 F(Rasterizer); |
2693 F(Looper); | 2685 F(Looper); |
2694 F(ImageFilter); | 2686 F(ImageFilter); |
2695 #undef F | 2687 #undef F |
2696 if (dirty & kTypeface_DirtyBit) buffer.writeTypeface(paint.getTypeface()); | 2688 if (dirty & kTypeface_DirtyBit) buffer.writeTypeface(paint.getTypeface()); |
2697 if (dirty & kAnnotation_DirtyBit) paint.getAnnotation()->writeToBuffer(buffe r); | 2689 if (dirty & kAnnotation_DirtyBit) paint.getAnnotation()->writeToBuffer(buffe r); |
2698 #ifdef SK_BUILD_FOR_ANDROID | 2690 #ifdef SK_BUILD_FOR_ANDROID |
2699 if (dirty & kPaintOptionsAndroid_DirtyBit) paint.getPaintOptionsAndroid().fl atten(buffer); | 2691 if (dirty & kPaintOptionsAndroid_DirtyBit) paint.getPaintOptionsAndroid().fl atten(buffer); |
2700 #endif | 2692 #endif |
2701 } | 2693 } |
2702 | 2694 |
2703 void SkPaint::FlatteningTraits::Unflatten(SkReadBuffer& buffer, SkPaint* paint) { | 2695 void SkPaint::FlatteningTraits::Unflatten(SkReadBuffer& buffer, SkPaint* paint) { |
2704 const uint32_t dirty = buffer.readUInt(); | 2696 const uint32_t dirty = buffer.readUInt(); |
2697 paint->setBitfields(buffer.readUInt()); | |
2705 if (dirty == 0) { | 2698 if (dirty == 0) { |
2706 return; | 2699 return; |
2707 } | 2700 } |
2708 #define F(field, reader) if (dirty & k##field##_DirtyBit) paint->set##field(buff er.reader()) | 2701 #define F(field, reader) if (dirty & k##field##_DirtyBit) paint->set##field(buff er.reader()) |
2709 // Same function, except it unrefs the object newly set on the paint: | 2702 // Same function, except it unrefs the object newly set on the paint: |
2710 #define F_UNREF(field, reader) \ | 2703 #define F_UNREF(field, reader) \ |
2711 if (dirty & k##field##_DirtyBit) \ | 2704 if (dirty & k##field##_DirtyBit) \ |
2712 paint->set##field(buffer.reader())->unref() | 2705 paint->set##field(buffer.reader())->unref() |
2713 | 2706 |
2714 F(Color, readUInt); | 2707 F(Color, readUInt); |
2715 F(Bitfields, readUInt); | |
2716 F(TextSize, readScalar); | 2708 F(TextSize, readScalar); |
2717 F(TextScaleX, readScalar); | 2709 F(TextScaleX, readScalar); |
2718 F(TextSkewX, readScalar); | 2710 F(TextSkewX, readScalar); |
2719 F(StrokeWidth, readScalar); | 2711 F(StrokeWidth, readScalar); |
2720 F(StrokeMiter, readScalar); | 2712 F(StrokeMiter, readScalar); |
2721 F_UNREF(PathEffect, readPathEffect); | 2713 F_UNREF(PathEffect, readPathEffect); |
2722 F_UNREF(Shader, readShader); | 2714 F_UNREF(Shader, readShader); |
2723 F_UNREF(Xfermode, readXfermode); | 2715 F_UNREF(Xfermode, readXfermode); |
2724 F_UNREF(MaskFilter, readMaskFilter); | 2716 F_UNREF(MaskFilter, readMaskFilter); |
2725 F_UNREF(ColorFilter, readColorFilter); | 2717 F_UNREF(ColorFilter, readColorFilter); |
2726 F_UNREF(Rasterizer, readRasterizer); | 2718 F_UNREF(Rasterizer, readRasterizer); |
2727 F_UNREF(Looper, readDrawLooper); | 2719 F_UNREF(Looper, readDrawLooper); |
2728 F_UNREF(ImageFilter, readImageFilter); | 2720 F_UNREF(ImageFilter, readImageFilter); |
2729 F(Typeface, readTypeface); | 2721 F(Typeface, readTypeface); |
2730 #undef F | 2722 #undef F |
2731 #undef F_UNREF | 2723 #undef F_UNREF |
2732 if (dirty & kAnnotation_DirtyBit) { | 2724 if (dirty & kAnnotation_DirtyBit) { |
2733 paint->setAnnotation(SkAnnotation::Create(buffer))->unref(); | 2725 paint->setAnnotation(SkAnnotation::Create(buffer))->unref(); |
2734 } | 2726 } |
2735 #ifdef SK_BUILD_FOR_ANDROID | 2727 #ifdef SK_BUILD_FOR_ANDROID |
2736 if (dirty & kPaintOptionsAndroid_DirtyBit) { | 2728 if (dirty & kPaintOptionsAndroid_DirtyBit) { |
2737 SkPaintOptionsAndroid options; | 2729 SkPaintOptionsAndroid options; |
2738 options.unflatten(buffer); | 2730 options.unflatten(buffer); |
2739 paint->setPaintOptionsAndroid(options); | 2731 paint->setPaintOptionsAndroid(options); |
2740 } | 2732 } |
2741 #endif | 2733 #endif |
2742 SkASSERT(dirty == paint->fDirtyBits); | 2734 SkASSERT(dirty == paint->fDirtyBits); |
2743 } | 2735 } |
OLD | NEW |