Fix for GrAALinearizingConvexPathRenderer incorrectly drawing non-convex paths

BUG=552080

Review URL: https://codereview.chromium.org/1522973002
This commit is contained in:
ethannicholas 2015-12-15 11:01:12 -08:00 committed by Commit bot
parent db284c52e6
commit c88cb8942e
3 changed files with 83 additions and 4 deletions

View File

@ -55,9 +55,29 @@ public:
return computedDir == dir;
}
static bool LastVerbIsClose(const SkPath& path) {
int count = path.countVerbs();
return count >= 1 && path.fPathRef->verbs()[~(count - 1)] == SkPath::Verb::kClose_Verb;
static bool IsClosedSingleContour(const SkPath& path) {
int verbCount = path.countVerbs();
if (verbCount == 0)
return false;
int moveCount = 0;
auto verbs = path.fPathRef->verbs();
for (int i = 0; i < verbCount; i++) {
switch (verbs[~i]) { // verbs are stored backwards; we use [~i] to get the i'th verb
case SkPath::Verb::kMove_Verb:
moveCount += 1;
if (moveCount > 1) {
return false;
}
break;
case SkPath::Verb::kClose_Verb:
if (i == verbCount - 1) {
return true;
}
return false;
default: break;
}
}
return false;
}
static void AddGenIDChangeListener(const SkPath& path, SkPathRef::GenIDChangeListener* listener) {

View File

@ -53,7 +53,7 @@ bool GrAALinearizingConvexPathRenderer::onCanDrawPath(const CanDrawPathArgs& arg
}
SkScalar strokeWidth = args.fViewMatrix->getMaxScale() * args.fStroke->getWidth();
return strokeWidth >= 1.0f && strokeWidth <= kMaxStrokeWidth && !args.fStroke->isDashed() &&
SkPathPriv::LastVerbIsClose(*args.fPath) &&
SkPathPriv::IsClosedSingleContour(*args.fPath) &&
args.fStroke->getJoin() != SkPaint::Join::kRound_Join;
}
return args.fStroke->getStyle() == SkStrokeRec::kFill_Style;

View File

@ -0,0 +1,59 @@
/*
* Copyright 2015 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "Test.h"
#include "SkPathPriv.h"
DEF_TEST(IsClosedSingleContourTest, reporter) {
SkPath p;
REPORTER_ASSERT(reporter, !SkPathPriv::IsClosedSingleContour(p));
p.reset();
p.close();
REPORTER_ASSERT(reporter, !SkPathPriv::IsClosedSingleContour(p));
p.reset();
p.moveTo(10, 10);
p.close();
REPORTER_ASSERT(reporter, SkPathPriv::IsClosedSingleContour(p));
p.reset();
p.moveTo(10, 10);
p.lineTo(20, 20);
p.close();
REPORTER_ASSERT(reporter, SkPathPriv::IsClosedSingleContour(p));
p.reset();
p.moveTo(10, 10);
p.lineTo(20, 20);
p.quadTo(30, 30, 40, 40);
p.cubicTo(50, 50, 60, 60, 70, 70);
p.conicTo(30, 30, 40, 40, 0.5);
p.close();
REPORTER_ASSERT(reporter, SkPathPriv::IsClosedSingleContour(p));
p.reset();
p.moveTo(10, 10);
p.lineTo(20, 20);
p.lineTo(20, 30);
REPORTER_ASSERT(reporter, !SkPathPriv::IsClosedSingleContour(p));
p.reset();
p.moveTo(10, 10);
p.lineTo(20, 20);
p.moveTo(10, 10);
p.lineTo(20, 30);
p.close();
REPORTER_ASSERT(reporter, !SkPathPriv::IsClosedSingleContour(p));
p.reset();
p.moveTo(10, 10);
p.lineTo(20, 20);
p.close();
p.lineTo(20, 30);
p.close();
REPORTER_ASSERT(reporter, !SkPathPriv::IsClosedSingleContour(p));
}