diff options
author | reed@android.com <reed@android.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2009-11-19 20:46:39 +0000 |
---|---|---|
committer | reed@android.com <reed@android.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2009-11-19 20:46:39 +0000 |
commit | e28ff55d980d2992618b6b721c848aba96cf759a (patch) | |
tree | 328fdbaace1f02476e4c2cc01eef1290c9e38393 /src/core/SkLineClipper.cpp | |
parent | 28bee9591d1b24de4a536dbd2ae948df8186ba94 (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.cpp | 62 |
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; |