Handle paths that do not report empty, but have no edges.
patch from issue 999963005 at patchset 1 (http://crrev.com/999963005#ps1) BUG=skia:3527 Review URL: https://codereview.chromium.org/1008883002
This commit is contained in:
parent
f7076a13e2
commit
c1b11f1db6
@ -268,7 +268,7 @@ static unsigned verb_to_max_edges(unsigned verb) {
|
||||
return gPathVerbToMaxEdges[verb];
|
||||
}
|
||||
|
||||
|
||||
// If returns 0, ignore itop and ibot
|
||||
static int count_path_runtype_values(const SkPath& path, int* itop, int* ibot) {
|
||||
SkPath::Iter iter(path, true);
|
||||
SkPoint pts[4];
|
||||
@ -298,13 +298,24 @@ static int count_path_runtype_values(const SkPath& path, int* itop, int* ibot) {
|
||||
}
|
||||
}
|
||||
}
|
||||
SkASSERT(top <= bot);
|
||||
if (0 == maxEdges) {
|
||||
return 0; // we have only moves+closes
|
||||
}
|
||||
|
||||
SkASSERT(top <= bot);
|
||||
*itop = SkScalarRoundToInt(top);
|
||||
*ibot = SkScalarRoundToInt(bot);
|
||||
return maxEdges;
|
||||
}
|
||||
|
||||
static bool check_inverse_on_empty_return(SkRegion* dst, const SkPath& path, const SkRegion& clip) {
|
||||
if (path.isInverseFillType()) {
|
||||
return dst->set(clip);
|
||||
} else {
|
||||
return dst->setEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
bool SkRegion::setPath(const SkPath& path, const SkRegion& clip) {
|
||||
SkDEBUGCODE(this->validate();)
|
||||
|
||||
@ -313,26 +324,24 @@ bool SkRegion::setPath(const SkPath& path, const SkRegion& clip) {
|
||||
}
|
||||
|
||||
if (path.isEmpty()) {
|
||||
if (path.isInverseFillType()) {
|
||||
return this->set(clip);
|
||||
} else {
|
||||
return this->setEmpty();
|
||||
}
|
||||
return check_inverse_on_empty_return(this, path, clip);
|
||||
}
|
||||
|
||||
// compute worst-case rgn-size for the path
|
||||
int pathTop, pathBot;
|
||||
int pathTransitions = count_path_runtype_values(path, &pathTop, &pathBot);
|
||||
int clipTop, clipBot;
|
||||
int clipTransitions;
|
||||
if (0 == pathTransitions) {
|
||||
return check_inverse_on_empty_return(this, path, clip);
|
||||
}
|
||||
|
||||
clipTransitions = clip.count_runtype_values(&clipTop, &clipBot);
|
||||
int clipTop, clipBot;
|
||||
int clipTransitions = clip.count_runtype_values(&clipTop, &clipBot);
|
||||
|
||||
int top = SkMax32(pathTop, clipTop);
|
||||
int bot = SkMin32(pathBot, clipBot);
|
||||
|
||||
if (top >= bot)
|
||||
return this->setEmpty();
|
||||
if (top >= bot) {
|
||||
return check_inverse_on_empty_return(this, path, clip);
|
||||
}
|
||||
|
||||
SkRgnBuilder builder;
|
||||
|
||||
|
@ -747,3 +747,19 @@ DEF_TEST(Canvas_SaveState, reporter) {
|
||||
canvas.restore();
|
||||
REPORTER_ASSERT(reporter, 1 == canvas.getSaveCount());
|
||||
}
|
||||
|
||||
DEF_TEST(Canvas_ClipEmptyPath, reporter) {
|
||||
SkCanvas canvas(10, 10);
|
||||
canvas.save();
|
||||
SkPath path;
|
||||
canvas.clipPath(path);
|
||||
canvas.restore();
|
||||
canvas.save();
|
||||
path.moveTo(5, 5);
|
||||
canvas.clipPath(path);
|
||||
canvas.restore();
|
||||
canvas.save();
|
||||
path.moveTo(7, 7);
|
||||
canvas.clipPath(path); // should not assert here
|
||||
canvas.restore();
|
||||
}
|
||||
|
@ -5,6 +5,7 @@
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "SkPath.h"
|
||||
#include "SkRandom.h"
|
||||
#include "SkRegion.h"
|
||||
#include "Test.h"
|
||||
@ -91,6 +92,13 @@ static void test_empties(skiatest::Reporter* reporter) {
|
||||
REPORTER_ASSERT(reporter, !empty.contains(empty2));
|
||||
REPORTER_ASSERT(reporter, !valid.contains(empty));
|
||||
REPORTER_ASSERT(reporter, !empty.contains(valid));
|
||||
|
||||
SkPath emptyPath;
|
||||
emptyPath.moveTo(1, 5);
|
||||
emptyPath.close();
|
||||
SkRegion openClip;
|
||||
openClip.setRect(-16000, -16000, 16000, 16000);
|
||||
empty.setPath(emptyPath, openClip); // should not assert
|
||||
}
|
||||
|
||||
enum {
|
||||
|
Loading…
Reference in New Issue
Block a user