1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc. 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */ 7c3b589a24eb4d567a906189f882c259ecf5c2f58fmalita 8c3b589a24eb4d567a906189f882c259ecf5c2f58fmalita#include "SkCanvas.h" 95c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com#include "SkClipStack.h" 105c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com#include "SkPath.h" 1146f935002c2b25331e552520dc7b1a912e12dfdcrobertphillips@google.com#include "SkThread.h" 1246f935002c2b25331e552520dc7b1a912e12dfdcrobertphillips@google.com 135c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com#include <new> 145c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 15607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 1646f935002c2b25331e552520dc7b1a912e12dfdcrobertphillips@google.com// 0-2 are reserved for invalid, empty & wide-open 17edb26fdb8349a727b226e90cbeab06cd25f5cac0bsalomon@google.comstatic const int32_t kFirstUnreservedGenID = 3; 18edb26fdb8349a727b226e90cbeab06cd25f5cac0bsalomon@google.comint32_t SkClipStack::gGenID = kFirstUnreservedGenID; 1946f935002c2b25331e552520dc7b1a912e12dfdcrobertphillips@google.com 206f954b956fc5c36ebbcac404d93ba9349fb0355fcommit-bot@chromium.orgSkClipStack::Element::Element(const Element& that) { 216f954b956fc5c36ebbcac404d93ba9349fb0355fcommit-bot@chromium.org switch (that.getType()) { 226f954b956fc5c36ebbcac404d93ba9349fb0355fcommit-bot@chromium.org case kEmpty_Type: 236f954b956fc5c36ebbcac404d93ba9349fb0355fcommit-bot@chromium.org fPath.reset(); 246f954b956fc5c36ebbcac404d93ba9349fb0355fcommit-bot@chromium.org break; 256f954b956fc5c36ebbcac404d93ba9349fb0355fcommit-bot@chromium.org case kRect_Type: // Rect uses rrect 266f954b956fc5c36ebbcac404d93ba9349fb0355fcommit-bot@chromium.org case kRRect_Type: 276f954b956fc5c36ebbcac404d93ba9349fb0355fcommit-bot@chromium.org fPath.reset(); 286f954b956fc5c36ebbcac404d93ba9349fb0355fcommit-bot@chromium.org fRRect = that.fRRect; 296f954b956fc5c36ebbcac404d93ba9349fb0355fcommit-bot@chromium.org break; 306f954b956fc5c36ebbcac404d93ba9349fb0355fcommit-bot@chromium.org case kPath_Type: 316f954b956fc5c36ebbcac404d93ba9349fb0355fcommit-bot@chromium.org fPath.set(that.getPath()); 326f954b956fc5c36ebbcac404d93ba9349fb0355fcommit-bot@chromium.org break; 336f954b956fc5c36ebbcac404d93ba9349fb0355fcommit-bot@chromium.org } 346f954b956fc5c36ebbcac404d93ba9349fb0355fcommit-bot@chromium.org 356f954b956fc5c36ebbcac404d93ba9349fb0355fcommit-bot@chromium.org fSaveCount = that.fSaveCount; 366f954b956fc5c36ebbcac404d93ba9349fb0355fcommit-bot@chromium.org fOp = that.fOp; 376f954b956fc5c36ebbcac404d93ba9349fb0355fcommit-bot@chromium.org fType = that.fType; 386f954b956fc5c36ebbcac404d93ba9349fb0355fcommit-bot@chromium.org fDoAA = that.fDoAA; 396f954b956fc5c36ebbcac404d93ba9349fb0355fcommit-bot@chromium.org fFiniteBoundType = that.fFiniteBoundType; 406f954b956fc5c36ebbcac404d93ba9349fb0355fcommit-bot@chromium.org fFiniteBound = that.fFiniteBound; 416f954b956fc5c36ebbcac404d93ba9349fb0355fcommit-bot@chromium.org fIsIntersectionOfRects = that.fIsIntersectionOfRects; 426f954b956fc5c36ebbcac404d93ba9349fb0355fcommit-bot@chromium.org fGenID = that.fGenID; 436f954b956fc5c36ebbcac404d93ba9349fb0355fcommit-bot@chromium.org} 446f954b956fc5c36ebbcac404d93ba9349fb0355fcommit-bot@chromium.org 45e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.orgbool SkClipStack::Element::operator== (const Element& element) const { 46e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org if (this == &element) { 47e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org return true; 48e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org } 49e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org if (fOp != element.fOp || 50e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org fType != element.fType || 51e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org fDoAA != element.fDoAA || 52e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org fSaveCount != element.fSaveCount) { 53e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org return false; 54e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org } 55e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org switch (fType) { 56e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org case kPath_Type: 576f954b956fc5c36ebbcac404d93ba9349fb0355fcommit-bot@chromium.org return this->getPath() == element.getPath(); 58e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org case kRRect_Type: 59e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org return fRRect == element.fRRect; 60e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org case kRect_Type: 61032a52fd4ceda001e44b80ff0462b570817bfe6fcommit-bot@chromium.org return this->getRect() == element.getRect(); 62e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org case kEmpty_Type: 63e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org return true; 64e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org default: 65e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org SkDEBUGFAIL("Unexpected type."); 66e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org return false; 67e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org } 68e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org} 69e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org 70c3b589a24eb4d567a906189f882c259ecf5c2f58fmalitavoid SkClipStack::Element::replay(SkCanvasClipVisitor* visitor) const { 71c3b589a24eb4d567a906189f882c259ecf5c2f58fmalita static const SkRect kEmptyRect = { 0, 0, 0, 0 }; 72c3b589a24eb4d567a906189f882c259ecf5c2f58fmalita 73c3b589a24eb4d567a906189f882c259ecf5c2f58fmalita switch (fType) { 74c3b589a24eb4d567a906189f882c259ecf5c2f58fmalita case kPath_Type: 75c3b589a24eb4d567a906189f882c259ecf5c2f58fmalita visitor->clipPath(this->getPath(), this->getOp(), this->isAA()); 76c3b589a24eb4d567a906189f882c259ecf5c2f58fmalita break; 77c3b589a24eb4d567a906189f882c259ecf5c2f58fmalita case kRRect_Type: 78c3b589a24eb4d567a906189f882c259ecf5c2f58fmalita visitor->clipRRect(this->getRRect(), this->getOp(), this->isAA()); 79c3b589a24eb4d567a906189f882c259ecf5c2f58fmalita break; 80c3b589a24eb4d567a906189f882c259ecf5c2f58fmalita case kRect_Type: 81c3b589a24eb4d567a906189f882c259ecf5c2f58fmalita visitor->clipRect(this->getRect(), this->getOp(), this->isAA()); 82c3b589a24eb4d567a906189f882c259ecf5c2f58fmalita break; 83c3b589a24eb4d567a906189f882c259ecf5c2f58fmalita case kEmpty_Type: 84c3b589a24eb4d567a906189f882c259ecf5c2f58fmalita visitor->clipRect(kEmptyRect, SkRegion::kIntersect_Op, false); 85c3b589a24eb4d567a906189f882c259ecf5c2f58fmalita break; 86c3b589a24eb4d567a906189f882c259ecf5c2f58fmalita } 87c3b589a24eb4d567a906189f882c259ecf5c2f58fmalita} 88c3b589a24eb4d567a906189f882c259ecf5c2f58fmalita 89c6b3e48cb3a22d83ba3f4b9a614a5a35b05958a0bsalomon@google.comvoid SkClipStack::Element::invertShapeFillType() { 90c6b3e48cb3a22d83ba3f4b9a614a5a35b05958a0bsalomon@google.com switch (fType) { 91c6b3e48cb3a22d83ba3f4b9a614a5a35b05958a0bsalomon@google.com case kRect_Type: 926f954b956fc5c36ebbcac404d93ba9349fb0355fcommit-bot@chromium.org fPath.init(); 936f954b956fc5c36ebbcac404d93ba9349fb0355fcommit-bot@chromium.org fPath.get()->addRect(this->getRect()); 946f954b956fc5c36ebbcac404d93ba9349fb0355fcommit-bot@chromium.org fPath.get()->setFillType(SkPath::kInverseEvenOdd_FillType); 95e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org fType = kPath_Type; 96e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org break; 97e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org case kRRect_Type: 986f954b956fc5c36ebbcac404d93ba9349fb0355fcommit-bot@chromium.org fPath.init(); 996f954b956fc5c36ebbcac404d93ba9349fb0355fcommit-bot@chromium.org fPath.get()->addRRect(fRRect); 1006f954b956fc5c36ebbcac404d93ba9349fb0355fcommit-bot@chromium.org fPath.get()->setFillType(SkPath::kInverseEvenOdd_FillType); 101c6b3e48cb3a22d83ba3f4b9a614a5a35b05958a0bsalomon@google.com fType = kPath_Type; 102c6b3e48cb3a22d83ba3f4b9a614a5a35b05958a0bsalomon@google.com break; 103c6b3e48cb3a22d83ba3f4b9a614a5a35b05958a0bsalomon@google.com case kPath_Type: 1046f954b956fc5c36ebbcac404d93ba9349fb0355fcommit-bot@chromium.org fPath.get()->toggleInverseFillType(); 105e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org break; 106c6b3e48cb3a22d83ba3f4b9a614a5a35b05958a0bsalomon@google.com case kEmpty_Type: 107e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org // Should this set to an empty, inverse filled path? 108e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org break; 109e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org } 110e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org} 111e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org 112e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.orgvoid SkClipStack::Element::initPath(int saveCount, const SkPath& path, SkRegion::Op op, 113e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org bool doAA) { 114e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org if (!path.isInverseFillType()) { 115e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org if (SkPath::kNone_PathAsRect != path.asRect()) { 116e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org this->initRect(saveCount, path.getBounds(), op, doAA); 117e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org return; 118e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org } 119e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org SkRect ovalRect; 120e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org if (path.isOval(&ovalRect)) { 121e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org SkRRect rrect; 122e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org rrect.setOval(ovalRect); 123e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org this->initRRect(saveCount, rrect, op, doAA); 124e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org return; 125e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org } 126e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org } 1276f954b956fc5c36ebbcac404d93ba9349fb0355fcommit-bot@chromium.org fPath.set(path); 128e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org fType = kPath_Type; 129e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org this->initCommon(saveCount, op, doAA); 130e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org} 131e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org 132e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.orgvoid SkClipStack::Element::asPath(SkPath* path) const { 133e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org switch (fType) { 134e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org case kEmpty_Type: 135e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org path->reset(); 136e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org break; 137e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org case kRect_Type: 138e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org path->reset(); 139032a52fd4ceda001e44b80ff0462b570817bfe6fcommit-bot@chromium.org path->addRect(this->getRect()); 140e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org break; 141e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org case kRRect_Type: 142e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org path->reset(); 143e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org path->addRRect(fRRect); 144e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org break; 145e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org case kPath_Type: 1466f954b956fc5c36ebbcac404d93ba9349fb0355fcommit-bot@chromium.org *path = *fPath.get(); 147c6b3e48cb3a22d83ba3f4b9a614a5a35b05958a0bsalomon@google.com break; 148c6b3e48cb3a22d83ba3f4b9a614a5a35b05958a0bsalomon@google.com } 149c6b3e48cb3a22d83ba3f4b9a614a5a35b05958a0bsalomon@google.com} 150c6b3e48cb3a22d83ba3f4b9a614a5a35b05958a0bsalomon@google.com 1519cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.orgvoid SkClipStack::Element::setEmpty() { 1529cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org fType = kEmpty_Type; 1539cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org fFiniteBound.setEmpty(); 1549cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org fFiniteBoundType = kNormal_BoundsType; 1559cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org fIsIntersectionOfRects = false; 1569cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org fRRect.setEmpty(); 1579cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org fPath.reset(); 1589cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org fGenID = kEmptyGenID; 1599cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org SkDEBUGCODE(this->checkEmpty();) 1609cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org} 1619cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org 1628a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.comvoid SkClipStack::Element::checkEmpty() const { 1638a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com SkASSERT(fFiniteBound.isEmpty()); 1648a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com SkASSERT(kNormal_BoundsType == fFiniteBoundType); 1658a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com SkASSERT(!fIsIntersectionOfRects); 1668a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com SkASSERT(kEmptyGenID == fGenID); 1676f954b956fc5c36ebbcac404d93ba9349fb0355fcommit-bot@chromium.org SkASSERT(!fPath.isValid()); 1688a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com} 1698a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com 1708a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.combool SkClipStack::Element::canBeIntersectedInPlace(int saveCount, SkRegion::Op op) const { 1718a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com if (kEmpty_Type == fType && 1728a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com (SkRegion::kDifference_Op == op || SkRegion::kIntersect_Op == op)) { 1738a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com return true; 17446f935002c2b25331e552520dc7b1a912e12dfdcrobertphillips@google.com } 1758a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // Only clips within the same save/restore frame (as captured by 1768a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // the save count) can be merged 1778a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com return fSaveCount == saveCount && 1788a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com SkRegion::kIntersect_Op == op && 1798a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com (SkRegion::kIntersect_Op == fOp || SkRegion::kReplace_Op == fOp); 1808a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com} 1818a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com 1828a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.combool SkClipStack::Element::rectRectIntersectAllowed(const SkRect& newR, bool newAA) const { 1838a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com SkASSERT(kRect_Type == fType); 1848a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com 1858a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com if (fDoAA == newAA) { 1868a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // if the AA setting is the same there is no issue 1878a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com return true; 18808eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com } 18908eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 190032a52fd4ceda001e44b80ff0462b570817bfe6fcommit-bot@chromium.org if (!SkRect::Intersects(this->getRect(), newR)) { 1918a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // The calling code will correctly set the result to the empty clip 1928a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com return true; 1931e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org } 1941e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org 195032a52fd4ceda001e44b80ff0462b570817bfe6fcommit-bot@chromium.org if (this->getRect().contains(newR)) { 1968a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // if the new rect carves out a portion of the old one there is no 1978a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // issue 1988a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com return true; 1991e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org } 2001e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org 2018a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // So either the two overlap in some complex manner or newR contains oldR. 2028a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // In the first, case the edges will require different AA. In the second, 2038a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // the AA setting that would be carried forward is incorrect (e.g., oldR 2048a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // is AA while newR is BW but since newR contains oldR, oldR will be 2058a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // drawn BW) since the new AA setting will predominate. 2068a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com return false; 2078a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com} 2088a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com 2098a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com// a mirror of combineBoundsRevDiff 2108a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.comvoid SkClipStack::Element::combineBoundsDiff(FillCombo combination, const SkRect& prevFinite) { 2118a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com switch (combination) { 2128a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com case kInvPrev_InvCur_FillCombo: 2138a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // In this case the only pixels that can remain set 2148a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // are inside the current clip rect since the extensions 2158a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // to infinity of both clips cancel out and whatever 2168a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // is outside of the current clip is removed 2178a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com fFiniteBoundType = kNormal_BoundsType; 2188a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com break; 2198a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com case kInvPrev_Cur_FillCombo: 2208a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // In this case the current op is finite so the only pixels 2218a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // that aren't set are whatever isn't set in the previous 2228a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // clip and whatever this clip carves out 2238a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com fFiniteBound.join(prevFinite); 2248a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com fFiniteBoundType = kInsideOut_BoundsType; 2258a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com break; 2268a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com case kPrev_InvCur_FillCombo: 2278a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // In this case everything outside of this clip's bound 2288a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // is erased, so the only pixels that can remain set 2298a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // occur w/in the intersection of the two finite bounds 2308a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com if (!fFiniteBound.intersect(prevFinite)) { 231e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org this->setEmpty(); 232e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org } else { 233e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org fFiniteBoundType = kNormal_BoundsType; 2348a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com } 2358a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com break; 2368a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com case kPrev_Cur_FillCombo: 2378a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // The most conservative result bound is that of the 2388a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // prior clip. This could be wildly incorrect if the 2398a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // second clip either exactly matches the first clip 2408a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // (which should yield the empty set) or reduces the 2418a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // size of the prior bound (e.g., if the second clip 2428a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // exactly matched the bottom half of the prior clip). 2438a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // We ignore these two possibilities. 2448a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com fFiniteBound = prevFinite; 2458a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com break; 2468a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com default: 2478a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com SkDEBUGFAIL("SkClipStack::Element::combineBoundsDiff Invalid fill combination"); 2488a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com break; 24908eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com } 2508a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com} 2518a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com 2528a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.comvoid SkClipStack::Element::combineBoundsXOR(int combination, const SkRect& prevFinite) { 2538a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com 2548a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com switch (combination) { 2558a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com case kInvPrev_Cur_FillCombo: // fall through 2568a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com case kPrev_InvCur_FillCombo: 2578a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // With only one of the clips inverted the result will always 2588a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // extend to infinity. The only pixels that may be un-writeable 2598a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // lie within the union of the two finite bounds 2608a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com fFiniteBound.join(prevFinite); 2618a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com fFiniteBoundType = kInsideOut_BoundsType; 2628a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com break; 2638a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com case kInvPrev_InvCur_FillCombo: 2648a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // The only pixels that can survive are within the 2658a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // union of the two bounding boxes since the extensions 2668a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // to infinity of both clips cancel out 2678a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // fall through! 2688a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com case kPrev_Cur_FillCombo: 2698a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // The most conservative bound for xor is the 2708a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // union of the two bounds. If the two clips exactly overlapped 2718a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // the xor could yield the empty set. Similarly the xor 2728a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // could reduce the size of the original clip's bound (e.g., 2738a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // if the second clip exactly matched the bottom half of the 2748a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // first clip). We ignore these two cases. 2758a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com fFiniteBound.join(prevFinite); 2768a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com fFiniteBoundType = kNormal_BoundsType; 2778a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com break; 2788a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com default: 2798a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com SkDEBUGFAIL("SkClipStack::Element::combineBoundsXOR Invalid fill combination"); 2808a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com break; 2815c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com } 2828a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com} 283607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 2848a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com// a mirror of combineBoundsIntersection 2858a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.comvoid SkClipStack::Element::combineBoundsUnion(int combination, const SkRect& prevFinite) { 28608eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 2878a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com switch (combination) { 2888a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com case kInvPrev_InvCur_FillCombo: 2898a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com if (!fFiniteBound.intersect(prevFinite)) { 2908a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com fFiniteBound.setEmpty(); 2918a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com fGenID = kWideOpenGenID; 2928a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com } 2938a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com fFiniteBoundType = kInsideOut_BoundsType; 2948a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com break; 2958a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com case kInvPrev_Cur_FillCombo: 2968a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // The only pixels that won't be drawable are inside 2978a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // the prior clip's finite bound 2988a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com fFiniteBound = prevFinite; 2998a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com fFiniteBoundType = kInsideOut_BoundsType; 3008a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com break; 3018a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com case kPrev_InvCur_FillCombo: 3028a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // The only pixels that won't be drawable are inside 3038a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // this clip's finite bound 3048a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com break; 3058a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com case kPrev_Cur_FillCombo: 3068a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com fFiniteBound.join(prevFinite); 3078a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com break; 3088a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com default: 3098a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com SkDEBUGFAIL("SkClipStack::Element::combineBoundsUnion Invalid fill combination"); 3108a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com break; 311607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com } 3128a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com} 3138a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com 3148a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com// a mirror of combineBoundsUnion 3158a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.comvoid SkClipStack::Element::combineBoundsIntersection(int combination, const SkRect& prevFinite) { 3168a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com 3178a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com switch (combination) { 3188a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com case kInvPrev_InvCur_FillCombo: 3198a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // The only pixels that aren't writable in this case 3208a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // occur in the union of the two finite bounds 3218a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com fFiniteBound.join(prevFinite); 3228a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com fFiniteBoundType = kInsideOut_BoundsType; 3238a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com break; 3248a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com case kInvPrev_Cur_FillCombo: 3258a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // In this case the only pixels that will remain writeable 3268a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // are within the current clip 3278a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com break; 3288a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com case kPrev_InvCur_FillCombo: 3298a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // In this case the only pixels that will remain writeable 3308a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // are with the previous clip 3318a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com fFiniteBound = prevFinite; 3328a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com fFiniteBoundType = kNormal_BoundsType; 3338a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com break; 3348a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com case kPrev_Cur_FillCombo: 3358a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com if (!fFiniteBound.intersect(prevFinite)) { 336e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org this->setEmpty(); 3378a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com } 3388a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com break; 3398a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com default: 3408a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com SkDEBUGFAIL("SkClipStack::Element::combineBoundsIntersection Invalid fill combination"); 3418a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com break; 342607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com } 3438a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com} 344607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 3458a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com// a mirror of combineBoundsDiff 3468a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.comvoid SkClipStack::Element::combineBoundsRevDiff(int combination, const SkRect& prevFinite) { 347607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 3488a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com switch (combination) { 3498a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com case kInvPrev_InvCur_FillCombo: 3508a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // The only pixels that can survive are in the 3518a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // previous bound since the extensions to infinity in 3528a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // both clips cancel out 3538a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com fFiniteBound = prevFinite; 3548a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com fFiniteBoundType = kNormal_BoundsType; 3558a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com break; 3568a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com case kInvPrev_Cur_FillCombo: 3578a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com if (!fFiniteBound.intersect(prevFinite)) { 358e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org this->setEmpty(); 359e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org } else { 360e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org fFiniteBoundType = kNormal_BoundsType; 3618a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com } 3628a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com break; 3638a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com case kPrev_InvCur_FillCombo: 3648a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com fFiniteBound.join(prevFinite); 3658a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com fFiniteBoundType = kInsideOut_BoundsType; 3668a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com break; 3678a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com case kPrev_Cur_FillCombo: 3688a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // Fall through - as with the kDifference_Op case, the 3698a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // most conservative result bound is the bound of the 3708a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // current clip. The prior clip could reduce the size of this 3718a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // bound (as in the kDifference_Op case) but we are ignoring 3728a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // those cases. 3738a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com break; 3748a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com default: 3758a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com SkDEBUGFAIL("SkClipStack::Element::combineBoundsRevDiff Invalid fill combination"); 3768a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com break; 377607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com } 3788a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com} 3798a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com 3808a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.comvoid SkClipStack::Element::updateBoundAndGenID(const Element* prior) { 3818a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // We set this first here but we may overwrite it later if we determine that the clip is 3828a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // either wide-open or empty. 3838a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com fGenID = GetNextGenID(); 3848a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com 3858a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // First, optimistically update the current Element's bound information 3868a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // with the current clip's bound 3878a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com fIsIntersectionOfRects = false; 388e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org switch (fType) { 389e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org case kRect_Type: 390032a52fd4ceda001e44b80ff0462b570817bfe6fcommit-bot@chromium.org fFiniteBound = this->getRect(); 391e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org fFiniteBoundType = kNormal_BoundsType; 3924c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com 393e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org if (SkRegion::kReplace_Op == fOp || 394e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org (SkRegion::kIntersect_Op == fOp && NULL == prior) || 395e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org (SkRegion::kIntersect_Op == fOp && prior->fIsIntersectionOfRects && 396032a52fd4ceda001e44b80ff0462b570817bfe6fcommit-bot@chromium.org prior->rectRectIntersectAllowed(this->getRect(), fDoAA))) { 397e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org fIsIntersectionOfRects = true; 398e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org } 399e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org break; 400e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org case kRRect_Type: 401e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org fFiniteBound = fRRect.getBounds(); 4028a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com fFiniteBoundType = kNormal_BoundsType; 403e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org break; 404e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org case kPath_Type: 4056f954b956fc5c36ebbcac404d93ba9349fb0355fcommit-bot@chromium.org fFiniteBound = fPath.get()->getBounds(); 406e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org 4076f954b956fc5c36ebbcac404d93ba9349fb0355fcommit-bot@chromium.org if (fPath.get()->isInverseFillType()) { 408e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org fFiniteBoundType = kInsideOut_BoundsType; 409e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org } else { 410e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org fFiniteBoundType = kNormal_BoundsType; 411e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org } 412e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org break; 413e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org case kEmpty_Type: 414e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org SkDEBUGFAIL("We shouldn't get here with an empty element."); 415e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org break; 4168a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com } 417607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 4188a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com if (!fDoAA) { 4198a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // Here we mimic a non-anti-aliased scanline system. If there is 4208a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // no anti-aliasing we can integerize the bounding box to exclude 4218a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // fractional parts that won't be rendered. 4228a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // Note: the left edge is handled slightly differently below. We 4238a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // are a bit more generous in the rounding since we don't want to 4248a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // risk missing the left pixels when fLeft is very close to .5 425e1ca705cac4b946993f6cbf798e2a0ba27e739f3reed@google.com fFiniteBound.set(SkScalarFloorToScalar(fFiniteBound.fLeft+0.45f), 426e1ca705cac4b946993f6cbf798e2a0ba27e739f3reed@google.com SkScalarRoundToScalar(fFiniteBound.fTop), 427e1ca705cac4b946993f6cbf798e2a0ba27e739f3reed@google.com SkScalarRoundToScalar(fFiniteBound.fRight), 428e1ca705cac4b946993f6cbf798e2a0ba27e739f3reed@google.com SkScalarRoundToScalar(fFiniteBound.fBottom)); 4298a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com } 430607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 4318a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // Now determine the previous Element's bound information taking into 4328a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // account that there may be no previous clip 4338a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com SkRect prevFinite; 4348a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com SkClipStack::BoundsType prevType; 4358a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com 4368a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com if (NULL == prior) { 4378a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // no prior clip means the entire plane is writable 4388a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com prevFinite.setEmpty(); // there are no pixels that cannot be drawn to 4398a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com prevType = kInsideOut_BoundsType; 4408a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com } else { 4418a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com prevFinite = prior->fFiniteBound; 4428a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com prevType = prior->fFiniteBoundType; 4438a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com } 444607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 4458a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com FillCombo combination = kPrev_Cur_FillCombo; 4468a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com if (kInsideOut_BoundsType == fFiniteBoundType) { 4478a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com combination = (FillCombo) (combination | 0x01); 4488a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com } 4498a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com if (kInsideOut_BoundsType == prevType) { 4508a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com combination = (FillCombo) (combination | 0x02); 4518a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com } 452607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 4538a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com SkASSERT(kInvPrev_InvCur_FillCombo == combination || 4548a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com kInvPrev_Cur_FillCombo == combination || 4558a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com kPrev_InvCur_FillCombo == combination || 4568a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com kPrev_Cur_FillCombo == combination); 4578a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com 4588a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // Now integrate with clip with the prior clips 4598a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com switch (fOp) { 4608a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com case SkRegion::kDifference_Op: 4618a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com this->combineBoundsDiff(combination, prevFinite); 4628a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com break; 4638a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com case SkRegion::kXOR_Op: 4648a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com this->combineBoundsXOR(combination, prevFinite); 4658a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com break; 4668a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com case SkRegion::kUnion_Op: 4678a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com this->combineBoundsUnion(combination, prevFinite); 4688a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com break; 4698a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com case SkRegion::kIntersect_Op: 4708a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com this->combineBoundsIntersection(combination, prevFinite); 4718a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com break; 4728a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com case SkRegion::kReverseDifference_Op: 4738a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com this->combineBoundsRevDiff(combination, prevFinite); 4748a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com break; 4758a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com case SkRegion::kReplace_Op: 4768a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // Replace just ignores everything prior 4778a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // The current clip's bound information is already filled in 4788a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // so nothing to do 4798a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com break; 4808a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com default: 481e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org SkDebugf("SkRegion::Op error\n"); 4828a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com SkASSERT(0); 4838a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com break; 484607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com } 4858a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com} 4865c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 4879128edc700ce1b722f1290c585af829542f98a33bsalomon@google.com// This constant determines how many Element's are allocated together as a block in 488f9a90847820a8ec4a3c97a2b544c622e3ca6b09arobertphillips@google.com// the deque. As such it needs to balance allocating too much memory vs. 489f9a90847820a8ec4a3c97a2b544c622e3ca6b09arobertphillips@google.com// incurring allocation/deallocation thrashing. It should roughly correspond to 490f9a90847820a8ec4a3c97a2b544c622e3ca6b09arobertphillips@google.com// the deepest save/restore stack we expect to see. 4919128edc700ce1b722f1290c585af829542f98a33bsalomon@google.comstatic const int kDefaultElementAllocCnt = 8; 49246f935002c2b25331e552520dc7b1a912e12dfdcrobertphillips@google.com 493fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.comSkClipStack::SkClipStack() 4949128edc700ce1b722f1290c585af829542f98a33bsalomon@google.com : fDeque(sizeof(Element), kDefaultElementAllocCnt) 49546f935002c2b25331e552520dc7b1a912e12dfdcrobertphillips@google.com , fSaveCount(0) { 4965c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com} 4975c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 498fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.comSkClipStack::SkClipStack(const SkClipStack& b) 4999128edc700ce1b722f1290c585af829542f98a33bsalomon@google.com : fDeque(sizeof(Element), kDefaultElementAllocCnt) { 5001e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org *this = b; 5011e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org} 5021e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org 503fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.comSkClipStack::SkClipStack(const SkRect& r) 5049128edc700ce1b722f1290c585af829542f98a33bsalomon@google.com : fDeque(sizeof(Element), kDefaultElementAllocCnt) 50546f935002c2b25331e552520dc7b1a912e12dfdcrobertphillips@google.com , fSaveCount(0) { 506cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com if (!r.isEmpty()) { 507cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com this->clipDevRect(r, SkRegion::kReplace_Op, false); 508cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com } 509cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com} 510cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 511fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.comSkClipStack::SkClipStack(const SkIRect& r) 5129128edc700ce1b722f1290c585af829542f98a33bsalomon@google.com : fDeque(sizeof(Element), kDefaultElementAllocCnt) 51346f935002c2b25331e552520dc7b1a912e12dfdcrobertphillips@google.com , fSaveCount(0) { 514641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com if (!r.isEmpty()) { 515641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com SkRect temp; 516641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com temp.set(r); 517641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com this->clipDevRect(temp, SkRegion::kReplace_Op, false); 518641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com } 519641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com} 520641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com 521610f716b00f214e4899a102c1bbc1d6a323e114evandebo@chromium.orgSkClipStack::~SkClipStack() { 522610f716b00f214e4899a102c1bbc1d6a323e114evandebo@chromium.org reset(); 523610f716b00f214e4899a102c1bbc1d6a323e114evandebo@chromium.org} 524610f716b00f214e4899a102c1bbc1d6a323e114evandebo@chromium.org 5251e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.orgSkClipStack& SkClipStack::operator=(const SkClipStack& b) { 5261e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org if (this == &b) { 5271e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org return *this; 5281e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org } 5291e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org reset(); 5301e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org 5311e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org fSaveCount = b.fSaveCount; 5321e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org SkDeque::F2BIter recIter(b.fDeque); 5339128edc700ce1b722f1290c585af829542f98a33bsalomon@google.com for (const Element* element = (const Element*)recIter.next(); 5349128edc700ce1b722f1290c585af829542f98a33bsalomon@google.com element != NULL; 5359128edc700ce1b722f1290c585af829542f98a33bsalomon@google.com element = (const Element*)recIter.next()) { 5369128edc700ce1b722f1290c585af829542f98a33bsalomon@google.com new (fDeque.push_back()) Element(*element); 5371e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org } 5381e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org 5391e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org return *this; 5401e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org} 5411e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org 5421e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.orgbool SkClipStack::operator==(const SkClipStack& b) const { 54386b39f311e174ddbd0d2f8de8d18dd45a8a2334fcommit-bot@chromium.org if (this->getTopmostGenID() == b.getTopmostGenID()) { 54486b39f311e174ddbd0d2f8de8d18dd45a8a2334fcommit-bot@chromium.org return true; 54586b39f311e174ddbd0d2f8de8d18dd45a8a2334fcommit-bot@chromium.org } 546fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com if (fSaveCount != b.fSaveCount || 54746f935002c2b25331e552520dc7b1a912e12dfdcrobertphillips@google.com fDeque.count() != b.fDeque.count()) { 5481e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org return false; 5491e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org } 5501e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org SkDeque::F2BIter myIter(fDeque); 5511e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org SkDeque::F2BIter bIter(b.fDeque); 5529128edc700ce1b722f1290c585af829542f98a33bsalomon@google.com const Element* myElement = (const Element*)myIter.next(); 5539128edc700ce1b722f1290c585af829542f98a33bsalomon@google.com const Element* bElement = (const Element*)bIter.next(); 5541e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org 5559128edc700ce1b722f1290c585af829542f98a33bsalomon@google.com while (myElement != NULL && bElement != NULL) { 5569128edc700ce1b722f1290c585af829542f98a33bsalomon@google.com if (*myElement != *bElement) { 5571e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org return false; 5581e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org } 5599128edc700ce1b722f1290c585af829542f98a33bsalomon@google.com myElement = (const Element*)myIter.next(); 5609128edc700ce1b722f1290c585af829542f98a33bsalomon@google.com bElement = (const Element*)bIter.next(); 5611e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org } 5629128edc700ce1b722f1290c585af829542f98a33bsalomon@google.com return myElement == NULL && bElement == NULL; 5631e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org} 5641e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org 5655c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.comvoid SkClipStack::reset() { 566610f716b00f214e4899a102c1bbc1d6a323e114evandebo@chromium.org // We used a placement new for each object in fDeque, so we're responsible 567610f716b00f214e4899a102c1bbc1d6a323e114evandebo@chromium.org // for calling the destructor on each of them as well. 568610f716b00f214e4899a102c1bbc1d6a323e114evandebo@chromium.org while (!fDeque.empty()) { 5699128edc700ce1b722f1290c585af829542f98a33bsalomon@google.com Element* element = (Element*)fDeque.back(); 5709128edc700ce1b722f1290c585af829542f98a33bsalomon@google.com element->~Element(); 571610f716b00f214e4899a102c1bbc1d6a323e114evandebo@chromium.org fDeque.pop_back(); 572610f716b00f214e4899a102c1bbc1d6a323e114evandebo@chromium.org } 5735c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 5745c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com fSaveCount = 0; 5755c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com} 5765c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 5775c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.comvoid SkClipStack::save() { 5785c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com fSaveCount += 1; 5795c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com} 5805c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 5815c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.comvoid SkClipStack::restore() { 5825c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com fSaveCount -= 1; 5836fbe54c663bd0eed6f6519c31a4c8e291db2613bcommit-bot@chromium.org restoreTo(fSaveCount); 5846fbe54c663bd0eed6f6519c31a4c8e291db2613bcommit-bot@chromium.org} 5856fbe54c663bd0eed6f6519c31a4c8e291db2613bcommit-bot@chromium.org 5866fbe54c663bd0eed6f6519c31a4c8e291db2613bcommit-bot@chromium.orgvoid SkClipStack::restoreTo(int saveCount) { 5875c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com while (!fDeque.empty()) { 5889128edc700ce1b722f1290c585af829542f98a33bsalomon@google.com Element* element = (Element*)fDeque.back(); 5896fbe54c663bd0eed6f6519c31a4c8e291db2613bcommit-bot@chromium.org if (element->fSaveCount <= saveCount) { 5905c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com break; 5915c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com } 5929128edc700ce1b722f1290c585af829542f98a33bsalomon@google.com element->~Element(); 5935c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com fDeque.pop_back(); 5945c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com } 5955c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com} 5965c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 597fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.comvoid SkClipStack::getBounds(SkRect* canvFiniteBound, 5984c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com BoundsType* boundType, 5994c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com bool* isIntersectionOfRects) const { 60049f085dddff10473b6ebf832a974288300224e60bsalomon SkASSERT(canvFiniteBound && boundType); 601607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 6029128edc700ce1b722f1290c585af829542f98a33bsalomon@google.com Element* element = (Element*)fDeque.back(); 603607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 6049128edc700ce1b722f1290c585af829542f98a33bsalomon@google.com if (NULL == element) { 605607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com // the clip is wide open - the infinite plane w/ no pixels un-writeable 6067b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com canvFiniteBound->setEmpty(); 607607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com *boundType = kInsideOut_BoundsType; 60849f085dddff10473b6ebf832a974288300224e60bsalomon if (isIntersectionOfRects) { 6094c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com *isIntersectionOfRects = false; 6104c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com } 611607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com return; 612607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com } 613607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 6149128edc700ce1b722f1290c585af829542f98a33bsalomon@google.com *canvFiniteBound = element->fFiniteBound; 6159128edc700ce1b722f1290c585af829542f98a33bsalomon@google.com *boundType = element->fFiniteBoundType; 61649f085dddff10473b6ebf832a974288300224e60bsalomon if (isIntersectionOfRects) { 6179128edc700ce1b722f1290c585af829542f98a33bsalomon@google.com *isIntersectionOfRects = element->fIsIntersectionOfRects; 6184c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com } 619607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com} 620607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 6213ab43d5c5b4d77f46dd0266618f92e5fefce2021bsalomon@google.combool SkClipStack::intersectRectWithClip(SkRect* rect) const { 62249f085dddff10473b6ebf832a974288300224e60bsalomon SkASSERT(rect); 6233ab43d5c5b4d77f46dd0266618f92e5fefce2021bsalomon@google.com 6243ab43d5c5b4d77f46dd0266618f92e5fefce2021bsalomon@google.com SkRect bounds; 6253ab43d5c5b4d77f46dd0266618f92e5fefce2021bsalomon@google.com SkClipStack::BoundsType bt; 6263ab43d5c5b4d77f46dd0266618f92e5fefce2021bsalomon@google.com this->getBounds(&bounds, &bt); 6273ab43d5c5b4d77f46dd0266618f92e5fefce2021bsalomon@google.com if (bt == SkClipStack::kInsideOut_BoundsType) { 6283ab43d5c5b4d77f46dd0266618f92e5fefce2021bsalomon@google.com if (bounds.contains(*rect)) { 6293ab43d5c5b4d77f46dd0266618f92e5fefce2021bsalomon@google.com return false; 6303ab43d5c5b4d77f46dd0266618f92e5fefce2021bsalomon@google.com } else { 6313ab43d5c5b4d77f46dd0266618f92e5fefce2021bsalomon@google.com // If rect's x values are both within bound's x range we 6323ab43d5c5b4d77f46dd0266618f92e5fefce2021bsalomon@google.com // could clip here. Same for y. But we don't bother to check. 6333ab43d5c5b4d77f46dd0266618f92e5fefce2021bsalomon@google.com return true; 6343ab43d5c5b4d77f46dd0266618f92e5fefce2021bsalomon@google.com } 6355b6f91643d3ad1bdcdd65329d656f0fc43174be3skia.committer@gmail.com } else { 6363ab43d5c5b4d77f46dd0266618f92e5fefce2021bsalomon@google.com return rect->intersect(bounds); 6373ab43d5c5b4d77f46dd0266618f92e5fefce2021bsalomon@google.com } 6383ab43d5c5b4d77f46dd0266618f92e5fefce2021bsalomon@google.com} 6393ab43d5c5b4d77f46dd0266618f92e5fefce2021bsalomon@google.com 6408cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.orgbool SkClipStack::quickContains(const SkRect& rect) const { 6418cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org 6428cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org Iter iter(*this, Iter::kTop_IterStart); 6438cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org const Element* element = iter.prev(); 6448cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org while (element != NULL) { 6458cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org if (SkRegion::kIntersect_Op != element->getOp() && SkRegion::kReplace_Op != element->getOp()) 6468cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org return false; 6478cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org if (element->isInverseFilled()) { 6488cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org // Part of 'rect' could be trimmed off by the inverse-filled clip element 6498cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org if (SkRect::Intersects(element->getBounds(), rect)) { 6508cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org return false; 6518cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org } 6528cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org } else { 6538cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org if (!element->contains(rect)) { 6548cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org return false; 6558cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org } 6568cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org } 6578cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org if (SkRegion::kReplace_Op == element->getOp()) { 6588cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org break; 6598cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org } 6608cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org element = iter.prev(); 6618cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org } 6628cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org return true; 6638cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org} 6648cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org 665e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.orgvoid SkClipStack::pushElement(const Element& element) { 66663ae1cfb10d0d14722df59cba0012f8a4370c090robertphillips@google.com // Use reverse iterator instead of back because Rect path may need previous 6674c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com SkDeque::Iter iter(fDeque, SkDeque::Iter::kBack_IterStart); 668e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org Element* prior = (Element*) iter.prev(); 6694c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com 67049f085dddff10473b6ebf832a974288300224e60bsalomon if (prior) { 671e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org if (prior->canBeIntersectedInPlace(fSaveCount, element.getOp())) { 672e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org switch (prior->fType) { 6736fbe54c663bd0eed6f6519c31a4c8e291db2613bcommit-bot@chromium.org case Element::kEmpty_Type: 674e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org SkDEBUGCODE(prior->checkEmpty();) 6756fbe54c663bd0eed6f6519c31a4c8e291db2613bcommit-bot@chromium.org return; 6766fbe54c663bd0eed6f6519c31a4c8e291db2613bcommit-bot@chromium.org case Element::kRect_Type: 677e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org if (Element::kRect_Type == element.getType()) { 678e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org if (prior->rectRectIntersectAllowed(element.getRect(), element.isAA())) { 679032a52fd4ceda001e44b80ff0462b570817bfe6fcommit-bot@chromium.org SkRect isectRect; 680032a52fd4ceda001e44b80ff0462b570817bfe6fcommit-bot@chromium.org if (!isectRect.intersect(prior->getRect(), element.getRect())) { 681e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org prior->setEmpty(); 682e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org return; 683e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org } 684e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org 685032a52fd4ceda001e44b80ff0462b570817bfe6fcommit-bot@chromium.org prior->fRRect.setRect(isectRect); 686e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org prior->fDoAA = element.isAA(); 687e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org Element* priorPrior = (Element*) iter.prev(); 688e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org prior->updateBoundAndGenID(priorPrior); 6896fbe54c663bd0eed6f6519c31a4c8e291db2613bcommit-bot@chromium.org return; 6906fbe54c663bd0eed6f6519c31a4c8e291db2613bcommit-bot@chromium.org } 691e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org break; 6926fbe54c663bd0eed6f6519c31a4c8e291db2613bcommit-bot@chromium.org } 693e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org // fallthrough 694e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org default: 695e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org if (!SkRect::Intersects(prior->getBounds(), element.getBounds())) { 696e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org prior->setEmpty(); 69708eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com return; 69808eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com } 6996fbe54c663bd0eed6f6519c31a4c8e291db2613bcommit-bot@chromium.org break; 7006fbe54c663bd0eed6f6519c31a4c8e291db2613bcommit-bot@chromium.org } 701e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org } else if (SkRegion::kReplace_Op == element.getOp()) { 7026fbe54c663bd0eed6f6519c31a4c8e291db2613bcommit-bot@chromium.org this->restoreTo(fSaveCount - 1); 703e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org prior = (Element*) fDeque.back(); 7045c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com } 7055c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com } 706e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org Element* newElement = SkNEW_PLACEMENT_ARGS(fDeque.push_back(), Element, (element)); 707e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org newElement->updateBoundAndGenID(prior); 7085c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com} 7095c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 710e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.orgvoid SkClipStack::clipDevRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA) { 711e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org Element element(fSaveCount, rrect, op, doAA); 712e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org this->pushElement(element); 713e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org} 71446f935002c2b25331e552520dc7b1a912e12dfdcrobertphillips@google.com 715e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.orgvoid SkClipStack::clipDevRect(const SkRect& rect, SkRegion::Op op, bool doAA) { 716e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org Element element(fSaveCount, rect, op, doAA); 717e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org this->pushElement(element); 7185c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com} 7195c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 720e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.orgvoid SkClipStack::clipDevPath(const SkPath& path, SkRegion::Op op, bool doAA) { 721e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org Element element(fSaveCount, path, op, doAA); 722e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org this->pushElement(element); 723e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org} 72463ae1cfb10d0d14722df59cba0012f8a4370c090robertphillips@google.com 725e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.orgvoid SkClipStack::clipEmpty() { 7269128edc700ce1b722f1290c585af829542f98a33bsalomon@google.com Element* element = (Element*) fDeque.back(); 72763ae1cfb10d0d14722df59cba0012f8a4370c090robertphillips@google.com 7289128edc700ce1b722f1290c585af829542f98a33bsalomon@google.com if (element && element->canBeIntersectedInPlace(fSaveCount, SkRegion::kIntersect_Op)) { 729e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org element->setEmpty(); 7300557d9ea94d5435a9072c9b4141a05190d648442reed@google.com } 7319128edc700ce1b722f1290c585af829542f98a33bsalomon@google.com new (fDeque.push_back()) Element(fSaveCount); 732fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 7339128edc700ce1b722f1290c585af829542f98a33bsalomon@google.com ((Element*)fDeque.back())->fGenID = kEmptyGenID; 7340557d9ea94d5435a9072c9b4141a05190d648442reed@google.com} 7350557d9ea94d5435a9072c9b4141a05190d648442reed@google.com 736fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.combool SkClipStack::isWideOpen() const { 737d3e5842db0cb169e10d6da1e62c94ba5cf182bb4commit-bot@chromium.org return this->getTopmostGenID() == kWideOpenGenID; 738cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com} 739cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 7405c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com/////////////////////////////////////////////////////////////////////////////// 7415c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 7425836b6dec5563e6273099fcf23984dd3818a168frobertphillips@google.comSkClipStack::Iter::Iter() : fStack(NULL) { 743d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com} 744d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com 7455836b6dec5563e6273099fcf23984dd3818a168frobertphillips@google.comSkClipStack::Iter::Iter(const SkClipStack& stack, IterStart startLoc) 7465836b6dec5563e6273099fcf23984dd3818a168frobertphillips@google.com : fStack(&stack) { 74752cb2c7cdf87f1e7d4b5d24b3609aaa514a26c10robertphillips@google.com this->reset(stack, startLoc); 7485c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com} 7495c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 7508182fa0cac76e7e6d583aebba060229230516887bsalomon@google.comconst SkClipStack::Element* SkClipStack::Iter::next() { 7518182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com return (const SkClipStack::Element*)fIter.next(); 7525c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com} 753d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com 7548182fa0cac76e7e6d583aebba060229230516887bsalomon@google.comconst SkClipStack::Element* SkClipStack::Iter::prev() { 7558182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com return (const SkClipStack::Element*)fIter.prev(); 75652cb2c7cdf87f1e7d4b5d24b3609aaa514a26c10robertphillips@google.com} 75752cb2c7cdf87f1e7d4b5d24b3609aaa514a26c10robertphillips@google.com 7588182fa0cac76e7e6d583aebba060229230516887bsalomon@google.comconst SkClipStack::Element* SkClipStack::Iter::skipToTopmost(SkRegion::Op op) { 7595836b6dec5563e6273099fcf23984dd3818a168frobertphillips@google.com 7605836b6dec5563e6273099fcf23984dd3818a168frobertphillips@google.com if (NULL == fStack) { 7615836b6dec5563e6273099fcf23984dd3818a168frobertphillips@google.com return NULL; 7625836b6dec5563e6273099fcf23984dd3818a168frobertphillips@google.com } 7635836b6dec5563e6273099fcf23984dd3818a168frobertphillips@google.com 7645836b6dec5563e6273099fcf23984dd3818a168frobertphillips@google.com fIter.reset(fStack->fDeque, SkDeque::Iter::kBack_IterStart); 7655836b6dec5563e6273099fcf23984dd3818a168frobertphillips@google.com 7669128edc700ce1b722f1290c585af829542f98a33bsalomon@google.com const SkClipStack::Element* element = NULL; 7675836b6dec5563e6273099fcf23984dd3818a168frobertphillips@google.com 7689128edc700ce1b722f1290c585af829542f98a33bsalomon@google.com for (element = (const SkClipStack::Element*) fIter.prev(); 76949f085dddff10473b6ebf832a974288300224e60bsalomon element; 7709128edc700ce1b722f1290c585af829542f98a33bsalomon@google.com element = (const SkClipStack::Element*) fIter.prev()) { 7715836b6dec5563e6273099fcf23984dd3818a168frobertphillips@google.com 7729128edc700ce1b722f1290c585af829542f98a33bsalomon@google.com if (op == element->fOp) { 7735836b6dec5563e6273099fcf23984dd3818a168frobertphillips@google.com // The Deque's iterator is actually one pace ahead of the 7749128edc700ce1b722f1290c585af829542f98a33bsalomon@google.com // returned value. So while "element" is the element we want to 7755836b6dec5563e6273099fcf23984dd3818a168frobertphillips@google.com // return, the iterator is actually pointing at (and will 7765836b6dec5563e6273099fcf23984dd3818a168frobertphillips@google.com // return on the next "next" or "prev" call) the element 777fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com // in front of it in the deque. Bump the iterator forward a 7785836b6dec5563e6273099fcf23984dd3818a168frobertphillips@google.com // step so we get the expected result. 7795836b6dec5563e6273099fcf23984dd3818a168frobertphillips@google.com if (NULL == fIter.next()) { 7805836b6dec5563e6273099fcf23984dd3818a168frobertphillips@google.com // The reverse iterator has run off the front of the deque 7815836b6dec5563e6273099fcf23984dd3818a168frobertphillips@google.com // (i.e., the "op" clip is the first clip) and can't 7825836b6dec5563e6273099fcf23984dd3818a168frobertphillips@google.com // recover. Reset the iterator to start at the front. 7835836b6dec5563e6273099fcf23984dd3818a168frobertphillips@google.com fIter.reset(fStack->fDeque, SkDeque::Iter::kFront_IterStart); 7845836b6dec5563e6273099fcf23984dd3818a168frobertphillips@google.com } 7855836b6dec5563e6273099fcf23984dd3818a168frobertphillips@google.com break; 7865836b6dec5563e6273099fcf23984dd3818a168frobertphillips@google.com } 7875836b6dec5563e6273099fcf23984dd3818a168frobertphillips@google.com } 7885836b6dec5563e6273099fcf23984dd3818a168frobertphillips@google.com 7899128edc700ce1b722f1290c585af829542f98a33bsalomon@google.com if (NULL == element) { 7905836b6dec5563e6273099fcf23984dd3818a168frobertphillips@google.com // There were no "op" clips 7915836b6dec5563e6273099fcf23984dd3818a168frobertphillips@google.com fIter.reset(fStack->fDeque, SkDeque::Iter::kFront_IterStart); 7925836b6dec5563e6273099fcf23984dd3818a168frobertphillips@google.com } 7935836b6dec5563e6273099fcf23984dd3818a168frobertphillips@google.com 7945836b6dec5563e6273099fcf23984dd3818a168frobertphillips@google.com return this->next(); 7955836b6dec5563e6273099fcf23984dd3818a168frobertphillips@google.com} 7965836b6dec5563e6273099fcf23984dd3818a168frobertphillips@google.com 79752cb2c7cdf87f1e7d4b5d24b3609aaa514a26c10robertphillips@google.comvoid SkClipStack::Iter::reset(const SkClipStack& stack, IterStart startLoc) { 798a6f11c4f717961070cd6fc5e60c361db14c5c4f3robertphillips@google.com fStack = &stack; 79952cb2c7cdf87f1e7d4b5d24b3609aaa514a26c10robertphillips@google.com fIter.reset(stack.fDeque, static_cast<SkDeque::Iter::IterStart>(startLoc)); 800d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com} 801607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 802607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com// helper method 803607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.comvoid SkClipStack::getConservativeBounds(int offsetX, 804607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com int offsetY, 805607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com int maxWidth, 806607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com int maxHeight, 8077b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com SkRect* devBounds, 8084c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com bool* isIntersectionOfRects) const { 80949f085dddff10473b6ebf832a974288300224e60bsalomon SkASSERT(devBounds); 810607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 811fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com devBounds->setLTRB(0, 0, 8127b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com SkIntToScalar(maxWidth), SkIntToScalar(maxHeight)); 813607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 814607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com SkRect temp; 815607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com SkClipStack::BoundsType boundType; 816fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 8177b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com // temp starts off in canvas space here 8184c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com this->getBounds(&temp, &boundType, isIntersectionOfRects); 819607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com if (SkClipStack::kInsideOut_BoundsType == boundType) { 820607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com return; 821607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com } 822607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 8237b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com // but is converted to device space here 824607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com temp.offset(SkIntToScalar(offsetX), SkIntToScalar(offsetY)); 825607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 8267b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com if (!devBounds->intersect(temp)) { 8277b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com devBounds->setEmpty(); 828607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com } 829607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com} 83046f935002c2b25331e552520dc7b1a912e12dfdcrobertphillips@google.com 83146f935002c2b25331e552520dc7b1a912e12dfdcrobertphillips@google.comint32_t SkClipStack::GetNextGenID() { 832edb26fdb8349a727b226e90cbeab06cd25f5cac0bsalomon@google.com // TODO: handle overflow. 83346f935002c2b25331e552520dc7b1a912e12dfdcrobertphillips@google.com return sk_atomic_inc(&gGenID); 83446f935002c2b25331e552520dc7b1a912e12dfdcrobertphillips@google.com} 83573e71023a05393ef0aa12bf3644a1c704feeec0crobertphillips@google.com 83673e71023a05393ef0aa12bf3644a1c704feeec0crobertphillips@google.comint32_t SkClipStack::getTopmostGenID() const { 837f0784bde753feaff601f703089872fc1af265328reed@google.com if (fDeque.empty()) { 838d3e5842db0cb169e10d6da1e62c94ba5cf182bb4commit-bot@chromium.org return kWideOpenGenID; 839679eb674fc064993d534df4d48a4ddaff4e33e06commit-bot@chromium.org } 840679eb674fc064993d534df4d48a4ddaff4e33e06commit-bot@chromium.org 841d3e5842db0cb169e10d6da1e62c94ba5cf182bb4commit-bot@chromium.org const Element* back = static_cast<const Element*>(fDeque.back()); 842d3e5842db0cb169e10d6da1e62c94ba5cf182bb4commit-bot@chromium.org if (kInsideOut_BoundsType == back->fFiniteBoundType && back->fFiniteBound.isEmpty()) { 843d3e5842db0cb169e10d6da1e62c94ba5cf182bb4commit-bot@chromium.org return kWideOpenGenID; 844d3e5842db0cb169e10d6da1e62c94ba5cf182bb4commit-bot@chromium.org } 845d3e5842db0cb169e10d6da1e62c94ba5cf182bb4commit-bot@chromium.org 846d3e5842db0cb169e10d6da1e62c94ba5cf182bb4commit-bot@chromium.org return back->getGenID(); 84773e71023a05393ef0aa12bf3644a1c704feeec0crobertphillips@google.com} 848b6b02526438d6839481fb40ccf610d28f7652397bsalomon 849b6b02526438d6839481fb40ccf610d28f7652397bsalomon#ifdef SK_DEVELOPER 850b6b02526438d6839481fb40ccf610d28f7652397bsalomonvoid SkClipStack::Element::dump() const { 851b6b02526438d6839481fb40ccf610d28f7652397bsalomon static const char* kTypeStrings[] = { 852b6b02526438d6839481fb40ccf610d28f7652397bsalomon "empty", 853b6b02526438d6839481fb40ccf610d28f7652397bsalomon "rect", 854b6b02526438d6839481fb40ccf610d28f7652397bsalomon "rrect", 855b6b02526438d6839481fb40ccf610d28f7652397bsalomon "path" 856b6b02526438d6839481fb40ccf610d28f7652397bsalomon }; 857b6b02526438d6839481fb40ccf610d28f7652397bsalomon SK_COMPILE_ASSERT(0 == kEmpty_Type, type_str); 858b6b02526438d6839481fb40ccf610d28f7652397bsalomon SK_COMPILE_ASSERT(1 == kRect_Type, type_str); 859b6b02526438d6839481fb40ccf610d28f7652397bsalomon SK_COMPILE_ASSERT(2 == kRRect_Type, type_str); 860b6b02526438d6839481fb40ccf610d28f7652397bsalomon SK_COMPILE_ASSERT(3 == kPath_Type, type_str); 861b6b02526438d6839481fb40ccf610d28f7652397bsalomon SK_COMPILE_ASSERT(SK_ARRAY_COUNT(kTypeStrings) == kTypeCnt, type_str); 862b6b02526438d6839481fb40ccf610d28f7652397bsalomon 863b6b02526438d6839481fb40ccf610d28f7652397bsalomon static const char* kOpStrings[] = { 864b6b02526438d6839481fb40ccf610d28f7652397bsalomon "difference", 865b6b02526438d6839481fb40ccf610d28f7652397bsalomon "intersect", 866b6b02526438d6839481fb40ccf610d28f7652397bsalomon "union", 867b6b02526438d6839481fb40ccf610d28f7652397bsalomon "xor", 868b6b02526438d6839481fb40ccf610d28f7652397bsalomon "reverse-difference", 869b6b02526438d6839481fb40ccf610d28f7652397bsalomon "replace", 870b6b02526438d6839481fb40ccf610d28f7652397bsalomon }; 871b6b02526438d6839481fb40ccf610d28f7652397bsalomon SK_COMPILE_ASSERT(0 == SkRegion::kDifference_Op, op_str); 872b6b02526438d6839481fb40ccf610d28f7652397bsalomon SK_COMPILE_ASSERT(1 == SkRegion::kIntersect_Op, op_str); 873b6b02526438d6839481fb40ccf610d28f7652397bsalomon SK_COMPILE_ASSERT(2 == SkRegion::kUnion_Op, op_str); 874b6b02526438d6839481fb40ccf610d28f7652397bsalomon SK_COMPILE_ASSERT(3 == SkRegion::kXOR_Op, op_str); 875b6b02526438d6839481fb40ccf610d28f7652397bsalomon SK_COMPILE_ASSERT(4 == SkRegion::kReverseDifference_Op, op_str); 876b6b02526438d6839481fb40ccf610d28f7652397bsalomon SK_COMPILE_ASSERT(5 == SkRegion::kReplace_Op, op_str); 877b6b02526438d6839481fb40ccf610d28f7652397bsalomon SK_COMPILE_ASSERT(SK_ARRAY_COUNT(kOpStrings) == SkRegion::kOpCnt, op_str); 878b6b02526438d6839481fb40ccf610d28f7652397bsalomon 879b6b02526438d6839481fb40ccf610d28f7652397bsalomon SkDebugf("Type: %s, Op: %s, AA: %s, Save Count: %d\n", kTypeStrings[fType], 880b6b02526438d6839481fb40ccf610d28f7652397bsalomon kOpStrings[fOp], (fDoAA ? "yes" : "no"), fSaveCount); 881b6b02526438d6839481fb40ccf610d28f7652397bsalomon switch (fType) { 882b6b02526438d6839481fb40ccf610d28f7652397bsalomon case kEmpty_Type: 883b6b02526438d6839481fb40ccf610d28f7652397bsalomon SkDebugf("\n"); 884b6b02526438d6839481fb40ccf610d28f7652397bsalomon break; 885b6b02526438d6839481fb40ccf610d28f7652397bsalomon case kRect_Type: 886b6b02526438d6839481fb40ccf610d28f7652397bsalomon this->getRect().dump(); 887b6b02526438d6839481fb40ccf610d28f7652397bsalomon SkDebugf("\n"); 888b6b02526438d6839481fb40ccf610d28f7652397bsalomon break; 889b6b02526438d6839481fb40ccf610d28f7652397bsalomon case kRRect_Type: 890b6b02526438d6839481fb40ccf610d28f7652397bsalomon this->getRRect().dump(); 891b6b02526438d6839481fb40ccf610d28f7652397bsalomon SkDebugf("\n"); 892b6b02526438d6839481fb40ccf610d28f7652397bsalomon break; 893b6b02526438d6839481fb40ccf610d28f7652397bsalomon case kPath_Type: 894e956259c5a4f71768afb34ec032eaed49dcbe9f2caryclark this->getPath().dump(NULL, true, false); 895b6b02526438d6839481fb40ccf610d28f7652397bsalomon break; 896b6b02526438d6839481fb40ccf610d28f7652397bsalomon } 897b6b02526438d6839481fb40ccf610d28f7652397bsalomon} 898b6b02526438d6839481fb40ccf610d28f7652397bsalomon 899b6b02526438d6839481fb40ccf610d28f7652397bsalomonvoid SkClipStack::dump() const { 900b6b02526438d6839481fb40ccf610d28f7652397bsalomon B2TIter iter(*this); 901b6b02526438d6839481fb40ccf610d28f7652397bsalomon const Element* e; 902b6b02526438d6839481fb40ccf610d28f7652397bsalomon while ((e = iter.next())) { 903b6b02526438d6839481fb40ccf610d28f7652397bsalomon e->dump(); 904b6b02526438d6839481fb40ccf610d28f7652397bsalomon SkDebugf("\n"); 905b6b02526438d6839481fb40ccf610d28f7652397bsalomon } 906b6b02526438d6839481fb40ccf610d28f7652397bsalomon} 907b6b02526438d6839481fb40ccf610d28f7652397bsalomon#endif 908