|
|
Chromium Code Reviews|
Created:
4 years, 11 months ago by robertphillips Modified:
4 years, 10 months ago Reviewers:
reed1 CC:
reviews_skia.org Base URL:
https://skia.googlesource.com/skia.git@master Target Ref:
refs/heads/master Project:
skia Visibility:
Public. |
DescriptionMove SkAvoidXfermode over from Android
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1649503002
Committed: https://skia.googlesource.com/skia/+/2a1d401bf2d500bab225b78a20cb6f16b2c67efb
Patch Set 1 #Patch Set 2 : update #
Messages
Total messages: 18 (10 generated)
Description was changed from
==========
git diff --git a/include/effects/SkAvoidXfermode.h
b/include/effects/SkAvoidXfermode.h index b1a56b9..c361d1b 100644 ---
a/include/effects/SkAvoidXfermode.h +++ b/include/effects/SkAvoidXfermode.h @@
-67,4 +67,4 @@ private: typedef SkXfermode INHERITED; };
-#endif
\ No newline at end of file
+#endif
diff --git a/src/effects/SkAvoidXfermode.cpp b/src/effects/SkAvoidXfermode.cpp
index eb15d14..7a1c1fc 100644
--- a/src/effects/SkAvoidXfermode.cpp
+++ b/src/effects/SkAvoidXfermode.cpp
@@ -174,4 +174,4 @@ void SkAvoidXfermode::toString(SkString* str) const {
str->appendf("mode: %s", gModeStrings[fMode]);
}
-#endif
\ No newline at end of file
+#endif
Initial commit diff --git a/include/effects/SkAvoidXfermode.h
b/include/effects/SkAvoidXfermode.h new file mode 100644 index 0000000..b1a56b9
--- /dev/null +++ b/include/effects/SkAvoidXfermode.h @@ -0,0 +1,70 @@ +/* + *
Copyright 2006 The Android Open Source Project + * + * Use of this source code
is governed by a BSD-style license that can be + * found in the LICENSE file. +
*/ + +#ifndef SkAvoidXfermode_DEFINED +#define SkAvoidXfermode_DEFINED +
+#include "SkColor.h" +#include "SkTypes.h" +#include "SkXfermode.h" + +/**
\class AvoidXfermode + +This xfermode will draw the src everywhere except on top
of the specified +color. +*/ +class SkAvoidXfermode : public SkXfermode {
+public: + enum Mode { + kAvoidColor_Mode, //!< draw everywhere
except on the opColor + kTargetColor_Mode //!< draw only on top of the
opColor + }; + + /** This xfermode draws, or doesn't draw, based on the
destination's + distance from an op-color. + + There are two modes, and
each mode interprets a tolerance value. + + Avoid: In this mode, drawing is
allowed only on destination pixels that + are different from the op-color. +
Tolerance near 0: avoid any colors even remotely similar to the op-color +
Tolerance near 255: avoid only colors nearly identical to the op-color + +
Target: In this mode, drawing only occurs on destination pixels that + are
similar to the op-color + Tolerance near 0: draw only on colors that are
nearly identical to the op-color + Tolerance near 255: draw on any colors
even remotely similar to the op-color + */ + static SkAvoidXfermode*
Create(SkColor opColor, U8CPU tolerance, Mode mode) { + return new
SkAvoidXfermode(opColor, tolerance, mode); + } + + // overrides from
SkXfermode + void xfer32(SkPMColor dst[], const SkPMColor src[], int count, +
const SkAlpha aa[]) const override; + void xfer16(uint16_t dst[],
const SkPMColor src[], int count, + const SkAlpha aa[]) const override; +
void xferA8(SkAlpha dst[], const SkPMColor src[], int count, + const
SkAlpha aa[]) const override; + + SK_TO_STRING_OVERRIDE() +
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(AvoidXfermode) + +protected:
+ SkAvoidXfermode(SkColor opColor, U8CPU tolerance, Mode mode); + void
flatten(SkWriteBuffer&) const override; + +private: + SkColor fOpColor; +
uint32_t fDistMul; // x.14 cached from fTolerance + uint8_t
fTolerance; + Mode fMode; + + typedef SkXfermode INHERITED; +}; +
+#endif \ No newline at end of file diff --git a/src/effects/SkAvoidXfermode.cpp
b/src/effects/SkAvoidXfermode.cpp new file mode 100644 index 0000000..eb15d14
--- /dev/null +++ b/src/effects/SkAvoidXfermode.cpp @@ -0,0 +1,177 @@ +/* + *
Copyright 2006 The Android Open Source Project + * + * Use of this source code
is governed by a BSD-style license that can be + * found in the LICENSE file. +
*/ + +#include "SkAvoidXfermode.h" +#include "SkColorPriv.h" +#include
"SkReadBuffer.h" +#include "SkWriteBuffer.h" +#include "SkString.h" +
+SkAvoidXfermode::SkAvoidXfermode(SkColor opColor, U8CPU tolerance, Mode mode) {
+ if (tolerance > 255) { + tolerance = 255; + } + fTolerance =
SkToU8(tolerance); + fOpColor = opColor; + fDistMul = (256 << 14) /
(tolerance + 1); + fMode = mode; +} + +SkFlattenable*
SkAvoidXfermode::CreateProc(SkReadBuffer& buffer) { + const SkColor color =
buffer.readColor(); + const unsigned tolerance = buffer.readUInt(); +
const unsigned mode = buffer.readUInt(); + return Create(color, tolerance,
(Mode)mode); +} + +void SkAvoidXfermode::flatten(SkWriteBuffer& buffer) const {
+ buffer.writeColor(fOpColor); + buffer.writeUInt(fTolerance); +
buffer.writeUInt(fMode); +} + +// returns 0..31 +static unsigned
color_dist16(uint16_t c, unsigned r, unsigned g, unsigned b) { + SkASSERT(r
<= SK_R16_MASK); + SkASSERT(g <= SK_G16_MASK); + SkASSERT(b <=
SK_B16_MASK); + + unsigned dr = SkAbs32(SkGetPackedR16(c) - r); + unsigned
dg = SkAbs32(SkGetPackedG16(c) - g) >> (SK_G16_BITS - SK_R16_BITS); +
unsigned db = SkAbs32(SkGetPackedB16(c) - b); + + return SkMax32(dr,
SkMax32(dg, db)); +} + +// returns 0..255 +static unsigned
color_dist32(SkPMColor c, U8CPU r, U8CPU g, U8CPU b) { + SkASSERT(r <= 0xFF);
+ SkASSERT(g <= 0xFF); + SkASSERT(b <= 0xFF); + + unsigned dr =
SkAbs32(SkGetPackedR32(c) - r); + unsigned dg = SkAbs32(SkGetPackedG32(c) -
g); + unsigned db = SkAbs32(SkGetPackedB32(c) - b); + + return SkMax32(dr,
SkMax32(dg, db)); +} + +static int scale_dist_14(int dist, uint32_t mul,
uint32_t sub) { + int tmp = dist * mul - sub; + int result = (tmp + (1 <<
13)) >> 14; + + return result; +} + +static inline unsigned
Accurate255To256(unsigned x) { + return x + (x >> 7); +} + +void
SkAvoidXfermode::xfer32(SkPMColor dst[], const SkPMColor src[], int count, +
const SkAlpha aa[]) const { + unsigned opR = SkColorGetR(fOpColor); +
unsigned opG = SkColorGetG(fOpColor); + unsigned opB =
SkColorGetB(fOpColor); + uint32_t mul = fDistMul; + uint32_t sub =
(fDistMul - (1 << 14)) << 8; + + int MAX, mask; + + if (kTargetColor_Mode
== fMode) { + mask = -1; + MAX = 255; + } else { + mask
= 0; + MAX = 0; + } + + for (int i = 0; i < count; i++) { +
int d = color_dist32(dst[i], opR, opG, opB); + // now reverse d if we
need to + d = MAX + (d ^ mask) - mask; + SkASSERT((unsigned)d <=
255); + d = Accurate255To256(d); + + d = scale_dist_14(d, mul,
sub); + SkASSERT(d <= 256); + + if (d > 0) { + if (aa)
{ + d = SkAlphaMul(d, Accurate255To256(*aa++)); +
if (0 == d) { + continue; + } + } +
dst[i] = SkFourByteInterp256(src[i], dst[i], d); + } + } +}
+ +static inline U16CPU SkBlend3216(SkPMColor src, U16CPU dst, unsigned scale) {
+ SkASSERT(scale <= 32); + scale <<= 3; + + return
SkPackRGB16(SkAlphaBlend(SkPacked32ToR16(src), SkGetPackedR16(dst), scale), +
SkAlphaBlend(SkPacked32ToG16(src), SkGetPackedG16(dst), scale), +
SkAlphaBlend(SkPacked32ToB16(src), SkGetPackedB16(dst), scale)); +} + +void
SkAvoidXfermode::xfer16(uint16_t dst[], const SkPMColor src[], int count, +
const SkAlpha aa[]) const { + unsigned opR = SkColorGetR(fOpColor) >> (8 -
SK_R16_BITS); + unsigned opG = SkColorGetG(fOpColor) >> (8 - SK_G16_BITS);
+ unsigned opB = SkColorGetB(fOpColor) >> (8 - SK_R16_BITS); + uint32_t
mul = fDistMul; + uint32_t sub = (fDistMul - (1 << 14)) << SK_R16_BITS;
+ + int MAX, mask; + + if (kTargetColor_Mode == fMode) { + mask =
-1; + MAX = 31; + } else { + mask = 0; + MAX = 0; + }
+ + for (int i = 0; i < count; i++) { + int d = color_dist16(dst[i],
opR, opG, opB); + // now reverse d if we need to + d = MAX + (d ^
mask) - mask; + SkASSERT((unsigned)d <= 31); + // convert from
0..31 to 0..32 + d += d >> 4; + d = scale_dist_14(d, mul, sub); +
SkASSERT(d <= 32); + + if (d > 0) { + if (aa) { +
d = SkAlphaMul(d, Accurate255To256(*aa++)); + if (0 == d)
{ + continue; + } + } +
dst[i] = SkBlend3216(src[i], dst[i], d); + } + } +} + +void
SkAvoidXfermode::xferA8(SkAlpha dst[], const SkPMColor src[], int count, +
const SkAlpha aa[]) const { +} + +#ifndef SK_IGNORE_TO_STRING +void
SkAvoidXfermode::toString(SkString* str) const { +
str->append("AvoidXfermode: opColor: "); + str->appendHex(fOpColor); +
str->appendf("distMul: %d ", fDistMul); + + static const char* gModeStrings[]
= { "Avoid", "Target" }; + + str->appendf("mode: %s", gModeStrings[fMode]);
+} +#endif \ No newline at end of file diff --git
a/src/ports/SkGlobalInitialization_default.cpp
b/src/ports/SkGlobalInitialization_default.cpp index de50527..4c06817 100644 ---
a/src/ports/SkGlobalInitialization_default.cpp +++
b/src/ports/SkGlobalInitialization_default.cpp @@ -10,6 +10,7 @@ #include
"SkAlphaThresholdFilter.h" #include "SkArithmeticMode.h" #include
"SkArcToPathEffect.h" +#include "SkAvoidXfermode.h" #include
"SkBitmapSourceDeserializer.h" #include "SkBlurDrawLooper.h" #include
"SkBlurImageFilter.h" @@ -82,6 +83,7 @@ void
SkFlattenable::PrivateInitializer::InitEffects() {
// Xfermode
SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPixelXorXfermode)
+ SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkAvoidXfermode)
// PathEffect
SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkArcToPathEffect)
git
BUG=skia:
==========
to
==========
git diff --git a/include/effects/SkAvoidXfermode.h
b/include/effects/SkAvoidXfermode.h index b1a56b9..c361d1b 100644 ---
a/include/effects/SkAvoidXfermode.h +++ b/include/effects/SkAvoidXfermode.h @@
-67,4 +67,4 @@ private: typedef SkXfermode INHERITED; };
-#endif
\ No newline at end of file
+#endif
diff --git a/src/effects/SkAvoidXfermode.cpp b/src/effects/SkAvoidXfermode.cpp
index eb15d14..7a1c1fc 100644
--- a/src/effects/SkAvoidXfermode.cpp
+++ b/src/effects/SkAvoidXfermode.cpp
@@ -174,4 +174,4 @@ void SkAvoidXfermode::toString(SkString* str) const {
str->appendf("mode: %s", gModeStrings[fMode]);
}
-#endif
\ No newline at end of file
+#endif
Initial commit diff --git a/include/effects/SkAvoidXfermode.h
b/include/effects/SkAvoidXfermode.h new file mode 100644 index 0000000..b1a56b9
--- /dev/null +++ b/include/effects/SkAvoidXfermode.h @@ -0,0 +1,70 @@ +/* + *
Copyright 2006 The Android Open Source Project + * + * Use of this source code
is governed by a BSD-style license that can be + * found in the LICENSE file. +
*/ + +#ifndef SkAvoidXfermode_DEFINED +#define SkAvoidXfermode_DEFINED +
+#include "SkColor.h" +#include "SkTypes.h" +#include "SkXfermode.h" + +/**
\class AvoidXfermode + +This xfermode will draw the src everywhere except on top
of the specified +color. +*/ +class SkAvoidXfermode : public SkXfermode {
+public: + enum Mode { + kAvoidColor_Mode, //!< draw everywhere
except on the opColor + kTargetColor_Mode //!< draw only on top of the
opColor + }; + + /** This xfermode draws, or doesn't draw, based on the
destination's + distance from an op-color. + + There are two modes, and
each mode interprets a tolerance value. + + Avoid: In this mode, drawing is
allowed only on destination pixels that + are different from the op-color. +
Tolerance near 0: avoid any colors even remotely similar to the op-color +
Tolerance near 255: avoid only colors nearly identical to the op-color + +
Target: In this mode, drawing only occurs on destination pixels that + are
similar to the op-color + Tolerance near 0: draw only on colors that are
nearly identical to the op-color + Tolerance near 255: draw on any colors
even remotely similar to the op-color + */ + static SkAvoidXfermode*
Create(SkColor opColor, U8CPU tolerance, Mode mode) { + return new
SkAvoidXfermode(opColor, tolerance, mode); + } + + // overrides from
SkXfermode + void xfer32(SkPMColor dst[], const SkPMColor src[], int count, +
const SkAlpha aa[]) const override; + void xfer16(uint16_t dst[],
const SkPMColor src[], int count, + const SkAlpha aa[]) const override; +
void xferA8(SkAlpha dst[], const SkPMColor src[], int count, + const
SkAlpha aa[]) const override; + + SK_TO_STRING_OVERRIDE() +
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(AvoidXfermode) + +protected:
+ SkAvoidXfermode(SkColor opColor, U8CPU tolerance, Mode mode); + void
flatten(SkWriteBuffer&) const override; + +private: + SkColor fOpColor; +
uint32_t fDistMul; // x.14 cached from fTolerance + uint8_t
fTolerance; + Mode fMode; + + typedef SkXfermode INHERITED; +}; +
+#endif \ No newline at end of file diff --git a/src/effects/SkAvoidXfermode.cpp
b/src/effects/SkAvoidXfermode.cpp new file mode 100644 index 0000000..eb15d14
--- /dev/null +++ b/src/effects/SkAvoidXfermode.cpp @@ -0,0 +1,177 @@ +/* + *
Copyright 2006 The Android Open Source Project + * + * Use of this source code
is governed by a BSD-style license that can be + * found in the LICENSE file. +
*/ + +#include "SkAvoidXfermode.h" +#include "SkColorPriv.h" +#include
"SkReadBuffer.h" +#include "SkWriteBuffer.h" +#include "SkString.h" +
+SkAvoidXfermode::SkAvoidXfermode(SkColor opColor, U8CPU tolerance, Mode mode) {
+ if (tolerance > 255) { + tolerance = 255; + } + fTolerance =
SkToU8(tolerance); + fOpColor = opColor; + fDistMul = (256 << 14) /
(tolerance + 1); + fMode = mode; +} + +SkFlattenable*
SkAvoidXfermode::CreateProc(SkReadBuffer& buffer) { + const SkColor color =
buffer.readColor(); + const unsigned tolerance = buffer.readUInt(); +
const unsigned mode = buffer.readUInt(); + return Create(color, tolerance,
(Mode)mode); +} + +void SkAvoidXfermode::flatten(SkWriteBuffer& buffer) const {
+ buffer.writeColor(fOpColor); + buffer.writeUInt(fTolerance); +
buffer.writeUInt(fMode); +} + +// returns 0..31 +static unsigned
color_dist16(uint16_t c, unsigned r, unsigned g, unsigned b) { + SkASSERT(r
<= SK_R16_MASK); + SkASSERT(g <= SK_G16_MASK); + SkASSERT(b <=
SK_B16_MASK); + + unsigned dr = SkAbs32(SkGetPackedR16(c) - r); + unsigned
dg = SkAbs32(SkGetPackedG16(c) - g) >> (SK_G16_BITS - SK_R16_BITS); +
unsigned db = SkAbs32(SkGetPackedB16(c) - b); + + return SkMax32(dr,
SkMax32(dg, db)); +} + +// returns 0..255 +static unsigned
color_dist32(SkPMColor c, U8CPU r, U8CPU g, U8CPU b) { + SkASSERT(r <= 0xFF);
+ SkASSERT(g <= 0xFF); + SkASSERT(b <= 0xFF); + + unsigned dr =
SkAbs32(SkGetPackedR32(c) - r); + unsigned dg = SkAbs32(SkGetPackedG32(c) -
g); + unsigned db = SkAbs32(SkGetPackedB32(c) - b); + + return SkMax32(dr,
SkMax32(dg, db)); +} + +static int scale_dist_14(int dist, uint32_t mul,
uint32_t sub) { + int tmp = dist * mul - sub; + int result = (tmp + (1 <<
13)) >> 14; + + return result; +} + +static inline unsigned
Accurate255To256(unsigned x) { + return x + (x >> 7); +} + +void
SkAvoidXfermode::xfer32(SkPMColor dst[], const SkPMColor src[], int count, +
const SkAlpha aa[]) const { + unsigned opR = SkColorGetR(fOpColor); +
unsigned opG = SkColorGetG(fOpColor); + unsigned opB =
SkColorGetB(fOpColor); + uint32_t mul = fDistMul; + uint32_t sub =
(fDistMul - (1 << 14)) << 8; + + int MAX, mask; + + if (kTargetColor_Mode
== fMode) { + mask = -1; + MAX = 255; + } else { + mask
= 0; + MAX = 0; + } + + for (int i = 0; i < count; i++) { +
int d = color_dist32(dst[i], opR, opG, opB); + // now reverse d if we
need to + d = MAX + (d ^ mask) - mask; + SkASSERT((unsigned)d <=
255); + d = Accurate255To256(d); + + d = scale_dist_14(d, mul,
sub); + SkASSERT(d <= 256); + + if (d > 0) { + if (aa)
{ + d = SkAlphaMul(d, Accurate255To256(*aa++)); +
if (0 == d) { + continue; + } + } +
dst[i] = SkFourByteInterp256(src[i], dst[i], d); + } + } +}
+ +static inline U16CPU SkBlend3216(SkPMColor src, U16CPU dst, unsigned scale) {
+ SkASSERT(scale <= 32); + scale <<= 3; + + return
SkPackRGB16(SkAlphaBlend(SkPacked32ToR16(src), SkGetPackedR16(dst), scale), +
SkAlphaBlend(SkPacked32ToG16(src), SkGetPackedG16(dst), scale), +
SkAlphaBlend(SkPacked32ToB16(src), SkGetPackedB16(dst), scale)); +} + +void
SkAvoidXfermode::xfer16(uint16_t dst[], const SkPMColor src[], int count, +
const SkAlpha aa[]) const { + unsigned opR = SkColorGetR(fOpColor) >> (8 -
SK_R16_BITS); + unsigned opG = SkColorGetG(fOpColor) >> (8 - SK_G16_BITS);
+ unsigned opB = SkColorGetB(fOpColor) >> (8 - SK_R16_BITS); + uint32_t
mul = fDistMul; + uint32_t sub = (fDistMul - (1 << 14)) << SK_R16_BITS;
+ + int MAX, mask; + + if (kTargetColor_Mode == fMode) { + mask =
-1; + MAX = 31; + } else { + mask = 0; + MAX = 0; + }
+ + for (int i = 0; i < count; i++) { + int d = color_dist16(dst[i],
opR, opG, opB); + // now reverse d if we need to + d = MAX + (d ^
mask) - mask; + SkASSERT((unsigned)d <= 31); + // convert from
0..31 to 0..32 + d += d >> 4; + d = scale_dist_14(d, mul, sub); +
SkASSERT(d <= 32); + + if (d > 0) { + if (aa) { +
d = SkAlphaMul(d, Accurate255To256(*aa++)); + if (0 == d)
{ + continue; + } + } +
dst[i] = SkBlend3216(src[i], dst[i], d); + } + } +} + +void
SkAvoidXfermode::xferA8(SkAlpha dst[], const SkPMColor src[], int count, +
const SkAlpha aa[]) const { +} + +#ifndef SK_IGNORE_TO_STRING +void
SkAvoidXfermode::toString(SkString* str) const { +
str->append("AvoidXfermode: opColor: "); + str->appendHex(fOpColor); +
str->appendf("distMul: %d ", fDistMul); + + static const char* gModeStrings[]
= { "Avoid", "Target" }; + + str->appendf("mode: %s", gModeStrings[fMode]);
+} +#endif \ No newline at end of file diff --git
a/src/ports/SkGlobalInitialization_default.cpp
b/src/ports/SkGlobalInitialization_default.cpp index de50527..4c06817 100644 ---
a/src/ports/SkGlobalInitialization_default.cpp +++
b/src/ports/SkGlobalInitialization_default.cpp @@ -10,6 +10,7 @@ #include
"SkAlphaThresholdFilter.h" #include "SkArithmeticMode.h" #include
"SkArcToPathEffect.h" +#include "SkAvoidXfermode.h" #include
"SkBitmapSourceDeserializer.h" #include "SkBlurDrawLooper.h" #include
"SkBlurImageFilter.h" @@ -82,6 +83,7 @@ void
SkFlattenable::PrivateInitializer::InitEffects() {
// Xfermode
SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPixelXorXfermode)
+ SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkAvoidXfermode)
// PathEffect
SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkArcToPathEffect)
git
BUG=skia:
GOLD_TRYBOT_URL=
https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&is...
==========
Description was changed from
==========
git diff --git a/include/effects/SkAvoidXfermode.h
b/include/effects/SkAvoidXfermode.h index b1a56b9..c361d1b 100644 ---
a/include/effects/SkAvoidXfermode.h +++ b/include/effects/SkAvoidXfermode.h @@
-67,4 +67,4 @@ private: typedef SkXfermode INHERITED; };
-#endif
\ No newline at end of file
+#endif
diff --git a/src/effects/SkAvoidXfermode.cpp b/src/effects/SkAvoidXfermode.cpp
index eb15d14..7a1c1fc 100644
--- a/src/effects/SkAvoidXfermode.cpp
+++ b/src/effects/SkAvoidXfermode.cpp
@@ -174,4 +174,4 @@ void SkAvoidXfermode::toString(SkString* str) const {
str->appendf("mode: %s", gModeStrings[fMode]);
}
-#endif
\ No newline at end of file
+#endif
Initial commit diff --git a/include/effects/SkAvoidXfermode.h
b/include/effects/SkAvoidXfermode.h new file mode 100644 index 0000000..b1a56b9
--- /dev/null +++ b/include/effects/SkAvoidXfermode.h @@ -0,0 +1,70 @@ +/* + *
Copyright 2006 The Android Open Source Project + * + * Use of this source code
is governed by a BSD-style license that can be + * found in the LICENSE file. +
*/ + +#ifndef SkAvoidXfermode_DEFINED +#define SkAvoidXfermode_DEFINED +
+#include "SkColor.h" +#include "SkTypes.h" +#include "SkXfermode.h" + +/**
\class AvoidXfermode + +This xfermode will draw the src everywhere except on top
of the specified +color. +*/ +class SkAvoidXfermode : public SkXfermode {
+public: + enum Mode { + kAvoidColor_Mode, //!< draw everywhere
except on the opColor + kTargetColor_Mode //!< draw only on top of the
opColor + }; + + /** This xfermode draws, or doesn't draw, based on the
destination's + distance from an op-color. + + There are two modes, and
each mode interprets a tolerance value. + + Avoid: In this mode, drawing is
allowed only on destination pixels that + are different from the op-color. +
Tolerance near 0: avoid any colors even remotely similar to the op-color +
Tolerance near 255: avoid only colors nearly identical to the op-color + +
Target: In this mode, drawing only occurs on destination pixels that + are
similar to the op-color + Tolerance near 0: draw only on colors that are
nearly identical to the op-color + Tolerance near 255: draw on any colors
even remotely similar to the op-color + */ + static SkAvoidXfermode*
Create(SkColor opColor, U8CPU tolerance, Mode mode) { + return new
SkAvoidXfermode(opColor, tolerance, mode); + } + + // overrides from
SkXfermode + void xfer32(SkPMColor dst[], const SkPMColor src[], int count, +
const SkAlpha aa[]) const override; + void xfer16(uint16_t dst[],
const SkPMColor src[], int count, + const SkAlpha aa[]) const override; +
void xferA8(SkAlpha dst[], const SkPMColor src[], int count, + const
SkAlpha aa[]) const override; + + SK_TO_STRING_OVERRIDE() +
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(AvoidXfermode) + +protected:
+ SkAvoidXfermode(SkColor opColor, U8CPU tolerance, Mode mode); + void
flatten(SkWriteBuffer&) const override; + +private: + SkColor fOpColor; +
uint32_t fDistMul; // x.14 cached from fTolerance + uint8_t
fTolerance; + Mode fMode; + + typedef SkXfermode INHERITED; +}; +
+#endif \ No newline at end of file diff --git a/src/effects/SkAvoidXfermode.cpp
b/src/effects/SkAvoidXfermode.cpp new file mode 100644 index 0000000..eb15d14
--- /dev/null +++ b/src/effects/SkAvoidXfermode.cpp @@ -0,0 +1,177 @@ +/* + *
Copyright 2006 The Android Open Source Project + * + * Use of this source code
is governed by a BSD-style license that can be + * found in the LICENSE file. +
*/ + +#include "SkAvoidXfermode.h" +#include "SkColorPriv.h" +#include
"SkReadBuffer.h" +#include "SkWriteBuffer.h" +#include "SkString.h" +
+SkAvoidXfermode::SkAvoidXfermode(SkColor opColor, U8CPU tolerance, Mode mode) {
+ if (tolerance > 255) { + tolerance = 255; + } + fTolerance =
SkToU8(tolerance); + fOpColor = opColor; + fDistMul = (256 << 14) /
(tolerance + 1); + fMode = mode; +} + +SkFlattenable*
SkAvoidXfermode::CreateProc(SkReadBuffer& buffer) { + const SkColor color =
buffer.readColor(); + const unsigned tolerance = buffer.readUInt(); +
const unsigned mode = buffer.readUInt(); + return Create(color, tolerance,
(Mode)mode); +} + +void SkAvoidXfermode::flatten(SkWriteBuffer& buffer) const {
+ buffer.writeColor(fOpColor); + buffer.writeUInt(fTolerance); +
buffer.writeUInt(fMode); +} + +// returns 0..31 +static unsigned
color_dist16(uint16_t c, unsigned r, unsigned g, unsigned b) { + SkASSERT(r
<= SK_R16_MASK); + SkASSERT(g <= SK_G16_MASK); + SkASSERT(b <=
SK_B16_MASK); + + unsigned dr = SkAbs32(SkGetPackedR16(c) - r); + unsigned
dg = SkAbs32(SkGetPackedG16(c) - g) >> (SK_G16_BITS - SK_R16_BITS); +
unsigned db = SkAbs32(SkGetPackedB16(c) - b); + + return SkMax32(dr,
SkMax32(dg, db)); +} + +// returns 0..255 +static unsigned
color_dist32(SkPMColor c, U8CPU r, U8CPU g, U8CPU b) { + SkASSERT(r <= 0xFF);
+ SkASSERT(g <= 0xFF); + SkASSERT(b <= 0xFF); + + unsigned dr =
SkAbs32(SkGetPackedR32(c) - r); + unsigned dg = SkAbs32(SkGetPackedG32(c) -
g); + unsigned db = SkAbs32(SkGetPackedB32(c) - b); + + return SkMax32(dr,
SkMax32(dg, db)); +} + +static int scale_dist_14(int dist, uint32_t mul,
uint32_t sub) { + int tmp = dist * mul - sub; + int result = (tmp + (1 <<
13)) >> 14; + + return result; +} + +static inline unsigned
Accurate255To256(unsigned x) { + return x + (x >> 7); +} + +void
SkAvoidXfermode::xfer32(SkPMColor dst[], const SkPMColor src[], int count, +
const SkAlpha aa[]) const { + unsigned opR = SkColorGetR(fOpColor); +
unsigned opG = SkColorGetG(fOpColor); + unsigned opB =
SkColorGetB(fOpColor); + uint32_t mul = fDistMul; + uint32_t sub =
(fDistMul - (1 << 14)) << 8; + + int MAX, mask; + + if (kTargetColor_Mode
== fMode) { + mask = -1; + MAX = 255; + } else { + mask
= 0; + MAX = 0; + } + + for (int i = 0; i < count; i++) { +
int d = color_dist32(dst[i], opR, opG, opB); + // now reverse d if we
need to + d = MAX + (d ^ mask) - mask; + SkASSERT((unsigned)d <=
255); + d = Accurate255To256(d); + + d = scale_dist_14(d, mul,
sub); + SkASSERT(d <= 256); + + if (d > 0) { + if (aa)
{ + d = SkAlphaMul(d, Accurate255To256(*aa++)); +
if (0 == d) { + continue; + } + } +
dst[i] = SkFourByteInterp256(src[i], dst[i], d); + } + } +}
+ +static inline U16CPU SkBlend3216(SkPMColor src, U16CPU dst, unsigned scale) {
+ SkASSERT(scale <= 32); + scale <<= 3; + + return
SkPackRGB16(SkAlphaBlend(SkPacked32ToR16(src), SkGetPackedR16(dst), scale), +
SkAlphaBlend(SkPacked32ToG16(src), SkGetPackedG16(dst), scale), +
SkAlphaBlend(SkPacked32ToB16(src), SkGetPackedB16(dst), scale)); +} + +void
SkAvoidXfermode::xfer16(uint16_t dst[], const SkPMColor src[], int count, +
const SkAlpha aa[]) const { + unsigned opR = SkColorGetR(fOpColor) >> (8 -
SK_R16_BITS); + unsigned opG = SkColorGetG(fOpColor) >> (8 - SK_G16_BITS);
+ unsigned opB = SkColorGetB(fOpColor) >> (8 - SK_R16_BITS); + uint32_t
mul = fDistMul; + uint32_t sub = (fDistMul - (1 << 14)) << SK_R16_BITS;
+ + int MAX, mask; + + if (kTargetColor_Mode == fMode) { + mask =
-1; + MAX = 31; + } else { + mask = 0; + MAX = 0; + }
+ + for (int i = 0; i < count; i++) { + int d = color_dist16(dst[i],
opR, opG, opB); + // now reverse d if we need to + d = MAX + (d ^
mask) - mask; + SkASSERT((unsigned)d <= 31); + // convert from
0..31 to 0..32 + d += d >> 4; + d = scale_dist_14(d, mul, sub); +
SkASSERT(d <= 32); + + if (d > 0) { + if (aa) { +
d = SkAlphaMul(d, Accurate255To256(*aa++)); + if (0 == d)
{ + continue; + } + } +
dst[i] = SkBlend3216(src[i], dst[i], d); + } + } +} + +void
SkAvoidXfermode::xferA8(SkAlpha dst[], const SkPMColor src[], int count, +
const SkAlpha aa[]) const { +} + +#ifndef SK_IGNORE_TO_STRING +void
SkAvoidXfermode::toString(SkString* str) const { +
str->append("AvoidXfermode: opColor: "); + str->appendHex(fOpColor); +
str->appendf("distMul: %d ", fDistMul); + + static const char* gModeStrings[]
= { "Avoid", "Target" }; + + str->appendf("mode: %s", gModeStrings[fMode]);
+} +#endif \ No newline at end of file diff --git
a/src/ports/SkGlobalInitialization_default.cpp
b/src/ports/SkGlobalInitialization_default.cpp index de50527..4c06817 100644 ---
a/src/ports/SkGlobalInitialization_default.cpp +++
b/src/ports/SkGlobalInitialization_default.cpp @@ -10,6 +10,7 @@ #include
"SkAlphaThresholdFilter.h" #include "SkArithmeticMode.h" #include
"SkArcToPathEffect.h" +#include "SkAvoidXfermode.h" #include
"SkBitmapSourceDeserializer.h" #include "SkBlurDrawLooper.h" #include
"SkBlurImageFilter.h" @@ -82,6 +83,7 @@ void
SkFlattenable::PrivateInitializer::InitEffects() {
// Xfermode
SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPixelXorXfermode)
+ SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkAvoidXfermode)
// PathEffect
SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkArcToPathEffect)
git
BUG=skia:
GOLD_TRYBOT_URL=
https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&is...
==========
to
==========
Move SkAvoidXfermode over from Android
GOLD_TRYBOT_URL=
https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&is...
==========
robertphillips@google.com changed reviewers: + reed@google.com
I will move the .h & .cpp once the platform-specific location CL lands.
lgtm
The CQ bit was checked by robertphillips@google.com to run a CQ dry run
Dry run: CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/patch-status/1649503002/40001 View timeline at https://chromium-cq-status.appspot.com/patch-timeline/1649503002/40001
The CQ bit was unchecked by commit-bot@chromium.org
Dry run: This issue passed the CQ dry run.
Patchset #3 (id:40001) has been deleted
The CQ bit was checked by robertphillips@google.com to run a CQ dry run
Dry run: CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/patch-status/1649503002/20001 View timeline at https://chromium-cq-status.appspot.com/patch-timeline/1649503002/20001
The CQ bit was unchecked by commit-bot@chromium.org
Dry run: This issue passed the CQ dry run.
The CQ bit was checked by robertphillips@google.com
CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/patch-status/1649503002/20001 View timeline at https://chromium-cq-status.appspot.com/patch-timeline/1649503002/20001
Message was sent while issue was closed.
Description was changed from ========== Move SkAvoidXfermode over from Android GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&is... ========== to ========== Move SkAvoidXfermode over from Android GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&is... Committed: https://skia.googlesource.com/skia/+/2a1d401bf2d500bab225b78a20cb6f16b2c67efb ==========
Message was sent while issue was closed.
Committed patchset #2 (id:20001) as https://skia.googlesource.com/skia/+/2a1d401bf2d500bab225b78a20cb6f16b2c67efb |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
