blob: a5120d4ff154c53f1ec2a18e8f5b43e941adab94 [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
robertphillips@google.comfa1d2912012-04-16 14:49:14 +000013GrClip::GrClip()
14 : fRequiresAA(false) {
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.com92669012011-09-27 19:10:05 +000019GrClip::GrClip(const GrClip& src) {
reed@google.comac10a2d2010-12-22 21:39:39 +000020 *this = src;
21}
22
bsalomon@google.com92669012011-09-27 19:10:05 +000023GrClip::GrClip(const GrIRect& rect) {
bsalomon@google.comd302f142011-03-03 13:54:13 +000024 this->setFromIRect(rect);
25}
26
bsalomon@google.com92669012011-09-27 19:10:05 +000027GrClip::GrClip(const GrRect& rect) {
bsalomon@google.comd302f142011-03-03 13:54:13 +000028 this->setFromRect(rect);
29}
30
reed@google.com6f8f2922011-03-04 22:27:10 +000031GrClip::GrClip(GrClipIterator* iter, GrScalar tx, GrScalar ty,
bsalomon@google.com92669012011-09-27 19:10:05 +000032 const GrRect* bounds) {
reed@google.com6f8f2922011-03-04 22:27:10 +000033 this->setFromIterator(iter, tx, ty, bounds);
reed@google.comac10a2d2010-12-22 21:39:39 +000034}
35
36GrClip::~GrClip() {}
37
38GrClip& GrClip::operator=(const GrClip& src) {
39 fList = src.fList;
bsalomon@google.com0b50b2e2011-03-08 21:07:21 +000040 fConservativeBounds = src.fConservativeBounds;
41 fConservativeBoundsValid = src.fConservativeBoundsValid;
robertphillips@google.comfa1d2912012-04-16 14:49:14 +000042 fRequiresAA = src.fRequiresAA;
reed@google.comac10a2d2010-12-22 21:39:39 +000043 return *this;
44}
45
46void GrClip::setEmpty() {
47 fList.reset();
bsalomon@google.com0b50b2e2011-03-08 21:07:21 +000048 fConservativeBounds.setEmpty();
49 fConservativeBoundsValid = true;
robertphillips@google.comfa1d2912012-04-16 14:49:14 +000050 fRequiresAA = false;
reed@google.comac10a2d2010-12-22 21:39:39 +000051}
52
bsalomon@google.comd302f142011-03-03 13:54:13 +000053void GrClip::setFromRect(const GrRect& r) {
54 fList.reset();
55 if (r.isEmpty()) {
56 // use a canonical empty rect for == testing.
57 setEmpty();
58 } else {
59 fList.push_back();
60 fList.back().fRect = r;
61 fList.back().fType = kRect_ClipType;
robertphillips@google.com0f191f32012-04-25 15:23:36 +000062 fList.back().fOp = SkRegion::kReplace_Op;
robertphillips@google.comfa1d2912012-04-16 14:49:14 +000063 fList.back().fDoAA = false;
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;
robertphillips@google.com0f191f32012-04-25 15:23:36 +000078 fList.back().fOp = SkRegion::kReplace_Op;
robertphillips@google.comfa1d2912012-04-16 14:49:14 +000079 fList.back().fDoAA = false;
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();
robertphillips@google.comfa1d2912012-04-16 14:49:14 +000094 fRequiresAA = false;
reed@google.comac10a2d2010-12-22 21:39:39 +000095
bsalomon@google.comd302f142011-03-03 13:54:13 +000096 int rectCount = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +000097
bsalomon@google.comd302f142011-03-03 13:54:13 +000098 // compute bounds for common case of series of intersecting rects.
99 bool isectRectValid = true;
reed@google.comac10a2d2010-12-22 21:39:39 +0000100
reed@google.comac10a2d2010-12-22 21:39:39 +0000101 if (iter) {
102 for (iter->rewind(); !iter->isDone(); iter->next()) {
bsalomon@google.comd302f142011-03-03 13:54:13 +0000103 Element& e = fList.push_back();
104 e.fType = iter->getType();
105 e.fOp = iter->getOp();
robertphillips@google.comfa1d2912012-04-16 14:49:14 +0000106 e.fDoAA = iter->getDoAA();
107 if (e.fDoAA) {
108 fRequiresAA = true;
109 }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000110 // iterators should not emit replace
robertphillips@google.com0f191f32012-04-25 15:23:36 +0000111 GrAssert(SkRegion::kReplace_Op != e.fOp);
bsalomon@google.comd302f142011-03-03 13:54:13 +0000112 switch (e.fType) {
113 case kRect_ClipType:
114 iter->getRect(&e.fRect);
reed@google.com6f8f2922011-03-04 22:27:10 +0000115 if (tx || ty) {
116 e.fRect.offset(tx, ty);
117 }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000118 ++rectCount;
119 if (isectRectValid) {
robertphillips@google.com0f191f32012-04-25 15:23:36 +0000120 if (SkRegion::kIntersect_Op == e.fOp) {
bsalomon@google.comd302f142011-03-03 13:54:13 +0000121 GrAssert(fList.count() <= 2);
122 if (fList.count() > 1) {
123 GrAssert(2 == rectCount);
124 rectCount = 1;
125 fList.pop_back();
126 GrAssert(kRect_ClipType == fList.back().fType);
reed@google.com20efde72011-05-09 17:00:02 +0000127 intersectWith(&fList.back().fRect, e.fRect);
bsalomon@google.comd302f142011-03-03 13:54:13 +0000128 }
129 } else {
130 isectRectValid = false;
131 }
132 }
133 break;
134 case kPath_ClipType:
reed@google.com07f3ee12011-05-16 17:21:57 +0000135 e.fPath = *iter->getPath();
reed@google.com6f8f2922011-03-04 22:27:10 +0000136 if (tx || ty) {
137 e.fPath.offset(tx, ty);
138 }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000139 e.fPathFill = iter->getPathFill();
140 isectRectValid = false;
141 break;
142 default:
143 GrCrash("Unknown clip element type.");
reed@google.comac10a2d2010-12-22 21:39:39 +0000144 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000145 }
146 }
bsalomon@google.com0b50b2e2011-03-08 21:07:21 +0000147 fConservativeBoundsValid = false;
epoger@google.com17b78942011-08-26 14:40:38 +0000148 if (isectRectValid && rectCount) {
149 fConservativeBounds = fList[0].fRect;
bsalomon@google.com0b50b2e2011-03-08 21:07:21 +0000150 fConservativeBoundsValid = true;
bsalomon@google.com0b50b2e2011-03-08 21:07:21 +0000151 } else if (NULL != conservativeBounds) {
152 fConservativeBounds = *conservativeBounds;
153 fConservativeBoundsValid = true;
bsalomon@google.comd302f142011-03-03 13:54:13 +0000154 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000155}