diff --git a/src/lib/sw_engine/tvgSwCommon.h b/src/lib/sw_engine/tvgSwCommon.h index e5d4719f..ee705998 100644 --- a/src/lib/sw_engine/tvgSwCommon.h +++ b/src/lib/sw_engine/tvgSwCommon.h @@ -38,8 +38,6 @@ static double timeStamp() } #endif -using namespace tvg; - #define SW_CURVE_TYPE_POINT 0 #define SW_CURVE_TYPE_CUBIC 1 #define SW_OUTLINE_FILL_WINDING 0 @@ -215,58 +213,40 @@ struct SwShape bool rect; //Fast Track: Othogonal rectangle? }; +struct SwCompositor +{ + uint32_t (*join)(uint8_t r, uint8_t g, uint8_t b, uint8_t a); + uint32_t (*alpha)(uint32_t rgba); +}; + +struct SwSurface : Surface +{ + SwCompositor comp; +}; static inline SwCoord TO_SWCOORD(float val) { return SwCoord(val * 64); } - -static inline uint32_t RGBA_ALPHA(uint32_t rgba) -{ - return rgba & 0x000000ff; -} - - -static inline uint32_t ARGB_ALPHA(uint32_t argb) -{ - return (argb >> 24) & 0xff; -} - - static inline uint32_t RGBA_ALPHA_BLEND(uint32_t rgba, uint32_t alpha) { - return (((((rgba >> 8) & 0x00ff00ff) * alpha) & 0xff00ff00) + - ((((rgba & 0x00ff00ff) * alpha) >> 8) & 0x00ff00ff)); + return (((((rgba >> 8) & 0x00ff00ff) * alpha) & 0xff00ff00) + + ((((rgba & 0x00ff00ff) * alpha) >> 8) & 0x00ff00ff)); } - static inline uint32_t RGBA_INTERPOLATE(uint32_t rgba1, uint32_t a, uint32_t rgba2, uint32_t b) { - auto t = (((rgba1 & 0xff00ff) * a + (rgba2 & 0xff00ff) * b) >> 8) & 0xff00ff; - rgba1 = (((rgba1 >> 8) & 0xff00ff) * a + ((rgba2 >> 8) & 0xff00ff) * b) & 0xff00ff00; - return (rgba1 |= t); + auto t = (((rgba1 & 0xff00ff) * a + (rgba2 & 0xff00ff) * b) >> 8) & 0xff00ff; + rgba1 = (((rgba1 >> 8) & 0xff00ff) * a + ((rgba2 >> 8) & 0xff00ff) * b) & 0xff00ff00; + return (rgba1 |= t); } - -static inline uint32_t RGBA_JOIN(uint8_t r, uint8_t g, uint8_t b, uint8_t a) -{ - return (r << 24 | g << 16 | b << 8 | a); -} - - -static inline uint32_t ARGB_JOIN(uint8_t r, uint8_t g, uint8_t b, uint8_t a) -{ - return (a << 24 | r << 16 | g << 8 | b); -} - - static inline uint8_t ALPHA_MULTIPLY(uint32_t c, uint32_t a) { return (c * a) >> 8; } - int64_t mathMultiply(int64_t a, int64_t b); int64_t mathDivide(int64_t a, int64_t b); int64_t mathMulDiv(int64_t a, int64_t b, int64_t c); @@ -290,7 +270,7 @@ void shapeResetStroke(SwShape* shape, const Shape* sdata, const Matrix* transfor bool shapeGenStrokeRle(SwShape* shape, const Shape* sdata, const Matrix* transform, const SwSize& clip); void shapeFree(SwShape* shape); void shapeDelStroke(SwShape* shape); -bool shapeGenFillColors(SwShape* shape, const Fill* fill, const Matrix* transform, uint32_t cs, bool ctable); +bool shapeGenFillColors(SwShape* shape, const Fill* fill, const Matrix* transform, SwSurface* surface, bool ctable); void shapeResetFill(SwShape* shape); void shapeDelFill(SwShape* shape); @@ -299,7 +279,7 @@ bool strokeParseOutline(SwStroke* stroke, const SwOutline& outline); SwOutline* strokeExportOutline(SwStroke* stroke); void strokeFree(SwStroke* stroke); -bool fillGenColorTable(SwFill* fill, const Fill* fdata, const Matrix* transform, uint32_t cs, bool ctable); +bool fillGenColorTable(SwFill* fill, const Fill* fdata, const Matrix* transform, SwSurface* surface, bool ctable); void fillReset(SwFill* fill); void fillFree(SwFill* fill); void fillFetchLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t offset, uint32_t len); @@ -308,10 +288,11 @@ void fillFetchRadial(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, SwRleData* rleRender(const SwOutline* outline, const SwBBox& bbox, const SwSize& clip, bool antiAlias); void rleFree(SwRleData* rle); -bool rasterGradientShape(Surface& surface, SwShape* shape, unsigned id); -bool rasterSolidShape(Surface& surface, SwShape* shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a); -bool rasterStroke(Surface& surface, SwShape* shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a); -bool rasterClear(Surface& surface); +bool rasterCompositor(SwSurface* surface); +bool rasterGradientShape(SwSurface* surface, SwShape* shape, unsigned id); +bool rasterSolidShape(SwSurface* surface, SwShape* shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a); +bool rasterStroke(SwSurface* surface, SwShape* shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a); +bool rasterClear(SwSurface* surface); static inline void rasterRGBA32(uint32_t *dst, uint32_t val, uint32_t offset, int32_t len) diff --git a/src/lib/sw_engine/tvgSwFill.cpp b/src/lib/sw_engine/tvgSwFill.cpp index cd68d0f1..e748651d 100644 --- a/src/lib/sw_engine/tvgSwFill.cpp +++ b/src/lib/sw_engine/tvgSwFill.cpp @@ -34,7 +34,7 @@ #define FIXPT_SIZE (1<g, pColors->a); auto b = ALPHA_MULTIPLY(pColors->b, pColors->a); - auto rgba = (cs == SwCanvas::RGBA8888) ? RGBA_JOIN(r, g, b, pColors->a) : ARGB_JOIN(r, g, b, pColors->a); + auto rgba = surface->comp.join(r, g, b, pColors->a); auto inc = 1.0f / static_cast(GRADIENT_STOP_SIZE); auto pos = 1.5f * inc; uint32_t i = 0; @@ -79,7 +79,7 @@ static bool _updateColorTable(SwFill* fill, const Fill* fdata, uint32_t cs) auto g = ALPHA_MULTIPLY(next->g, next->a); auto b = ALPHA_MULTIPLY(next->b, next->a); - auto rgba2 = (cs == SwCanvas::RGBA8888) ? RGBA_JOIN(r, g, b, next->a) : ARGB_JOIN(r, g, b, next->a); + auto rgba2 = surface->comp.join(r, g, b, next->a); while (pos < next->offset && i < GRADIENT_STOP_SIZE) { auto t = (pos - curr->offset) * delta; @@ -282,7 +282,7 @@ void fillFetchLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, } -bool fillGenColorTable(SwFill* fill, const Fill* fdata, const Matrix* transform, uint32_t cs, bool ctable) +bool fillGenColorTable(SwFill* fill, const Fill* fdata, const Matrix* transform, SwSurface* surface, bool ctable) { if (!fill) return false; @@ -291,7 +291,7 @@ bool fillGenColorTable(SwFill* fill, const Fill* fdata, const Matrix* transform, fill->spread = fdata->spread(); if (ctable) { - if (!_updateColorTable(fill, fdata, cs)) return false; + if (!_updateColorTable(fill, fdata, surface)) return false; } if (fdata->id() == FILL_ID_LINEAR) { diff --git a/src/lib/sw_engine/tvgSwRaster.cpp b/src/lib/sw_engine/tvgSwRaster.cpp index d07d7eb1..072c74ce 100644 --- a/src/lib/sw_engine/tvgSwRaster.cpp +++ b/src/lib/sw_engine/tvgSwRaster.cpp @@ -28,27 +28,51 @@ /* Internal Class Implementation */ /************************************************************************/ -static SwBBox _clipRegion(Surface& surface, SwBBox& in) +static uint32_t _rgbaAlpha(uint32_t rgba) +{ + return rgba & 0x000000ff; +} + + +static uint32_t _argbAlpha(uint32_t argb) +{ + return (argb >> 24) & 0xff; +} + + +static uint32_t _rgbaJoin(uint8_t r, uint8_t g, uint8_t b, uint8_t a) +{ + return (r << 24 | g << 16 | b << 8 | a); +} + + +static uint32_t _argbJoin(uint8_t r, uint8_t g, uint8_t b, uint8_t a) +{ + return (a << 24 | r << 16 | g << 8 | b); +} + + +static SwBBox _clipRegion(Surface* surface, SwBBox& in) { auto bbox = in; if (bbox.min.x < 0) bbox.min.x = 0; if (bbox.min.y < 0) bbox.min.y = 0; - if (bbox.max.x > static_cast(surface.w)) bbox.max.x = surface.w; - if (bbox.max.y > static_cast(surface.h)) bbox.max.y = surface.h; + if (bbox.max.x > static_cast(surface->w)) bbox.max.x = surface->w; + if (bbox.max.y > static_cast(surface->h)) bbox.max.y = surface->h; return bbox; } -static bool _rasterTranslucentRect(Surface& surface, const SwBBox& region, uint32_t color) +static bool _rasterTranslucentRect(SwSurface* surface, const SwBBox& region, uint32_t color) { - auto buffer = surface.buffer + (region.min.y * surface.stride) + region.min.x; + auto buffer = surface->buffer + (region.min.y * surface->stride) + region.min.x; auto h = static_cast(region.max.y - region.min.y); auto w = static_cast(region.max.x - region.min.x); - auto ialpha = 255 - (surface.cs == SwCanvas::RGBA8888)? RGBA_ALPHA(color) : ARGB_ALPHA(color); + auto ialpha = 255 - surface->comp.alpha(color); for (uint32_t y = 0; y < h; ++y) { - auto dst = &buffer[y * surface.stride]; + auto dst = &buffer[y * surface->stride]; for (uint32_t x = 0; x < w; ++x) { dst[x] = color + RGBA_ALPHA_BLEND(dst[x], ialpha); } @@ -57,20 +81,20 @@ static bool _rasterTranslucentRect(Surface& surface, const SwBBox& region, uint3 } -static bool _rasterSolidRect(Surface& surface, const SwBBox& region, uint32_t color) +static bool _rasterSolidRect(SwSurface* surface, const SwBBox& region, uint32_t color) { - auto buffer = surface.buffer + (region.min.y * surface.stride); + auto buffer = surface->buffer + (region.min.y * surface->stride); auto w = static_cast(region.max.x - region.min.x); auto h = static_cast(region.max.y - region.min.y); for (uint32_t y = 0; y < h; ++y) { - rasterRGBA32(buffer + y * surface.stride, color, region.min.x, w); + rasterRGBA32(buffer + y * surface->stride, color, region.min.x, w); } return true; } -static bool _rasterTranslucentRle(Surface& surface, SwRleData* rle, uint32_t color) +static bool _rasterTranslucentRle(SwSurface* surface, SwRleData* rle, uint32_t color) { if (!rle) return false; @@ -78,10 +102,10 @@ static bool _rasterTranslucentRle(Surface& surface, SwRleData* rle, uint32_t col uint32_t src; for (uint32_t i = 0; i < rle->size; ++i) { - auto dst = &surface.buffer[span->y * surface.stride + span->x]; + auto dst = &surface->buffer[span->y * surface->stride + span->x]; if (span->coverage < 255) src = RGBA_ALPHA_BLEND(color, span->coverage); else src = color; - auto ialpha = 255 - ((surface.cs == SwCanvas::RGBA8888)? RGBA_ALPHA(src) : ARGB_ALPHA(src)); + auto ialpha = 255 - surface->comp.alpha(src); for (uint32_t i = 0; i < span->len; ++i) { dst[i] = src + RGBA_ALPHA_BLEND(dst[i], ialpha); } @@ -91,7 +115,7 @@ static bool _rasterTranslucentRle(Surface& surface, SwRleData* rle, uint32_t col } -static bool _rasterSolidRle(Surface& surface, SwRleData* rle, uint32_t color) +static bool _rasterSolidRle(SwSurface* surface, SwRleData* rle, uint32_t color) { if (!rle) return false; @@ -99,9 +123,9 @@ static bool _rasterSolidRle(Surface& surface, SwRleData* rle, uint32_t color) for (uint32_t i = 0; i < rle->size; ++i) { if (span->coverage == 255) { - rasterRGBA32(surface.buffer + span->y * surface.stride, color, span->x, span->len); + rasterRGBA32(surface->buffer + span->y * surface->stride, color, span->x, span->len); } else { - auto dst = &surface.buffer[span->y * surface.stride + span->x]; + auto dst = &surface->buffer[span->y * surface->stride + span->x]; auto src = RGBA_ALPHA_BLEND(color, span->coverage); auto ialpha = 255 - span->coverage; for (uint32_t i = 0; i < span->len; ++i) { @@ -114,74 +138,62 @@ static bool _rasterSolidRle(Surface& surface, SwRleData* rle, uint32_t color) } -static bool _rasterLinearGradientRect(Surface& surface, const SwBBox& region, const SwFill* fill) +static bool _rasterLinearGradientRect(SwSurface* surface, const SwBBox& region, const SwFill* fill) { if (!fill) return false; - auto buffer = surface.buffer + (region.min.y * surface.stride) + region.min.x; + auto buffer = surface->buffer + (region.min.y * surface->stride) + region.min.x; auto h = static_cast(region.max.y - region.min.y); auto w = static_cast(region.max.x - region.min.x); //Translucent Gradient if (fill->translucent) { - auto tmpBuf = static_cast(alloca(surface.w * sizeof(uint32_t))); + auto tmpBuf = static_cast(alloca(surface->w * sizeof(uint32_t))); if (!tmpBuf) return false; for (uint32_t y = 0; y < h; ++y) { - auto dst = &buffer[y * surface.stride]; + auto dst = &buffer[y * surface->stride]; fillFetchLinear(fill, tmpBuf, region.min.y + y, region.min.x, 0, w); - if (surface.cs == SwCanvas::RGBA8888) { - for (uint32_t x = 0; x < w; ++x) { - dst[x] = tmpBuf[x] + RGBA_ALPHA_BLEND(dst[x], 255 - RGBA_ALPHA(tmpBuf[x])); - } - } else { - for (uint32_t x = 0; x < w; ++x) { - dst[x] = tmpBuf[x] + RGBA_ALPHA_BLEND(dst[x], 255 - ARGB_ALPHA(tmpBuf[x])); - } + for (uint32_t x = 0; x < w; ++x) { + dst[x] = tmpBuf[x] + RGBA_ALPHA_BLEND(dst[x], 255 - surface->comp.alpha(tmpBuf[x])); } } //Opaque Gradient } else { for (uint32_t y = 0; y < h; ++y) { - fillFetchLinear(fill, buffer + y * surface.stride, region.min.y + y, region.min.x, 0, w); + fillFetchLinear(fill, buffer + y * surface->stride, region.min.y + y, region.min.x, 0, w); } } return true; } -static bool _rasterRadialGradientRect(Surface& surface, const SwBBox& region, const SwFill* fill) +static bool _rasterRadialGradientRect(SwSurface* surface, const SwBBox& region, const SwFill* fill) { if (!fill) return false; - auto buffer = surface.buffer + (region.min.y * surface.stride) + region.min.x; + auto buffer = surface->buffer + (region.min.y * surface->stride) + region.min.x; auto h = static_cast(region.max.y - region.min.y); auto w = static_cast(region.max.x - region.min.x); //Translucent Gradient if (fill->translucent) { - auto tmpBuf = static_cast(alloca(surface.w * sizeof(uint32_t))); + auto tmpBuf = static_cast(alloca(surface->w * sizeof(uint32_t))); if (!tmpBuf) return false; for (uint32_t y = 0; y < h; ++y) { - auto dst = &buffer[y * surface.stride]; + auto dst = &buffer[y * surface->stride]; fillFetchRadial(fill, tmpBuf, region.min.y + y, region.min.x, w); - if (surface.cs == SwCanvas::RGBA8888) { - for (uint32_t x = 0; x < w; ++x) { - dst[x] = tmpBuf[x] + RGBA_ALPHA_BLEND(dst[x], 255 - RGBA_ALPHA(tmpBuf[x])); - } - } else { - for (uint32_t x = 0; x < w; ++x) { - dst[x] = tmpBuf[x] + RGBA_ALPHA_BLEND(dst[x], 255 - ARGB_ALPHA(tmpBuf[x])); - } + for (uint32_t x = 0; x < w; ++x) { + dst[x] = tmpBuf[x] + RGBA_ALPHA_BLEND(dst[x], 255 - surface->comp.alpha(tmpBuf[x])); } } //Opaque Gradient } else { for (uint32_t y = 0; y < h; ++y) { - auto dst = &buffer[y * surface.stride]; + auto dst = &buffer[y * surface->stride]; fillFetchRadial(fill, dst, region.min.y + y, region.min.x, w); } } @@ -189,11 +201,11 @@ static bool _rasterRadialGradientRect(Surface& surface, const SwBBox& region, co } -static bool _rasterLinearGradientRle(Surface& surface, SwRleData* rle, const SwFill* fill) +static bool _rasterLinearGradientRle(SwSurface* surface, SwRleData* rle, const SwFill* fill) { if (!rle || !fill) return false; - auto buf = static_cast(alloca(surface.w * sizeof(uint32_t))); + auto buf = static_cast(alloca(surface->w * sizeof(uint32_t))); if (!buf) return false; auto span = rle->spans; @@ -201,29 +213,16 @@ static bool _rasterLinearGradientRle(Surface& surface, SwRleData* rle, const SwF //Translucent Gradient if (fill->translucent) { for (uint32_t i = 0; i < rle->size; ++i) { - auto dst = &surface.buffer[span->y * surface.stride + span->x]; + auto dst = &surface->buffer[span->y * surface->stride + span->x]; fillFetchLinear(fill, buf, span->y, span->x, 0, span->len); - if (surface.cs == SwCanvas::RGBA8888) { - if (span->coverage == 255) { - for (uint32_t i = 0; i < span->len; ++i) { - dst[i] = buf[i] + RGBA_ALPHA_BLEND(dst[i], 255 - RGBA_ALPHA(buf[i])); - } - } else { - for (uint32_t i = 0; i < span->len; ++i) { - auto tmp = RGBA_ALPHA_BLEND(buf[i], span->coverage); - dst[i] = tmp + RGBA_ALPHA_BLEND(dst[i], 255 - RGBA_ALPHA(tmp)); - } + if (span->coverage == 255) { + for (uint32_t i = 0; i < span->len; ++i) { + dst[i] = buf[i] + RGBA_ALPHA_BLEND(dst[i], 255 - surface->comp.alpha(buf[i])); } } else { - if (span->coverage == 255) { - for (uint32_t i = 0; i < span->len; ++i) { - dst[i] = buf[i] + RGBA_ALPHA_BLEND(dst[i], 255 - ARGB_ALPHA(buf[i])); - } - } else { - for (uint32_t i = 0; i < span->len; ++i) { - auto tmp = RGBA_ALPHA_BLEND(buf[i], span->coverage); - dst[i] = tmp + RGBA_ALPHA_BLEND(dst[i], 255 - ARGB_ALPHA(tmp)); - } + for (uint32_t i = 0; i < span->len; ++i) { + auto tmp = RGBA_ALPHA_BLEND(buf[i], span->coverage); + dst[i] = tmp + RGBA_ALPHA_BLEND(dst[i], 255 - surface->comp.alpha(tmp)); } } ++span; @@ -232,9 +231,9 @@ static bool _rasterLinearGradientRle(Surface& surface, SwRleData* rle, const SwF } else { for (uint32_t i = 0; i < rle->size; ++i) { if (span->coverage == 255) { - fillFetchLinear(fill, surface.buffer + span->y * surface.stride, span->y, span->x, span->x, span->len); + fillFetchLinear(fill, surface->buffer + span->y * surface->stride, span->y, span->x, span->x, span->len); } else { - auto dst = &surface.buffer[span->y * surface.stride + span->x]; + auto dst = &surface->buffer[span->y * surface->stride + span->x]; fillFetchLinear(fill, buf, span->y, span->x, 0, span->len); auto ialpha = 255 - span->coverage; for (uint32_t i = 0; i < span->len; ++i) { @@ -248,11 +247,11 @@ static bool _rasterLinearGradientRle(Surface& surface, SwRleData* rle, const SwF } -static bool _rasterRadialGradientRle(Surface& surface, SwRleData* rle, const SwFill* fill) +static bool _rasterRadialGradientRle(SwSurface* surface, SwRleData* rle, const SwFill* fill) { if (!rle || !fill) return false; - auto buf = static_cast(alloca(surface.w * sizeof(uint32_t))); + auto buf = static_cast(alloca(surface->w * sizeof(uint32_t))); if (!buf) return false; auto span = rle->spans; @@ -260,29 +259,16 @@ static bool _rasterRadialGradientRle(Surface& surface, SwRleData* rle, const SwF //Translucent Gradient if (fill->translucent) { for (uint32_t i = 0; i < rle->size; ++i) { - auto dst = &surface.buffer[span->y * surface.stride + span->x]; + auto dst = &surface->buffer[span->y * surface->stride + span->x]; fillFetchRadial(fill, buf, span->y, span->x, span->len); - if (surface.cs == SwCanvas::RGBA8888) { - if (span->coverage == 255) { - for (uint32_t i = 0; i < span->len; ++i) { - dst[i] = buf[i] + RGBA_ALPHA_BLEND(dst[i], 255 - RGBA_ALPHA(buf[i])); - } - } else { - for (uint32_t i = 0; i < span->len; ++i) { - auto tmp = RGBA_ALPHA_BLEND(buf[i], span->coverage); - dst[i] = tmp + RGBA_ALPHA_BLEND(dst[i], 255 - RGBA_ALPHA(tmp)); - } + if (span->coverage == 255) { + for (uint32_t i = 0; i < span->len; ++i) { + dst[i] = buf[i] + RGBA_ALPHA_BLEND(dst[i], 255 - surface->comp.alpha(buf[i])); } } else { - if (span->coverage == 255) { - for (uint32_t i = 0; i < span->len; ++i) { - dst[i] = buf[i] + RGBA_ALPHA_BLEND(dst[i], 255 - ARGB_ALPHA(buf[i])); - } - } else { - for (uint32_t i = 0; i < span->len; ++i) { - auto tmp = RGBA_ALPHA_BLEND(buf[i], span->coverage); - dst[i] = tmp + RGBA_ALPHA_BLEND(dst[i], 255 - ARGB_ALPHA(tmp)); - } + for (uint32_t i = 0; i < span->len; ++i) { + auto tmp = RGBA_ALPHA_BLEND(buf[i], span->coverage); + dst[i] = tmp + RGBA_ALPHA_BLEND(dst[i], 255 - surface->comp.alpha(tmp)); } } ++span; @@ -290,7 +276,7 @@ static bool _rasterRadialGradientRle(Surface& surface, SwRleData* rle, const SwF //Opaque Gradient } else { for (uint32_t i = 0; i < rle->size; ++i) { - auto dst = &surface.buffer[span->y * surface.stride + span->x]; + auto dst = &surface->buffer[span->y * surface->stride + span->x]; if (span->coverage == 255) { fillFetchRadial(fill, dst, span->y, span->x, span->len); } else { @@ -311,7 +297,24 @@ static bool _rasterRadialGradientRle(Surface& surface, SwRleData* rle, const SwF /* External Class Implementation */ /************************************************************************/ -bool rasterGradientShape(Surface& surface, SwShape* shape, unsigned id) +bool rasterCompositor(SwSurface* surface) +{ + if (surface->cs == SwCanvas::RGBA8888) { + surface->comp.alpha = _rgbaAlpha; + surface->comp.join = _rgbaJoin; + } else if (surface->cs == SwCanvas::ARGB8888) { + surface->comp.alpha = _argbAlpha; + surface->comp.join = _argbJoin; + } else { + //What Color Space ??? + return false; + } + + return true; +} + + +bool rasterGradientShape(SwSurface* surface, SwShape* shape, unsigned id) { //Fast Track if (shape->rect) { @@ -326,13 +329,13 @@ bool rasterGradientShape(Surface& surface, SwShape* shape, unsigned id) } -bool rasterSolidShape(Surface& surface, SwShape* shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +bool rasterSolidShape(SwSurface* surface, SwShape* shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a) { r = ALPHA_MULTIPLY(r, a); g = ALPHA_MULTIPLY(g, a); b = ALPHA_MULTIPLY(b, a); - auto color = (surface.cs == SwCanvas::RGBA8888) ? RGBA_JOIN(r, g, b, a) : ARGB_JOIN(r, g, b, a); + auto color = surface->comp.join(r, g, b, a); //Fast Track if (shape->rect) { @@ -347,28 +350,28 @@ bool rasterSolidShape(Surface& surface, SwShape* shape, uint8_t r, uint8_t g, ui } -bool rasterStroke(Surface& surface, SwShape* shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +bool rasterStroke(SwSurface* surface, SwShape* shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a) { r = ALPHA_MULTIPLY(r, a); g = ALPHA_MULTIPLY(g, a); b = ALPHA_MULTIPLY(b, a); - auto color = (surface.cs == SwCanvas::RGBA8888) ? RGBA_JOIN(r, g, b, a) : ARGB_JOIN(r, g, b, a); + auto color = surface->comp.join(r, g, b, a); if (a == 255) return _rasterSolidRle(surface, shape->strokeRle, color); return _rasterTranslucentRle(surface, shape->strokeRle, color); } -bool rasterClear(Surface& surface) +bool rasterClear(SwSurface* surface) { - if (!surface.buffer || surface.stride <= 0 || surface.w <= 0 || surface.h <= 0) return false; + if (!surface || !surface->buffer || surface->stride <= 0 || surface->w <= 0 || surface->h <= 0) return false; - if (surface.w == surface.stride) { - rasterRGBA32(surface.buffer, 0x00000000, 0, surface.w * surface.h); + if (surface->w == surface->stride) { + rasterRGBA32(surface->buffer, 0x00000000, 0, surface->w * surface->h); } else { - for (uint32_t i = 0; i < surface.h; i++) { - rasterRGBA32(surface.buffer + surface.stride * i, 0x00000000, 0, surface.w); + for (uint32_t i = 0; i < surface->h; i++) { + rasterRGBA32(surface->buffer + surface->stride * i, 0x00000000, 0, surface->w); } } return true; diff --git a/src/lib/sw_engine/tvgSwRenderer.cpp b/src/lib/sw_engine/tvgSwRenderer.cpp index 66608f54..8d02b404 100644 --- a/src/lib/sw_engine/tvgSwRenderer.cpp +++ b/src/lib/sw_engine/tvgSwRenderer.cpp @@ -37,6 +37,7 @@ static RenderInitializer renderInit; SwRenderer::~SwRenderer() { + if (surface) delete(surface); } @@ -44,13 +45,18 @@ bool SwRenderer::target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t { if (!buffer || stride == 0 || w == 0 || h == 0) return false; - surface.buffer = buffer; - surface.stride = stride; - surface.w = w; - surface.h = h; - surface.cs = cs; + if (!surface) { + surface = new SwSurface; + if (!surface) return false; + } - return true; + surface->buffer = buffer; + surface->stride = stride; + surface->w = w; + surface->h = h; + surface->cs = cs; + + return rasterCompositor(surface); } @@ -100,7 +106,7 @@ void* SwRenderer::prepare(const Shape& sdata, void* data, const RenderTransform* if (flags == RenderUpdateFlag::None) return shape; - SwSize clip = {static_cast(surface.w), static_cast(surface.h)}; + SwSize clip = {static_cast(surface->w), static_cast(surface->h)}; //Valid Stroking? uint8_t strokeAlpha = 0; @@ -130,7 +136,7 @@ void* SwRenderer::prepare(const Shape& sdata, void* data, const RenderTransform* if (fill) { auto ctable = (flags & RenderUpdateFlag::Gradient) ? true : false; if (ctable) shapeResetFill(shape); - if (!shapeGenFillColors(shape, fill, matrix, surface.cs, ctable)) return shape; + if (!shapeGenFillColors(shape, fill, matrix, surface, ctable)) return shape; } else { shapeDelFill(shape); } diff --git a/src/lib/sw_engine/tvgSwRenderer.h b/src/lib/sw_engine/tvgSwRenderer.h index 5657602b..2185f344 100644 --- a/src/lib/sw_engine/tvgSwRenderer.h +++ b/src/lib/sw_engine/tvgSwRenderer.h @@ -22,11 +22,11 @@ #ifndef _TVG_SW_RENDERER_H_ #define _TVG_SW_RENDERER_H_ +struct SwSurface; + namespace tvg { -struct SwTask; - class SwRenderer : public RenderMethod { public: @@ -43,7 +43,7 @@ public: static int term(); private: - Surface surface = {nullptr, 0, 0, 0}; + SwSurface* surface = nullptr; SwRenderer(){}; ~SwRenderer(); diff --git a/src/lib/sw_engine/tvgSwShape.cpp b/src/lib/sw_engine/tvgSwShape.cpp index 3704a2cb..c94ef260 100644 --- a/src/lib/sw_engine/tvgSwShape.cpp +++ b/src/lib/sw_engine/tvgSwShape.cpp @@ -672,9 +672,9 @@ bool shapeGenStrokeRle(SwShape* shape, const Shape* sdata, const Matrix* transfo } -bool shapeGenFillColors(SwShape* shape, const Fill* fill, const Matrix* transform, uint32_t cs, bool ctable) +bool shapeGenFillColors(SwShape* shape, const Fill* fill, const Matrix* transform, SwSurface* surface, bool ctable) { - return fillGenColorTable(shape->fill, fill, transform, cs, ctable); + return fillGenColorTable(shape->fill, fill, transform, surface, ctable); }