| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2008 The Android Open Source Project | 2 * Copyright 2008 The Android Open Source Project |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 | 8 |
| 9 #include "SkCanvas.h" | 9 #include "SkCanvas.h" |
| 10 #include "SkCanvasPriv.h" | 10 #include "SkCanvasPriv.h" |
| (...skipping 1281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1292 // and clip against that, since it can handle any matrix. However, to | 1292 // and clip against that, since it can handle any matrix. However, to |
| 1293 // avoid recursion in the case where we are subclassed (e.g. Pictures) | 1293 // avoid recursion in the case where we are subclassed (e.g. Pictures) |
| 1294 // we explicitly call "our" version of clipPath. | 1294 // we explicitly call "our" version of clipPath. |
| 1295 SkPath path; | 1295 SkPath path; |
| 1296 | 1296 |
| 1297 path.addRect(rect); | 1297 path.addRect(rect); |
| 1298 this->SkCanvas::onClipPath(path, op, edgeStyle); | 1298 this->SkCanvas::onClipPath(path, op, edgeStyle); |
| 1299 } | 1299 } |
| 1300 } | 1300 } |
| 1301 | 1301 |
| 1302 static void clip_path_helper(const SkCanvas* canvas, SkRasterClip* currClip, | 1302 static void rasterclip_path(SkRasterClip* rc, const SkCanvas* canvas, const SkPa
th& devPath, |
| 1303 const SkPath& devPath, SkRegion::Op op, bool doAA)
{ | 1303 SkRegion::Op op, bool doAA) { |
| 1304 // base is used to limit the size (and therefore memory allocation) of the | 1304 // base is used to limit the size (and therefore memory allocation) of the |
| 1305 // region that results from scan converting devPath. | 1305 // region that results from scan converting devPath. |
| 1306 SkRegion base; | 1306 SkRegion base; |
| 1307 | 1307 |
| 1308 if (SkRegion::kIntersect_Op == op) { | 1308 if (SkRegion::kIntersect_Op == op) { |
| 1309 // since we are intersect, we can do better (tighter) with currRgn's | 1309 // since we are intersect, we can do better (tighter) with currRgn's |
| 1310 // bounds, than just using the device. However, if currRgn is complex, | 1310 // bounds, than just using the device. However, if currRgn is complex, |
| 1311 // our region blitter may hork, so we do that case in two steps. | 1311 // our region blitter may hork, so we do that case in two steps. |
| 1312 if (currClip->isRect()) { | 1312 if (rc->isRect()) { |
| 1313 // FIXME: we should also be able to do this when currClip->isBW(), | 1313 // FIXME: we should also be able to do this when rc->isBW(), |
| 1314 // but relaxing the test above triggers GM asserts in | 1314 // but relaxing the test above triggers GM asserts in |
| 1315 // SkRgnBuilder::blitH(). We need to investigate what's going on. | 1315 // SkRgnBuilder::blitH(). We need to investigate what's going on. |
| 1316 currClip->setPath(devPath, currClip->bwRgn(), doAA); | 1316 rc->setPath(devPath, rc->bwRgn(), doAA); |
| 1317 } else { | 1317 } else { |
| 1318 base.setRect(currClip->getBounds()); | 1318 base.setRect(rc->getBounds()); |
| 1319 SkRasterClip clip; | 1319 SkRasterClip clip; |
| 1320 clip.setPath(devPath, base, doAA); | 1320 clip.setPath(devPath, base, doAA); |
| 1321 currClip->op(clip, op); | 1321 rc->op(clip, op); |
| 1322 } | 1322 } |
| 1323 } else { | 1323 } else { |
| 1324 const SkISize size = canvas->getBaseLayerSize(); | 1324 const SkISize size = canvas->getBaseLayerSize(); |
| 1325 base.setRect(0, 0, size.width(), size.height()); | 1325 base.setRect(0, 0, size.width(), size.height()); |
| 1326 | 1326 |
| 1327 if (SkRegion::kReplace_Op == op) { | 1327 if (SkRegion::kReplace_Op == op) { |
| 1328 currClip->setPath(devPath, base, doAA); | 1328 rc->setPath(devPath, base, doAA); |
| 1329 } else { | 1329 } else { |
| 1330 SkRasterClip clip; | 1330 SkRasterClip clip; |
| 1331 clip.setPath(devPath, base, doAA); | 1331 clip.setPath(devPath, base, doAA); |
| 1332 currClip->op(clip, op); | 1332 rc->op(clip, op); |
| 1333 } | 1333 } |
| 1334 } | 1334 } |
| 1335 } | 1335 } |
| 1336 | 1336 |
| 1337 void SkCanvas::clipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA) { | 1337 void SkCanvas::clipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA) { |
| 1338 ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle; | 1338 ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle; |
| 1339 if (rrect.isRect()) { | 1339 if (rrect.isRect()) { |
| 1340 this->onClipRect(rrect.getBounds(), op, edgeStyle); | 1340 this->onClipRect(rrect.getBounds(), op, edgeStyle); |
| 1341 } else { | 1341 } else { |
| 1342 this->onClipRRect(rrect, op, edgeStyle); | 1342 this->onClipRRect(rrect, op, edgeStyle); |
| 1343 } | 1343 } |
| 1344 } | 1344 } |
| 1345 | 1345 |
| 1346 void SkCanvas::onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle
edgeStyle) { | 1346 void SkCanvas::onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle
edgeStyle) { |
| 1347 SkRRect transformedRRect; | 1347 SkRRect transformedRRect; |
| 1348 if (rrect.transform(fMCRec->fMatrix, &transformedRRect)) { | 1348 if (rrect.transform(fMCRec->fMatrix, &transformedRRect)) { |
| 1349 AutoValidateClip avc(this); | 1349 AutoValidateClip avc(this); |
| 1350 | 1350 |
| 1351 fDeviceCMDirty = true; | 1351 fDeviceCMDirty = true; |
| 1352 fCachedLocalClipBoundsDirty = true; | 1352 fCachedLocalClipBoundsDirty = true; |
| 1353 if (!fAllowSoftClip) { | 1353 if (!fAllowSoftClip) { |
| 1354 edgeStyle = kHard_ClipEdgeStyle; | 1354 edgeStyle = kHard_ClipEdgeStyle; |
| 1355 } | 1355 } |
| 1356 | 1356 |
| 1357 fClipStack.clipDevRRect(transformedRRect, op, kSoft_ClipEdgeStyle == edg
eStyle); | 1357 fClipStack.clipDevRRect(transformedRRect, op, kSoft_ClipEdgeStyle == edg
eStyle); |
| 1358 | 1358 |
| 1359 SkPath devPath; | 1359 SkPath devPath; |
| 1360 devPath.addRRect(transformedRRect); | 1360 devPath.addRRect(transformedRRect); |
| 1361 | 1361 |
| 1362 clip_path_helper(this, &fMCRec->fRasterClip, devPath, op, kSoft_ClipEdge
Style == edgeStyle); | 1362 rasterclip_path(&fMCRec->fRasterClip, this, devPath, op, kSoft_ClipEdgeS
tyle == edgeStyle); |
| 1363 return; | 1363 return; |
| 1364 } | 1364 } |
| 1365 | 1365 |
| 1366 SkPath path; | 1366 SkPath path; |
| 1367 path.addRRect(rrect); | 1367 path.addRRect(rrect); |
| 1368 // call the non-virtual version | 1368 // call the non-virtual version |
| 1369 this->SkCanvas::onClipPath(path, op, edgeStyle); | 1369 this->SkCanvas::onClipPath(path, op, edgeStyle); |
| 1370 } | 1370 } |
| 1371 | 1371 |
| 1372 void SkCanvas::clipPath(const SkPath& path, SkRegion::Op op, bool doAA) { | 1372 void SkCanvas::clipPath(const SkPath& path, SkRegion::Op op, bool doAA) { |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1441 // if the prev and curr clips disagree about aa -vs- not, favor the
aa request. | 1441 // if the prev and curr clips disagree about aa -vs- not, favor the
aa request. |
| 1442 // perhaps we need an API change to avoid this sort of mixed-signals
about | 1442 // perhaps we need an API change to avoid this sort of mixed-signals
about |
| 1443 // clipping. | 1443 // clipping. |
| 1444 if (element->isAA()) { | 1444 if (element->isAA()) { |
| 1445 edgeStyle = kSoft_ClipEdgeStyle; | 1445 edgeStyle = kSoft_ClipEdgeStyle; |
| 1446 } | 1446 } |
| 1447 } | 1447 } |
| 1448 op = SkRegion::kReplace_Op; | 1448 op = SkRegion::kReplace_Op; |
| 1449 } | 1449 } |
| 1450 | 1450 |
| 1451 clip_path_helper(this, &fMCRec->fRasterClip, devPath, op, edgeStyle); | 1451 rasterclip_path(&fMCRec->fRasterClip, this, devPath, op, edgeStyle); |
| 1452 } | 1452 } |
| 1453 | 1453 |
| 1454 void SkCanvas::updateClipConservativelyUsingBounds(const SkRect& bounds, SkRegio
n::Op op, | 1454 void SkCanvas::updateClipConservativelyUsingBounds(const SkRect& bounds, SkRegio
n::Op op, |
| 1455 bool inverseFilled) { | 1455 bool inverseFilled) { |
| 1456 // This is for updating the clip conservatively using only bounds | 1456 // This is for updating the clip conservatively using only bounds |
| 1457 // information. | 1457 // information. |
| 1458 // Contract: | 1458 // Contract: |
| 1459 // The current clip must contain the true clip. The true | 1459 // The current clip must contain the true clip. The true |
| 1460 // clip is the clip that would have normally been computed | 1460 // clip is the clip that would have normally been computed |
| 1461 // by calls to clipPath and clipRRect | 1461 // by calls to clipPath and clipRRect |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1564 case SkClipStack::Element::kRect_Type: | 1564 case SkClipStack::Element::kRect_Type: |
| 1565 element->getRect().round(&ir); | 1565 element->getRect().round(&ir); |
| 1566 tmpClip.op(ir, element->getOp()); | 1566 tmpClip.op(ir, element->getOp()); |
| 1567 break; | 1567 break; |
| 1568 case SkClipStack::Element::kEmpty_Type: | 1568 case SkClipStack::Element::kEmpty_Type: |
| 1569 tmpClip.setEmpty(); | 1569 tmpClip.setEmpty(); |
| 1570 break; | 1570 break; |
| 1571 default: { | 1571 default: { |
| 1572 SkPath path; | 1572 SkPath path; |
| 1573 element->asPath(&path); | 1573 element->asPath(&path); |
| 1574 clip_path_helper(this, &tmpClip, path, element->getOp(), element
->isAA()); | 1574 rasterclip_path(&tmpClip, this, path, element->getOp(), element-
>isAA()); |
| 1575 break; | 1575 break; |
| 1576 } | 1576 } |
| 1577 } | 1577 } |
| 1578 } | 1578 } |
| 1579 } | 1579 } |
| 1580 #endif | 1580 #endif |
| 1581 | 1581 |
| 1582 void SkCanvas::replayClips(ClipVisitor* visitor) const { | 1582 void SkCanvas::replayClips(ClipVisitor* visitor) const { |
| 1583 SkClipStack::B2TIter iter(fClipStack); | 1583 SkClipStack::B2TIter iter(fClipStack); |
| 1584 const SkClipStack::Element* element; | 1584 const SkClipStack::Element* element; |
| (...skipping 987 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2572 } | 2572 } |
| 2573 | 2573 |
| 2574 if (NULL != matrix) { | 2574 if (NULL != matrix) { |
| 2575 canvas->concat(*matrix); | 2575 canvas->concat(*matrix); |
| 2576 } | 2576 } |
| 2577 } | 2577 } |
| 2578 | 2578 |
| 2579 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { | 2579 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { |
| 2580 fCanvas->restoreToCount(fSaveCount); | 2580 fCanvas->restoreToCount(fSaveCount); |
| 2581 } | 2581 } |
| OLD | NEW |