diff --git a/src/renderer/wg_engine/tvgWgGeometry.cpp b/src/renderer/wg_engine/tvgWgGeometry.cpp index 5365b71c..73c20adc 100644 --- a/src/renderer/wg_engine/tvgWgGeometry.cpp +++ b/src/renderer/wg_engine/tvgWgGeometry.cpp @@ -87,13 +87,14 @@ void WgPolyline::appendPoint(WgPoint pt) } -void WgPolyline::appendCubic(WgPoint p1, WgPoint p2, WgPoint p3) +void WgPolyline::appendCubic(WgPoint p1, WgPoint p2, WgPoint p3, size_t nsegs) { WgPoint p0 = pts.count > 0 ? pts.last() : WgPoint(0.0f, 0.0f); - size_t segs = ((uint32_t)(p0.dist(p3) / 8.0f)); - segs = segs == 0 ? 1 : segs; - for (size_t i = 1; i <= segs; i++) { - float t = i / (float)segs; + nsegs = nsegs == 0 ? 1 : nsegs; + float dt = 1.0f / (float)nsegs; + float t = 0.0f; + for (size_t i = 1; i <= nsegs; i++) { + t += dt; // get cubic spline interpolation coefficients float t0 = 1.0f * (1.0f - t) * (1.0f - t) * (1.0f - t); float t1 = 3.0f * (1.0f - t) * (1.0f - t) * t; diff --git a/src/renderer/wg_engine/tvgWgGeometry.h b/src/renderer/wg_engine/tvgWgGeometry.h index 46149b25..99c01fcc 100644 --- a/src/renderer/wg_engine/tvgWgGeometry.h +++ b/src/renderer/wg_engine/tvgWgGeometry.h @@ -57,6 +57,7 @@ public: inline void normalize() { float rlen = 1.0f / length(); x *= rlen; y *= rlen; } inline WgPoint normal() const { float rlen = 1.0f / length(); return { x * rlen, y * rlen }; } inline WgPoint lerp(const WgPoint& p, float t) const { return { x + (p.x - x) * t, y + (p.y - y) * t }; }; + inline WgPoint trans(const Matrix& m) const { return { x * m.e11 + y * m.e12, x * m.e21 + y * m.e22 }; }; }; struct WgMath @@ -85,7 +86,7 @@ struct WgPolyline WgPolyline(); void appendPoint(WgPoint pt); - void appendCubic(WgPoint p1, WgPoint p2, WgPoint p3); + void appendCubic(WgPoint p1, WgPoint p2, WgPoint p3, size_t nsegs = 16); void trim(WgPolyline* polyline, float trimBegin, float trimEnd) const; diff --git a/src/renderer/wg_engine/tvgWgRenderData.cpp b/src/renderer/wg_engine/tvgWgRenderData.cpp index db433f8b..10eeb628 100644 --- a/src/renderer/wg_engine/tvgWgRenderData.cpp +++ b/src/renderer/wg_engine/tvgWgRenderData.cpp @@ -275,7 +275,7 @@ void WgRenderDataShape::updateBBox(WgPoint pmin, WgPoint pmax) } -void WgRenderDataShape::updateMeshes(WgContext &context, const RenderShape &rshape) +void WgRenderDataShape::updateMeshes(WgContext &context, const RenderShape &rshape, const RenderTransform* rt) { releaseMeshes(context); strokeFirst = rshape.stroke ? rshape.stroke->strokeFirst : false; @@ -298,10 +298,17 @@ void WgRenderDataShape::updateMeshes(WgContext &context, const RenderShape &rsha } else if (cmd == PathCommand::Close) { polyline.close(); } else if (cmd == PathCommand::CubicTo) { + assert(polyline.pts.count > 0); + WgPoint pt0 = polyline.pts.last().trans(rt->m); + WgPoint pt1 = WgPoint(rshape.path.pts[pntIndex + 0]).trans(rt->m); + WgPoint pt2 = WgPoint(rshape.path.pts[pntIndex + 1]).trans(rt->m); + WgPoint pt3 = WgPoint(rshape.path.pts[pntIndex + 2]).trans(rt->m); + uint32_t nsegs = (uint32_t)(pt0.dist(pt1) + pt1.dist(pt2) + pt2.dist(pt3)); polyline.appendCubic( rshape.path.pts[pntIndex + 0], rshape.path.pts[pntIndex + 1], - rshape.path.pts[pntIndex + 2]); + rshape.path.pts[pntIndex + 2], + nsegs / 2); pntIndex += 3; } } diff --git a/src/renderer/wg_engine/tvgWgRenderData.h b/src/renderer/wg_engine/tvgWgRenderData.h index eb80bd88..4d509854 100644 --- a/src/renderer/wg_engine/tvgWgRenderData.h +++ b/src/renderer/wg_engine/tvgWgRenderData.h @@ -108,7 +108,7 @@ struct WgRenderDataShape: public WgRenderDataPaint FillRule fillRule{}; void updateBBox(WgPoint pmin, WgPoint pmax); - void updateMeshes(WgContext& context, const RenderShape& rshape); + void updateMeshes(WgContext& context, const RenderShape& rshape, const RenderTransform* rt); void updateMeshes(WgContext& context, const WgPolyline* polyline, const RenderStroke* rstroke); void releaseMeshes(WgContext& context); void release(WgContext& context) override; diff --git a/src/renderer/wg_engine/tvgWgRenderer.cpp b/src/renderer/wg_engine/tvgWgRenderer.cpp index 001faa8f..2fa0ffa5 100644 --- a/src/renderer/wg_engine/tvgWgRenderer.cpp +++ b/src/renderer/wg_engine/tvgWgRenderer.cpp @@ -77,7 +77,7 @@ RenderData WgRenderer::prepare(const RenderShape& rshape, RenderData data, const // update geometry if ((!data) || (flags & (RenderUpdateFlag::Path | RenderUpdateFlag::Stroke))) { - renderDataShape->updateMeshes(mContext, rshape); + renderDataShape->updateMeshes(mContext, rshape, transform); } // update paint settings