mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-14 12:04:29 +00:00
gl_engine: support trimmed fill
This commit changes the API behavior. @Issue: https://github.com/thorvg/thorvg/issues/3118
This commit is contained in:
parent
05a5a7ea0b
commit
8f9527ccf1
3 changed files with 31 additions and 47 deletions
|
@ -28,11 +28,18 @@
|
||||||
|
|
||||||
bool GlGeometry::tesselate(const RenderShape& rshape, RenderUpdateFlag flag)
|
bool GlGeometry::tesselate(const RenderShape& rshape, RenderUpdateFlag flag)
|
||||||
{
|
{
|
||||||
|
const RenderPath* path = nullptr;
|
||||||
|
RenderPath trimmedPath;
|
||||||
|
if (rshape.trimpath()) {
|
||||||
|
if (!rshape.stroke->trim.trim(rshape.path, trimmedPath)) return true;
|
||||||
|
path = &trimmedPath;
|
||||||
|
} else path = &rshape.path;
|
||||||
|
|
||||||
if (flag & (RenderUpdateFlag::Color | RenderUpdateFlag::Gradient | RenderUpdateFlag::Transform | RenderUpdateFlag::Path)) {
|
if (flag & (RenderUpdateFlag::Color | RenderUpdateFlag::Gradient | RenderUpdateFlag::Transform | RenderUpdateFlag::Path)) {
|
||||||
fill.clear();
|
fill.clear();
|
||||||
|
|
||||||
BWTessellator bwTess{&fill};
|
BWTessellator bwTess{&fill};
|
||||||
bwTess.tessellate(&rshape, matrix);
|
bwTess.tessellate(*path, matrix);
|
||||||
fillRule = rshape.rule;
|
fillRule = rshape.rule;
|
||||||
bounds = bwTess.bounds();
|
bounds = bwTess.bounds();
|
||||||
}
|
}
|
||||||
|
@ -41,7 +48,7 @@ bool GlGeometry::tesselate(const RenderShape& rshape, RenderUpdateFlag flag)
|
||||||
stroke.clear();
|
stroke.clear();
|
||||||
|
|
||||||
Stroker stroker{&stroke, matrix};
|
Stroker stroker{&stroke, matrix};
|
||||||
stroker.stroke(&rshape);
|
stroker.stroke(&rshape, *path);
|
||||||
bounds = stroker.bounds();
|
bounds = stroker.bounds();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -850,16 +850,11 @@ Tessellator::~Tessellator()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Tessellator::tessellate(const RenderShape *rshape, bool antialias)
|
bool Tessellator::tessellate(const RenderShape *rshape, const RenderPath& path, bool antialias)
|
||||||
{
|
{
|
||||||
auto cmds = rshape->path.cmds.data;
|
|
||||||
auto cmdCnt = rshape->path.cmds.count;
|
|
||||||
auto pts = rshape->path.pts.data;
|
|
||||||
auto ptsCnt = rshape->path.pts.count;
|
|
||||||
|
|
||||||
this->fillRule = rshape->rule;
|
this->fillRule = rshape->rule;
|
||||||
|
|
||||||
this->visitShape(cmds, cmdCnt, pts, ptsCnt);
|
this->visitShape(path.cmds.data, path.cmds.count, path.pts.data, path.pts.count);
|
||||||
this->buildMesh();
|
this->buildMesh();
|
||||||
this->mergeVertices();
|
this->mergeVertices();
|
||||||
|
|
||||||
|
@ -888,12 +883,14 @@ void Tessellator::tessellate(const Array<const RenderShape *> &shapes)
|
||||||
this->fillRule = FillRule::NonZero;
|
this->fillRule = FillRule::NonZero;
|
||||||
|
|
||||||
for (uint32_t i = 0; i < shapes.count; i++) {
|
for (uint32_t i = 0; i < shapes.count; i++) {
|
||||||
auto cmds = shapes[i]->path.cmds.data;
|
const RenderPath* path = nullptr;
|
||||||
auto cmdCnt = shapes[i]->path.cmds.count;
|
RenderPath trimmedPath;
|
||||||
auto pts = shapes[i]->path.pts.data;
|
if (shapes[i]->trimpath()) {
|
||||||
auto ptsCnt = shapes[i]->path.pts.count;
|
if (!shapes[i]->stroke->trim.trim(shapes[i]->path, trimmedPath)) continue;
|
||||||
|
path = &trimmedPath;
|
||||||
|
} else path = &shapes[i]->path;
|
||||||
|
|
||||||
this->visitShape(cmds, cmdCnt, pts, ptsCnt);
|
this->visitShape(path->cmds.data, path->cmds.count, path->pts.data, path->pts.count);
|
||||||
}
|
}
|
||||||
|
|
||||||
this->buildMesh();
|
this->buildMesh();
|
||||||
|
@ -1527,7 +1524,7 @@ Stroker::Stroker(GlGeometryBuffer* buffer, const Matrix& matrix) : mBuffer(buffe
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Stroker::stroke(const RenderShape *rshape)
|
void Stroker::stroke(const RenderShape *rshape, const RenderPath& path)
|
||||||
{
|
{
|
||||||
mMiterLimit = rshape->strokeMiterlimit();
|
mMiterLimit = rshape->strokeMiterlimit();
|
||||||
mStrokeCap = rshape->strokeCap();
|
mStrokeCap = rshape->strokeCap();
|
||||||
|
@ -1540,27 +1537,10 @@ void Stroker::stroke(const RenderShape *rshape)
|
||||||
mStrokeWidth = strokeWidth / mMatrix.e11;
|
mStrokeWidth = strokeWidth / mMatrix.e11;
|
||||||
}
|
}
|
||||||
|
|
||||||
PathCommand *cmds, *trimmedCmds = nullptr;
|
auto cmds = path.cmds.data;
|
||||||
Point *pts, *trimmedPts = nullptr;
|
auto pts = path.pts.data;
|
||||||
uint32_t cmdCnt = 0, ptsCnt = 0;
|
auto cmdCnt = path.cmds.count;
|
||||||
|
auto ptsCnt = path.pts.count;
|
||||||
if (rshape->trimpath()) {
|
|
||||||
RenderPath trimmedPath;
|
|
||||||
if (!rshape->stroke->trim.trim(rshape->path, trimmedPath)) return;
|
|
||||||
|
|
||||||
cmds = trimmedCmds = trimmedPath.cmds.data;
|
|
||||||
cmdCnt = trimmedPath.cmds.count;
|
|
||||||
pts = trimmedPts = trimmedPath.pts.data;
|
|
||||||
ptsCnt = trimmedPath.pts.count;
|
|
||||||
|
|
||||||
trimmedPath.cmds.data = nullptr;
|
|
||||||
trimmedPath.pts.data = nullptr;
|
|
||||||
} else {
|
|
||||||
cmds = rshape->path.cmds.data;
|
|
||||||
cmdCnt = rshape->path.cmds.count;
|
|
||||||
pts = rshape->path.pts.data;
|
|
||||||
ptsCnt = rshape->path.pts.count;
|
|
||||||
}
|
|
||||||
|
|
||||||
const float *dash_pattern = nullptr;
|
const float *dash_pattern = nullptr;
|
||||||
auto dash_offset = 0.0f;
|
auto dash_offset = 0.0f;
|
||||||
|
@ -1568,9 +1548,6 @@ void Stroker::stroke(const RenderShape *rshape)
|
||||||
|
|
||||||
if (dashCnt == 0) doStroke(cmds, cmdCnt, pts, ptsCnt);
|
if (dashCnt == 0) doStroke(cmds, cmdCnt, pts, ptsCnt);
|
||||||
else doDashStroke(cmds, cmdCnt, pts, ptsCnt, dashCnt, dash_pattern, dash_offset);
|
else doDashStroke(cmds, cmdCnt, pts, ptsCnt, dashCnt, dash_pattern, dash_offset);
|
||||||
|
|
||||||
tvg::free(trimmedCmds);
|
|
||||||
tvg::free(trimmedPts);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2169,12 +2146,12 @@ BWTessellator::BWTessellator(GlGeometryBuffer* buffer): mBuffer(buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void BWTessellator::tessellate(const RenderShape *rshape, const Matrix& matrix)
|
void BWTessellator::tessellate(const RenderPath& path, const Matrix& matrix)
|
||||||
{
|
{
|
||||||
auto cmds = rshape->path.cmds.data;
|
auto cmds = path.cmds.data;
|
||||||
auto cmdCnt = rshape->path.cmds.count;
|
auto cmdCnt = path.cmds.count;
|
||||||
auto pts = rshape->path.pts.data;
|
auto pts = path.pts.data;
|
||||||
auto ptsCnt = rshape->path.pts.count;
|
auto ptsCnt = path.pts.count;
|
||||||
|
|
||||||
if (ptsCnt <= 2) return;
|
if (ptsCnt <= 2) return;
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ class Tessellator final
|
||||||
public:
|
public:
|
||||||
Tessellator(GlGeometryBuffer* buffer);
|
Tessellator(GlGeometryBuffer* buffer);
|
||||||
~Tessellator();
|
~Tessellator();
|
||||||
bool tessellate(const RenderShape *rshape, bool antialias = false);
|
bool tessellate(const RenderShape *rshape, const RenderPath& path, bool antialias = false);
|
||||||
void tessellate(const Array<const RenderShape*> &shapes);
|
void tessellate(const Array<const RenderShape*> &shapes);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -81,7 +81,7 @@ class Stroker
|
||||||
public:
|
public:
|
||||||
Stroker(GlGeometryBuffer* buffer, const Matrix& matrix);
|
Stroker(GlGeometryBuffer* buffer, const Matrix& matrix);
|
||||||
~Stroker() = default;
|
~Stroker() = default;
|
||||||
void stroke(const RenderShape *rshape);
|
void stroke(const RenderShape *rshape, const RenderPath& path);
|
||||||
RenderRegion bounds() const;
|
RenderRegion bounds() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -148,7 +148,7 @@ class BWTessellator
|
||||||
public:
|
public:
|
||||||
BWTessellator(GlGeometryBuffer* buffer);
|
BWTessellator(GlGeometryBuffer* buffer);
|
||||||
~BWTessellator() = default;
|
~BWTessellator() = default;
|
||||||
void tessellate(const RenderShape *rshape, const Matrix& matrix);
|
void tessellate(const RenderPath& path, const Matrix& matrix);
|
||||||
RenderRegion bounds() const;
|
RenderRegion bounds() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
Loading…
Add table
Reference in a new issue