blob: afa143a95b6e2df9d6f9645ae2c1b536b26693e1 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
reed@google.comac10a2d2010-12-22 21:39:39 +00002/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00003 * Copyright 2010 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
reed@google.comac10a2d2010-12-22 21:39:39 +00007 */
8
9
epoger@google.comec3ed6a2011-07-28 14:26:00 +000010
reed@google.comac10a2d2010-12-22 21:39:39 +000011#include "GrClip.h"
12
bsalomon@google.comd302f142011-03-03 13:54:13 +000013GrClip::GrClip()
bsalomon@google.coma55847b2011-04-20 15:47:04 +000014 : fList(&fListStorage) {
bsalomon@google.com0b50b2e2011-03-08 21:07:21 +000015 fConservativeBounds.setEmpty();
16 fConservativeBoundsValid = true;
reed@google.comac10a2d2010-12-22 21:39:39 +000017}
18
bsalomon@google.comd302f142011-03-03 13:54:13 +000019GrClip::GrClip(const GrClip& src)
bsalomon@google.coma55847b2011-04-20 15:47:04 +000020 : fList(&fListStorage) {
reed@google.comac10a2d2010-12-22 21:39:39 +000021 *this = src;
22}
23
bsalomon@google.comd302f142011-03-03 13:54:13 +000024GrClip::GrClip(const GrIRect& rect)
bsalomon@google.coma55847b2011-04-20 15:47:04 +000025 : fList(&fListStorage) {
bsalomon@google.comd302f142011-03-03 13:54:13 +000026 this->setFromIRect(rect);
27}
28
29GrClip::GrClip(const GrRect& rect)
bsalomon@google.coma55847b2011-04-20 15:47:04 +000030 : fList(&fListStorage) {
bsalomon@google.comd302f142011-03-03 13:54:13 +000031 this->setFromRect(rect);
32}
33
reed@google.com6f8f2922011-03-04 22:27:10 +000034GrClip::GrClip(GrClipIterator* iter, GrScalar tx, GrScalar ty,
35 const GrRect* bounds)
bsalomon@google.coma55847b2011-04-20 15:47:04 +000036 : fList(&fListStorage) {
reed@google.com6f8f2922011-03-04 22:27:10 +000037 this->setFromIterator(iter, tx, ty, bounds);
reed@google.comac10a2d2010-12-22 21:39:39 +000038}
39
40GrClip::~GrClip() {}
41
42GrClip& GrClip::operator=(const GrClip& src) {
43 fList = src.fList;
bsalomon@google.com0b50b2e2011-03-08 21:07:21 +000044 fConservativeBounds = src.fConservativeBounds;
45 fConservativeBoundsValid = src.fConservativeBoundsValid;
reed@google.comac10a2d2010-12-22 21:39:39 +000046 return *this;
47}
48
49void GrClip::setEmpty() {
50 fList.reset();
bsalomon@google.com0b50b2e2011-03-08 21:07:21 +000051 fConservativeBounds.setEmpty();
52 fConservativeBoundsValid = true;
reed@google.comac10a2d2010-12-22 21:39:39 +000053}
54
bsalomon@google.comd302f142011-03-03 13:54:13 +000055void GrClip::setFromRect(const GrRect& r) {
56 fList.reset();
57 if (r.isEmpty()) {
58 // use a canonical empty rect for == testing.
59 setEmpty();
60 } else {
61 fList.push_back();
62 fList.back().fRect = r;
63 fList.back().fType = kRect_ClipType;
bsalomon@google.comab3dee52011-08-29 15:18:41 +000064 fList.back().fOp = kReplace_SetOp;
bsalomon@google.com0b50b2e2011-03-08 21:07:21 +000065 fConservativeBounds = r;
66 fConservativeBoundsValid = true;
bsalomon@google.comd302f142011-03-03 13:54:13 +000067 }
68}
69
70void GrClip::setFromIRect(const GrIRect& r) {
71 fList.reset();
72 if (r.isEmpty()) {
73 // use a canonical empty rect for == testing.
74 setEmpty();
75 } else {
76 fList.push_back();
77 fList.back().fRect.set(r);
78 fList.back().fType = kRect_ClipType;
bsalomon@google.comab3dee52011-08-29 15:18:41 +000079 fList.back().fOp = kReplace_SetOp;
bsalomon@google.com0b50b2e2011-03-08 21:07:21 +000080 fConservativeBounds.set(r);
81 fConservativeBoundsValid = true;
bsalomon@google.comd302f142011-03-03 13:54:13 +000082 }
83}
84
reed@google.com20efde72011-05-09 17:00:02 +000085static void intersectWith(SkRect* dst, const SkRect& src) {
86 if (!dst->intersect(src)) {
87 dst->setEmpty();
88 }
89}
90
reed@google.com6f8f2922011-03-04 22:27:10 +000091void GrClip::setFromIterator(GrClipIterator* iter, GrScalar tx, GrScalar ty,
bsalomon@google.com0b50b2e2011-03-08 21:07:21 +000092 const GrRect* conservativeBounds) {
reed@google.comac10a2d2010-12-22 21:39:39 +000093 fList.reset();
94
bsalomon@google.comd302f142011-03-03 13:54:13 +000095 int rectCount = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +000096
bsalomon@google.comd302f142011-03-03 13:54:13 +000097 // compute bounds for common case of series of intersecting rects.
98 bool isectRectValid = true;
reed@google.comac10a2d2010-12-22 21:39:39 +000099
reed@google.comac10a2d2010-12-22 21:39:39 +0000100 if (iter) {
101 for (iter->rewind(); !iter->isDone(); iter->next()) {
bsalomon@google.comd302f142011-03-03 13:54:13 +0000102 Element& e = fList.push_back();
103 e.fType = iter->getType();
104 e.fOp = iter->getOp();
105 // iterators should not emit replace
106 GrAssert(kReplace_SetOp != e.fOp);
107 switch (e.fType) {
108 case kRect_ClipType:
109 iter->getRect(&e.fRect);
reed@google.com6f8f2922011-03-04 22:27:10 +0000110 if (tx || ty) {
111 e.fRect.offset(tx, ty);
112 }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000113 ++rectCount;
114 if (isectRectValid) {
bsalomon@google.comab3dee52011-08-29 15:18:41 +0000115 if (kIntersect_SetOp == e.fOp) {
bsalomon@google.comd302f142011-03-03 13:54:13 +0000116 GrAssert(fList.count() <= 2);
117 if (fList.count() > 1) {
118 GrAssert(2 == rectCount);
119 rectCount = 1;
120 fList.pop_back();
121 GrAssert(kRect_ClipType == fList.back().fType);
reed@google.com20efde72011-05-09 17:00:02 +0000122 intersectWith(&fList.back().fRect, e.fRect);
bsalomon@google.comd302f142011-03-03 13:54:13 +0000123 }
124 } else {
125 isectRectValid = false;
126 }
127 }
128 break;
129 case kPath_ClipType:
reed@google.com07f3ee12011-05-16 17:21:57 +0000130 e.fPath = *iter->getPath();
reed@google.com6f8f2922011-03-04 22:27:10 +0000131 if (tx || ty) {
132 e.fPath.offset(tx, ty);
133 }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000134 e.fPathFill = iter->getPathFill();
135 isectRectValid = false;
136 break;
137 default:
138 GrCrash("Unknown clip element type.");
reed@google.comac10a2d2010-12-22 21:39:39 +0000139 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000140 }
141 }
bsalomon@google.com0b50b2e2011-03-08 21:07:21 +0000142 fConservativeBoundsValid = false;
epoger@google.com17b78942011-08-26 14:40:38 +0000143 if (isectRectValid && rectCount) {
144 fConservativeBounds = fList[0].fRect;
bsalomon@google.com0b50b2e2011-03-08 21:07:21 +0000145 fConservativeBoundsValid = true;
bsalomon@google.com0b50b2e2011-03-08 21:07:21 +0000146 } else if (NULL != conservativeBounds) {
147 fConservativeBounds = *conservativeBounds;
148 fConservativeBoundsValid = true;
bsalomon@google.comd302f142011-03-03 13:54:13 +0000149 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000150}