aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkLineClipper.cpp
diff options
context:
space:
mode:
authorGravatar reed@android.com <reed@android.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2009-11-19 20:46:39 +0000
committerGravatar reed@android.com <reed@android.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2009-11-19 20:46:39 +0000
commite28ff55d980d2992618b6b721c848aba96cf759a (patch)
tree328fdbaace1f02476e4c2cc01eef1290c9e38393 /src/core/SkLineClipper.cpp
parent28bee9591d1b24de4a536dbd2ae948df8186ba94 (diff)
retool clipping in hairlines to catch huge coordinates
git-svn-id: http://skia.googlecode.com/svn/trunk@436 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/core/SkLineClipper.cpp')
-rw-r--r--src/core/SkLineClipper.cpp62
1 files changed, 62 insertions, 0 deletions
diff --git a/src/core/SkLineClipper.cpp b/src/core/SkLineClipper.cpp
index ef37a14bb0..9164f7c13f 100644
--- a/src/core/SkLineClipper.cpp
+++ b/src/core/SkLineClipper.cpp
@@ -22,6 +22,68 @@ static SkScalar sect_with_vertical(const SkPoint src[2], SkScalar X) {
}
}
+///////////////////////////////////////////////////////////////////////////////
+
+bool SkLineClipper::IntersectLine(const SkPoint src[2], const SkRect& clip,
+ SkPoint dst[2]) {
+ SkRect bounds;
+
+ bounds.set(src, 2);
+ if (bounds.fLeft >= clip.fRight || clip.fLeft >= bounds.fRight ||
+ bounds.fTop >= clip.fBottom || clip.fTop >= bounds.fBottom) {
+ return false;
+ }
+ if (clip.contains(bounds)) {
+ if (src != dst) {
+ memcpy(dst, src, 2 * sizeof(SkPoint));
+ }
+ return true;
+ }
+
+ int index0, index1;
+
+ if (src[0].fY < src[1].fY) {
+ index0 = 0;
+ index1 = 1;
+ } else {
+ index0 = 1;
+ index1 = 0;
+ }
+
+ SkPoint tmp[2];
+ memcpy(tmp, src, sizeof(tmp));
+
+ // now compute Y intersections
+ if (tmp[index0].fY < clip.fTop) {
+ tmp[index0].set(sect_with_horizontal(src, clip.fTop), clip.fTop);
+ }
+ if (tmp[index1].fY > clip.fBottom) {
+ tmp[index1].set(sect_with_horizontal(src, clip.fBottom), clip.fBottom);
+ }
+
+ if (tmp[0].fX < tmp[1].fX) {
+ index0 = 0;
+ index1 = 1;
+ } else {
+ index0 = 1;
+ index1 = 0;
+ }
+
+ // check for quick-reject in X again, now that we may have been chopped
+ if (tmp[index1].fX <= clip.fLeft || tmp[index0].fX >= clip.fRight) {
+ return false;
+ }
+
+ if (tmp[index0].fX < clip.fLeft) {
+ tmp[index0].set(clip.fLeft, sect_with_vertical(src, clip.fLeft));
+ }
+ if (tmp[index1].fX > clip.fRight) {
+ tmp[index1].set(clip.fRight, sect_with_vertical(src, clip.fRight));
+ }
+ memcpy(dst, tmp, sizeof(tmp));
+ return true;
+}
+
int SkLineClipper::ClipLine(const SkPoint pts[], const SkRect& clip,
SkPoint lines[]) {
int index0, index1;