• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /*
3  * 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.
7  */
8 
9 
10 
11 #include "GrClip.h"
12 
GrClip()13 GrClip::GrClip() {
14     fConservativeBounds.setEmpty();
15     fConservativeBoundsValid = true;
16 }
17 
GrClip(const GrClip & src)18 GrClip::GrClip(const GrClip& src) {
19     *this = src;
20 }
21 
GrClip(const GrIRect & rect)22 GrClip::GrClip(const GrIRect& rect) {
23     this->setFromIRect(rect);
24 }
25 
GrClip(const GrRect & rect)26 GrClip::GrClip(const GrRect& rect) {
27     this->setFromRect(rect);
28 }
29 
GrClip(GrClipIterator * iter,GrScalar tx,GrScalar ty,const GrRect * bounds)30 GrClip::GrClip(GrClipIterator* iter, GrScalar tx, GrScalar ty,
31                const GrRect* bounds) {
32     this->setFromIterator(iter, tx, ty, bounds);
33 }
34 
~GrClip()35 GrClip::~GrClip() {}
36 
operator =(const GrClip & src)37 GrClip& GrClip::operator=(const GrClip& src) {
38     fList = src.fList;
39     fConservativeBounds = src.fConservativeBounds;
40     fConservativeBoundsValid = src.fConservativeBoundsValid;
41     return *this;
42 }
43 
setEmpty()44 void GrClip::setEmpty() {
45     fList.reset();
46     fConservativeBounds.setEmpty();
47     fConservativeBoundsValid = true;
48 }
49 
setFromRect(const GrRect & r)50 void 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;
59         fList.back().fOp = kReplace_SetOp;
60         fConservativeBounds = r;
61         fConservativeBoundsValid = true;
62     }
63 }
64 
setFromIRect(const GrIRect & r)65 void 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;
74         fList.back().fOp = kReplace_SetOp;
75         fConservativeBounds.set(r);
76         fConservativeBoundsValid = true;
77     }
78 }
79 
intersectWith(SkRect * dst,const SkRect & src)80 static void intersectWith(SkRect* dst, const SkRect& src) {
81     if (!dst->intersect(src)) {
82         dst->setEmpty();
83     }
84 }
85 
setFromIterator(GrClipIterator * iter,GrScalar tx,GrScalar ty,const GrRect * conservativeBounds)86 void GrClip::setFromIterator(GrClipIterator* iter, GrScalar tx, GrScalar ty,
87                              const GrRect* conservativeBounds) {
88     fList.reset();
89 
90     int rectCount = 0;
91 
92     // compute bounds for common case of series of intersecting rects.
93     bool isectRectValid = true;
94 
95     if (iter) {
96         for (iter->rewind(); !iter->isDone(); iter->next()) {
97             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);
105                     if (tx || ty) {
106                         e.fRect.offset(tx, ty);
107                     }
108                     ++rectCount;
109                     if (isectRectValid) {
110                         if (kIntersect_SetOp == e.fOp) {
111                             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);
117                                 intersectWith(&fList.back().fRect, e.fRect);
118                             }
119                         } else {
120                             isectRectValid = false;
121                         }
122                     }
123                     break;
124                 case kPath_ClipType:
125                     e.fPath = *iter->getPath();
126                     if (tx || ty) {
127                         e.fPath.offset(tx, ty);
128                     }
129                     e.fPathFill = iter->getPathFill();
130                     isectRectValid = false;
131                     break;
132                 default:
133                     GrCrash("Unknown clip element type.");
134             }
135         }
136     }
137     fConservativeBoundsValid = false;
138     if (isectRectValid && rectCount) {
139         fConservativeBounds = fList[0].fRect;
140         fConservativeBoundsValid = true;
141     } else if (NULL != conservativeBounds) {
142         fConservativeBounds = *conservativeBounds;
143         fConservativeBoundsValid = true;
144     }
145 }
146