aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar reed <reed@google.com>2015-02-09 08:33:07 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2015-02-09 08:33:07 -0800
commit31223e0cb74f47f63b094520a9830c525b72fe87 (patch)
treee8d733c11acb5c64c089fca92e0cc868f49fb7e3
parent70a8ca8351b0338b7d63917a818433dc8d71d291 (diff)
cull edges that are to the right of the clip
-rw-r--r--src/core/SkEdgeBuilder.cpp12
-rw-r--r--src/core/SkEdgeClipper.cpp8
-rw-r--r--src/core/SkEdgeClipper.h5
-rw-r--r--src/core/SkLineClipper.cpp12
-rw-r--r--src/core/SkLineClipper.h5
-rw-r--r--src/core/SkScan_Path.cpp10
-rw-r--r--tests/ClipperTest.cpp2
7 files changed, 30 insertions, 24 deletions
diff --git a/src/core/SkEdgeBuilder.cpp b/src/core/SkEdgeBuilder.cpp
index 00811203b4..6a8ea8926a 100644
--- a/src/core/SkEdgeBuilder.cpp
+++ b/src/core/SkEdgeBuilder.cpp
@@ -80,7 +80,7 @@ static void setShiftedClip(SkRect* dst, const SkIRect& src, int shift) {
}
int SkEdgeBuilder::buildPoly(const SkPath& path, const SkIRect* iclip, int shiftUp,
- bool clipToTheRight) {
+ bool canCullToTheRight) {
SkPath::Iter iter(path, true);
SkPoint pts[4];
SkPath::Verb verb;
@@ -115,7 +115,7 @@ int SkEdgeBuilder::buildPoly(const SkPath& path, const SkIRect* iclip, int shift
break;
case SkPath::kLine_Verb: {
SkPoint lines[SkLineClipper::kMaxPoints];
- int lineCount = SkLineClipper::ClipLine(pts, clip, lines, clipToTheRight);
+ int lineCount = SkLineClipper::ClipLine(pts, clip, lines, canCullToTheRight);
SkASSERT(lineCount <= SkLineClipper::kMaxClippedLineSegments);
for (int i = 0; i < lineCount; i++) {
if (edge->setLine(lines[i], lines[i + 1], shiftUp)) {
@@ -162,13 +162,13 @@ static void handle_quad(SkEdgeBuilder* builder, const SkPoint pts[3]) {
}
int SkEdgeBuilder::build(const SkPath& path, const SkIRect* iclip, int shiftUp,
- bool clipToTheRight) {
+ bool canCullToTheRight) {
fAlloc.reset();
fList.reset();
fShiftUp = shiftUp;
if (SkPath::kLine_SegmentMask == path.getSegmentMasks()) {
- return this->buildPoly(path, iclip, shiftUp, clipToTheRight);
+ return this->buildPoly(path, iclip, shiftUp, canCullToTheRight);
}
SkAutoConicToQuads quadder;
@@ -181,7 +181,7 @@ int SkEdgeBuilder::build(const SkPath& path, const SkIRect* iclip, int shiftUp,
if (iclip) {
SkRect clip;
setShiftedClip(&clip, *iclip, shiftUp);
- SkEdgeClipper clipper;
+ SkEdgeClipper clipper(canCullToTheRight);
while ((verb = iter.next(pts, false)) != SkPath::kDone_Verb) {
switch (verb) {
@@ -192,7 +192,7 @@ int SkEdgeBuilder::build(const SkPath& path, const SkIRect* iclip, int shiftUp,
break;
case SkPath::kLine_Verb: {
SkPoint lines[SkLineClipper::kMaxPoints];
- int lineCount = SkLineClipper::ClipLine(pts, clip, lines, clipToTheRight);
+ int lineCount = SkLineClipper::ClipLine(pts, clip, lines, canCullToTheRight);
for (int i = 0; i < lineCount; i++) {
this->addLine(&lines[i]);
}
diff --git a/src/core/SkEdgeClipper.cpp b/src/core/SkEdgeClipper.cpp
index 00a1dd2494..32277bcf8e 100644
--- a/src/core/SkEdgeClipper.cpp
+++ b/src/core/SkEdgeClipper.cpp
@@ -148,7 +148,9 @@ void SkEdgeClipper::clipMonoQuad(const SkPoint srcPts[3], const SkRect& clip) {
return;
}
if (pts[0].fX >= clip.fRight) { // wholly to the right
- this->appendVLine(clip.fRight, pts[0].fY, pts[2].fY, reverse);
+ if (!this->canCullToTheRight()) {
+ this->appendVLine(clip.fRight, pts[0].fY, pts[2].fY, reverse);
+ }
return;
}
@@ -350,7 +352,9 @@ void SkEdgeClipper::clipMonoCubic(const SkPoint src[4], const SkRect& clip) {
return;
}
if (pts[0].fX >= clip.fRight) { // wholly to the right
- this->appendVLine(clip.fRight, pts[0].fY, pts[3].fY, reverse);
+ if (!this->canCullToTheRight()) {
+ this->appendVLine(clip.fRight, pts[0].fY, pts[3].fY, reverse);
+ }
return;
}
diff --git a/src/core/SkEdgeClipper.h b/src/core/SkEdgeClipper.h
index e16ed552ca..16887b4a32 100644
--- a/src/core/SkEdgeClipper.h
+++ b/src/core/SkEdgeClipper.h
@@ -17,14 +17,19 @@
*/
class SkEdgeClipper {
public:
+ SkEdgeClipper(bool canCullToTheRight) : fCanCullToTheRight(canCullToTheRight) {}
+
bool clipQuad(const SkPoint pts[3], const SkRect& clip);
bool clipCubic(const SkPoint pts[4], const SkRect& clip);
SkPath::Verb next(SkPoint pts[]);
+ bool canCullToTheRight() const { return fCanCullToTheRight; }
+
private:
SkPoint* fCurrPoint;
SkPath::Verb* fCurrVerb;
+ const bool fCanCullToTheRight;
enum {
kMaxVerbs = 13,
diff --git a/src/core/SkLineClipper.cpp b/src/core/SkLineClipper.cpp
index 3ff8948913..4558430e33 100644
--- a/src/core/SkLineClipper.cpp
+++ b/src/core/SkLineClipper.cpp
@@ -1,10 +1,10 @@
-
/*
* Copyright 2011 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
+
#include "SkLineClipper.h"
template <typename T> T pin_unsorted(T value, T limit0, T limit1) {
@@ -172,12 +172,8 @@ static void sect_with_horizontal_test_for_pin_results() {
}
#endif
-int SkLineClipper::ClipLine(const SkPoint pts[], const SkRect& clip,
- SkPoint lines[], bool canClipToTheRight) {
-#if 1
- // Disable this while we investigate layouttest failures
- canClipToTheRight = false;
-#endif
+int SkLineClipper::ClipLine(const SkPoint pts[], const SkRect& clip, SkPoint lines[],
+ bool canCullToTheRight) {
#ifdef SK_DEBUG
{
@@ -246,7 +242,7 @@ int SkLineClipper::ClipLine(const SkPoint pts[], const SkRect& clip,
result = tmp;
reverse = false;
} else if (tmp[index0].fX >= clip.fRight) { // wholly to the right
- if (canClipToTheRight) {
+ if (canCullToTheRight) {
return 0;
}
tmp[0].fX = tmp[1].fX = clip.fRight;
diff --git a/src/core/SkLineClipper.h b/src/core/SkLineClipper.h
index d966dbc74c..11e0a73ca2 100644
--- a/src/core/SkLineClipper.h
+++ b/src/core/SkLineClipper.h
@@ -30,7 +30,7 @@ public:
3rd segment: lines[2]..lines[3]
*/
static int ClipLine(const SkPoint pts[2], const SkRect& clip,
- SkPoint lines[kMaxPoints], bool canClipToTheRight);
+ SkPoint lines[kMaxPoints], bool canCullToTheRight);
/* Intersect the line segment against the rect. If there is a non-empty
resulting segment, return true and set dst[] to that segment. If not,
@@ -40,8 +40,7 @@ public:
segments on the sides to show where the line extended beyond the
left or right sides. IntersectLine does not.
*/
- static bool IntersectLine(const SkPoint src[2], const SkRect& clip,
- SkPoint dst[2]);
+ static bool IntersectLine(const SkPoint src[2], const SkRect& clip, SkPoint dst[2]);
};
#endif
diff --git a/src/core/SkScan_Path.cpp b/src/core/SkScan_Path.cpp
index 4142d1092f..fd04609c21 100644
--- a/src/core/SkScan_Path.cpp
+++ b/src/core/SkScan_Path.cpp
@@ -431,12 +431,14 @@ void sk_fill_path(const SkPath& path, const SkIRect* clipRect, SkBlitter* blitte
SkEdgeBuilder builder;
// If we're convex, then we need both edges, even the right edge is past the clip
- const bool cullToTheRight = !path.isConvex();
+ const bool canCullToTheRight = !path.isConvex();
+
+ int count = builder.build(path, clipRect, shiftEdgesUp, canCullToTheRight);
+ SkASSERT(count >= 0);
- int count = builder.build(path, clipRect, shiftEdgesUp, cullToTheRight);
SkEdge** list = builder.edgeList();
- if (count < 2) {
+ if (0 == count) {
if (path.isInverseFillType()) {
/*
* Since we are in inverse-fill, our caller has already drawn above
@@ -458,7 +460,6 @@ void sk_fill_path(const SkPath& path, const SkIRect* clipRect, SkBlitter* blitte
rect.height() << shiftEdgesUp);
}
}
-
return;
}
@@ -498,6 +499,7 @@ void sk_fill_path(const SkPath& path, const SkIRect* clipRect, SkBlitter* blitte
}
if (path.isConvex() && (NULL == proc)) {
+ SkASSERT(count >= 2); // convex walker does not handle missing right edges
walk_convex_edges(&headEdge, path.getFillType(), blitter, start_y, stop_y, NULL);
} else {
int rightEdge;
diff --git a/tests/ClipperTest.cpp b/tests/ClipperTest.cpp
index 00b62293b2..8ebd9b479f 100644
--- a/tests/ClipperTest.cpp
+++ b/tests/ClipperTest.cpp
@@ -48,7 +48,7 @@ static void test_hairclipping(skiatest::Reporter* reporter) {
}
static void test_edgeclipper() {
- SkEdgeClipper clipper;
+ SkEdgeClipper clipper(false);
const SkPoint pts[] = {
{ 3.0995476e+010f, 42.929779f },