mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-08 13:43:43 +00:00
sw_engine: code chores & fix gradient filling bugs.
renaming internal methods for integrating with upcoming blending features. this also fixes minor wrong gradient filling blending equations.
This commit is contained in:
parent
b60a291edc
commit
eea54f5fea
3 changed files with 66 additions and 47 deletions
|
@ -239,6 +239,7 @@ struct SwImage
|
||||||
bool scaled = false; //draw scaled image
|
bool scaled = false; //draw scaled image
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef uint32_t(*SwBlender)(uint32_t s, uint32_t d, uint8_t sa); //src, dst, alpha
|
||||||
typedef uint32_t(*SwJoin)(uint8_t r, uint8_t g, uint8_t b, uint8_t a); //color channel join
|
typedef uint32_t(*SwJoin)(uint8_t r, uint8_t g, uint8_t b, uint8_t a); //color channel join
|
||||||
typedef uint8_t(*SwAlpha)(uint8_t*); //blending alpha
|
typedef uint8_t(*SwAlpha)(uint8_t*); //blending alpha
|
||||||
|
|
||||||
|
@ -314,48 +315,66 @@ static inline uint8_t IALPHA(uint32_t c)
|
||||||
return (~c >> 24);
|
return (~c >> 24);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline uint32_t opBlendInterp(uint32_t s, uint32_t d, uint8_t a)
|
||||||
|
{
|
||||||
|
return INTERPOLATE(s, d, a);
|
||||||
|
}
|
||||||
|
|
||||||
typedef uint32_t(*SwBlendOp)(uint32_t s, uint32_t d, uint8_t a); //src, dst, alpha
|
static inline uint32_t opBlendNormal(uint32_t s, uint32_t d, uint8_t a)
|
||||||
|
|
||||||
static inline uint32_t opAlphaBlend(uint32_t s, uint32_t d, uint8_t a)
|
|
||||||
{
|
{
|
||||||
auto t = ALPHA_BLEND(s, a);
|
auto t = ALPHA_BLEND(s, a);
|
||||||
return t + ALPHA_BLEND(d, IALPHA(t));
|
return t + ALPHA_BLEND(d, IALPHA(t));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t opBlend(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a)
|
static inline uint32_t opBlendPreNormal(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a)
|
||||||
{
|
{
|
||||||
return s + ALPHA_BLEND(d, IALPHA(s));
|
return s + ALPHA_BLEND(d, IALPHA(s));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t opDirect(uint32_t s, TVG_UNUSED uint32_t d, TVG_UNUSED uint8_t a)
|
static inline uint32_t opBlendSrcOver(uint32_t s, TVG_UNUSED uint32_t d, TVG_UNUSED uint8_t a)
|
||||||
{
|
{
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t opAddMask(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a)
|
static inline uint32_t opMaskAdd(uint32_t s, uint32_t d, uint8_t a)
|
||||||
{
|
{
|
||||||
return opBlend(s, d, a);
|
return opBlendNormal(s, d, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t opSubMask(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a)
|
static inline uint32_t opMaskSubtract(uint32_t s, uint32_t d, uint8_t a)
|
||||||
|
{
|
||||||
|
return ALPHA_BLEND(d, MULTIPLY(IALPHA(s), a));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t opMaskDifference(uint32_t s, uint32_t d, uint8_t a)
|
||||||
|
{
|
||||||
|
auto t = ALPHA_BLEND(s, a);
|
||||||
|
return ALPHA_BLEND(t, IALPHA(d)) + ALPHA_BLEND(d, IALPHA(t));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t opMaskIntersect(uint32_t s, uint32_t d, uint8_t a)
|
||||||
|
{
|
||||||
|
return ALPHA_BLEND(d, MULTIPLY(IALPHA(s), a));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t opMaskPreAdd(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a)
|
||||||
|
{
|
||||||
|
return opBlendPreNormal(s, d, a);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t opMaskPreSubtract(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a)
|
||||||
{
|
{
|
||||||
return ALPHA_BLEND(d, IALPHA(s));
|
return ALPHA_BLEND(d, IALPHA(s));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t opIntMask(TVG_UNUSED uint32_t s, uint32_t d, uint8_t a)
|
static inline uint32_t opMaskPreDifference(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a)
|
||||||
{
|
|
||||||
return ALPHA_BLEND(d, a);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t opDifMask(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a)
|
|
||||||
{
|
{
|
||||||
return ALPHA_BLEND(s, IALPHA(d)) + ALPHA_BLEND(d, IALPHA(s));
|
return ALPHA_BLEND(s, IALPHA(d)) + ALPHA_BLEND(d, IALPHA(s));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t opInterpolate(uint32_t s, uint32_t d, uint8_t a)
|
static inline uint32_t opMaskPreIntersect(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a)
|
||||||
{
|
{
|
||||||
return INTERPOLATE(s, d, a);
|
return ALPHA_BLEND(d, MULTIPLY(a, IALPHA(s)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -407,9 +426,9 @@ bool fillGenColorTable(SwFill* fill, const Fill* fdata, const Matrix* transform,
|
||||||
void fillReset(SwFill* fill);
|
void fillReset(SwFill* fill);
|
||||||
void fillFree(SwFill* fill);
|
void fillFree(SwFill* fill);
|
||||||
//OPTIMIZE_ME: Skip the function pointer access
|
//OPTIMIZE_ME: Skip the function pointer access
|
||||||
void fillLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, SwBlendOp op, uint8_t a); //blending ver.
|
void fillLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, SwBlender op, uint8_t a); //blending ver.
|
||||||
void fillLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, uint8_t* cmp, SwAlpha alpha, uint8_t csize, uint8_t opacity); //masking ver.
|
void fillLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, uint8_t* cmp, SwAlpha alpha, uint8_t csize, uint8_t opacity); //masking ver.
|
||||||
void fillRadial(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, SwBlendOp op, uint8_t a); //blending ver.
|
void fillRadial(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, SwBlender op, uint8_t a); //blending ver.
|
||||||
void fillRadial(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, uint8_t* cmp, SwAlpha alpha, uint8_t csize, uint8_t opacity); //masking ver.
|
void fillRadial(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, uint8_t* cmp, SwAlpha alpha, uint8_t csize, uint8_t opacity); //masking ver.
|
||||||
|
|
||||||
SwRleData* rleRender(SwRleData* rle, const SwOutline* outline, const SwBBox& renderRegion, bool antiAlias);
|
SwRleData* rleRender(SwRleData* rle, const SwOutline* outline, const SwBBox& renderRegion, bool antiAlias);
|
||||||
|
|
|
@ -246,13 +246,13 @@ void fillRadial(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint3
|
||||||
|
|
||||||
if (opacity == 255) {
|
if (opacity == 255) {
|
||||||
for (uint32_t i = 0 ; i < len ; ++i, ++dst, cmp += csize) {
|
for (uint32_t i = 0 ; i < len ; ++i, ++dst, cmp += csize) {
|
||||||
*dst = opAlphaBlend(_pixel(fill, sqrtf(det)), *dst, alpha(cmp));
|
*dst = opBlendNormal(_pixel(fill, sqrtf(det)), *dst, alpha(cmp));
|
||||||
det += detFirstDerivative;
|
det += detFirstDerivative;
|
||||||
detFirstDerivative += detSecondDerivative;
|
detFirstDerivative += detSecondDerivative;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (uint32_t i = 0 ; i < len ; ++i, ++dst, cmp += csize) {
|
for (uint32_t i = 0 ; i < len ; ++i, ++dst, cmp += csize) {
|
||||||
*dst = opAlphaBlend(_pixel(fill, sqrtf(det)), *dst, MULTIPLY(opacity, alpha(cmp)));
|
*dst = opBlendNormal(_pixel(fill, sqrtf(det)), *dst, MULTIPLY(opacity, alpha(cmp)));
|
||||||
det += detFirstDerivative;
|
det += detFirstDerivative;
|
||||||
detFirstDerivative += detSecondDerivative;
|
detFirstDerivative += detSecondDerivative;
|
||||||
}
|
}
|
||||||
|
@ -260,7 +260,7 @@ void fillRadial(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint3
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void fillRadial(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, SwBlendOp op, uint8_t a)
|
void fillRadial(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, SwBlender op, uint8_t a)
|
||||||
{
|
{
|
||||||
auto rx = (x + 0.5f) * fill->radial.a11 + (y + 0.5f) * fill->radial.a12 + fill->radial.shiftX;
|
auto rx = (x + 0.5f) * fill->radial.a11 + (y + 0.5f) * fill->radial.a12 + fill->radial.shiftX;
|
||||||
auto ry = (x + 0.5f) * fill->radial.a21 + (y + 0.5f) * fill->radial.a22 + fill->radial.shiftY;
|
auto ry = (x + 0.5f) * fill->radial.a21 + (y + 0.5f) * fill->radial.a22 + fill->radial.shiftY;
|
||||||
|
@ -291,7 +291,7 @@ void fillLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint3
|
||||||
if (mathZero(inc)) {
|
if (mathZero(inc)) {
|
||||||
auto color = _fixedPixel(fill, static_cast<int32_t>(t * FIXPT_SIZE));
|
auto color = _fixedPixel(fill, static_cast<int32_t>(t * FIXPT_SIZE));
|
||||||
for (uint32_t i = 0; i < len; ++i, ++dst, cmp += csize) {
|
for (uint32_t i = 0; i < len; ++i, ++dst, cmp += csize) {
|
||||||
*dst = opAlphaBlend(color, *dst, alpha(cmp));
|
*dst = opBlendNormal(color, *dst, alpha(cmp));
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -305,14 +305,14 @@ void fillLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint3
|
||||||
auto t2 = static_cast<int32_t>(t * FIXPT_SIZE);
|
auto t2 = static_cast<int32_t>(t * FIXPT_SIZE);
|
||||||
auto inc2 = static_cast<int32_t>(inc * FIXPT_SIZE);
|
auto inc2 = static_cast<int32_t>(inc * FIXPT_SIZE);
|
||||||
for (uint32_t j = 0; j < len; ++j, ++dst, cmp += csize) {
|
for (uint32_t j = 0; j < len; ++j, ++dst, cmp += csize) {
|
||||||
*dst = opAlphaBlend(_fixedPixel(fill, t2), *dst, alpha(cmp));
|
*dst = opBlendNormal(_fixedPixel(fill, t2), *dst, alpha(cmp));
|
||||||
t2 += inc2;
|
t2 += inc2;
|
||||||
}
|
}
|
||||||
//we have to fallback to float math
|
//we have to fallback to float math
|
||||||
} else {
|
} else {
|
||||||
uint32_t counter = 0;
|
uint32_t counter = 0;
|
||||||
while (counter++ < len) {
|
while (counter++ < len) {
|
||||||
*dst = opAlphaBlend(_pixel(fill, t / GRADIENT_STOP_SIZE), *dst, alpha(cmp));
|
*dst = opBlendNormal(_pixel(fill, t / GRADIENT_STOP_SIZE), *dst, alpha(cmp));
|
||||||
++dst;
|
++dst;
|
||||||
t += inc;
|
t += inc;
|
||||||
cmp += csize;
|
cmp += csize;
|
||||||
|
@ -322,7 +322,7 @@ void fillLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint3
|
||||||
if (mathZero(inc)) {
|
if (mathZero(inc)) {
|
||||||
auto color = _fixedPixel(fill, static_cast<int32_t>(t * FIXPT_SIZE));
|
auto color = _fixedPixel(fill, static_cast<int32_t>(t * FIXPT_SIZE));
|
||||||
for (uint32_t i = 0; i < len; ++i, ++dst, cmp += csize) {
|
for (uint32_t i = 0; i < len; ++i, ++dst, cmp += csize) {
|
||||||
*dst = opAlphaBlend(color, *dst, MULTIPLY(alpha(cmp), opacity));
|
*dst = opBlendNormal(color, *dst, MULTIPLY(alpha(cmp), opacity));
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -336,14 +336,14 @@ void fillLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint3
|
||||||
auto t2 = static_cast<int32_t>(t * FIXPT_SIZE);
|
auto t2 = static_cast<int32_t>(t * FIXPT_SIZE);
|
||||||
auto inc2 = static_cast<int32_t>(inc * FIXPT_SIZE);
|
auto inc2 = static_cast<int32_t>(inc * FIXPT_SIZE);
|
||||||
for (uint32_t j = 0; j < len; ++j, ++dst, cmp += csize) {
|
for (uint32_t j = 0; j < len; ++j, ++dst, cmp += csize) {
|
||||||
*dst = opAlphaBlend(_fixedPixel(fill, t2), *dst, MULTIPLY(alpha(cmp), opacity));
|
*dst = opBlendNormal(_fixedPixel(fill, t2), *dst, MULTIPLY(alpha(cmp), opacity));
|
||||||
t2 += inc2;
|
t2 += inc2;
|
||||||
}
|
}
|
||||||
//we have to fallback to float math
|
//we have to fallback to float math
|
||||||
} else {
|
} else {
|
||||||
uint32_t counter = 0;
|
uint32_t counter = 0;
|
||||||
while (counter++ < len) {
|
while (counter++ < len) {
|
||||||
*dst = opAlphaBlend(_pixel(fill, t / GRADIENT_STOP_SIZE), *dst, MULTIPLY(opacity, alpha(cmp)));
|
*dst = opBlendNormal(_pixel(fill, t / GRADIENT_STOP_SIZE), *dst, MULTIPLY(opacity, alpha(cmp)));
|
||||||
++dst;
|
++dst;
|
||||||
t += inc;
|
t += inc;
|
||||||
cmp += csize;
|
cmp += csize;
|
||||||
|
@ -353,7 +353,7 @@ void fillLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint3
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void fillLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, SwBlendOp op, uint8_t a)
|
void fillLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, SwBlender op, uint8_t a)
|
||||||
{
|
{
|
||||||
//Rotation
|
//Rotation
|
||||||
float rx = x + 0.5f;
|
float rx = x + 0.5f;
|
||||||
|
|
|
@ -39,7 +39,7 @@ constexpr auto DOWN_SCALE_TOLERANCE = 0.5f;
|
||||||
|
|
||||||
struct FillLinear
|
struct FillLinear
|
||||||
{
|
{
|
||||||
void operator()(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, SwBlendOp op, uint8_t a)
|
void operator()(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, SwBlender op, uint8_t a)
|
||||||
{
|
{
|
||||||
fillLinear(fill, dst, y, x, len, op, a);
|
fillLinear(fill, dst, y, x, len, op, a);
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ struct FillLinear
|
||||||
|
|
||||||
struct FillRadial
|
struct FillRadial
|
||||||
{
|
{
|
||||||
void operator()(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, SwBlendOp op, uint8_t a)
|
void operator()(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, SwBlender op, uint8_t a)
|
||||||
{
|
{
|
||||||
fillRadial(fill, dst, y, x, len, op, a);
|
fillRadial(fill, dst, y, x, len, op, a);
|
||||||
}
|
}
|
||||||
|
@ -694,7 +694,7 @@ static bool _rasterScaledMaskedRleRGBAImage(SwSurface* surface, const SwImage* i
|
||||||
|
|
||||||
if (method == CompositeMethod::AddMask) _rasterScaledMaskedRleRGBAImageDup<AddMaskOp, AddMaskAOp>(surface, image, itransform, region, opacity, halfScale);
|
if (method == CompositeMethod::AddMask) _rasterScaledMaskedRleRGBAImageDup<AddMaskOp, AddMaskAOp>(surface, image, itransform, region, opacity, halfScale);
|
||||||
else if (method == CompositeMethod::SubtractMask) _rasterScaledMaskedRleRGBAImageDup<SubMaskOp, SubMaskAOp>(surface, image, itransform, region, opacity, halfScale);
|
else if (method == CompositeMethod::SubtractMask) _rasterScaledMaskedRleRGBAImageDup<SubMaskOp, SubMaskAOp>(surface, image, itransform, region, opacity, halfScale);
|
||||||
else if (method == CompositeMethod::IntersectMask) _rasterScaledMaskedRleRGBAImageDup<DifMaskOp, DifMaskAOp>(surface, image, itransform, region, opacity, halfScale);
|
else if (method == CompositeMethod::DifferenceMask) _rasterScaledMaskedRleRGBAImageDup<DifMaskOp, DifMaskAOp>(surface, image, itransform, region, opacity, halfScale);
|
||||||
else if (method == CompositeMethod::IntersectMask) _rasterScaledMaskedRleRGBAImageInt(surface, image, itransform, region, opacity, halfScale);
|
else if (method == CompositeMethod::IntersectMask) _rasterScaledMaskedRleRGBAImageInt(surface, image, itransform, region, opacity, halfScale);
|
||||||
else return false;
|
else return false;
|
||||||
|
|
||||||
|
@ -1341,7 +1341,7 @@ static bool _rasterRGBAImage(SwSurface* surface, SwImage* image, const Matrix* t
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
|
||||||
template<typename fillMethod>
|
template<typename fillMethod>
|
||||||
static void _rasterGradientMaskedRectDup(SwSurface* surface, const SwBBox& region, const SwFill* fill, SwBlendOp maskOp)
|
static void _rasterGradientMaskedRectDup(SwSurface* surface, const SwBBox& region, const SwFill* fill, SwBlender maskOp)
|
||||||
{
|
{
|
||||||
auto h = static_cast<uint32_t>(region.max.y - region.min.y);
|
auto h = static_cast<uint32_t>(region.max.y - region.min.y);
|
||||||
auto w = static_cast<uint32_t>(region.max.x - region.min.x);
|
auto w = static_cast<uint32_t>(region.max.x - region.min.x);
|
||||||
|
@ -1370,7 +1370,7 @@ static void _rasterGradientMaskedRectInt(SwSurface* surface, const SwBBox& regio
|
||||||
auto x = surface->compositor->bbox.min.x;
|
auto x = surface->compositor->bbox.min.x;
|
||||||
while (x < surface->compositor->bbox.max.x) {
|
while (x < surface->compositor->bbox.max.x) {
|
||||||
if (x == region.min.x) {
|
if (x == region.min.x) {
|
||||||
fillMethod()(fill, tmp, y2, x, w, opIntMask, 255);
|
fillMethod()(fill, tmp, y2, x, w, opMaskPreIntersect, 255);
|
||||||
x += w;
|
x += w;
|
||||||
tmp += w;
|
tmp += w;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1397,9 +1397,9 @@ static bool _rasterGradientMaskedRect(SwSurface* surface, const SwBBox& region,
|
||||||
|
|
||||||
TVGLOG("SW_ENGINE", "Masked(%d) Gradient [Region: %lu %lu %lu %lu]", (int)surface->compositor->method, region.min.x, region.min.y, region.max.x - region.min.x, region.max.y - region.min.y);
|
TVGLOG("SW_ENGINE", "Masked(%d) Gradient [Region: %lu %lu %lu %lu]", (int)surface->compositor->method, region.min.x, region.min.y, region.max.x - region.min.x, region.max.y - region.min.y);
|
||||||
|
|
||||||
if (method == CompositeMethod::AddMask) _rasterGradientMaskedRectDup<fillMethod>(surface, region, fill, opAddMask);
|
if (method == CompositeMethod::AddMask) _rasterGradientMaskedRectDup<fillMethod>(surface, region, fill, opMaskPreAdd);
|
||||||
else if (method == CompositeMethod::SubtractMask) _rasterGradientMaskedRectDup<fillMethod>(surface, region, fill, opSubMask);
|
else if (method == CompositeMethod::SubtractMask) _rasterGradientMaskedRectDup<fillMethod>(surface, region, fill, opMaskPreSubtract);
|
||||||
else if (method == CompositeMethod::DifferenceMask) _rasterGradientMaskedRectDup<fillMethod>(surface, region, fill, opDifMask);
|
else if (method == CompositeMethod::DifferenceMask) _rasterGradientMaskedRectDup<fillMethod>(surface, region, fill, opMaskPreDifference);
|
||||||
else if (method == CompositeMethod::IntersectMask) _rasterGradientMaskedRectInt<fillMethod>(surface, region, fill);
|
else if (method == CompositeMethod::IntersectMask) _rasterGradientMaskedRectInt<fillMethod>(surface, region, fill);
|
||||||
else return false;
|
else return false;
|
||||||
|
|
||||||
|
@ -1437,7 +1437,7 @@ static bool _rasterTranslucentGradientRect(SwSurface* surface, const SwBBox& reg
|
||||||
auto w = static_cast<uint32_t>(region.max.x - region.min.x);
|
auto w = static_cast<uint32_t>(region.max.x - region.min.x);
|
||||||
|
|
||||||
for (uint32_t y = 0; y < h; ++y) {
|
for (uint32_t y = 0; y < h; ++y) {
|
||||||
fillMethod()(fill, buffer, region.min.y + y, region.min.x, w, opBlend, 255);
|
fillMethod()(fill, buffer, region.min.y + y, region.min.x, w, opBlendPreNormal, 255);
|
||||||
buffer += surface->stride;
|
buffer += surface->stride;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -1452,7 +1452,7 @@ static bool _rasterSolidGradientRect(SwSurface* surface, const SwBBox& region, c
|
||||||
auto h = static_cast<uint32_t>(region.max.y - region.min.y);
|
auto h = static_cast<uint32_t>(region.max.y - region.min.y);
|
||||||
|
|
||||||
for (uint32_t y = 0; y < h; ++y) {
|
for (uint32_t y = 0; y < h; ++y) {
|
||||||
fillMethod()(fill, buffer + y * surface->stride, region.min.y + y, region.min.x, w, opDirect, 0);
|
fillMethod()(fill, buffer + y * surface->stride, region.min.y + y, region.min.x, w, opBlendSrcOver, 255);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1494,7 +1494,7 @@ static bool _rasterRadialGradientRect(SwSurface* surface, const SwBBox& region,
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
|
||||||
template<typename fillMethod>
|
template<typename fillMethod>
|
||||||
static void _rasterGradientMaskedRleDup(SwSurface* surface, const SwRleData* rle, const SwFill* fill, SwBlendOp maskOp)
|
static void _rasterGradientMaskedRleDup(SwSurface* surface, const SwRleData* rle, const SwFill* fill, SwBlender maskOp)
|
||||||
{
|
{
|
||||||
auto span = rle->spans;
|
auto span = rle->spans;
|
||||||
auto cstride = surface->compositor->image.stride;
|
auto cstride = surface->compositor->image.stride;
|
||||||
|
@ -1519,7 +1519,7 @@ static void _rasterGradientMaskedRleInt(SwSurface* surface, const SwRleData* rle
|
||||||
uint32_t x = surface->compositor->bbox.min.x;
|
uint32_t x = surface->compositor->bbox.min.x;
|
||||||
while (x < surface->compositor->bbox.max.x) {
|
while (x < surface->compositor->bbox.max.x) {
|
||||||
if (y == span->y && x == span->x && x + span->len <= surface->compositor->bbox.max.x) {
|
if (y == span->y && x == span->x && x + span->len <= surface->compositor->bbox.max.x) {
|
||||||
fillMethod()(fill, cmp, span->y, span->x, span->len, opIntMask, span->coverage);
|
fillMethod()(fill, cmp, span->y, span->x, span->len, opMaskIntersect, span->coverage);
|
||||||
x += span->len;
|
x += span->len;
|
||||||
++span;
|
++span;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1538,9 +1538,9 @@ static bool _rasterGradientMaskedRle(SwSurface* surface, const SwRleData* rle, c
|
||||||
|
|
||||||
auto method = surface->compositor->method;
|
auto method = surface->compositor->method;
|
||||||
|
|
||||||
if (method == CompositeMethod::AddMask) _rasterGradientMaskedRleDup<fillMethod>(surface, rle, fill, opAddMask);
|
if (method == CompositeMethod::AddMask) _rasterGradientMaskedRleDup<fillMethod>(surface, rle, fill, opMaskAdd);
|
||||||
else if (method == CompositeMethod::SubtractMask) _rasterGradientMaskedRleDup<fillMethod>(surface, rle, fill, opSubMask);
|
else if (method == CompositeMethod::SubtractMask) _rasterGradientMaskedRleDup<fillMethod>(surface, rle, fill, opMaskSubtract);
|
||||||
else if (method == CompositeMethod::DifferenceMask) _rasterGradientMaskedRleDup<fillMethod>(surface, rle, fill, opDifMask);
|
else if (method == CompositeMethod::DifferenceMask) _rasterGradientMaskedRleDup<fillMethod>(surface, rle, fill, opMaskDifference);
|
||||||
else if (method == CompositeMethod::IntersectMask) _rasterGradientMaskedRleInt<fillMethod>(surface, rle, fill);
|
else if (method == CompositeMethod::IntersectMask) _rasterGradientMaskedRleInt<fillMethod>(surface, rle, fill);
|
||||||
else return false;
|
else return false;
|
||||||
|
|
||||||
|
@ -1575,8 +1575,8 @@ static bool _rasterTranslucentGradientRle(SwSurface* surface, const SwRleData* r
|
||||||
|
|
||||||
for (uint32_t i = 0; i < rle->size; ++i, ++span) {
|
for (uint32_t i = 0; i < rle->size; ++i, ++span) {
|
||||||
auto dst = &surface->buf32[span->y * surface->stride + span->x];
|
auto dst = &surface->buf32[span->y * surface->stride + span->x];
|
||||||
if (span->coverage == 255) fillMethod()(fill, dst, span->y, span->x, span->len, opBlend, 255);
|
if (span->coverage == 255) fillMethod()(fill, dst, span->y, span->x, span->len, opBlendPreNormal, 255);
|
||||||
else fillMethod()(fill, dst, span->y, span->x, span->len, opAlphaBlend, span->coverage);
|
else fillMethod()(fill, dst, span->y, span->x, span->len, opBlendNormal, span->coverage);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1589,8 +1589,8 @@ static bool _rasterSolidGradientRle(SwSurface* surface, const SwRleData* rle, co
|
||||||
|
|
||||||
for (uint32_t i = 0; i < rle->size; ++i, ++span) {
|
for (uint32_t i = 0; i < rle->size; ++i, ++span) {
|
||||||
auto dst = &surface->buf32[span->y * surface->stride + span->x];
|
auto dst = &surface->buf32[span->y * surface->stride + span->x];
|
||||||
if (span->coverage == 255) fillMethod()(fill, dst, span->y, span->x, span->len, opDirect, 0);
|
if (span->coverage == 255) fillMethod()(fill, dst, span->y, span->x, span->len, opBlendSrcOver, 255);
|
||||||
else fillMethod()(fill, dst, span->y, span->x, span->len, opInterpolate, span->coverage);
|
else fillMethod()(fill, dst, span->y, span->x, span->len, opBlendInterp, span->coverage);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue