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];
}
}
}
- 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();)
}
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;
* found in the LICENSE file.
*/
+#include "SkPath.h"
#include "SkRandom.h"
#include "SkRegion.h"
#include "Test.h"
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 {