Revert "Quality and performance fixes for AA tessellating path renderer."
This reverts commit d4b2155248
.
Reason for revert: accidentally added some unwanted changes
Original change's description:
> Quality and performance fixes for AA tessellating path renderer.
>
> Use quads rather than triangles for the edge geometry. This allows
> us to perform a simpler edge categorization (see below). It also
> improves performance by reducing the number of edges processed during
> the simplify and tessellate steps.
>
> Label AA edges as three types: inner, outer, and connector. This
> results in correct alpha values for intersected edges, even when
> the top or bottom vertex has been merged with a vertex on edges
> of different types.
>
> Changed the "collinear edges" sample from the concavepaths GM for a
> "fast-foward" shape, which more clearly shows the problem being fixed
> here. (The collinearity from the "collinear edges" was actually being
> removed earlier up the stack, causing the path to become convex and
> not exercise the concave path renderers anyway.)
>
> NOTE: this will cause changes in the "concavepaths" GM results, and
> minor pixel diffs in a number of other tests.
>
> BUG=660893
>
> Change-Id: Ide49374d6d173404c7223f7316dd439df1435787
> Reviewed-on: https://skia-review.googlesource.com/6427
> Commit-Queue: Stephan White <senorblanco@chromium.org>
> Reviewed-by: Brian Salomon <bsalomon@google.com>
>
TBR=bsalomon@google.com,senorblanco@chromium.org,reviews@skia.org
BUG=660893
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
Change-Id: I06a36e397645bfc42442a5a9e7c27328f6048ab9
Reviewed-on: https://skia-review.googlesource.com/6428
Commit-Queue: Stephan White <senorblanco@chromium.org>
Reviewed-by: Stephan White <senorblanco@chromium.org>
This commit is contained in:
parent
d4b2155248
commit
021f927e4c
@ -80,18 +80,15 @@ void test_fish(SkCanvas* canvas, const SkPaint& paint) {
|
|||||||
canvas->restore();
|
canvas->restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Overlapping "Fast-forward" icon: tests coincidence of inner and outer
|
// Collinear edges
|
||||||
// vertices generated by intersection.
|
void test_collinear_edges(SkCanvas* canvas, const SkPaint& paint) {
|
||||||
void test_fast_forward(SkCanvas* canvas, const SkPaint& paint) {
|
|
||||||
SkPath path;
|
SkPath path;
|
||||||
canvas->save();
|
canvas->save();
|
||||||
canvas->translate(100, 100);
|
canvas->translate(100, 100);
|
||||||
path.moveTo(SkIntToScalar(20), SkIntToScalar(20));
|
path.moveTo(SkIntToScalar(20), SkIntToScalar(20));
|
||||||
path.lineTo(SkIntToScalar(60), SkIntToScalar(50));
|
path.lineTo(SkIntToScalar(50), SkIntToScalar(20));
|
||||||
path.lineTo(SkIntToScalar(20), SkIntToScalar(80));
|
path.lineTo(SkIntToScalar(80), SkIntToScalar(20));
|
||||||
path.moveTo(SkIntToScalar(40), SkIntToScalar(20));
|
path.lineTo(SkIntToScalar(50), SkIntToScalar(80));
|
||||||
path.lineTo(SkIntToScalar(40), SkIntToScalar(80));
|
|
||||||
path.lineTo(SkIntToScalar(80), SkIntToScalar(50));
|
|
||||||
canvas->drawPath(path, paint);
|
canvas->drawPath(path, paint);
|
||||||
canvas->restore();
|
canvas->restore();
|
||||||
}
|
}
|
||||||
@ -387,7 +384,7 @@ protected:
|
|||||||
test_bowtie(canvas, paint);
|
test_bowtie(canvas, paint);
|
||||||
test_fake_bowtie(canvas, paint);
|
test_fake_bowtie(canvas, paint);
|
||||||
test_fish(canvas, paint);
|
test_fish(canvas, paint);
|
||||||
test_fast_forward(canvas, paint);
|
test_collinear_edges(canvas, paint);
|
||||||
test_hole(canvas, paint);
|
test_hole(canvas, paint);
|
||||||
test_star(canvas, paint);
|
test_star(canvas, paint);
|
||||||
test_stairstep(canvas, paint);
|
test_stairstep(canvas, paint);
|
||||||
|
@ -35,9 +35,9 @@ GrPathRendererChain::GrPathRendererChain(GrContext* context, const Options& opti
|
|||||||
this->addPathRenderer(pr)->unref();
|
this->addPathRenderer(pr)->unref();
|
||||||
}
|
}
|
||||||
#ifndef SK_BUILD_FOR_ANDROID_FRAMEWORK
|
#ifndef SK_BUILD_FOR_ANDROID_FRAMEWORK
|
||||||
// if (caps.sampleShadingSupport()) {
|
if (caps.sampleShadingSupport()) {
|
||||||
// this->addPathRenderer(new GrMSAAPathRenderer)->unref();
|
this->addPathRenderer(new GrMSAAPathRenderer)->unref();
|
||||||
// }
|
}
|
||||||
#endif
|
#endif
|
||||||
this->addPathRenderer(new GrAAHairLinePathRenderer)->unref();
|
this->addPathRenderer(new GrAAHairLinePathRenderer)->unref();
|
||||||
this->addPathRenderer(new GrAAConvexPathRenderer)->unref();
|
this->addPathRenderer(new GrAAConvexPathRenderer)->unref();
|
||||||
@ -45,9 +45,9 @@ GrPathRendererChain::GrPathRendererChain(GrContext* context, const Options& opti
|
|||||||
if (caps.shaderCaps()->plsPathRenderingSupport()) {
|
if (caps.shaderCaps()->plsPathRenderingSupport()) {
|
||||||
this->addPathRenderer(new GrPLSPathRenderer)->unref();
|
this->addPathRenderer(new GrPLSPathRenderer)->unref();
|
||||||
}
|
}
|
||||||
// if (!options.fDisableDistanceFieldRenderer) {
|
if (!options.fDisableDistanceFieldRenderer) {
|
||||||
// this->addPathRenderer(new GrAADistanceFieldPathRenderer)->unref();
|
this->addPathRenderer(new GrAADistanceFieldPathRenderer)->unref();
|
||||||
// }
|
}
|
||||||
this->addPathRenderer(new GrTessellatingPathRenderer)->unref();
|
this->addPathRenderer(new GrTessellatingPathRenderer)->unref();
|
||||||
this->addPathRenderer(new GrDefaultPathRenderer(caps.twoSidedStencilSupport(),
|
this->addPathRenderer(new GrDefaultPathRenderer(caps.twoSidedStencilSupport(),
|
||||||
caps.stencilWrapOpsSupport()))->unref();
|
caps.stencilWrapOpsSupport()))->unref();
|
||||||
|
@ -309,12 +309,10 @@ struct Line {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
struct Edge {
|
struct Edge {
|
||||||
enum class Type { kInner, kOuter, kConnector };
|
Edge(Vertex* top, Vertex* bottom, int winding)
|
||||||
Edge(Vertex* top, Vertex* bottom, int winding, Type type)
|
|
||||||
: fWinding(winding)
|
: fWinding(winding)
|
||||||
, fTop(top)
|
, fTop(top)
|
||||||
, fBottom(bottom)
|
, fBottom(bottom)
|
||||||
, fType(type)
|
|
||||||
, fLeft(nullptr)
|
, fLeft(nullptr)
|
||||||
, fRight(nullptr)
|
, fRight(nullptr)
|
||||||
, fPrevEdgeAbove(nullptr)
|
, fPrevEdgeAbove(nullptr)
|
||||||
@ -334,7 +332,6 @@ struct Edge {
|
|||||||
int fWinding; // 1 == edge goes downward; -1 = edge goes upward.
|
int fWinding; // 1 == edge goes downward; -1 = edge goes upward.
|
||||||
Vertex* fTop; // The top vertex in vertex-sort-order (sweep_lt).
|
Vertex* fTop; // The top vertex in vertex-sort-order (sweep_lt).
|
||||||
Vertex* fBottom; // The bottom vertex in vertex-sort-order.
|
Vertex* fBottom; // The bottom vertex in vertex-sort-order.
|
||||||
Type fType;
|
|
||||||
Edge* fLeft; // The linked list of edges in the active edge list.
|
Edge* fLeft; // The linked list of edges in the active edge list.
|
||||||
Edge* fRight; // "
|
Edge* fRight; // "
|
||||||
Edge* fPrevEdgeAbove; // The linked list of edges in the bottom Vertex's "edges above".
|
Edge* fPrevEdgeAbove; // The linked list of edges in the bottom Vertex's "edges above".
|
||||||
@ -534,8 +531,7 @@ struct Poly {
|
|||||||
fTail->addEdge(e);
|
fTail->addEdge(e);
|
||||||
fCount++;
|
fCount++;
|
||||||
} else {
|
} else {
|
||||||
e = ALLOC_NEW(Edge, (fTail->fLastEdge->fBottom, e->fBottom, 1, Edge::Type::kInner),
|
e = ALLOC_NEW(Edge, (fTail->fLastEdge->fBottom, e->fBottom, 1), alloc);
|
||||||
alloc);
|
|
||||||
fTail->addEdge(e);
|
fTail->addEdge(e);
|
||||||
fCount++;
|
fCount++;
|
||||||
if (partner) {
|
if (partner) {
|
||||||
@ -771,11 +767,12 @@ inline bool apply_fill_type(SkPath::FillType fillType, Poly* poly) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Edge* new_edge(Vertex* prev, Vertex* next, SkChunkAlloc& alloc, Comparator& c, Edge::Type type) {
|
Edge* new_edge(Vertex* prev, Vertex* next, SkChunkAlloc& alloc, Comparator& c,
|
||||||
int winding = c.sweep_lt(prev->fPoint, next->fPoint) ? 1 : -1;
|
int winding_scale = 1) {
|
||||||
|
int winding = c.sweep_lt(prev->fPoint, next->fPoint) ? winding_scale : -winding_scale;
|
||||||
Vertex* top = winding < 0 ? next : prev;
|
Vertex* top = winding < 0 ? next : prev;
|
||||||
Vertex* bottom = winding < 0 ? prev : next;
|
Vertex* bottom = winding < 0 ? prev : next;
|
||||||
return ALLOC_NEW(Edge, (top, bottom, winding, type), alloc);
|
return ALLOC_NEW(Edge, (top, bottom, winding), alloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void remove_edge(Edge* edge, EdgeList* edges) {
|
void remove_edge(Edge* edge, EdgeList* edges) {
|
||||||
@ -828,10 +825,7 @@ void find_enclosing_edges(Edge* edge, EdgeList* edges, Comparator& c, Edge** lef
|
|||||||
}
|
}
|
||||||
|
|
||||||
void fix_active_state(Edge* edge, EdgeList* activeEdges, Comparator& c) {
|
void fix_active_state(Edge* edge, EdgeList* activeEdges, Comparator& c) {
|
||||||
if (!activeEdges) {
|
if (activeEdges && activeEdges->contains(edge)) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (activeEdges->contains(edge)) {
|
|
||||||
if (edge->fBottom->fProcessed || !edge->fTop->fProcessed) {
|
if (edge->fBottom->fProcessed || !edge->fTop->fProcessed) {
|
||||||
remove_edge(edge, activeEdges);
|
remove_edge(edge, activeEdges);
|
||||||
}
|
}
|
||||||
@ -1027,7 +1021,7 @@ void split_edge(Edge* edge, Vertex* v, EdgeList* activeEdges, Comparator& c, SkC
|
|||||||
} else if (c.sweep_gt(v->fPoint, edge->fBottom->fPoint)) {
|
} else if (c.sweep_gt(v->fPoint, edge->fBottom->fPoint)) {
|
||||||
set_bottom(edge, v, activeEdges, c);
|
set_bottom(edge, v, activeEdges, c);
|
||||||
} else {
|
} else {
|
||||||
Edge* newEdge = ALLOC_NEW(Edge, (v, edge->fBottom, edge->fWinding, edge->fType), alloc);
|
Edge* newEdge = ALLOC_NEW(Edge, (v, edge->fBottom, edge->fWinding), alloc);
|
||||||
insert_edge_below(newEdge, v, c);
|
insert_edge_below(newEdge, v, c);
|
||||||
insert_edge_above(newEdge, edge->fBottom, c);
|
insert_edge_above(newEdge, edge->fBottom, c);
|
||||||
set_bottom(edge, v, activeEdges, c);
|
set_bottom(edge, v, activeEdges, c);
|
||||||
@ -1037,8 +1031,9 @@ void split_edge(Edge* edge, Vertex* v, EdgeList* activeEdges, Comparator& c, SkC
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Edge* connect(Vertex* prev, Vertex* next, SkChunkAlloc& alloc, Comparator c, Edge::Type type) {
|
Edge* connect(Vertex* prev, Vertex* next, SkChunkAlloc& alloc, Comparator c,
|
||||||
Edge* edge = new_edge(prev, next, alloc, c, type);
|
int winding_scale = 1) {
|
||||||
|
Edge* edge = new_edge(prev, next, alloc, c, winding_scale);
|
||||||
if (edge->fWinding > 0) {
|
if (edge->fWinding > 0) {
|
||||||
insert_edge_below(edge, prev, c);
|
insert_edge_below(edge, prev, c);
|
||||||
insert_edge_above(edge, next, c);
|
insert_edge_above(edge, next, c);
|
||||||
@ -1068,14 +1063,8 @@ void merge_vertices(Vertex* src, Vertex* dst, Vertex** head, Comparator& c, SkCh
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint8_t max_edge_alpha(Edge* a, Edge* b) {
|
uint8_t max_edge_alpha(Edge* a, Edge* b) {
|
||||||
if (a->fType == Edge::Type::kInner && b->fType == Edge::Type::kInner) {
|
return SkTMax(SkTMax(a->fTop->fAlpha, a->fBottom->fAlpha),
|
||||||
return 255;
|
SkTMax(b->fTop->fAlpha, b->fBottom->fAlpha));
|
||||||
} else if (a->fType == Edge::Type::kOuter && b->fType == Edge::Type::kOuter) {
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
return SkTMax(SkTMax(a->fTop->fAlpha, a->fBottom->fAlpha),
|
|
||||||
SkTMax(b->fTop->fAlpha, b->fBottom->fAlpha));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Vertex* check_for_intersection(Edge* edge, Edge* other, EdgeList* activeEdges, Comparator& c,
|
Vertex* check_for_intersection(Edge* edge, Edge* other, EdgeList* activeEdges, Comparator& c,
|
||||||
@ -1180,7 +1169,7 @@ Vertex* build_edges(Vertex** contours, int contourCnt, Comparator& c, SkChunkAll
|
|||||||
for (int i = 0; i < contourCnt; ++i) {
|
for (int i = 0; i < contourCnt; ++i) {
|
||||||
for (Vertex* v = contours[i]; v != nullptr;) {
|
for (Vertex* v = contours[i]; v != nullptr;) {
|
||||||
Vertex* vNext = v->fNext;
|
Vertex* vNext = v->fNext;
|
||||||
connect(v->fPrev, v, alloc, c, Edge::Type::kInner);
|
connect(v->fPrev, v, alloc, c);
|
||||||
if (prev) {
|
if (prev) {
|
||||||
prev->fNext = v;
|
prev->fNext = v;
|
||||||
v->fPrev = prev;
|
v->fPrev = prev;
|
||||||
@ -1306,8 +1295,8 @@ void simplify(Vertex* vertices, Comparator& c, SkChunkAlloc& alloc) {
|
|||||||
}
|
}
|
||||||
} while (restartChecks);
|
} while (restartChecks);
|
||||||
if (v->fAlpha == 0) {
|
if (v->fAlpha == 0) {
|
||||||
if ((leftEnclosingEdge && leftEnclosingEdge->fWinding > 0) &&
|
if ((leftEnclosingEdge && leftEnclosingEdge->fWinding < 0) &&
|
||||||
(rightEnclosingEdge && rightEnclosingEdge->fWinding < 0)) {
|
(rightEnclosingEdge && rightEnclosingEdge->fWinding > 0)) {
|
||||||
v->fAlpha = max_edge_alpha(leftEnclosingEdge, rightEnclosingEdge);
|
v->fAlpha = max_edge_alpha(leftEnclosingEdge, rightEnclosingEdge);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1402,8 +1391,7 @@ Poly* tessellate(Vertex* vertices, SkChunkAlloc& alloc) {
|
|||||||
rightEnclosingEdge->fLeftPoly = rightPoly;
|
rightEnclosingEdge->fLeftPoly = rightPoly;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Edge* join = ALLOC_NEW(Edge,
|
Edge* join = ALLOC_NEW(Edge, (leftPoly->lastVertex(), v, 1), alloc);
|
||||||
(leftPoly->lastVertex(), v, 1, Edge::Type::kInner), alloc);
|
|
||||||
leftPoly = leftPoly->addEdge(join, Poly::kRight_Side, alloc);
|
leftPoly = leftPoly->addEdge(join, Poly::kRight_Side, alloc);
|
||||||
rightPoly = rightPoly->addEdge(join, Poly::kLeft_Side, alloc);
|
rightPoly = rightPoly->addEdge(join, Poly::kLeft_Side, alloc);
|
||||||
}
|
}
|
||||||
@ -1481,7 +1469,7 @@ void simplify_boundary(EdgeList* boundary, Comparator& c, SkChunkAlloc& alloc) {
|
|||||||
get_edge_normal(e, &normal);
|
get_edge_normal(e, &normal);
|
||||||
float denom = 0.25f * static_cast<float>(e->fLine.magSq());
|
float denom = 0.25f * static_cast<float>(e->fLine.magSq());
|
||||||
if (prevNormal.dot(normal) < 0.0 && (dist * dist) <= denom) {
|
if (prevNormal.dot(normal) < 0.0 && (dist * dist) <= denom) {
|
||||||
Edge* join = new_edge(prev, next, alloc, c, Edge::Type::kInner);
|
Edge* join = new_edge(prev, next, alloc, c);
|
||||||
insert_edge(join, e, boundary);
|
insert_edge(join, e, boundary);
|
||||||
remove_edge(prevEdge, boundary);
|
remove_edge(prevEdge, boundary);
|
||||||
remove_edge(e, boundary);
|
remove_edge(e, boundary);
|
||||||
@ -1529,8 +1517,8 @@ void boundary_to_aa_mesh(EdgeList* boundary, VertexList* mesh, Comparator& c, Sk
|
|||||||
Vertex* innerVertex = ALLOC_NEW(Vertex, (innerPoint, 255), alloc);
|
Vertex* innerVertex = ALLOC_NEW(Vertex, (innerPoint, 255), alloc);
|
||||||
Vertex* outerVertex = ALLOC_NEW(Vertex, (outerPoint, 0), alloc);
|
Vertex* outerVertex = ALLOC_NEW(Vertex, (outerPoint, 0), alloc);
|
||||||
if (innerVertices.fTail && outerVertices.fTail) {
|
if (innerVertices.fTail && outerVertices.fTail) {
|
||||||
Edge innerEdge(innerVertices.fTail, innerVertex, 1, Edge::Type::kInner);
|
Edge innerEdge(innerVertices.fTail, innerVertex, 1);
|
||||||
Edge outerEdge(outerVertices.fTail, outerVertex, 1, Edge::Type::kInner);
|
Edge outerEdge(outerVertices.fTail, outerVertex, 1);
|
||||||
SkVector innerNormal;
|
SkVector innerNormal;
|
||||||
get_edge_normal(&innerEdge, &innerNormal);
|
get_edge_normal(&innerEdge, &innerNormal);
|
||||||
SkVector outerNormal;
|
SkVector outerNormal;
|
||||||
@ -1572,9 +1560,10 @@ void boundary_to_aa_mesh(EdgeList* boundary, VertexList* mesh, Comparator& c, Sk
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
connect(outerVertex->fPrev, outerVertex, alloc, c, Edge::Type::kOuter);
|
connect(outerVertex->fNext, outerVertex, alloc, c);
|
||||||
connect(innerVertex->fPrev, innerVertex, alloc, c, Edge::Type::kInner);
|
connect(innerVertex->fNext, innerVertex, alloc, c, 2);
|
||||||
connect(outerVertex, innerVertex, alloc, c, Edge::Type::kConnector)->fWinding = 0;
|
connect(innerVertex, outerVertex->fNext, alloc, c, 2);
|
||||||
|
connect(outerVertex, innerVertex, alloc, c, 2);
|
||||||
Vertex* innerNext = innerVertex->fNext;
|
Vertex* innerNext = innerVertex->fNext;
|
||||||
Vertex* outerNext = outerVertex->fNext;
|
Vertex* outerNext = outerVertex->fNext;
|
||||||
mesh->append(innerVertex);
|
mesh->append(innerVertex);
|
||||||
@ -1648,9 +1637,9 @@ Vertex* contours_to_mesh(Vertex** contours, int contourCnt, bool antialias,
|
|||||||
return build_edges(contours, contourCnt, c, alloc);
|
return build_edges(contours, contourCnt, c, alloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sort_and_simplify(Vertex** vertices, Comparator& c, SkChunkAlloc& alloc) {
|
Poly* mesh_to_polys(Vertex** vertices, Comparator& c, SkChunkAlloc& alloc) {
|
||||||
if (!vertices || !*vertices) {
|
if (!vertices || !*vertices) {
|
||||||
return;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort vertices in Y (secondarily in X).
|
// Sort vertices in Y (secondarily in X).
|
||||||
@ -1663,10 +1652,6 @@ void sort_and_simplify(Vertex** vertices, Comparator& c, SkChunkAlloc& alloc) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
simplify(*vertices, c, alloc);
|
simplify(*vertices, c, alloc);
|
||||||
}
|
|
||||||
|
|
||||||
Poly* mesh_to_polys(Vertex** vertices, Comparator& c, SkChunkAlloc& alloc) {
|
|
||||||
sort_and_simplify(vertices, c, alloc);
|
|
||||||
return tessellate(*vertices, alloc);
|
return tessellate(*vertices, alloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1692,8 +1677,7 @@ Poly* contours_to_polys(Vertex** contours, int contourCnt, SkPath::FillType fill
|
|||||||
boundary_to_aa_mesh(boundary, &aaMesh, c, alloc);
|
boundary_to_aa_mesh(boundary, &aaMesh, c, alloc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sort_and_simplify(&aaMesh.fHead, c, alloc);
|
return mesh_to_polys(&aaMesh.fHead, c, alloc);
|
||||||
return tessellate(aaMesh.fHead, alloc);
|
|
||||||
}
|
}
|
||||||
return polys;
|
return polys;
|
||||||
}
|
}
|
||||||
|
@ -141,15 +141,15 @@ bool GrTessellatingPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) cons
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (GrAAType::kCoverage == args.fAAType) {
|
if (GrAAType::kCoverage == args.fAAType) {
|
||||||
//#ifdef SK_DISABLE_SCREENSPACE_TESS_AA_PATH_RENDERER
|
#ifdef SK_DISABLE_SCREENSPACE_TESS_AA_PATH_RENDERER
|
||||||
// return false;
|
return false;
|
||||||
//#else
|
#else
|
||||||
// SkPath path;
|
SkPath path;
|
||||||
// args.fShape->asPath(&path);
|
args.fShape->asPath(&path);
|
||||||
// if (path.countVerbs() > 10) {
|
if (path.countVerbs() > 10) {
|
||||||
// return false;
|
return false;
|
||||||
// }
|
}
|
||||||
//#endif
|
#endif
|
||||||
} else if (!args.fShape->hasUnstyledKey()) {
|
} else if (!args.fShape->hasUnstyledKey()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user