From 4d72eeda1556e179ecf7b60bc2a7829a476ef8e8 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Tue, 21 Jul 2020 20:24:25 +0900 Subject: [PATCH] sw_engine: revise scale transform logic. Basically, stroke width size is linear, engine couldn't apply scale factor from the matrix which contains 2 dimensional values. Thus, we can apply it if the scale factor of x/y is identical. Otherwise, we should transform every stroke points in the stroking process. That scenario can be improved with another patch. Change-Id: I070dcf29d2e42f21e182bdf4239781464158ef73 --- src/lib/sw_engine/tvgSwCommon.h | 5 +++-- src/lib/sw_engine/tvgSwRenderer.cpp | 4 ++-- src/lib/sw_engine/tvgSwShape.cpp | 4 ++-- src/lib/sw_engine/tvgSwStroke.cpp | 11 +++++++++-- src/lib/tvgRender.h | 2 +- 5 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/lib/sw_engine/tvgSwCommon.h b/src/lib/sw_engine/tvgSwCommon.h index 3639166..b1d38af 100644 --- a/src/lib/sw_engine/tvgSwCommon.h +++ b/src/lib/sw_engine/tvgSwCommon.h @@ -156,6 +156,7 @@ struct SwStroke bool firstPt; bool openSubPath; bool handleWideStrokes; + bool preScaled; }; struct SwDashStroke @@ -259,7 +260,7 @@ 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); +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); @@ -267,7 +268,7 @@ bool shapeGenFillColors(SwShape& shape, const Fill* fill, const Matrix* transfor void shapeResetFill(SwShape& shape); void shapeDelFill(SwShape& shape); -void strokeReset(SwStroke& stroke, const Shape* 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); diff --git a/src/lib/sw_engine/tvgSwRenderer.cpp b/src/lib/sw_engine/tvgSwRenderer.cpp index 7c3ca8d..aac6d8e 100644 --- a/src/lib/sw_engine/tvgSwRenderer.cpp +++ b/src/lib/sw_engine/tvgSwRenderer.cpp @@ -211,7 +211,7 @@ void* SwRenderer::prepare(const Shape& sdata, void* data, const RenderTransform* //Stroke if (task->flags & (RenderUpdateFlag::Stroke | RenderUpdateFlag::Transform)) { if (strokeAlpha > 0) { - shapeResetStroke(task->shape, task->sdata); + shapeResetStroke(task->shape, task->sdata, task->transform); if (!shapeGenStrokeRle(task->shape, task->sdata, task->transform, task->clip)) return; } else { shapeDelStroke(task->shape); @@ -257,4 +257,4 @@ SwRenderer* SwRenderer::inst() return static_cast(RenderInitializer::inst(renderInit)); } -#endif /* _TVG_SW_RENDERER_CPP_ */ +#endif /* _TVG_SW_RENDERER_CPP_ */ \ No newline at end of file diff --git a/src/lib/sw_engine/tvgSwShape.cpp b/src/lib/sw_engine/tvgSwShape.cpp index d302fd7..c3aced8 100644 --- a/src/lib/sw_engine/tvgSwShape.cpp +++ b/src/lib/sw_engine/tvgSwShape.cpp @@ -618,13 +618,13 @@ void shapeDelStroke(SwShape& shape) } -void shapeResetStroke(SwShape& shape, const Shape* sdata) +void shapeResetStroke(SwShape& shape, const Shape* sdata, const Matrix* transform) { if (!shape.stroke) shape.stroke = static_cast(calloc(1, sizeof(SwStroke))); auto stroke = shape.stroke; assert(stroke); - strokeReset(*stroke, sdata); + strokeReset(*stroke, sdata, transform); rleFree(shape.strokeRle); shape.strokeRle = nullptr; diff --git a/src/lib/sw_engine/tvgSwStroke.cpp b/src/lib/sw_engine/tvgSwStroke.cpp index d45ddd8..abaf455 100644 --- a/src/lib/sw_engine/tvgSwStroke.cpp +++ b/src/lib/sw_engine/tvgSwStroke.cpp @@ -818,11 +818,18 @@ void strokeFree(SwStroke* stroke) } -void strokeReset(SwStroke& stroke, const Shape* sdata) +void strokeReset(SwStroke& stroke, const Shape* sdata, const Matrix* transform) { assert(sdata); - stroke.width = TO_SWCOORD(sdata->strokeWidth() * 0.5); + //If x/y scale factor is identical, we can scale width size simply. + auto scale = 1.0f; + if (transform && fabsf(transform->e11 - transform->e22) < FLT_EPSILON) { + scale = transform->e11; + stroke.preScaled = true; + } + + stroke.width = TO_SWCOORD(sdata->strokeWidth() * 0.5 * scale); stroke.cap = sdata->strokeCap(); //Save line join: it can be temporarily changed when stroking curves... diff --git a/src/lib/tvgRender.h b/src/lib/tvgRender.h index 576961e..6a0897e 100644 --- a/src/lib/tvgRender.h +++ b/src/lib/tvgRender.h @@ -32,7 +32,7 @@ enum RenderUpdateFlag {None = 0, Path = 1, Color = 2, Gradient = 4, Stroke = 8, struct RenderTransform { - Matrix m; //3x3 Matrix Elements + Matrix m; //3x3 Matrix Elements float x = 0.0f; float y = 0.0f; float degree = 0.0f; //rotation degree -- 2.7.4