aboutsummaryrefslogtreecommitdiffstats
path: root/src/core/SkXfermode.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/SkXfermode.cpp')
-rw-r--r--src/core/SkXfermode.cpp242
1 files changed, 130 insertions, 112 deletions
diff --git a/src/core/SkXfermode.cpp b/src/core/SkXfermode.cpp
index 110ccb3..90cf13a 100644
--- a/src/core/SkXfermode.cpp
+++ b/src/core/SkXfermode.cpp
@@ -98,7 +98,7 @@ static SkPMColor dst_modeproc(SkPMColor src, SkPMColor dst) {
return dst;
}
-// kSrcOver_Mode, //!< [Sa + Da - Sa*Da, Sc + (1 - Sa)*Dc]
+// kSrcOver_Mode, //!< [Sa + Da - Sa*Da, Sc + (1 - Sa)*Dc]
static SkPMColor srcover_modeproc(SkPMColor src, SkPMColor dst) {
#if 0
// this is the old, more-correct way, but it doesn't guarantee that dst==255
@@ -335,7 +335,7 @@ static SkPMColor colorburn_modeproc(SkPMColor src, SkPMColor dst) {
if (0 == dst) {
return src;
}
-
+
int sa = SkGetPackedA32(src);
int da = SkGetPackedA32(dst);
int a = srcover_byte(sa, da);
@@ -469,7 +469,7 @@ bool SkXfermode::asCoeff(Coeff* src, Coeff* dst) {
}
bool SkXfermode::asMode(Mode* mode) {
- return IsMode(this, mode);
+ return false;
}
SkPMColor SkXfermode::xferColor(SkPMColor src, SkPMColor dst) {
@@ -531,7 +531,7 @@ void SkXfermode::xfer4444(SK_RESTRICT SkPMColor16 dst[],
const SK_RESTRICT SkAlpha aa[])
{
SkASSERT(dst && src && count >= 0);
-
+
if (NULL == aa) {
for (int i = count - 1; i >= 0; --i) {
SkPMColor dstC = SkPixel4444ToPixel32(dst[i]);
@@ -642,7 +642,7 @@ void SkProcXfermode::xfer4444(SK_RESTRICT SkPMColor16 dst[],
const SK_RESTRICT SkPMColor src[], int count,
const SK_RESTRICT SkAlpha aa[]) {
SkASSERT(dst && src && count >= 0);
-
+
SkXfermodeProc proc = fProc;
if (NULL != proc) {
@@ -700,24 +700,10 @@ void SkProcXfermode::xferA8(SK_RESTRICT SkAlpha dst[],
SkProcXfermode::SkProcXfermode(SkFlattenableReadBuffer& buffer)
: SkXfermode(buffer) {
fProc = (SkXfermodeProc)buffer.readFunctionPtr();
- fMode = (Mode) buffer.readInt();
}
void SkProcXfermode::flatten(SkFlattenableWriteBuffer& buffer) {
buffer.writeFunctionPtr((void*)fProc);
- buffer.writeInt(fMode);
-}
-
-bool SkProcXfermode::asMode(SkXfermode::Mode* mode) {
- for (size_t i = 0; i < SK_ARRAY_COUNT(gProcCoeffs); i++) {
- if (gProcCoeffs[i].fProc == fProc) {
- if (mode) {
- *mode = static_cast<Mode>(i);
- }
- return true;
- }
- }
- return false;
}
///////////////////////////////////////////////////////////////////////////////
@@ -725,11 +711,26 @@ bool SkProcXfermode::asMode(SkXfermode::Mode* mode) {
class SkProcCoeffXfermode : public SkProcXfermode {
public:
- SkProcCoeffXfermode(SkXfermodeProc proc, Coeff sc, Coeff dc)
- : INHERITED(proc), fSrcCoeff(sc), fDstCoeff(dc) {
+ SkProcCoeffXfermode(const ProcCoeff& rec, Mode mode)
+ : INHERITED(rec.fProc) {
+ fMode = mode;
+ // these may be valid, or may be CANNOT_USE_COEFF
+ fSrcCoeff = rec.fSC;
+ fDstCoeff = rec.fDC;
}
-
+
+ virtual bool asMode(Mode* mode) {
+ if (mode) {
+ *mode = fMode;
+ }
+ return true;
+ }
+
virtual bool asCoeff(Coeff* sc, Coeff* dc) {
+ if (CANNOT_USE_COEFF == fSrcCoeff) {
+ return false;
+ }
+
if (sc) {
*sc = fSrcCoeff;
}
@@ -738,26 +739,31 @@ public:
}
return true;
}
-
+
virtual Factory getFactory() { return CreateProc; }
virtual void flatten(SkFlattenableWriteBuffer& buffer) {
this->INHERITED::flatten(buffer);
+ buffer.write32(fMode);
buffer.write32(fSrcCoeff);
buffer.write32(fDstCoeff);
}
+ static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
+ return SkNEW_ARGS(SkProcCoeffXfermode, (buffer));
+ }
+
protected:
SkProcCoeffXfermode(SkFlattenableReadBuffer& buffer)
: INHERITED(buffer) {
+ fMode = (SkXfermode::Mode)buffer.readU32();
fSrcCoeff = (Coeff)buffer.readU32();
fDstCoeff = (Coeff)buffer.readU32();
}
-
+
private:
+ Mode fMode;
Coeff fSrcCoeff, fDstCoeff;
-
- static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
- return SkNEW_ARGS(SkProcCoeffXfermode, (buffer)); }
+
typedef SkProcXfermode INHERITED;
};
@@ -766,8 +772,7 @@ private:
class SkClearXfermode : public SkProcCoeffXfermode {
public:
- SkClearXfermode() : SkProcCoeffXfermode(clear_modeproc,
- kZero_Coeff, kZero_Coeff) {}
+ SkClearXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kClear_Mode) {}
virtual void xfer32(SK_RESTRICT SkPMColor dst[],
const SK_RESTRICT SkPMColor[], int count,
@@ -805,24 +810,24 @@ public:
}
}
}
-
+
virtual Factory getFactory() { return CreateProc; }
-private:
- SkClearXfermode(SkFlattenableReadBuffer& buffer)
- : SkProcCoeffXfermode(buffer) {}
-
static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
return SkNEW_ARGS(SkClearXfermode, (buffer));
}
+
+private:
+ SkClearXfermode(SkFlattenableReadBuffer& buffer)
+ : SkProcCoeffXfermode(buffer) {}
+
};
///////////////////////////////////////////////////////////////////////////////
class SkSrcXfermode : public SkProcCoeffXfermode {
public:
- SkSrcXfermode() : SkProcCoeffXfermode(src_modeproc,
- kOne_Coeff, kZero_Coeff) {}
+ SkSrcXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kSrc_Mode) {}
virtual void xfer32(SK_RESTRICT SkPMColor dst[],
const SK_RESTRICT SkPMColor src[], int count,
@@ -866,35 +871,35 @@ public:
}
}
}
-
+
virtual Factory getFactory() { return CreateProc; }
-private:
- SkSrcXfermode(SkFlattenableReadBuffer& buffer)
- : SkProcCoeffXfermode(buffer) {}
-
static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
return SkNEW_ARGS(SkSrcXfermode, (buffer));
}
+
+private:
+ SkSrcXfermode(SkFlattenableReadBuffer& buffer)
+ : SkProcCoeffXfermode(buffer) {}
+
};
class SkDstInXfermode : public SkProcCoeffXfermode {
public:
- SkDstInXfermode() : SkProcCoeffXfermode(dstin_modeproc,
- kZero_Coeff, kSA_Coeff) {}
-
+ SkDstInXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kDstIn_Mode) {}
+
virtual void xfer32(SK_RESTRICT SkPMColor dst[],
const SK_RESTRICT SkPMColor src[], int count,
const SK_RESTRICT SkAlpha aa[]) {
SkASSERT(dst && src);
-
+
if (count <= 0) {
return;
}
if (NULL != aa) {
return this->INHERITED::xfer32(dst, src, count, aa);
}
-
+
do {
unsigned a = SkGetPackedA32(*src);
*dst = SkAlphaMulQ(*dst, SkAlpha255To256(a));
@@ -902,36 +907,35 @@ public:
src++;
} while (--count != 0);
}
-
+
virtual Factory getFactory() { return CreateProc; }
-
-private:
- SkDstInXfermode(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {}
-
+
static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
return SkNEW_ARGS(SkDstInXfermode, (buffer));
}
-
+
+private:
+ SkDstInXfermode(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {}
+
typedef SkProcCoeffXfermode INHERITED;
};
class SkDstOutXfermode : public SkProcCoeffXfermode {
public:
- SkDstOutXfermode() : SkProcCoeffXfermode(dstout_modeproc,
- kZero_Coeff, kISA_Coeff) {}
-
+ SkDstOutXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kDstOut_Mode) {}
+
virtual void xfer32(SK_RESTRICT SkPMColor dst[],
const SK_RESTRICT SkPMColor src[], int count,
const SK_RESTRICT SkAlpha aa[]) {
SkASSERT(dst && src);
-
+
if (count <= 0) {
return;
}
if (NULL != aa) {
return this->INHERITED::xfer32(dst, src, count, aa);
}
-
+
do {
unsigned a = SkGetPackedA32(*src);
*dst = SkAlphaMulQ(*dst, SkAlpha255To256(255 - a));
@@ -939,17 +943,17 @@ public:
src++;
} while (--count != 0);
}
-
+
virtual Factory getFactory() { return CreateProc; }
-
-private:
- SkDstOutXfermode(SkFlattenableReadBuffer& buffer)
- : INHERITED(buffer) {}
-
+
static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
return SkNEW_ARGS(SkDstOutXfermode, (buffer));
}
-
+
+private:
+ SkDstOutXfermode(SkFlattenableReadBuffer& buffer)
+ : INHERITED(buffer) {}
+
typedef SkProcCoeffXfermode INHERITED;
};
@@ -959,72 +963,71 @@ SkXfermode* SkXfermode::Create(Mode mode) {
SkASSERT(SK_ARRAY_COUNT(gProcCoeffs) == kModeCount);
SkASSERT((unsigned)mode < kModeCount);
- SkXfermode* xferMode = NULL;
+ const ProcCoeff& rec = gProcCoeffs[mode];
+
switch (mode) {
case kClear_Mode:
- xferMode = SkNEW(SkClearXfermode);
- break;
+ return SkNEW_ARGS(SkClearXfermode, (rec));
case kSrc_Mode:
- xferMode = SkNEW(SkSrcXfermode);
- break;
+ return SkNEW_ARGS(SkSrcXfermode, (rec));
case kSrcOver_Mode:
return NULL;
case kDstIn_Mode:
- xferMode = SkNEW(SkDstInXfermode);
- break;
+ return SkNEW_ARGS(SkDstInXfermode, (rec));
case kDstOut_Mode:
- xferMode = SkNEW(SkDstOutXfermode);
- break;
- // use the table
- default: {
- const ProcCoeff& rec = gProcCoeffs[mode];
- if ((unsigned)rec.fSC < SkXfermode::kCoeffCount &&
- (unsigned)rec.fDC < SkXfermode::kCoeffCount) {
- xferMode = SkNEW_ARGS(SkProcCoeffXfermode, (rec.fProc, rec.fSC, rec.fDC));
- } else {
- xferMode = SkNEW_ARGS(SkProcXfermode, (rec.fProc));
- }
- break;
- }
+ return SkNEW_ARGS(SkDstOutXfermode, (rec));
+ default:
+ return SkNEW_ARGS(SkProcCoeffXfermode, (rec, mode));
}
- xferMode->fMode = mode;
- return xferMode;
}
-bool SkXfermode::IsMode(SkXfermode* xfer, Mode* mode) {
+SkXfermodeProc SkXfermode::GetProc(Mode mode) {
+ SkXfermodeProc proc = NULL;
+ if ((unsigned)mode < kModeCount) {
+ proc = gProcCoeffs[mode].fProc;
+ }
+ return proc;
+}
+
+bool SkXfermode::ModeAsCoeff(Mode mode, Coeff* src, Coeff* dst) {
+ SkASSERT(SK_ARRAY_COUNT(gProcCoeffs) == kModeCount);
+
+ if ((unsigned)mode >= (unsigned)kModeCount) {
+ // illegal mode parameter
+ return false;
+ }
+
+ const ProcCoeff& rec = gProcCoeffs[mode];
+
+ if (CANNOT_USE_COEFF == rec.fSC) {
+ return false;
+ }
+
+ SkASSERT(CANNOT_USE_COEFF != rec.fDC);
+ if (src) {
+ *src = rec.fSC;
+ }
+ if (dst) {
+ *dst = rec.fDC;
+ }
+ return true;
+}
+
+bool SkXfermode::AsMode(SkXfermode* xfer, Mode* mode) {
if (NULL == xfer) {
if (mode) {
*mode = kSrcOver_Mode;
}
return true;
}
-
- SkXfermode::Coeff sc, dc;
- if (xfer->asCoeff(&sc, &dc)) {
- SkASSERT((unsigned)sc < (unsigned)SkXfermode::kCoeffCount);
- SkASSERT((unsigned)dc < (unsigned)SkXfermode::kCoeffCount);
-
- const ProcCoeff* rec = gProcCoeffs;
- for (size_t i = 0; i < SK_ARRAY_COUNT(gProcCoeffs); i++) {
- if (rec[i].fSC == sc && rec[i].fDC == dc) {
- if (mode) {
- *mode = static_cast<Mode>(i);
- }
- return true;
- }
- }
- }
-
- // no coefficients, or not found in our table
- return false;
+ return xfer->asMode(mode);
}
-SkXfermodeProc SkXfermode::GetProc(Mode mode) {
- SkXfermodeProc proc = NULL;
- if ((unsigned)mode < kModeCount) {
- proc = gProcCoeffs[mode].fProc;
+bool SkXfermode::AsCoeff(SkXfermode* xfer, Coeff* src, Coeff* dst) {
+ if (NULL == xfer) {
+ return ModeAsCoeff(kSrcOver_Mode, src, dst);
}
- return proc;
+ return xfer->asCoeff(src, dst);
}
///////////////////////////////////////////////////////////////////////////////
@@ -1081,7 +1084,7 @@ static uint16_t dstout_modeproc16_0(SkPMColor src, uint16_t dst) {
static uint16_t srcatop_modeproc16(SkPMColor src, uint16_t dst) {
unsigned isa = 255 - SkGetPackedA32(src);
-
+
return SkPackRGB16(
SkPacked32ToR16(src) + SkAlphaMulAlpha(SkGetPackedR16(dst), isa),
SkPacked32ToG16(src) + SkAlphaMulAlpha(SkGetPackedG16(dst), isa),
@@ -1195,3 +1198,18 @@ SkXfermodeProc16 SkXfermode::GetProc16(Mode mode, SkColor srcColor) {
return proc16;
}
+static SkFlattenable::Registrar
+ gSkProcCoeffXfermodeReg("SkProcCoeffXfermode",
+ SkProcCoeffXfermode::CreateProc);
+
+static SkFlattenable::Registrar
+ gSkClearXfermodeReg("SkClearXfermode", SkClearXfermode::CreateProc);
+
+static SkFlattenable::Registrar
+ gSkSrcXfermodeReg("SkSrcXfermode", SkSrcXfermode::CreateProc);
+
+static SkFlattenable::Registrar
+ gSkDstInXfermodeReg("SkDstInXfermode", SkDstInXfermode::CreateProc);
+
+static SkFlattenable::Registrar
+ gSkDstOutXfermodeReg("SkDstOutXfermode", SkDstOutXfermode::CreateProc);