OLD | NEW |
---|---|
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2008 The Android Open Source Project | 3 * Copyright 2008 The Android Open Source Project |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 | 9 |
10 #include "SkCanvas.h" | 10 #include "SkCanvas.h" |
(...skipping 1261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1272 // perhaps we need an API change to avoid this sort of mixed-signals about | 1272 // perhaps we need an API change to avoid this sort of mixed-signals about |
1273 // clipping. | 1273 // clipping. |
1274 doAA |= element->isAA(); | 1274 doAA |= element->isAA(); |
1275 } | 1275 } |
1276 op = SkRegion::kReplace_Op; | 1276 op = SkRegion::kReplace_Op; |
1277 } | 1277 } |
1278 | 1278 |
1279 return clipPathHelper(this, fMCRec->fRasterClip, devPath, op, doAA); | 1279 return clipPathHelper(this, fMCRec->fRasterClip, devPath, op, doAA); |
1280 } | 1280 } |
1281 | 1281 |
1282 bool SkCanvas::updateClipConservativelyUsingBounds(const SkRect& bounds, SkRegio n::Op op, | |
reed1
2013/05/29 18:54:01
/**
* This *never* calls back through a virtual o
| |
1283 bool inverseFilled) { | |
1284 // This is for updating the clip conservatively using only bounds | |
1285 // information. | |
1286 // Contract: | |
1287 // The current clip must contain the true clip. The true | |
1288 // clip is the clip that would have normally been computed | |
1289 // by calls to clipPath and clipRRect | |
1290 // Objective: | |
1291 // Keep the current clip as small as possible without | |
1292 // breaking the contract, using only clip bounding rectangles | |
1293 // (for performance). | |
1294 if (inverseFilled) { | |
1295 switch (op) { | |
1296 case SkRegion::kIntersect_Op: | |
1297 case SkRegion::kDifference_Op: | |
1298 // These ops can only shrink the current clip. So leaving | |
1299 // the clip unchanges conservatively respects the contract. | |
1300 return this->getClipDeviceBounds(NULL); | |
1301 case SkRegion::kUnion_Op: | |
1302 case SkRegion::kReplace_Op: | |
1303 case SkRegion::kReverseDifference_Op: | |
1304 case SkRegion::kXOR_Op: | |
1305 { | |
1306 // These ops can grow the current clip up to the extents of | |
1307 // the input clip, which is inverse filled, so we just set | |
1308 // the current clip to the device bounds. | |
1309 SkRect deviceBounds; | |
1310 SkIRect deviceIBounds; | |
1311 this->getDevice()->getGlobalBounds(&deviceIBounds); | |
1312 deviceBounds = SkRect::MakeFromIRect(deviceIBounds); | |
1313 this->SkCanvas::save(SkCanvas::kMatrix_SaveFlag); | |
1314 // set the clip in device space | |
1315 this->SkCanvas::setMatrix(SkMatrix::I()); | |
1316 bool result = this->SkCanvas::clipRect(deviceBounds, | |
1317 SkRegion::kReplace_Op, false); | |
1318 this->SkCanvas::restore(); //pop the matrix, but keep the cl ip | |
1319 return result; | |
1320 } | |
1321 default: | |
1322 SkASSERT(0); // unhandled op? | |
1323 } | |
1324 } else { | |
1325 // Not inverse filled | |
1326 switch (op) { | |
1327 case SkRegion::kIntersect_Op: | |
1328 case SkRegion::kUnion_Op: | |
1329 case SkRegion::kReplace_Op: | |
1330 return this->SkCanvas::clipRect(bounds, op, false); | |
1331 case SkRegion::kDifference_Op: | |
1332 // Difference can only shrink the current clip. | |
1333 // Leaving clip unchanged conservatively fullfills the contract. | |
1334 return this->getClipDeviceBounds(NULL); | |
1335 case SkRegion::kReverseDifference_Op: | |
1336 // To reverse, we swap in the bounds with a replace op. | |
1337 // As with difference, leave it unchanged. | |
1338 return this->SkCanvas::clipRect(bounds, SkRegion::kReplace_Op, f alse); | |
1339 case SkRegion::kXOR_Op: | |
1340 // Be conservative, based on (A XOR B) always included in (A uni on B), | |
1341 // which is always included in (bounds(A) union bounds(B)) | |
1342 return this->SkCanvas::clipRect(bounds, SkRegion::kUnion_Op, fal se); | |
1343 default: | |
1344 SkASSERT(0); // unhandled op? | |
1345 } | |
1346 } | |
1347 return true; | |
1348 } | |
1349 | |
1282 bool SkCanvas::clipRegion(const SkRegion& rgn, SkRegion::Op op) { | 1350 bool SkCanvas::clipRegion(const SkRegion& rgn, SkRegion::Op op) { |
1283 AutoValidateClip avc(this); | 1351 AutoValidateClip avc(this); |
1284 | 1352 |
1285 fDeviceCMDirty = true; | 1353 fDeviceCMDirty = true; |
1286 fLocalBoundsCompareTypeDirty = true; | 1354 fLocalBoundsCompareTypeDirty = true; |
1287 | 1355 |
1288 // todo: signal fClipStack that we have a region, and therefore (I guess) | 1356 // todo: signal fClipStack that we have a region, and therefore (I guess) |
1289 // we have to ignore it, and use the region directly? | 1357 // we have to ignore it, and use the region directly? |
1290 fClipStack.clipDevRect(rgn.getBounds(), op); | 1358 fClipStack.clipDevRect(rgn.getBounds(), op); |
1291 | 1359 |
(...skipping 879 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2171 return *paint; | 2239 return *paint; |
2172 } | 2240 } |
2173 | 2241 |
2174 const SkRegion& SkCanvas::LayerIter::clip() const { return fImpl->getClip(); } | 2242 const SkRegion& SkCanvas::LayerIter::clip() const { return fImpl->getClip(); } |
2175 int SkCanvas::LayerIter::x() const { return fImpl->getX(); } | 2243 int SkCanvas::LayerIter::x() const { return fImpl->getX(); } |
2176 int SkCanvas::LayerIter::y() const { return fImpl->getY(); } | 2244 int SkCanvas::LayerIter::y() const { return fImpl->getY(); } |
2177 | 2245 |
2178 /////////////////////////////////////////////////////////////////////////////// | 2246 /////////////////////////////////////////////////////////////////////////////// |
2179 | 2247 |
2180 SkCanvas::ClipVisitor::~ClipVisitor() { } | 2248 SkCanvas::ClipVisitor::~ClipVisitor() { } |
OLD | NEW |