diff --git a/src/lib/sw_engine/tvgSwRaster.cpp b/src/lib/sw_engine/tvgSwRaster.cpp index a94bd52f..c1284cab 100644 --- a/src/lib/sw_engine/tvgSwRaster.cpp +++ b/src/lib/sw_engine/tvgSwRaster.cpp @@ -1349,58 +1349,67 @@ static bool _rasterRGBAImage(SwSurface* surface, SwImage* image, const Matrix* t /************************************************************************/ template -static bool _rasterGradientMaskedRect(SwSurface* surface, const SwBBox& region, const SwFill* fill) +static void _rasterGradientMaskedRectDup(SwSurface* surface, const SwBBox& region, const SwFill* fill, SwBlendOp maskOp) { auto h = static_cast(region.max.y - region.min.y); auto w = static_cast(region.max.x - region.min.x); auto cstride = surface->compositor->image.stride; auto cbuffer = surface->compositor->image.buf32 + (region.min.y * cstride + region.min.x); - auto method = surface->compositor->method; - TVGLOG("SW_ENGINE", "Masked(%d) Gradient [Region: %lu %lu %u %u]", (int)surface->compositor->method, region.min.x, region.min.y, w, h); + for (uint32_t y = 0; y < h; ++y) { + fillMethod()(fill, cbuffer, region.min.y + y, region.min.x, w, maskOp, 255); + cbuffer += surface->stride; + } +} - if (method == CompositeMethod::AddMask) { - for (uint32_t y = 0; y < h; ++y) { - fillMethod()(fill, cbuffer, region.min.y + y, region.min.x, w, opAddMask, 255); - cbuffer += surface->stride; - } - } else if (method == CompositeMethod::SubtractMask) { - for (uint32_t y = 0; y < h; ++y) { - fillMethod()(fill, cbuffer, region.min.y + y, region.min.x, w, opSubMask, 255); - cbuffer += surface->stride; - } - } else if (method == CompositeMethod::IntersectMask) { - for (uint32_t y = surface->compositor->bbox.min.y; y < surface->compositor->bbox.max.y; ++y) { - auto cmp = surface->compositor->image.buf32 + (y * cstride + surface->compositor->bbox.min.x); - if (y == region.min.y) { - for (uint32_t y2 = y; y2 < region.max.y; ++y2) { - auto tmp = cmp; - auto x = surface->compositor->bbox.min.x; - while (x < surface->compositor->bbox.max.x) { - if (x == region.min.x) { - fillMethod()(fill, tmp, y2, x, w, opIntMask, 255); - x += w; - tmp += w; - } else { - *tmp = 0; - ++tmp; - ++x; - } + +template +static void _rasterGradientMaskedRectInt(SwSurface* surface, const SwBBox& region, const SwFill* fill) +{ + auto h = static_cast(region.max.y - region.min.y); + auto w = static_cast(region.max.x - region.min.x); + auto cstride = surface->compositor->image.stride; + + for (uint32_t y = surface->compositor->bbox.min.y; y < surface->compositor->bbox.max.y; ++y) { + auto cmp = surface->compositor->image.buf32 + (y * cstride + surface->compositor->bbox.min.x); + if (y == region.min.y) { + for (uint32_t y2 = y; y2 < region.max.y; ++y2) { + auto tmp = cmp; + auto x = surface->compositor->bbox.min.x; + while (x < surface->compositor->bbox.max.x) { + if (x == region.min.x) { + fillMethod()(fill, tmp, y2, x, w, opIntMask, 255); + x += w; + tmp += w; + } else { + *tmp = 0; + ++tmp; + ++x; } - cmp += cstride; } - y += (h - 1); - } else { - rasterRGBA32(cmp, 0x00000000, 0, surface->compositor->bbox.max.x -surface->compositor->bbox.min.x); cmp += cstride; } + y += (h - 1); + } else { + rasterRGBA32(cmp, 0x00000000, 0, surface->compositor->bbox.max.x -surface->compositor->bbox.min.x); + cmp += cstride; } - } else if (method == CompositeMethod::DifferenceMask) { - for (uint32_t y = 0; y < h; ++y) { - fillMethod()(fill, cbuffer, region.min.y + y, region.min.x, w, opDifMask, 255); - cbuffer += surface->stride; - } - } else return false; + } +} + + +template +static bool _rasterGradientMaskedRect(SwSurface* surface, const SwBBox& region, const SwFill* fill) +{ + auto method = surface->compositor->method; + + 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(surface, region, fill, opAddMask); + else if (method == CompositeMethod::SubtractMask) _rasterGradientMaskedRectDup(surface, region, fill, opSubMask); + else if (method == CompositeMethod::DifferenceMask) _rasterGradientMaskedRectDup(surface, region, fill, opDifMask); + else if (method == CompositeMethod::IntersectMask) _rasterGradientMaskedRectInt(surface, region, fill); + else return false; //Masking Composition return _rasterDirectRGBAImage(surface, &surface->compositor->image, surface->compositor->bbox, 255); @@ -1492,47 +1501,56 @@ static bool _rasterRadialGradientRect(SwSurface* surface, const SwBBox& region, /* Rle Gradient */ /************************************************************************/ +template +static void _rasterGradientMaskedRleDup(SwSurface* surface, const SwRleData* rle, const SwFill* fill, SwBlendOp maskOp) +{ + auto span = rle->spans; + auto cstride = surface->compositor->image.stride; + auto cbuffer = surface->compositor->image.buf32; + + for (uint32_t i = 0; i < rle->size; ++i, ++span) { + auto cmp = &cbuffer[span->y * cstride + span->x]; + fillMethod()(fill, cmp, span->y, span->x, span->len, maskOp, span->coverage); + } +} + + +template +static void _rasterGradientMaskedRleInt(SwSurface* surface, const SwRleData* rle, const SwFill* fill) +{ + auto span = rle->spans; + auto cstride = surface->compositor->image.stride; + auto cbuffer = surface->compositor->image.buf32; + + for (uint32_t y = surface->compositor->bbox.min.y; y < surface->compositor->bbox.max.y; ++y) { + auto cmp = &cbuffer[y * cstride]; + uint32_t x = surface->compositor->bbox.min.x; + while (x < 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); + x += span->len; + ++span; + } else { + cmp[x] = 0; + ++x; + } + } + } +} + + template static bool _rasterGradientMaskedRle(SwSurface* surface, const SwRleData* rle, const SwFill* fill) { TVGLOG("SW_ENGINE", "Masked(%d) Rle Linear Gradient", (int)surface->compositor->method); - auto span = rle->spans; - auto cstride = surface->compositor->image.stride; - auto cbuffer = surface->compositor->image.buf32; auto method = surface->compositor->method; - if (method == CompositeMethod::AddMask) { - for (uint32_t i = 0; i < rle->size; ++i, ++span) { - auto cmp = &cbuffer[span->y * cstride + span->x]; - fillMethod()(fill, cmp, span->y, span->x, span->len, opAddMask, span->coverage); - } - } else if (method == CompositeMethod::SubtractMask) { - for (uint32_t i = 0; i < rle->size; ++i, ++span) { - auto cmp = &cbuffer[span->y * cstride + span->x]; - fillMethod()(fill, cmp, span->y, span->x, span->len, opSubMask, span->coverage); - } - } else if (method == CompositeMethod::IntersectMask) { - for (uint32_t y = surface->compositor->bbox.min.y; y < surface->compositor->bbox.max.y; ++y) { - auto cmp = &cbuffer[y * cstride]; - uint32_t x = surface->compositor->bbox.min.x; - while (x < 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); - x += span->len; - ++span; - } else { - cmp[x] = 0; - ++x; - } - } - } - } else if (method == CompositeMethod::DifferenceMask) { - for (uint32_t i = 0; i < rle->size; ++i, ++span) { - auto cmp = &cbuffer[span->y * cstride + span->x]; - fillMethod()(fill, cmp, span->y, span->x, span->len, opDifMask, span->coverage); - } - } else return false; + if (method == CompositeMethod::AddMask) _rasterGradientMaskedRleDup(surface, rle, fill, opAddMask); + else if (method == CompositeMethod::SubtractMask) _rasterGradientMaskedRleDup(surface, rle, fill, opSubMask); + else if (method == CompositeMethod::DifferenceMask) _rasterGradientMaskedRleDup(surface, rle, fill, opDifMask); + else if (method == CompositeMethod::IntersectMask) _rasterGradientMaskedRleInt(surface, rle, fill); + else return false; //Masking Composition return _rasterDirectRGBAImage(surface, &surface->compositor->image, surface->compositor->bbox, 255);