aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/GrClip.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpu/GrClip.cpp')
-rw-r--r--src/gpu/GrClip.cpp145
1 files changed, 145 insertions, 0 deletions
diff --git a/src/gpu/GrClip.cpp b/src/gpu/GrClip.cpp
new file mode 100644
index 0000000000..a02d9f4504
--- /dev/null
+++ b/src/gpu/GrClip.cpp
@@ -0,0 +1,145 @@
+
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+
+#include "GrClip.h"
+
+GrClip::GrClip() {
+ fConservativeBounds.setEmpty();
+ fConservativeBoundsValid = true;
+}
+
+GrClip::GrClip(const GrClip& src) {
+ *this = src;
+}
+
+GrClip::GrClip(const GrIRect& rect) {
+ this->setFromIRect(rect);
+}
+
+GrClip::GrClip(const GrRect& rect) {
+ this->setFromRect(rect);
+}
+
+GrClip::GrClip(GrClipIterator* iter, GrScalar tx, GrScalar ty,
+ const GrRect* bounds) {
+ this->setFromIterator(iter, tx, ty, bounds);
+}
+
+GrClip::~GrClip() {}
+
+GrClip& GrClip::operator=(const GrClip& src) {
+ fList = src.fList;
+ fConservativeBounds = src.fConservativeBounds;
+ fConservativeBoundsValid = src.fConservativeBoundsValid;
+ return *this;
+}
+
+void GrClip::setEmpty() {
+ fList.reset();
+ fConservativeBounds.setEmpty();
+ fConservativeBoundsValid = true;
+}
+
+void GrClip::setFromRect(const GrRect& r) {
+ fList.reset();
+ if (r.isEmpty()) {
+ // use a canonical empty rect for == testing.
+ setEmpty();
+ } else {
+ fList.push_back();
+ fList.back().fRect = r;
+ fList.back().fType = kRect_ClipType;
+ fList.back().fOp = kReplace_SetOp;
+ fConservativeBounds = r;
+ fConservativeBoundsValid = true;
+ }
+}
+
+void GrClip::setFromIRect(const GrIRect& r) {
+ fList.reset();
+ if (r.isEmpty()) {
+ // use a canonical empty rect for == testing.
+ setEmpty();
+ } else {
+ fList.push_back();
+ fList.back().fRect.set(r);
+ fList.back().fType = kRect_ClipType;
+ fList.back().fOp = kReplace_SetOp;
+ fConservativeBounds.set(r);
+ fConservativeBoundsValid = true;
+ }
+}
+
+static void intersectWith(SkRect* dst, const SkRect& src) {
+ if (!dst->intersect(src)) {
+ dst->setEmpty();
+ }
+}
+
+void GrClip::setFromIterator(GrClipIterator* iter, GrScalar tx, GrScalar ty,
+ const GrRect* conservativeBounds) {
+ fList.reset();
+
+ int rectCount = 0;
+
+ // compute bounds for common case of series of intersecting rects.
+ bool isectRectValid = true;
+
+ if (iter) {
+ for (iter->rewind(); !iter->isDone(); iter->next()) {
+ Element& e = fList.push_back();
+ e.fType = iter->getType();
+ e.fOp = iter->getOp();
+ // iterators should not emit replace
+ GrAssert(kReplace_SetOp != e.fOp);
+ switch (e.fType) {
+ case kRect_ClipType:
+ iter->getRect(&e.fRect);
+ if (tx || ty) {
+ e.fRect.offset(tx, ty);
+ }
+ ++rectCount;
+ if (isectRectValid) {
+ if (kIntersect_SetOp == e.fOp) {
+ GrAssert(fList.count() <= 2);
+ if (fList.count() > 1) {
+ GrAssert(2 == rectCount);
+ rectCount = 1;
+ fList.pop_back();
+ GrAssert(kRect_ClipType == fList.back().fType);
+ intersectWith(&fList.back().fRect, e.fRect);
+ }
+ } else {
+ isectRectValid = false;
+ }
+ }
+ break;
+ case kPath_ClipType:
+ e.fPath = *iter->getPath();
+ if (tx || ty) {
+ e.fPath.offset(tx, ty);
+ }
+ e.fPathFill = iter->getPathFill();
+ isectRectValid = false;
+ break;
+ default:
+ GrCrash("Unknown clip element type.");
+ }
+ }
+ }
+ fConservativeBoundsValid = false;
+ if (isectRectValid && rectCount) {
+ fConservativeBounds = fList[0].fRect;
+ fConservativeBoundsValid = true;
+ } else if (NULL != conservativeBounds) {
+ fConservativeBounds = *conservativeBounds;
+ fConservativeBoundsValid = true;
+ }
+}