we can't control any threads count that could drop the performance.
remove async() and will come back with fine-tuned threading-pool.
Change-Id: I17c39792234acfce6db334abc0ce12da23978a9a
bool mathSmallCubic(SwPoint* base, SwFixed& angleIn, SwFixed& angleMid, SwFixed& angleOut);
SwFixed mathMean(SwFixed angle1, SwFixed angle2);
-void shapeReset(SwShape& shape);
-bool shapeGenOutline(SwShape& shape, const Shape* sdata, const Matrix* transform);
-bool shapePrepare(SwShape& shape, const Shape* sdata, const SwSize& clip, const Matrix* transform);
-bool shapeGenRle(SwShape& shape, const Shape* sdata, const SwSize& clip, bool antiAlias);
-void shapeDelOutline(SwShape& shape);
-void shapeResetStroke(SwShape& shape, const Shape* sdata, const Matrix* transform);
-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, bool ctable);
-void shapeResetFill(SwShape& shape);
-void shapeDelFill(SwShape& shape);
-
-void strokeReset(SwStroke& stroke, const Shape* shape, const Matrix* transform);
-bool strokeParseOutline(SwStroke& stroke, const SwOutline& outline);
-SwOutline* strokeExportOutline(SwStroke& stroke);
+void shapeReset(SwShape* shape);
+bool shapeGenOutline(SwShape* shape, const Shape* sdata, const Matrix* transform);
+bool shapePrepare(SwShape* shape, const Shape* sdata, const SwSize& clip, const Matrix* transform);
+bool shapeGenRle(SwShape* shape, const Shape* sdata, const SwSize& clip, bool antiAlias);
+void shapeDelOutline(SwShape* shape);
+void shapeResetStroke(SwShape* shape, const Shape* sdata, const Matrix* transform);
+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, bool ctable);
+void shapeResetFill(SwShape* shape);
+void shapeDelFill(SwShape* shape);
+
+void strokeReset(SwStroke* stroke, const Shape* shape, const Matrix* transform);
+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, bool ctable);
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 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);
/* External Class Implementation */
/************************************************************************/
-bool rasterGradientShape(Surface& surface, SwShape& shape, unsigned id)
+bool rasterGradientShape(Surface& surface, SwShape* shape, unsigned id)
{
//Fast Track
- if (shape.rect) {
- auto region = _clipRegion(surface, shape.bbox);
- if (id == FILL_ID_LINEAR) return _rasterLinearGradientRect(surface, region, shape.fill);
- return _rasterRadialGradientRect(surface, region, shape.fill);
+ if (shape->rect) {
+ auto region = _clipRegion(surface, shape->bbox);
+ if (id == FILL_ID_LINEAR) return _rasterLinearGradientRect(surface, region, shape->fill);
+ return _rasterRadialGradientRect(surface, region, shape->fill);
} else {
- if (id == FILL_ID_LINEAR) return _rasterLinearGradientRle(surface, shape.rle, shape.fill);
- return _rasterRadialGradientRle(surface, shape.rle, shape.fill);
+ if (id == FILL_ID_LINEAR) return _rasterLinearGradientRle(surface, shape->rle, shape->fill);
+ return _rasterRadialGradientRle(surface, shape->rle, shape->fill);
}
return false;
}
-bool rasterSolidShape(Surface& surface, SwShape& shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a)
+bool rasterSolidShape(Surface& surface, SwShape* shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a)
{
r = COLOR_ALPHA_MULTIPLY(r, a);
g = COLOR_ALPHA_MULTIPLY(g, a);
b = COLOR_ALPHA_MULTIPLY(b, a);
//Fast Track
- if (shape.rect) {
- auto region = _clipRegion(surface, shape.bbox);
+ if (shape->rect) {
+ auto region = _clipRegion(surface, shape->bbox);
if (a == 255) return _rasterSolidRect(surface, region, COLOR_ARGB_JOIN(r, g, b, a));
return _rasterTranslucentRect(surface, region, COLOR_ARGB_JOIN(r, g, b, a));
} else{
- if (a == 255) return _rasterSolidRle(surface, shape.rle, COLOR_ARGB_JOIN(r, g, b, a));
- return _rasterTranslucentRle(surface, shape.rle, COLOR_ARGB_JOIN(r, g, b, a));
+ if (a == 255) return _rasterSolidRle(surface, shape->rle, COLOR_ARGB_JOIN(r, g, b, a));
+ return _rasterTranslucentRle(surface, shape->rle, COLOR_ARGB_JOIN(r, g, b, a));
}
return false;
}
-bool rasterStroke(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)
{
r = COLOR_ALPHA_MULTIPLY(r, a);
g = COLOR_ALPHA_MULTIPLY(g, a);
b = COLOR_ALPHA_MULTIPLY(b, a);
- if (a == 255) return _rasterSolidRle(surface, shape.strokeRle, COLOR_ARGB_JOIN(r, g, b, a));
- return _rasterTranslucentRle(surface, shape.strokeRle, COLOR_ARGB_JOIN(r, g, b, a));
+ if (a == 255) return _rasterSolidRle(surface, shape->strokeRle, COLOR_ARGB_JOIN(r, g, b, a));
+ return _rasterTranslucentRle(surface, shape->strokeRle, COLOR_ARGB_JOIN(r, g, b, a));
}
#ifndef _TVG_SW_RENDERER_CPP_
#define _TVG_SW_RENDERER_CPP_
-using namespace std;
-
#include "tvgSwCommon.h"
#include "tvgSwRenderer.h"
-
/************************************************************************/
/* Internal Class Implementation */
/************************************************************************/
-namespace tvg {
- struct SwTask
- {
- SwShape shape;
- const Shape* sdata;
- SwSize clip;
- Matrix* transform;
- RenderUpdateFlag flags;
- future<void> progress;
- };
-}
-
static RenderInitializer renderInit;
SwRenderer::~SwRenderer()
{
- flush();
-}
-
-
-bool SwRenderer::clear()
-{
- return flush();
}
bool SwRenderer::preRender()
{
- //before we start rendering, we should finish all preparing tasks
- while (prepareTasks.size() > 0) {
- auto task = prepareTasks.front();
- if (task->progress.valid()) task->progress.get();
- prepareTasks.pop();
- renderTasks.push(task);
- }
- return true;
-}
-
-
-bool SwRenderer::postRender()
-{
- auto asyncTask = [](SwRenderer* renderer) {
- renderer->doRender();
- };
-
- progress = async(launch::async, asyncTask, this);
-
- return true;
+ return rasterClear(surface);
}
-void SwRenderer::doRender()
+bool SwRenderer::render(const Shape& sdata, TVG_UNUSED void *data)
{
- rasterClear(surface);
-
- while (renderTasks.size() > 0) {
- auto task = renderTasks.front();
- uint8_t r, g, b, a;
- if (auto fill = task->sdata->fill()) {
- rasterGradientShape(surface, task->shape, fill->id());
- } else{
- task->sdata->fill(&r, &g, &b, &a);
- if (a > 0) rasterSolidShape(surface, task->shape, r, g, b, a);
- }
- task->sdata->strokeColor(&r, &g, &b, &a);
- if (a > 0) rasterStroke(surface, task->shape, r, g, b, a);
- renderTasks.pop();
- }
-}
+ auto shape = static_cast<SwShape*>(data);
+ if (!shape) return false;
+ uint8_t r, g, b, a;
-bool SwRenderer::flush()
-{
- while (prepareTasks.size() > 0) {
- auto task = prepareTasks.front();
- if (task->progress.valid()) task->progress.get();
- prepareTasks.pop();
+ if (auto fill = sdata.fill()) {
+ rasterGradientShape(surface, shape, fill->id());
+ } else{
+ sdata.fill(&r, &g, &b, &a);
+ if (a > 0) rasterSolidShape(surface, shape, r, g, b, a);
}
-
- if (progress.valid()) progress.get();
-
- return true;
-}
-
-
-bool SwRenderer::render(TVG_UNUSED const Shape& sdata, TVG_UNUSED void *data)
-{
- //Do Nothing
+ sdata.strokeColor(&r, &g, &b, &a);
+ if (a > 0) rasterStroke(surface, shape, r, g, b, a);
return true;
}
bool SwRenderer::dispose(TVG_UNUSED const Shape& sdata, void *data)
{
- auto task = static_cast<SwTask*>(data);
- if (!task) return true;
- if (task->progress.valid()) task->progress.get();
- shapeFree(task->shape);
- if (task->transform) free(task->transform);
- free(task);
+ auto shape = static_cast<SwShape*>(data);
+ if (!shape) return false;
+ shapeFree(shape);
return true;
}
void* SwRenderer::prepare(const Shape& sdata, void* data, const RenderTransform* transform, RenderUpdateFlag flags)
{
- //prepare task
- auto task = static_cast<SwTask*>(data);
- if (!task) {
- task = static_cast<SwTask*>(calloc(1, sizeof(SwTask)));
- if (!task) return nullptr;
+ //prepare shape data
+ auto shape = static_cast<SwShape*>(data);
+ if (!shape) {
+ shape = static_cast<SwShape*>(calloc(1, sizeof(SwShape)));
+ assert(shape);
}
- if (flags == RenderUpdateFlag::None || task->progress.valid()) return task;
+ if (flags == RenderUpdateFlag::None) return shape;
- task->sdata = &sdata;
- task->clip = {static_cast<SwCoord>(surface.w), static_cast<SwCoord>(surface.h)};
+ SwSize clip = {static_cast<SwCoord>(surface.w), static_cast<SwCoord>(surface.h)};
- if (transform) {
- if (!task->transform) task->transform = static_cast<Matrix*>(malloc(sizeof(Matrix)));
- assert(task->transform);
- *task->transform = transform->m;
- } else {
- if (task->transform) free(task->transform);
- task->transform = nullptr;
+ //Valid Stroking?
+ uint8_t strokeAlpha = 0;
+ auto strokeWidth = sdata.strokeWidth();
+ if (strokeWidth > FLT_EPSILON) {
+ sdata.strokeColor(nullptr, nullptr, nullptr, &strokeAlpha);
}
- task->flags = flags;
-
- auto asyncTask = [](SwTask* task) {
-
- //Valid Stroking?
- uint8_t strokeAlpha = 0;
- auto strokeWidth = task->sdata->strokeWidth();
- if (strokeWidth > FLT_EPSILON) {
- task->sdata->strokeColor(nullptr, nullptr, nullptr, &strokeAlpha);
- }
-
- //Shape
- if (task->flags & (RenderUpdateFlag::Path | RenderUpdateFlag::Transform)) {
- shapeReset(task->shape);
- uint8_t alpha = 0;
- task->sdata->fill(nullptr, nullptr, nullptr, &alpha);
- bool renderShape = (alpha > 0 || task->sdata->fill());
- if (renderShape || strokeAlpha) {
- if (!shapePrepare(task->shape, task->sdata, task->clip, task->transform)) return;
- if (renderShape) {
- auto antiAlias = (strokeAlpha > 0 && strokeWidth >= 2) ? false : true;
- if (!shapeGenRle(task->shape, task->sdata, task->clip, antiAlias)) return;
- }
+ const Matrix* matrix = (transform ? &transform->m : nullptr);
+
+ //Shape
+ if (flags & (RenderUpdateFlag::Path | RenderUpdateFlag::Transform)) {
+ shapeReset(shape);
+ uint8_t alpha = 0;
+ sdata.fill(nullptr, nullptr, nullptr, &alpha);
+ bool renderShape = (alpha > 0 || sdata.fill());
+ if (renderShape || strokeAlpha) {
+ if (!shapePrepare(shape, &sdata, clip, matrix)) return shape;
+ if (renderShape) {
+ auto antiAlias = (strokeAlpha > 0 && strokeWidth >= 2) ? false : true;
+ if (!shapeGenRle(shape, &sdata, clip, antiAlias)) return shape;
}
}
//Fill
- if (task->flags & (RenderUpdateFlag::Gradient | RenderUpdateFlag::Transform)) {
- auto fill = task->sdata->fill();
+ if (flags & (RenderUpdateFlag::Gradient | RenderUpdateFlag::Transform)) {
+ auto fill = sdata.fill();
if (fill) {
- auto ctable = (task->flags & RenderUpdateFlag::Gradient) ? true : false;
- if (ctable) shapeResetFill(task->shape);
- if (!shapeGenFillColors(task->shape, fill, task->transform, ctable)) return;
+ auto ctable = (flags & RenderUpdateFlag::Gradient) ? true : false;
+ if (ctable) shapeResetFill(shape);
+ if (!shapeGenFillColors(shape, fill, matrix, ctable)) return shape;
} else {
- shapeDelFill(task->shape);
+ shapeDelFill(shape);
}
}
//Stroke
- if (task->flags & (RenderUpdateFlag::Stroke | RenderUpdateFlag::Transform)) {
+ if (flags & (RenderUpdateFlag::Stroke | RenderUpdateFlag::Transform)) {
if (strokeAlpha > 0) {
- shapeResetStroke(task->shape, task->sdata, task->transform);
- if (!shapeGenStrokeRle(task->shape, task->sdata, task->transform, task->clip)) return;
+ shapeResetStroke(shape, &sdata, matrix);
+ if (!shapeGenStrokeRle(shape, &sdata, matrix, clip)) return shape;
} else {
- shapeDelStroke(task->shape);
+ shapeDelStroke(shape);
}
}
- shapeDelOutline(task->shape);
- };
-
- prepareTasks.push(task);
- task->progress = async((launch::async | launch::deferred), asyncTask, task);
+ shapeDelOutline(shape);
+ }
- return task;
+ return shape;
}
#ifndef _TVG_SW_RENDERER_H_
#define _TVG_SW_RENDERER_H_
-#include <queue>
-#include <future>
-#include <thread>
-
namespace tvg
{
bool dispose(const Shape& shape, void *data) override;
bool preRender() override;
bool render(const Shape& shape, void *data) override;
- bool postRender() override;
bool target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t h);
- bool clear() override;
- bool flush() override;
uint32_t ref() override;
uint32_t unref() override;
static int init();
static int term();
- void doRender(); //Internally used for threading
-
private:
Surface surface = {nullptr, 0, 0, 0};
- future<void> progress;
- queue<SwTask*> prepareTasks;
- queue<SwTask*> renderTasks;
SwRenderer(){};
~SwRenderer();
/* External Class Implementation */
/************************************************************************/
-bool shapePrepare(SwShape& shape, const Shape* sdata, const SwSize& clip, const Matrix* transform)
+bool shapePrepare(SwShape* shape, const Shape* sdata, const SwSize& clip, const Matrix* transform)
{
if (!shapeGenOutline(shape, sdata, transform)) return false;
- if (!_updateBBox(shape.outline, shape.bbox)) return false;
+ if (!_updateBBox(shape->outline, shape->bbox)) return false;
- if (!_checkValid(shape.outline, shape.bbox, clip)) return false;
+ if (!_checkValid(shape->outline, shape->bbox, clip)) return false;
return true;
}
-bool shapeGenRle(SwShape& shape, TVG_UNUSED const Shape* sdata, const SwSize& clip, bool antiAlias)
+bool shapeGenRle(SwShape* shape, TVG_UNUSED const Shape* sdata, const SwSize& clip, bool antiAlias)
{
//FIXME: Should we draw it?
//Case: Stroke Line
//if (shape.outline->opened) return true;
//Case A: Fast Track Rectangle Drawing
- if ((shape.rect = _fastTrack(shape.outline))) return true;
+ if ((shape->rect = _fastTrack(shape->outline))) return true;
//Case B: Normale Shape RLE Drawing
- if ((shape.rle = rleRender(shape.outline, shape.bbox, clip, antiAlias))) return true;
+ if ((shape->rle = rleRender(shape->outline, shape->bbox, clip, antiAlias))) return true;
return false;
}
-void shapeDelOutline(SwShape& shape)
+void shapeDelOutline(SwShape* shape)
{
- auto outline = shape.outline;
+ auto outline = shape->outline;
_delOutline(outline);
- shape.outline = nullptr;
+ shape->outline = nullptr;
}
-void shapeReset(SwShape& shape)
+void shapeReset(SwShape* shape)
{
shapeDelOutline(shape);
- rleFree(shape.rle);
- shape.rle = nullptr;
- shape.rect = false;
- _initBBox(shape.bbox);
+ rleFree(shape->rle);
+ shape->rle = nullptr;
+ shape->rect = false;
+ _initBBox(shape->bbox);
}
-bool shapeGenOutline(SwShape& shape, const Shape* sdata, const Matrix* transform)
+bool shapeGenOutline(SwShape* shape, const Shape* sdata, const Matrix* transform)
{
assert(sdata);
++outlinePtsCnt; //for close
++outlineCntrsCnt; //for end
- auto outline = shape.outline;
+ auto outline = shape->outline;
if (!outline) outline = static_cast<SwOutline*>(calloc(1, sizeof(SwOutline)));
assert(outline);
outline->opened = true;
//FIXME:
//outline->flags = SwOutline::FillRule::Winding;
- shape.outline = outline;
+ shape->outline = outline;
return true;
}
-void shapeFree(SwShape& shape)
+void shapeFree(SwShape* shape)
{
shapeDelOutline(shape);
- rleFree(shape.rle);
+ rleFree(shape->rle);
shapeDelFill(shape);
- if (shape.stroke) {
- rleFree(shape.strokeRle);
- strokeFree(shape.stroke);
+ if (shape->stroke) {
+ rleFree(shape->strokeRle);
+ strokeFree(shape->stroke);
}
}
-void shapeDelStroke(SwShape& shape)
+void shapeDelStroke(SwShape* shape)
{
- if (!shape.stroke) return;
- rleFree(shape.strokeRle);
- shape.strokeRle = nullptr;
- strokeFree(shape.stroke);
- shape.stroke = nullptr;
+ if (!shape->stroke) return;
+ rleFree(shape->strokeRle);
+ shape->strokeRle = nullptr;
+ strokeFree(shape->stroke);
+ shape->stroke = nullptr;
}
-void shapeResetStroke(SwShape& shape, const Shape* sdata, const Matrix* transform)
+void shapeResetStroke(SwShape* shape, const Shape* sdata, const Matrix* transform)
{
- if (!shape.stroke) shape.stroke = static_cast<SwStroke*>(calloc(1, sizeof(SwStroke)));
- auto stroke = shape.stroke;
- assert(stroke);
+ if (!shape->stroke) shape->stroke = static_cast<SwStroke*>(calloc(1, sizeof(SwStroke)));
+ auto stroke = shape->stroke;
+ if (!stroke) return;
- strokeReset(*stroke, sdata, transform);
+ strokeReset(stroke, sdata, transform);
- rleFree(shape.strokeRle);
- shape.strokeRle = nullptr;
+ rleFree(shape->strokeRle);
+ shape->strokeRle = nullptr;
}
-bool shapeGenStrokeRle(SwShape& shape, const Shape* sdata, const Matrix* transform, const SwSize& clip)
+bool shapeGenStrokeRle(SwShape* shape, const Shape* sdata, const Matrix* transform, const SwSize& clip)
{
assert(sdata);
if (!shapeOutline) return false;
//Normal Style stroke
} else {
- if (!shape.outline) {
+ if (!shape->outline) {
if (!shapeGenOutline(shape, sdata, transform)) return false;
}
- shapeOutline = shape.outline;
+ shapeOutline = shape->outline;
}
- if (!strokeParseOutline(*shape.stroke, *shapeOutline)) return false;
+ if (!strokeParseOutline(shape->stroke, *shapeOutline)) return false;
- auto strokeOutline = strokeExportOutline(*shape.stroke);
+ auto strokeOutline = strokeExportOutline(shape->stroke);
if (!strokeOutline) return false;
SwBBox bbox;
if (!_checkValid(strokeOutline, bbox, clip)) return false;
- shape.strokeRle = rleRender(strokeOutline, bbox, clip, true);
+ shape->strokeRle = rleRender(strokeOutline, bbox, clip, true);
_delOutline(strokeOutline);
}
-bool shapeGenFillColors(SwShape& shape, const Fill* fill, const Matrix* transform, bool ctable)
+bool shapeGenFillColors(SwShape* shape, const Fill* fill, const Matrix* transform, bool ctable)
{
- return fillGenColorTable(shape.fill, fill, transform, ctable);
+ return fillGenColorTable(shape->fill, fill, transform, ctable);
}
-void shapeResetFill(SwShape& shape)
+void shapeResetFill(SwShape* shape)
{
- if (!shape.fill) shape.fill = static_cast<SwFill*>(calloc(1, sizeof(SwFill)));
- assert(shape.fill);
-
- fillReset(shape.fill);
+ if (!shape->fill) {
+ shape->fill = static_cast<SwFill*>(calloc(1, sizeof(SwFill)));
+ if (!shape->fill) return;
+ }
+ fillReset(shape->fill);
}
-void shapeDelFill(SwShape& shape)
+void shapeDelFill(SwShape* shape)
{
- if (!shape.fill) return;
- fillFree(shape.fill);
- shape.fill = nullptr;
+ if (!shape->fill) return;
+ fillFree(shape->fill);
+ shape->fill = nullptr;
}
}
-void strokeReset(SwStroke& stroke, const Shape* sdata, const Matrix* transform)
+void strokeReset(SwStroke* stroke, const Shape* sdata, const Matrix* transform)
{
assert(sdata);
if (transform) {
- stroke.sx = sqrt(pow(transform->e11, 2) + pow(transform->e21, 2));
- stroke.sy = sqrt(pow(transform->e12, 2) + pow(transform->e22, 2));
+ stroke->sx = sqrt(pow(transform->e11, 2) + pow(transform->e21, 2));
+ stroke->sy = sqrt(pow(transform->e12, 2) + pow(transform->e22, 2));
} else {
- stroke.sx = stroke.sy = 1.0f;
+ stroke->sx = stroke->sy = 1.0f;
}
- stroke.width = TO_SWCOORD(sdata->strokeWidth() * 0.5);
- stroke.cap = sdata->strokeCap();
+ stroke->width = TO_SWCOORD(sdata->strokeWidth() * 0.5);
+ stroke->cap = sdata->strokeCap();
//Save line join: it can be temporarily changed when stroking curves...
- stroke.joinSaved = stroke.join = sdata->strokeJoin();
+ stroke->joinSaved = stroke->join = sdata->strokeJoin();
- stroke.borders[0].ptsCnt = 0;
- stroke.borders[0].start = -1;
- stroke.borders[0].valid = false;
+ stroke->borders[0].ptsCnt = 0;
+ stroke->borders[0].start = -1;
+ stroke->borders[0].valid = false;
- stroke.borders[1].ptsCnt = 0;
- stroke.borders[1].start = -1;
- stroke.borders[1].valid = false;
+ stroke->borders[1].ptsCnt = 0;
+ stroke->borders[1].start = -1;
+ stroke->borders[1].valid = false;
}
-bool strokeParseOutline(SwStroke& stroke, const SwOutline& outline)
+bool strokeParseOutline(SwStroke* stroke, const SwOutline& outline)
{
uint32_t first = 0;
//A contour cannot start with a cubic control point
if (type == SW_CURVE_TYPE_CUBIC) return false;
- _beginSubPath(stroke, start, outline.opened);
+ _beginSubPath(*stroke, start, outline.opened);
while (pt < limit) {
++pt;
//emit a signel line_to
if (types[0] == SW_CURVE_TYPE_POINT) {
- _lineTo(stroke, *pt);
+ _lineTo(*stroke, *pt);
//types cubic
} else {
if (pt + 1 > limit || types[1] != SW_CURVE_TYPE_CUBIC) return false;
types += 2;
if (pt <= limit) {
- _cubicTo(stroke, pt[-2], pt[-1], pt[0]);
+ _cubicTo(*stroke, pt[-2], pt[-1], pt[0]);
continue;
}
- _cubicTo(stroke, pt[-2], pt[-1], start);
+ _cubicTo(*stroke, pt[-2], pt[-1], start);
goto close;
}
}
close:
- if (!stroke.firstPt) _endSubPath(stroke);
+ if (!stroke->firstPt) _endSubPath(*stroke);
first = last + 1;
}
return true;
}
-SwOutline* strokeExportOutline(SwStroke& stroke)
+SwOutline* strokeExportOutline(SwStroke* stroke)
{
uint32_t count1, count2, count3, count4;
- _getCounts(stroke.borders + 0, count1, count2);
- _getCounts(stroke.borders + 1, count3, count4);
+ _getCounts(stroke->borders + 0, count1, count2);
+ _getCounts(stroke->borders + 1, count3, count4);
auto ptsCnt = count1 + count3;
auto cntrsCnt = count2 + count4;
outline->cntrs = static_cast<uint32_t*>(malloc(sizeof(uint32_t) * cntrsCnt));
assert(outline->cntrs);
- _exportBorderOutline(stroke, outline, 0); //left
- _exportBorderOutline(stroke, outline, 1); //right
+ _exportBorderOutline(*stroke, outline, 0); //left
+ _exportBorderOutline(*stroke, outline, 1); //right
return outline;
}
public:
virtual ~RenderMethod() {}
virtual void* prepare(TVG_UNUSED const Shape& shape, TVG_UNUSED void* data, TVG_UNUSED const RenderTransform* transform, TVG_UNUSED RenderUpdateFlag flags) { return nullptr; }
- virtual bool dispose(TVG_UNUSED const Shape& shape, TVG_UNUSED void *data) { return false; }
- virtual bool preRender() { return false; }
- virtual bool render(TVG_UNUSED const Shape& shape, TVG_UNUSED void *data) { return false; }
- virtual bool postRender() { return false; }
- virtual bool clear() { return false; }
- virtual bool flush() { return false; }
+ virtual bool dispose(TVG_UNUSED const Shape& shape, TVG_UNUSED void *data) { return true; }
+ virtual bool preRender() { return true; }
+ virtual bool render(TVG_UNUSED const Shape& shape, TVG_UNUSED void *data) { return true; }
+ virtual bool postRender() { return true; }
+ virtual bool clear() { return true; }
+ virtual bool flush() { return true; }
virtual uint32_t ref() { return 0; }
virtual uint32_t unref() { return 0; }
};
{
if (content.empty()) return false;
- auto asyncTask = [](SvgLoader *loader) {
- bool res = simpleXmlParse(loader->content.c_str(), loader->content.size(), true, _svgLoaderParser, &(loader->loaderData));
-
- if (!res) return unique_ptr<Scene>(nullptr);
-
- if (loader->loaderData.doc) {
- SvgNode *defs;
- _updateStyle(loader->loaderData.doc, nullptr);
- defs = loader->loaderData.doc->node.doc.defs;
- if (defs) _updateGradient(loader->loaderData.doc, defs->node.defs.gradients);
- else {
- if (!loader->loaderData.gradients.empty()) {
- vector<SvgStyleGradient*> gradientList;
- for (auto gradient : loader->loaderData.gradients) {
- gradientList.push_back(gradient);
- }
- _updateGradient(loader->loaderData.doc, gradientList);
- gradientList.clear();
- }
+ loaderData = {vector<SvgNode*>(),
+ nullptr,
+ nullptr,
+ vector<SvgStyleGradient*>(),
+ nullptr,
+ nullptr,
+ 0,
+ false};
+
+ loaderData.svgParse = (SvgParser*)malloc(sizeof(SvgParser));
+
+ if (!simpleXmlParse(content.c_str(), content.size(), true, _svgLoaderParser, &loaderData)) return false;
+
+ if (loaderData.doc) {
+ _updateStyle(loaderData.doc, nullptr);
+ auto defs = loaderData.doc->node.doc.defs;
+ if (defs) _updateGradient(loaderData.doc, defs->node.defs.gradients);
+ else {
+ if (!loaderData.gradients.empty()) {
+ vector<SvgStyleGradient*> gradientList;
+ std::copy(loaderData.gradients.begin(), loaderData.gradients.end(), gradientList.begin());
+ _updateGradient(loaderData.doc, gradientList);
+ gradientList.clear();
}
}
- return loader->builder.build(loader->loaderData.doc);
- };
+ }
- rootProgress = async((launch::async | launch::deferred), asyncTask, this);
+ root = builder.build(loaderData.doc);
return true;
}
bool SvgLoader::close()
{
- if (rootProgress.valid()) root = rootProgress.get();
-
if (loaderData.svgParse) {
free(loaderData.svgParse);
loaderData.svgParse = nullptr;
unique_ptr<Scene> SvgLoader::data()
{
- if (rootProgress.valid()) root = rootProgress.get();
-
- if (root) return move(root);
- else return unique_ptr<Scene>(nullptr);
+ return move(root);
}
#endif //_TVG_SVG_LOADER_CPP_
#include "tvgSvgLoaderCommon.h"
#include "tvgSvgSceneBuilder.h"
-#include <future>
+
class SvgLoader : public Loader
{
string content;
SvgLoaderData loaderData;
SvgSceneBuilder builder;
- future<unique_ptr<Scene>> rootProgress;
unique_ptr<Scene> root;
public: