blob: 7ccec261a1be49d05a19bc3cdc52b436dc89d284 [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.com0b50b2e2011-03-08 21:07:21 +000064 fConservativeBounds = r;
65 fConservativeBoundsValid = true;
bsalomon@google.comd302f142011-03-03 13:54:13 +000066 }
67}
68
69void GrClip::setFromIRect(const GrIRect& r) {
70 fList.reset();
71 if (r.isEmpty()) {
72 // use a canonical empty rect for == testing.
73 setEmpty();
74 } else {
75 fList.push_back();
76 fList.back().fRect.set(r);
77 fList.back().fType = kRect_ClipType;
bsalomon@google.com0b50b2e2011-03-08 21:07:21 +000078 fConservativeBounds.set(r);
79 fConservativeBoundsValid = true;
bsalomon@google.comd302f142011-03-03 13:54:13 +000080 }
81}
82
reed@google.com20efde72011-05-09 17:00:02 +000083static void intersectWith(SkRect* dst, const SkRect& src) {
84 if (!dst->intersect(src)) {
85 dst->setEmpty();
86 }
87}
88
reed@google.com6f8f2922011-03-04 22:27:10 +000089void GrClip::setFromIterator(GrClipIterator* iter, GrScalar tx, GrScalar ty,
bsalomon@google.com0b50b2e2011-03-08 21:07:21 +000090 const GrRect* conservativeBounds) {
reed@google.comac10a2d2010-12-22 21:39:39 +000091 fList.reset();
92
bsalomon@google.comd302f142011-03-03 13:54:13 +000093 int rectCount = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +000094
bsalomon@google.comd302f142011-03-03 13:54:13 +000095 // compute bounds for common case of series of intersecting rects.
96 bool isectRectValid = true;
reed@google.comac10a2d2010-12-22 21:39:39 +000097
reed@google.comac10a2d2010-12-22 21:39:39 +000098 if (iter) {
99 for (iter->rewind(); !iter->isDone(); iter->next()) {
bsalomon@google.comd302f142011-03-03 13:54:13 +0000100 Element& e = fList.push_back();
101 e.fType = iter->getType();
102 e.fOp = iter->getOp();
103 // iterators should not emit replace
104 GrAssert(kReplace_SetOp != e.fOp);
105 switch (e.fType) {
106 case kRect_ClipType:
107 iter->getRect(&e.fRect);
reed@google.com6f8f2922011-03-04 22:27:10 +0000108 if (tx || ty) {
109 e.fRect.offset(tx, ty);
110 }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000111 ++rectCount;
112 if (isectRectValid) {
113 if (1 == rectCount || kIntersect_SetOp == e.fOp) {
114 GrAssert(fList.count() <= 2);
115 if (fList.count() > 1) {
116 GrAssert(2 == rectCount);
117 rectCount = 1;
118 fList.pop_back();
119 GrAssert(kRect_ClipType == fList.back().fType);
reed@google.com20efde72011-05-09 17:00:02 +0000120 intersectWith(&fList.back().fRect, e.fRect);
bsalomon@google.comd302f142011-03-03 13:54:13 +0000121 }
122 } else {
123 isectRectValid = false;
124 }
125 }
126 break;
127 case kPath_ClipType:
reed@google.com07f3ee12011-05-16 17:21:57 +0000128 e.fPath = *iter->getPath();
reed@google.com6f8f2922011-03-04 22:27:10 +0000129 if (tx || ty) {
130 e.fPath.offset(tx, ty);
131 }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000132 e.fPathFill = iter->getPathFill();
133 isectRectValid = false;
134 break;
135 default:
136 GrCrash("Unknown clip element type.");
reed@google.comac10a2d2010-12-22 21:39:39 +0000137 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000138 }
139 }
bsalomon@google.com0b50b2e2011-03-08 21:07:21 +0000140 fConservativeBoundsValid = false;
141 if (isectRectValid) {
142 fConservativeBoundsValid = true;
143 if (rectCount > 0) {
144 fConservativeBounds = fList[0].fRect;
145 } else {
146 fConservativeBounds.setEmpty();
bsalomon@google.comd302f142011-03-03 13:54:13 +0000147 }
bsalomon@google.com0b50b2e2011-03-08 21:07:21 +0000148 } else if (NULL != conservativeBounds) {
149 fConservativeBounds = *conservativeBounds;
150 fConservativeBoundsValid = true;
bsalomon@google.comd302f142011-03-03 13:54:13 +0000151 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000152}