From 419fa93989450c550f0a19e4eea9fa297a9ef132 Mon Sep 17 00:00:00 2001 From: Sergii Liebodkin Date: Thu, 13 Jun 2024 16:51:27 +0300 Subject: [PATCH] wg_engine: fix strokes failers and visual atrifacts Ignoring rezo-width strokes, single point strokes. Fix visual artifacts in case of mitter joints. --- src/renderer/wg_engine/tvgWgGeometry.cpp | 25 ++++------------------ src/renderer/wg_engine/tvgWgRenderData.cpp | 23 ++++++++++++-------- 2 files changed, 18 insertions(+), 30 deletions(-) diff --git a/src/renderer/wg_engine/tvgWgGeometry.cpp b/src/renderer/wg_engine/tvgWgGeometry.cpp index ea459b92..5365b71c 100644 --- a/src/renderer/wg_engine/tvgWgGeometry.cpp +++ b/src/renderer/wg_engine/tvgWgGeometry.cpp @@ -310,11 +310,9 @@ void WgGeometryData::appendStrokeDashed(const WgPolyline* polyline, const Render assert(polyline); static WgPolyline dashed; dashed.clear(); - // append single point polyline - if (polyline->pts.count == 1) - appendStroke(polyline, stroke); + // ignore singpe points polyline // append multy points dashed polyline - else if (polyline->pts.count >= 2) { + if (polyline->pts.count >= 2) { auto& pts = polyline->pts; auto& dist = polyline->dist; // starting state @@ -357,22 +355,7 @@ void WgGeometryData::appendStroke(const WgPolyline* polyline, const RenderStroke assert(stroke); assert(polyline); float wdt = stroke->width / 2; - // single point sub-path - if (polyline->pts.count == 1) { - if (stroke->cap == StrokeCap::Round) { - appendCircle(polyline->pts[0], wdt); - } else if (stroke->cap == StrokeCap::Butt) { - // for zero length sub-paths no stroke is rendered - } else if (stroke->cap == StrokeCap::Square) { - appendRect( - polyline->pts[0] + WgPoint(+wdt, +wdt), - polyline->pts[0] + WgPoint(+wdt, -wdt), - polyline->pts[0] + WgPoint(-wdt, +wdt), - polyline->pts[0] + WgPoint(-wdt, -wdt) - ); - } - } else - + // single line sub-path if (polyline->pts.count == 2) { WgPoint v0 = polyline->pts[0]; @@ -474,7 +457,7 @@ void WgGeometryData::appendStroke(const WgPolyline* polyline, const RenderStroke } else if (stroke->join == StrokeJoin::Miter) { WgPoint nrm = (nrm0 + nrm1).normal(); float cosine = nrm.dot(nrm0); - if ((cosine != 0.0f) && (abs(cosine) != 1.0f) && (abs(wdt / cosine) <= stroke->miterlimit * 2)) { + if ((cosine != 0.0f) && (abs(cosine) < 1.0f) && (abs(wdt / cosine) <= stroke->miterlimit * 2)) { appendRect(v1 + nrm * (wdt / cosine), v1 + offset0, v1 + offset1, v1); appendRect(v1 - nrm * (wdt / cosine), v1 - offset0, v1 - offset1, v1); } else { diff --git a/src/renderer/wg_engine/tvgWgRenderData.cpp b/src/renderer/wg_engine/tvgWgRenderData.cpp index 0da56925..1bdd4650 100644 --- a/src/renderer/wg_engine/tvgWgRenderData.cpp +++ b/src/renderer/wg_engine/tvgWgRenderData.cpp @@ -321,16 +321,19 @@ void WgRenderDataShape::updateMeshes(WgContext& context, const WgPolyline* polyl updateBBox(pmin, pmax); } // generate strokes geometry - if ((polyline->pts.count >= 1) && rstroke) { + if ((polyline->pts.count >= 1) && rstroke && (rstroke->width > 0.0f)) { static WgGeometryData geometryData; geometryData.clear(); static WgPolyline trimmed; // trim -> split -> stroke - if ((rstroke->dashPattern) && ((rstroke->trim.begin != 0.0f) || (rstroke->trim.end != 1.0f))) { - polyline->trim(&trimmed, rstroke->trim.begin, rstroke->trim.end); + float trimBegin = rstroke->trim.begin < rstroke->trim.end ? rstroke->trim.begin : rstroke->trim.end; + float trimEnd = rstroke->trim.begin < rstroke->trim.end ? rstroke->trim.end : rstroke->trim.begin; + if (trimBegin == trimEnd) return; + if ((rstroke->dashPattern) && ((trimBegin != 0.0f) || (trimEnd != 1.0f))) { + polyline->trim(&trimmed, trimBegin, trimEnd); geometryData.appendStrokeDashed(&trimmed, rstroke); } else // trim -> stroke - if ((rstroke->trim.begin != 0.0f) || (rstroke->trim.end != 1.0f)) { - polyline->trim(&trimmed, rstroke->trim.begin, rstroke->trim.end); + if ((trimBegin != 0.0f) || (trimEnd != 1.0f)) { + polyline->trim(&trimmed, trimBegin, trimEnd); geometryData.appendStroke(&trimmed, rstroke); } else // split -> stroke if (rstroke->dashPattern) { @@ -339,10 +342,12 @@ void WgRenderDataShape::updateMeshes(WgContext& context, const WgPolyline* polyl geometryData.appendStroke(polyline, rstroke); } // append render meshes and bboxes - WgPoint pmin{}, pmax{}; - geometryData.positions.getBBox(pmin, pmax); - meshGroupStrokes.append(context, &geometryData); - meshGroupStrokesBBox.append(context, pmin, pmax); + if(geometryData.positions.pts.count >= 3) { + WgPoint pmin{}, pmax{}; + geometryData.positions.getBBox(pmin, pmax); + meshGroupStrokes.append(context, &geometryData); + meshGroupStrokesBBox.append(context, pmin, pmax); + } } }