mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-10 22:51:58 +00:00
wg_engine: fix strokes triangulation artifacts
Fixed detection of close vertices using comparison with epsilon and related artifacts in stencil buffer as extra pixels. Fixed incorrect tessellation of curves using scaling.
This commit is contained in:
parent
79e5a0f3eb
commit
1daf6a010c
4 changed files with 48 additions and 43 deletions
|
@ -65,7 +65,10 @@ void WgPolyline::appendPoint(WgPoint pt)
|
||||||
{
|
{
|
||||||
if (pts.count > 0) {
|
if (pts.count > 0) {
|
||||||
float distance = pts.last().dist(pt);
|
float distance = pts.last().dist(pt);
|
||||||
if (distance > 0) {
|
// adjust precision because of real user data points
|
||||||
|
// can be further than the accepted accuracy,
|
||||||
|
// but still be considered tha same
|
||||||
|
if (!tvg::zero(distance*1e-1)) {
|
||||||
// update min and max indexes
|
// update min and max indexes
|
||||||
iminx = pts[iminx].x >= pt.x ? pts.count : iminx;
|
iminx = pts[iminx].x >= pt.x ? pts.count : iminx;
|
||||||
imaxx = pts[imaxx].x <= pt.x ? pts.count : imaxx;
|
imaxx = pts[imaxx].x <= pt.x ? pts.count : imaxx;
|
||||||
|
@ -217,13 +220,13 @@ void WgGeometryData::appendRect(WgPoint p0, WgPoint p1, WgPoint p2, WgPoint p3)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void WgGeometryData::appendCircle(WgPoint center, float radius)
|
void WgGeometryData::appendCircle(WgPoint center, float radius, float scale)
|
||||||
{
|
{
|
||||||
uint32_t indexCenter = positions.pts.count;
|
uint32_t indexCenter = positions.pts.count;
|
||||||
positions.appendPoint(center);
|
positions.appendPoint(center);
|
||||||
uint32_t index = positions.pts.count;
|
uint32_t index = positions.pts.count;
|
||||||
positions.appendPoint({ center.x + gMath->sinus[0] * radius, center.y + gMath->cosin[0] * radius });
|
positions.appendPoint({ center.x + gMath->sinus[0] * radius, center.y + gMath->cosin[0] * radius });
|
||||||
uint32_t nPoints = (uint32_t)(radius * 2.0f);
|
uint32_t nPoints = (uint32_t)(scale * radius * 2.0f);
|
||||||
nPoints = nPoints < 8 ? 8 : nPoints;
|
nPoints = nPoints < 8 ? 8 : nPoints;
|
||||||
const uint32_t step = gMath->sinus.count / nPoints;
|
const uint32_t step = gMath->sinus.count / nPoints;
|
||||||
for (uint32_t i = step; i < gMath->sinus.count; i += step) {
|
for (uint32_t i = step; i < gMath->sinus.count; i += step) {
|
||||||
|
@ -279,7 +282,7 @@ void WgGeometryData::appendBlitBox()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void WgGeometryData::appendStrokeDashed(const WgPolyline* polyline, const RenderStroke *stroke)
|
void WgGeometryData::appendStrokeDashed(const WgPolyline* polyline, const RenderStroke *stroke, float scale)
|
||||||
{
|
{
|
||||||
assert(stroke);
|
assert(stroke);
|
||||||
assert(polyline);
|
assert(polyline);
|
||||||
|
@ -308,7 +311,7 @@ void WgGeometryData::appendStrokeDashed(const WgPolyline* polyline, const Render
|
||||||
currentLength += stroke->dashPattern[dashIndex];
|
currentLength += stroke->dashPattern[dashIndex];
|
||||||
// append stroke if dash
|
// append stroke if dash
|
||||||
if (dashIndex % 2 != 0) {
|
if (dashIndex % 2 != 0) {
|
||||||
appendStroke(&dashed, stroke);
|
appendStroke(&dashed, stroke, scale);
|
||||||
dashed.clear();
|
dashed.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -318,14 +321,14 @@ void WgGeometryData::appendStrokeDashed(const WgPolyline* polyline, const Render
|
||||||
// draw last subline
|
// draw last subline
|
||||||
if (dashIndex % 2 == 0) {
|
if (dashIndex % 2 == 0) {
|
||||||
dashed.appendPoint(pts.last());
|
dashed.appendPoint(pts.last());
|
||||||
appendStroke(&dashed, stroke);
|
appendStroke(&dashed, stroke, scale);
|
||||||
dashed.clear();
|
dashed.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void WgGeometryData::appendStrokeJoin(const WgPoint& v0, const WgPoint& v1, const WgPoint& v2, StrokeJoin join, float halfWidth, float miterLimit)
|
void WgGeometryData::appendStrokeJoin(const WgPoint& v0, const WgPoint& v1, const WgPoint& v2, StrokeJoin join, float halfWidth, float miterLimit, float scale)
|
||||||
{
|
{
|
||||||
WgPoint dir0 = (v1 - v0).normal();
|
WgPoint dir0 = (v1 - v0).normal();
|
||||||
WgPoint dir1 = (v2 - v1).normal();
|
WgPoint dir1 = (v2 - v1).normal();
|
||||||
|
@ -334,12 +337,13 @@ void WgGeometryData::appendStrokeJoin(const WgPoint& v0, const WgPoint& v1, cons
|
||||||
WgPoint offset0 = nrm0 * halfWidth;
|
WgPoint offset0 = nrm0 * halfWidth;
|
||||||
WgPoint offset1 = nrm1 * halfWidth;
|
WgPoint offset1 = nrm1 * halfWidth;
|
||||||
if (join == StrokeJoin::Round) {
|
if (join == StrokeJoin::Round) {
|
||||||
appendCircle(v1, halfWidth);
|
appendCircle(v1, halfWidth, scale);
|
||||||
} else if (join == StrokeJoin::Bevel) {
|
} else if (join == StrokeJoin::Bevel) {
|
||||||
appendRect(v1 - offset0, v1 + offset1, v1 - offset1, v1 + offset0);
|
appendRect(v1 - offset0, v1 + offset1, v1 - offset1, v1 + offset0);
|
||||||
} else if (join == StrokeJoin::Miter) {
|
} else if (join == StrokeJoin::Miter) {
|
||||||
WgPoint nrm = (nrm0 + nrm1);
|
WgPoint nrm = (nrm0 + nrm1);
|
||||||
if (!tvg::zero(dir0.x * dir1.y - dir0.y * dir1.x)) {
|
// adjust precision because dot product could return above 1 that results acos returns Nan
|
||||||
|
if (!tvg::zero((dir0.x * dir1.y - dir0.y * dir1.x)*1e-1)) {
|
||||||
nrm.normalize();
|
nrm.normalize();
|
||||||
float cosine = nrm.dot(nrm0);
|
float cosine = nrm.dot(nrm0);
|
||||||
float angle = std::acos(dir0.dot(dir1.negative()));
|
float angle = std::acos(dir0.dot(dir1.negative()));
|
||||||
|
@ -355,7 +359,7 @@ void WgGeometryData::appendStrokeJoin(const WgPoint& v0, const WgPoint& v1, cons
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void WgGeometryData::appendStroke(const WgPolyline* polyline, const RenderStroke *stroke)
|
void WgGeometryData::appendStroke(const WgPolyline* polyline, const RenderStroke *stroke, float scale)
|
||||||
{
|
{
|
||||||
assert(stroke);
|
assert(stroke);
|
||||||
assert(polyline);
|
assert(polyline);
|
||||||
|
@ -369,8 +373,8 @@ void WgGeometryData::appendStroke(const WgPolyline* polyline, const RenderStroke
|
||||||
WgPoint nrm0 = WgPoint{ -dir0.y, +dir0.x };
|
WgPoint nrm0 = WgPoint{ -dir0.y, +dir0.x };
|
||||||
if (stroke->cap == StrokeCap::Round) {
|
if (stroke->cap == StrokeCap::Round) {
|
||||||
appendRect(v0 - nrm0 * wdt, v0 + nrm0 * wdt, v1 - nrm0 * wdt, v1 + nrm0 * wdt);
|
appendRect(v0 - nrm0 * wdt, v0 + nrm0 * wdt, v1 - nrm0 * wdt, v1 + nrm0 * wdt);
|
||||||
appendCircle(polyline->pts[0], wdt);
|
appendCircle(polyline->pts[0], wdt, scale);
|
||||||
appendCircle(polyline->pts[1], wdt);
|
appendCircle(polyline->pts[1], wdt, scale);
|
||||||
} else if (stroke->cap == StrokeCap::Butt) {
|
} else if (stroke->cap == StrokeCap::Butt) {
|
||||||
appendRect(v0 - nrm0 * wdt, v0 + nrm0 * wdt, v1 - nrm0 * wdt, v1 + nrm0 * wdt);
|
appendRect(v0 - nrm0 * wdt, v0 + nrm0 * wdt, v1 - nrm0 * wdt, v1 + nrm0 * wdt);
|
||||||
} else if (stroke->cap == StrokeCap::Square) {
|
} else if (stroke->cap == StrokeCap::Square) {
|
||||||
|
@ -384,7 +388,7 @@ void WgGeometryData::appendStroke(const WgPolyline* polyline, const RenderStroke
|
||||||
WgPoint v0 = polyline->pts[polyline->pts.count - 2];
|
WgPoint v0 = polyline->pts[polyline->pts.count - 2];
|
||||||
WgPoint v1 = polyline->pts[0];
|
WgPoint v1 = polyline->pts[0];
|
||||||
WgPoint v2 = polyline->pts[1];
|
WgPoint v2 = polyline->pts[1];
|
||||||
appendStrokeJoin(v0, v1, v2, stroke->join, wdt, stroke->miterlimit);
|
appendStrokeJoin(v0, v1, v2, stroke->join, wdt, stroke->miterlimit, scale);
|
||||||
} else {
|
} else {
|
||||||
// append first cap
|
// append first cap
|
||||||
WgPoint v0 = polyline->pts[0];
|
WgPoint v0 = polyline->pts[0];
|
||||||
|
@ -392,7 +396,7 @@ void WgGeometryData::appendStroke(const WgPolyline* polyline, const RenderStroke
|
||||||
WgPoint dir0 = (v1 - v0) / polyline->dist[1];
|
WgPoint dir0 = (v1 - v0) / polyline->dist[1];
|
||||||
WgPoint nrm0 = WgPoint{ -dir0.y, +dir0.x };
|
WgPoint nrm0 = WgPoint{ -dir0.y, +dir0.x };
|
||||||
if (stroke->cap == StrokeCap::Round) {
|
if (stroke->cap == StrokeCap::Round) {
|
||||||
appendCircle(v0, wdt);
|
appendCircle(v0, wdt, scale);
|
||||||
} else if (stroke->cap == StrokeCap::Butt) {
|
} else if (stroke->cap == StrokeCap::Butt) {
|
||||||
// no cap needed
|
// no cap needed
|
||||||
} else if (stroke->cap == StrokeCap::Square) {
|
} else if (stroke->cap == StrokeCap::Square) {
|
||||||
|
@ -405,7 +409,7 @@ void WgGeometryData::appendStroke(const WgPolyline* polyline, const RenderStroke
|
||||||
dir0 = (v1 - v0) / polyline->dist[polyline->pts.count - 1];
|
dir0 = (v1 - v0) / polyline->dist[polyline->pts.count - 1];
|
||||||
nrm0 = WgPoint{ -dir0.y, +dir0.x };
|
nrm0 = WgPoint{ -dir0.y, +dir0.x };
|
||||||
if (stroke->cap == StrokeCap::Round) {
|
if (stroke->cap == StrokeCap::Round) {
|
||||||
appendCircle(v1, wdt);
|
appendCircle(v1, wdt, scale);
|
||||||
} else if (stroke->cap == StrokeCap::Butt) {
|
} else if (stroke->cap == StrokeCap::Butt) {
|
||||||
// no cap needed
|
// no cap needed
|
||||||
} else if (stroke->cap == StrokeCap::Square) {
|
} else if (stroke->cap == StrokeCap::Square) {
|
||||||
|
@ -425,7 +429,7 @@ void WgGeometryData::appendStroke(const WgPolyline* polyline, const RenderStroke
|
||||||
|
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
WgPoint v0 = polyline->pts[i - 1];
|
WgPoint v0 = polyline->pts[i - 1];
|
||||||
appendStrokeJoin(v0, v1, v2, stroke->join, wdt, stroke->miterlimit);
|
appendStrokeJoin(v0, v1, v2, stroke->join, wdt, stroke->miterlimit, scale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,16 +111,15 @@ struct WgGeometryData
|
||||||
WgGeometryData();
|
WgGeometryData();
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
void appendCubic(WgPoint p1, WgPoint p2, WgPoint p3);
|
|
||||||
void appendBox(WgPoint pmin, WgPoint pmax);
|
void appendBox(WgPoint pmin, WgPoint pmax);
|
||||||
void appendRect(WgPoint p0, WgPoint p1, WgPoint p2, WgPoint p3);
|
void appendRect(WgPoint p0, WgPoint p1, WgPoint p2, WgPoint p3);
|
||||||
void appendCircle(WgPoint center, float radius);
|
void appendCircle(WgPoint center, float radius, float scale = 1.0f);
|
||||||
void appendImageBox(float w, float h);
|
void appendImageBox(float w, float h);
|
||||||
void appendBlitBox();
|
void appendBlitBox();
|
||||||
void appendStrokeDashed(const WgPolyline* polyline, const RenderStroke *stroke);
|
void appendStrokeDashed(const WgPolyline* polyline, const RenderStroke *stroke, float scale);
|
||||||
void appendStrokeJoin(const WgPoint& v0, const WgPoint& v1, const WgPoint& v2,
|
void appendStrokeJoin(const WgPoint& v0, const WgPoint& v1, const WgPoint& v2,
|
||||||
StrokeJoin join, float halfWidth, float miterLimit);
|
StrokeJoin join, float halfWidth, float miterLimit, float scale);
|
||||||
void appendStroke(const WgPolyline* polyline, const RenderStroke *stroke);
|
void appendStroke(const WgPolyline* polyline, const RenderStroke *stroke, float scale);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _TVG_WG_GEOMETRY_H_
|
#endif // _TVG_WG_GEOMETRY_H_
|
|
@ -22,6 +22,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include "tvgMath.h"
|
||||||
#include "tvgWgRenderData.h"
|
#include "tvgWgRenderData.h"
|
||||||
#include "tvgWgShaderTypes.h"
|
#include "tvgWgShaderTypes.h"
|
||||||
|
|
||||||
|
@ -327,11 +328,12 @@ void WgRenderDataShape::updateAABB(const Matrix& rt) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void WgRenderDataShape::updateMeshes(WgContext &context, const RenderShape &rshape, const Matrix& rt)
|
void WgRenderDataShape::updateMeshes(WgContext &context, const RenderShape &rshape, const Matrix& tr)
|
||||||
{
|
{
|
||||||
releaseMeshes(context);
|
releaseMeshes(context);
|
||||||
strokeFirst = rshape.stroke ? rshape.stroke->strokeFirst : false;
|
strokeFirst = rshape.stroke ? rshape.stroke->strokeFirst : false;
|
||||||
|
|
||||||
|
float scale = std::max(sqrt(tr.e11*tr.e11 + tr.e21*tr.e21), 1.0f);
|
||||||
Array<WgPolyline*> polylines{};
|
Array<WgPolyline*> polylines{};
|
||||||
// decode path
|
// decode path
|
||||||
size_t pntIndex = 0;
|
size_t pntIndex = 0;
|
||||||
|
@ -349,16 +351,16 @@ void WgRenderDataShape::updateMeshes(WgContext &context, const RenderShape &rsha
|
||||||
polylines.last()->close();
|
polylines.last()->close();
|
||||||
} else if (cmd == PathCommand::CubicTo) {
|
} else if (cmd == PathCommand::CubicTo) {
|
||||||
assert(polylines.last()->pts.count > 0);
|
assert(polylines.last()->pts.count > 0);
|
||||||
WgPoint pt0 = polylines.last()->pts.last().trans(rt);
|
WgPoint pt0 = polylines.last()->pts.last().trans(tr);
|
||||||
WgPoint pt1 = WgPoint(rshape.path.pts[pntIndex + 0]).trans(rt);
|
WgPoint pt1 = WgPoint(rshape.path.pts[pntIndex + 0]).trans(tr);
|
||||||
WgPoint pt2 = WgPoint(rshape.path.pts[pntIndex + 1]).trans(rt);
|
WgPoint pt2 = WgPoint(rshape.path.pts[pntIndex + 1]).trans(tr);
|
||||||
WgPoint pt3 = WgPoint(rshape.path.pts[pntIndex + 2]).trans(rt);
|
WgPoint pt3 = WgPoint(rshape.path.pts[pntIndex + 2]).trans(tr);
|
||||||
uint32_t nsegs = (uint32_t)(pt0.dist(pt1) + pt1.dist(pt2) + pt2.dist(pt3));
|
uint32_t nsegs = std::max((uint32_t)(pt0.dist(pt1) + pt1.dist(pt2) + pt2.dist(pt3)), 32U);
|
||||||
polylines.last()->appendCubic(
|
polylines.last()->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);
|
nsegs / 4);
|
||||||
pntIndex += 3;
|
pntIndex += 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -375,13 +377,13 @@ void WgRenderDataShape::updateMeshes(WgContext &context, const RenderShape &rsha
|
||||||
if (!rshape.stroke->strokeTrim(trimBegin, trimEnd)) { trimBegin = 0.0f; trimEnd = 1.0f; }
|
if (!rshape.stroke->strokeTrim(trimBegin, trimEnd)) { trimBegin = 0.0f; trimEnd = 1.0f; }
|
||||||
if (rshape.stroke->trim.simultaneous) {
|
if (rshape.stroke->trim.simultaneous) {
|
||||||
for (uint32_t i = 0; i < polylines.count; i++)
|
for (uint32_t i = 0; i < polylines.count; i++)
|
||||||
updateStrokes(context, polylines[i], rshape.stroke, trimBegin, trimEnd);
|
updateStrokes(context, polylines[i], rshape.stroke, scale, trimBegin, trimEnd);
|
||||||
} else {
|
} else {
|
||||||
if (trimBegin <= trimEnd) {
|
if (trimBegin <= trimEnd) {
|
||||||
updateStrokesList(context, polylines, rshape.stroke, totalLen, trimBegin, trimEnd);
|
updateStrokesList(context, polylines, rshape.stroke, totalLen, scale, trimBegin, trimEnd);
|
||||||
} else {
|
} else {
|
||||||
updateStrokesList(context, polylines, rshape.stroke, totalLen, 0.0f, trimEnd);
|
updateStrokesList(context, polylines, rshape.stroke, totalLen, scale, 0.0f, trimEnd);
|
||||||
updateStrokesList(context, polylines, rshape.stroke, totalLen, trimBegin, 1.0f);
|
updateStrokesList(context, polylines, rshape.stroke, totalLen, scale, trimBegin, 1.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -389,7 +391,7 @@ void WgRenderDataShape::updateMeshes(WgContext &context, const RenderShape &rsha
|
||||||
for (uint32_t i = 0; i < polylines.count; i++)
|
for (uint32_t i = 0; i < polylines.count; i++)
|
||||||
delete polylines[i];
|
delete polylines[i];
|
||||||
// update shapes bbox
|
// update shapes bbox
|
||||||
updateAABB(rt);
|
updateAABB(tr);
|
||||||
meshDataBBox.update(context, pMin, pMax);
|
meshDataBBox.update(context, pMin, pMax);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -407,7 +409,7 @@ void WgRenderDataShape::updateShapes(WgContext& context, const WgPolyline* polyl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WgRenderDataShape::updateStrokesList(WgContext& context, Array<WgPolyline*> polylines, const RenderStroke* rstroke, float totalLen, float trimBegin, float trimEnd)
|
void WgRenderDataShape::updateStrokesList(WgContext& context, Array<WgPolyline*> polylines, const RenderStroke* rstroke, float scale, float totalLen, float trimBegin, float trimEnd)
|
||||||
{
|
{
|
||||||
float tp1 = totalLen * trimBegin; // trim point begin
|
float tp1 = totalLen * trimBegin; // trim point begin
|
||||||
float tp2 = totalLen * trimEnd; // trim point end
|
float tp2 = totalLen * trimEnd; // trim point end
|
||||||
|
@ -417,7 +419,7 @@ void WgRenderDataShape::updateStrokesList(WgContext& context, Array<WgPolyline*>
|
||||||
float trimBegin = ((pc <= tp1) && (pc + pl > tp1)) ? (tp1 - pc) / pl : 0.0f;
|
float trimBegin = ((pc <= tp1) && (pc + pl > tp1)) ? (tp1 - pc) / pl : 0.0f;
|
||||||
float trimEnd = ((pc <= tp2) && (pc + pl > tp2)) ? (tp2 - pc) / pl : 1.0f;
|
float trimEnd = ((pc <= tp2) && (pc + pl > tp2)) ? (tp2 - pc) / pl : 1.0f;
|
||||||
if ((pc + pl >= tp1) && (pc <= tp2))
|
if ((pc + pl >= tp1) && (pc <= tp2))
|
||||||
updateStrokes(context, polylines[i], rstroke, trimBegin, trimEnd);
|
updateStrokes(context, polylines[i], rstroke, scale, trimBegin, trimEnd);
|
||||||
pc += pl;
|
pc += pl;
|
||||||
// break if reached the tail
|
// break if reached the tail
|
||||||
if (pc > tp2) break;
|
if (pc > tp2) break;
|
||||||
|
@ -425,7 +427,7 @@ void WgRenderDataShape::updateStrokesList(WgContext& context, Array<WgPolyline*>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void WgRenderDataShape::updateStrokes(WgContext& context, const WgPolyline* polyline, const RenderStroke* rstroke, float trimBegin, float trimEnd)
|
void WgRenderDataShape::updateStrokes(WgContext& context, const WgPolyline* polyline, const RenderStroke* rstroke, float scale, float trimBegin, float trimEnd)
|
||||||
{
|
{
|
||||||
assert(polyline);
|
assert(polyline);
|
||||||
// generate strokes geometry
|
// generate strokes geometry
|
||||||
|
@ -442,7 +444,7 @@ void WgRenderDataShape::updateStrokes(WgContext& context, const WgPolyline* poly
|
||||||
polyline->trim(&trimmed, trimBegin, 1.0f);
|
polyline->trim(&trimmed, trimBegin, 1.0f);
|
||||||
polyline->trim(&trimmed, 0.0f, trimEnd);
|
polyline->trim(&trimmed, 0.0f, trimEnd);
|
||||||
}
|
}
|
||||||
geometryData.appendStrokeDashed(&trimmed, rstroke);
|
geometryData.appendStrokeDashed(&trimmed, rstroke, scale);
|
||||||
} else // trim -> stroke
|
} else // trim -> stroke
|
||||||
if ((trimBegin != 0.0f) || (trimEnd != 1.0f)) {
|
if ((trimBegin != 0.0f) || (trimEnd != 1.0f)) {
|
||||||
trimmed.clear();
|
trimmed.clear();
|
||||||
|
@ -452,12 +454,12 @@ void WgRenderDataShape::updateStrokes(WgContext& context, const WgPolyline* poly
|
||||||
polyline->trim(&trimmed, trimBegin, 1.0f);
|
polyline->trim(&trimmed, trimBegin, 1.0f);
|
||||||
polyline->trim(&trimmed, 0.0f, trimEnd);
|
polyline->trim(&trimmed, 0.0f, trimEnd);
|
||||||
}
|
}
|
||||||
geometryData.appendStroke(&trimmed, rstroke);
|
geometryData.appendStroke(&trimmed, rstroke, scale);
|
||||||
} else // split -> stroke
|
} else // split -> stroke
|
||||||
if (rstroke->dashPattern) {
|
if (rstroke->dashPattern) {
|
||||||
geometryData.appendStrokeDashed(polyline, rstroke);
|
geometryData.appendStrokeDashed(polyline, rstroke, scale);
|
||||||
} else { // stroke
|
} else { // stroke
|
||||||
geometryData.appendStroke(polyline, rstroke);
|
geometryData.appendStroke(polyline, rstroke, scale);
|
||||||
}
|
}
|
||||||
// append render meshes and bboxes
|
// append render meshes and bboxes
|
||||||
if(geometryData.positions.pts.count >= 3) {
|
if(geometryData.positions.pts.count >= 3) {
|
||||||
|
|
|
@ -126,10 +126,10 @@ struct WgRenderDataShape: public WgRenderDataPaint
|
||||||
|
|
||||||
void updateBBox(WgPoint pmin, WgPoint pmax);
|
void updateBBox(WgPoint pmin, WgPoint pmax);
|
||||||
void updateAABB(const Matrix& rt);
|
void updateAABB(const Matrix& rt);
|
||||||
void updateMeshes(WgContext& context, const RenderShape& rshape, const Matrix& rt);
|
void updateMeshes(WgContext& context, const RenderShape& rshape, const Matrix& tr);
|
||||||
void updateShapes(WgContext& context, const WgPolyline* polyline);
|
void updateShapes(WgContext& context, const WgPolyline* polyline);
|
||||||
void updateStrokesList(WgContext& context, Array<WgPolyline*> polylines, const RenderStroke* rstroke, float totalLen, float trimBegin, float trimEnd);
|
void updateStrokesList(WgContext& context, Array<WgPolyline*> polylines, const RenderStroke* rstroke, float scale, float totalLen, float trimBegin, float trimEnd);
|
||||||
void updateStrokes(WgContext& context, const WgPolyline* polyline, const RenderStroke* rstroke, float trimBegin, float trimEnd);
|
void updateStrokes(WgContext& context, const WgPolyline* polyline, const RenderStroke* rstroke, float scale, float trimBegin, float trimEnd);
|
||||||
void releaseMeshes(WgContext& context);
|
void releaseMeshes(WgContext& context);
|
||||||
void release(WgContext& context) override;
|
void release(WgContext& context) override;
|
||||||
Type type() override { return Type::Shape; };
|
Type type() override { return Type::Shape; };
|
||||||
|
|
Loading…
Add table
Reference in a new issue