mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-08 05:33:36 +00:00
wg_engine: fix incorrect geomatry
Fix computation of segments count for cubic curves. Using screen coordinates of base points, instead of world coordinates
This commit is contained in:
parent
7a76c58057
commit
53de5f2ff7
5 changed files with 19 additions and 10 deletions
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue