blob: a02d9f450444c2591103e4c2433936e6c70ee760 [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.com92669012011-09-27 19:10:05 +000013GrClip::GrClip() {
bsalomon@google.com0b50b2e2011-03-08 21:07:21 +000014 fConservativeBounds.setEmpty();
15 fConservativeBoundsValid = true;
reed@google.comac10a2d2010-12-22 21:39:39 +000016}
17
bsalomon@google.com92669012011-09-27 19:10:05 +000018GrClip::GrClip(const GrClip& src) {
reed@google.comac10a2d2010-12-22 21:39:39 +000019 *this = src;
20}
21
bsalomon@google.com92669012011-09-27 19:10:05 +000022GrClip::GrClip(const GrIRect& rect) {
bsalomon@google.comd302f142011-03-03 13:54:13 +000023 this->setFromIRect(rect);
24}
25
bsalomon@google.com92669012011-09-27 19:10:05 +000026GrClip::GrClip(const GrRect& rect) {
bsalomon@google.comd302f142011-03-03 13:54:13 +000027 this->setFromRect(rect);
28}
29
reed@google.com6f8f2922011-03-04 22:27:10 +000030GrClip::GrClip(GrClipIterator* iter, GrScalar tx, GrScalar ty,
bsalomon@google.com92669012011-09-27 19:10:05 +000031 const GrRect* bounds) {
reed@google.com6f8f2922011-03-04 22:27:10 +000032 this->setFromIterator(iter, tx, ty, bounds);
reed@google.comac10a2d2010-12-22 21:39:39 +000033}
34
35GrClip::~GrClip() {}
36
37GrClip& GrClip::operator=(const GrClip& src) {
38 fList = src.fList;
bsalomon@google.com0b50b2e2011-03-08 21:07:21 +000039 fConservativeBounds = src.fConservativeBounds;
40 fConservativeBoundsValid = src.fConservativeBoundsValid;
reed@google.comac10a2d2010-12-22 21:39:39 +000041 return *this;
42}
43
44void GrClip::setEmpty() {
45 fList.reset();
bsalomon@google.com0b50b2e2011-03-08 21:07:21 +000046 fConservativeBounds.setEmpty();
47 fConservativeBoundsValid = true;
reed@google.comac10a2d2010-12-22 21:39:39 +000048}
49
bsalomon@google.comd302f142011-03-03 13:54:13 +000050void GrClip::setFromRect(const GrRect& r) {
51 fList.reset();
52 if (r.isEmpty()) {
53 // use a canonical empty rect for == testing.
54 setEmpty();
55 } else {
56 fList.push_back();
57 fList.back().fRect = r;
58 fList.back().fType = kRect_ClipType;
bsalomon@google.comab3dee52011-08-29 15:18:41 +000059 fList.back().fOp = kReplace_SetOp;
bsalomon@google.com0b50b2e2011-03-08 21:07:21 +000060 fConservativeBounds = r;
61 fConservativeBoundsValid = true;
bsalomon@google.comd302f142011-03-03 13:54:13 +000062 }
63}
64
65void GrClip::setFromIRect(const GrIRect& r) {
66 fList.reset();
67 if (r.isEmpty()) {
68 // use a canonical empty rect for == testing.
69 setEmpty();
70 } else {
71 fList.push_back();
72 fList.back().fRect.set(r);
73 fList.back().fType = kRect_ClipType;
bsalomon@google.comab3dee52011-08-29 15:18:41 +000074 fList.back().fOp = kReplace_SetOp;
bsalomon@google.com0b50b2e2011-03-08 21:07:21 +000075 fConservativeBounds.set(r);
76 fConservativeBoundsValid = true;
bsalomon@google.comd302f142011-03-03 13:54:13 +000077 }
78}
79
reed@google.com20efde72011-05-09 17:00:02 +000080static void intersectWith(SkRect* dst, const SkRect& src) {
81 if (!dst->intersect(src)) {
82 dst->setEmpty();
83 }
84}
85
reed@google.com6f8f2922011-03-04 22:27:10 +000086void GrClip::setFromIterator(GrClipIterator* iter, GrScalar tx, GrScalar ty,
bsalomon@google.com0b50b2e2011-03-08 21:07:21 +000087 const GrRect* conservativeBounds) {
reed@google.comac10a2d2010-12-22 21:39:39 +000088 fList.reset();
89
bsalomon@google.comd302f142011-03-03 13:54:13 +000090 int rectCount = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +000091
bsalomon@google.comd302f142011-03-03 13:54:13 +000092 // compute bounds for common case of series of intersecting rects.
93 bool isectRectValid = true;
reed@google.comac10a2d2010-12-22 21:39:39 +000094
reed@google.comac10a2d2010-12-22 21:39:39 +000095 if (iter) {
96 for (iter->rewind(); !iter->isDone(); iter->next()) {
bsalomon@google.comd302f142011-03-03 13:54:13 +000097 Element& e = fList.push_back();
98 e.fType = iter->getType();
99 e.fOp = iter->getOp();
100 // iterators should not emit replace
101 GrAssert(kReplace_SetOp != e.fOp);
102 switch (e.fType) {
103 case kRect_ClipType:
104 iter->getRect(&e.fRect);
reed@google.com6f8f2922011-03-04 22:27:10 +0000105 if (tx || ty) {
106 e.fRect.offset(tx, ty);
107 }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000108 ++rectCount;
109 if (isectRectValid) {
bsalomon@google.comab3dee52011-08-29 15:18:41 +0000110 if (kIntersect_SetOp == e.fOp) {
bsalomon@google.comd302f142011-03-03 13:54:13 +0000111 GrAssert(fList.count() <= 2);
112 if (fList.count() > 1) {
113 GrAssert(2 == rectCount);
114 rectCount = 1;
115 fList.pop_back();
116 GrAssert(kRect_ClipType == fList.back().fType);
reed@google.com20efde72011-05-09 17:00:02 +0000117 intersectWith(&fList.back().fRect, e.fRect);
bsalomon@google.comd302f142011-03-03 13:54:13 +0000118 }
119 } else {
120 isectRectValid = false;
121 }
122 }
123 break;
124 case kPath_ClipType:
reed@google.com07f3ee12011-05-16 17:21:57 +0000125 e.fPath = *iter->getPath();
reed@google.com6f8f2922011-03-04 22:27:10 +0000126 if (tx || ty) {
127 e.fPath.offset(tx, ty);
128 }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000129 e.fPathFill = iter->getPathFill();
130 isectRectValid = false;
131 break;
132 default:
133 GrCrash("Unknown clip element type.");
reed@google.comac10a2d2010-12-22 21:39:39 +0000134 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000135 }
136 }
bsalomon@google.com0b50b2e2011-03-08 21:07:21 +0000137 fConservativeBoundsValid = false;
epoger@google.com17b78942011-08-26 14:40:38 +0000138 if (isectRectValid && rectCount) {
139 fConservativeBounds = fList[0].fRect;
bsalomon@google.com0b50b2e2011-03-08 21:07:21 +0000140 fConservativeBoundsValid = true;
bsalomon@google.com0b50b2e2011-03-08 21:07:21 +0000141 } else if (NULL != conservativeBounds) {
142 fConservativeBounds = *conservativeBounds;
143 fConservativeBoundsValid = true;
bsalomon@google.comd302f142011-03-03 13:54:13 +0000144 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000145}