}
#endif
-using namespace tvg;
-
#define SW_CURVE_TYPE_POINT 0
#define SW_CURVE_TYPE_CUBIC 1
#define SW_OUTLINE_FILL_WINDING 0
bool rect; //Fast Track: Othogonal rectangle?
};
-
-static inline SwCoord TO_SWCOORD(float val)
+struct SwCompositor
{
- return SwCoord(val * 64);
-}
-
+ uint32_t (*join)(uint8_t r, uint8_t g, uint8_t b, uint8_t a);
+ uint32_t (*alpha)(uint32_t rgba);
+};
-static inline uint32_t RGBA_ALPHA(uint32_t rgba)
+struct SwSurface : Surface
{
- return rgba & 0x000000ff;
-}
-
+ SwCompositor comp;
+};
-static inline uint32_t ARGB_ALPHA(uint32_t argb)
+static inline SwCoord TO_SWCOORD(float val)
{
- return (argb >> 24) & 0xff;
+ return SwCoord(val * 64);
}
-
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);
-}
-
-
-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);
+ 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 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);
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);
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);
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)
/* 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<SwCoord>(surface.w)) bbox.max.x = surface.w;
- if (bbox.max.y > static_cast<SwCoord>(surface.h)) bbox.max.y = surface.h;
+ if (bbox.max.x > static_cast<SwCoord>(surface->w)) bbox.max.x = surface->w;
+ if (bbox.max.y > static_cast<SwCoord>(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<uint32_t>(region.max.y - region.min.y);
auto w = static_cast<uint32_t>(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);
}
}
-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<uint32_t>(region.max.x - region.min.x);
auto h = static_cast<uint32_t>(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;
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);
}
}
-static bool _rasterSolidRle(Surface& surface, SwRleData* rle, uint32_t color)
+static bool _rasterSolidRle(SwSurface* surface, SwRleData* rle, uint32_t color)
{
if (!rle) return false;
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) {
}
-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<uint32_t>(region.max.y - region.min.y);
auto w = static_cast<uint32_t>(region.max.x - region.min.x);
//Translucent Gradient
if (fill->translucent) {
- auto tmpBuf = static_cast<uint32_t*>(alloca(surface.w * sizeof(uint32_t)));
+ auto tmpBuf = static_cast<uint32_t*>(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<uint32_t>(region.max.y - region.min.y);
auto w = static_cast<uint32_t>(region.max.x - region.min.x);
//Translucent Gradient
if (fill->translucent) {
- auto tmpBuf = static_cast<uint32_t*>(alloca(surface.w * sizeof(uint32_t)));
+ auto tmpBuf = static_cast<uint32_t*>(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);
}
}
}
-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<uint32_t*>(alloca(surface.w * sizeof(uint32_t)));
+ auto buf = static_cast<uint32_t*>(alloca(surface->w * sizeof(uint32_t)));
if (!buf) return false;
auto span = rle->spans;
//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;
} 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) {
}
-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<uint32_t*>(alloca(surface.w * sizeof(uint32_t)));
+ auto buf = static_cast<uint32_t*>(alloca(surface->w * sizeof(uint32_t)));
if (!buf) return false;
auto span = rle->spans;
//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;
//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 {
/* 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) {
}
-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) {
}
-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;