| Index: src/core/SkPaint.cpp
|
| diff --git a/src/core/SkPaint.cpp b/src/core/SkPaint.cpp
|
| index 9cb61bd9d128707299306f36f695bd2eb7f1d9df..682c4ed19ec1346a9309674eaf2feb582f67ee41 100644
|
| --- a/src/core/SkPaint.cpp
|
| +++ b/src/core/SkPaint.cpp
|
| @@ -251,27 +251,10 @@ void SkPaint::setPaintOptionsAndroid(const SkPaintOptionsAndroid& options) {
|
| }
|
| #endif
|
|
|
| -SkPaint::FilterLevel SkPaint::getFilterLevel() const {
|
| - int level = 0;
|
| - if (fFlags & kFilterBitmap_Flag) {
|
| - level |= 1;
|
| - }
|
| - if (fFlags & kHighQualityFilterBitmap_Flag) {
|
| - level |= 2;
|
| - }
|
| - return (FilterLevel)level;
|
| -}
|
| -
|
| void SkPaint::setFilterLevel(FilterLevel level) {
|
| - unsigned mask = kFilterBitmap_Flag | kHighQualityFilterBitmap_Flag;
|
| - unsigned flags = 0;
|
| - if (level & 1) {
|
| - flags |= kFilterBitmap_Flag;
|
| - }
|
| - if (level & 2) {
|
| - flags |= kHighQualityFilterBitmap_Flag;
|
| - }
|
| - this->setFlags((fFlags & ~mask) | flags);
|
| + GEN_ID_INC_EVAL((unsigned) level != fFilterLevel);
|
| + fFilterLevel = level;
|
| + fDirtyBits |= kBitfields_DirtyBit;
|
| }
|
|
|
| void SkPaint::setHinting(Hinting hintingLevel) {
|
| @@ -2026,12 +2009,89 @@ static uint32_t pack_4(unsigned a, unsigned b, unsigned c, unsigned d) {
|
| return (a << 24) | (b << 16) | (c << 8) | d;
|
| }
|
|
|
| +#ifdef SK_DEBUG
|
| + static void ASSERT_FITS_IN(uint32_t value, int bitCount) {
|
| + SkASSERT(bitCount > 0 && bitCount <= 32);
|
| + uint32_t mask = ~0U;
|
| + mask >>= (32 - bitCount);
|
| + SkASSERT(0 == (value & ~mask));
|
| + }
|
| +#else
|
| + #define ASSERT_FITS_IN(value, bitcount)
|
| +#endif
|
| +
|
| enum FlatFlags {
|
| kHasTypeface_FlatFlag = 0x01,
|
| kHasEffects_FlatFlag = 0x02,
|
| kHasNonDefaultPaintOptionsAndroid_FlatFlag = 0x04,
|
| +
|
| + kFlatFlagMask = 0x7,
|
| +};
|
| +
|
| +enum BitsPerField {
|
| + kFlags_BPF = 16,
|
| + kHint_BPF = 2,
|
| + kAlign_BPF = 2,
|
| + kFilter_BPF = 2,
|
| + kFlatFlags_BPF = 3,
|
| };
|
|
|
| +static inline int BPF_Mask(int bits) {
|
| + return (1 << bits) - 1;
|
| +}
|
| +
|
| +static uint32_t pack_paint_flags(unsigned flags, unsigned hint, unsigned align,
|
| + unsigned filter, unsigned flatFlags) {
|
| + ASSERT_FITS_IN(flags, kFlags_BPF);
|
| + ASSERT_FITS_IN(hint, kHint_BPF);
|
| + ASSERT_FITS_IN(align, kAlign_BPF);
|
| + ASSERT_FITS_IN(filter, kFilter_BPF);
|
| + ASSERT_FITS_IN(flatFlags, kFlatFlags_BPF);
|
| +
|
| + // left-align the fields of "known" size, and right-align the last (flatFlags) so it can easly
|
| + // add more bits in the future.
|
| + return (flags << 16) | (hint << 14) | (align << 12) | (filter << 10) | flatFlags;
|
| +}
|
| +
|
| +static FlatFlags unpack_paint_flags(SkPaint* paint, uint32_t packed) {
|
| + paint->setFlags(packed >> 16);
|
| + paint->setHinting((SkPaint::Hinting)((packed >> 14) & BPF_Mask(kHint_BPF)));
|
| + paint->setTextAlign((SkPaint::Align)((packed >> 12) & BPF_Mask(kAlign_BPF)));
|
| + paint->setFilterLevel((SkPaint::FilterLevel)((packed >> 10) & BPF_Mask(kFilter_BPF)));
|
| + return (FlatFlags)(packed & kFlatFlagMask);
|
| +}
|
| +
|
| +// V22_COMPATIBILITY_CODE
|
| +static FlatFlags unpack_paint_flags_v22(SkPaint* paint, uint32_t packed) {
|
| + enum {
|
| + kFilterBitmap_Flag = 0x02,
|
| + kHighQualityFilterBitmap_Flag = 0x4000,
|
| +
|
| + kAll_Flags = kFilterBitmap_Flag | kHighQualityFilterBitmap_Flag
|
| + };
|
| +
|
| + // previously flags:16, textAlign:8, flatFlags:8
|
| + // now flags:16, hinting:4, textAlign:4, flatFlags:8
|
| + unsigned flags = packed >> 16;
|
| + int filter = 0;
|
| + if (flags & kFilterBitmap_Flag) {
|
| + filter |= 1;
|
| + }
|
| + if (flags & kHighQualityFilterBitmap_Flag) {
|
| + filter |= 2;
|
| + }
|
| + paint->setFilterLevel((SkPaint::FilterLevel)filter);
|
| + flags &= ~kAll_Flags; // remove these (now dead) bit flags
|
| +
|
| + paint->setFlags(flags);
|
| +
|
| + // hinting added later. 0 in this nibble means use the default.
|
| + uint32_t hinting = (packed >> 12) & 0xF;
|
| + paint->setHinting(0 == hinting ? SkPaint::kNormal_Hinting : static_cast<SkPaint::Hinting>(hinting-1));
|
| + paint->setTextAlign(static_cast<SkPaint::Align>((packed >> 8) & 0xF));
|
| + return (FlatFlags)(packed & kFlatFlagMask);
|
| +}
|
| +
|
| // The size of a flat paint's POD fields
|
| static const uint32_t kPODPaintSize = 5 * sizeof(SkScalar) +
|
| 1 * sizeof(SkColor) +
|
| @@ -2072,13 +2132,9 @@ void SkPaint::flatten(SkWriteBuffer& buffer) const {
|
| ptr = write_scalar(ptr, this->getStrokeWidth());
|
| ptr = write_scalar(ptr, this->getStrokeMiter());
|
| *ptr++ = this->getColor();
|
| - // previously flags:16, textAlign:8, flatFlags:8
|
| - // now flags:16, hinting:4, textAlign:4, flatFlags:8
|
| - *ptr++ = (this->getFlags() << 16) |
|
| - // hinting added later. 0 in this nibble means use the default.
|
| - ((this->getHinting()+1) << 12) |
|
| - (this->getTextAlign() << 8) |
|
| - flatFlags;
|
| +
|
| + *ptr++ = pack_paint_flags(this->getFlags(), this->getHinting(), this->getTextAlign(),
|
| + this->getFilterLevel(), flatFlags);
|
| *ptr++ = pack_4(this->getStrokeCap(), this->getStrokeJoin(),
|
| this->getStyle(), this->getTextEncoding());
|
|
|
| @@ -2112,7 +2168,6 @@ void SkPaint::flatten(SkWriteBuffer& buffer) const {
|
| }
|
|
|
| void SkPaint::unflatten(SkReadBuffer& buffer) {
|
| - uint8_t flatFlags = 0;
|
| SkASSERT(SkAlign4(kPODPaintSize) == kPODPaintSize);
|
| const void* podData = buffer.skip(kPODPaintSize);
|
| const uint32_t* pod = reinterpret_cast<const uint32_t*>(podData);
|
| @@ -2125,20 +2180,15 @@ void SkPaint::unflatten(SkReadBuffer& buffer) {
|
| this->setStrokeMiter(read_scalar(pod));
|
| this->setColor(*pod++);
|
|
|
| - // previously flags:16, textAlign:8, flatFlags:8
|
| - // now flags:16, hinting:4, textAlign:4, flatFlags:8
|
| - uint32_t tmp = *pod++;
|
| - this->setFlags(tmp >> 16);
|
| -
|
| - // hinting added later. 0 in this nibble means use the default.
|
| - uint32_t hinting = (tmp >> 12) & 0xF;
|
| - this->setHinting(0 == hinting ? kNormal_Hinting : static_cast<Hinting>(hinting-1));
|
| -
|
| - this->setTextAlign(static_cast<Align>((tmp >> 8) & 0xF));
|
| -
|
| - flatFlags = tmp & 0xFF;
|
| + const int picVer = buffer.pictureVersion();
|
| + unsigned flatFlags = 0;
|
| + if (picVer > 0 && picVer <= 22) {
|
| + flatFlags = unpack_paint_flags_v22(this, *pod++);
|
| + } else {
|
| + flatFlags = unpack_paint_flags(this, *pod++);
|
| + }
|
|
|
| - tmp = *pod++;
|
| + uint32_t tmp = *pod++;
|
| this->setStrokeCap(static_cast<Cap>((tmp >> 24) & 0xFF));
|
| this->setStrokeJoin(static_cast<Join>((tmp >> 16) & 0xFF));
|
| this->setStyle(static_cast<Style>((tmp >> 8) & 0xFF));
|
|
|