mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-08 13:43:43 +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);
|
WgPoint p0 = pts.count > 0 ? pts.last() : WgPoint(0.0f, 0.0f);
|
||||||
size_t segs = ((uint32_t)(p0.dist(p3) / 8.0f));
|
nsegs = nsegs == 0 ? 1 : nsegs;
|
||||||
segs = segs == 0 ? 1 : segs;
|
float dt = 1.0f / (float)nsegs;
|
||||||
for (size_t i = 1; i <= segs; i++) {
|
float t = 0.0f;
|
||||||
float t = i / (float)segs;
|
for (size_t i = 1; i <= nsegs; i++) {
|
||||||
|
t += dt;
|
||||||
// get cubic spline interpolation coefficients
|
// get cubic spline interpolation coefficients
|
||||||
float t0 = 1.0f * (1.0f - t) * (1.0f - t) * (1.0f - t);
|
float t0 = 1.0f * (1.0f - t) * (1.0f - t) * (1.0f - t);
|
||||||
float t1 = 3.0f * (1.0f - t) * (1.0f - t) * 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 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 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 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
|
struct WgMath
|
||||||
|
@ -85,7 +86,7 @@ struct WgPolyline
|
||||||
WgPolyline();
|
WgPolyline();
|
||||||
|
|
||||||
void appendPoint(WgPoint pt);
|
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;
|
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);
|
releaseMeshes(context);
|
||||||
strokeFirst = rshape.stroke ? rshape.stroke->strokeFirst : false;
|
strokeFirst = rshape.stroke ? rshape.stroke->strokeFirst : false;
|
||||||
|
@ -298,10 +298,17 @@ void WgRenderDataShape::updateMeshes(WgContext &context, const RenderShape &rsha
|
||||||
} else if (cmd == PathCommand::Close) {
|
} else if (cmd == PathCommand::Close) {
|
||||||
polyline.close();
|
polyline.close();
|
||||||
} else if (cmd == PathCommand::CubicTo) {
|
} 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(
|
polyline.appendCubic(
|
||||||
rshape.path.pts[pntIndex + 0],
|
rshape.path.pts[pntIndex + 0],
|
||||||
rshape.path.pts[pntIndex + 1],
|
rshape.path.pts[pntIndex + 1],
|
||||||
rshape.path.pts[pntIndex + 2]);
|
rshape.path.pts[pntIndex + 2],
|
||||||
|
nsegs / 2);
|
||||||
pntIndex += 3;
|
pntIndex += 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,7 +108,7 @@ struct WgRenderDataShape: public WgRenderDataPaint
|
||||||
FillRule fillRule{};
|
FillRule fillRule{};
|
||||||
|
|
||||||
void updateBBox(WgPoint pmin, WgPoint pmax);
|
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 updateMeshes(WgContext& context, const WgPolyline* polyline, const RenderStroke* rstroke);
|
||||||
void releaseMeshes(WgContext& context);
|
void releaseMeshes(WgContext& context);
|
||||||
void release(WgContext& context) override;
|
void release(WgContext& context) override;
|
||||||
|
|
|
@ -77,7 +77,7 @@ RenderData WgRenderer::prepare(const RenderShape& rshape, RenderData data, const
|
||||||
|
|
||||||
// update geometry
|
// update geometry
|
||||||
if ((!data) || (flags & (RenderUpdateFlag::Path | RenderUpdateFlag::Stroke))) {
|
if ((!data) || (flags & (RenderUpdateFlag::Path | RenderUpdateFlag::Stroke))) {
|
||||||
renderDataShape->updateMeshes(mContext, rshape);
|
renderDataShape->updateMeshes(mContext, rshape, transform);
|
||||||
}
|
}
|
||||||
|
|
||||||
// update paint settings
|
// update paint settings
|
||||||
|
|
Loading…
Add table
Reference in a new issue