1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc. 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */ 85c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com#ifndef SkClipStack_DEFINED 95c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com#define SkClipStack_DEFINED 105c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 115c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com#include "SkDeque.h" 128a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com#include "SkPath.h" 138a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com#include "SkRect.h" 14e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org#include "SkRRect.h" 155c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com#include "SkRegion.h" 1646f935002c2b25331e552520dc7b1a912e12dfdcrobertphillips@google.com#include "SkTDArray.h" 176f954b956fc5c36ebbcac404d93ba9349fb0355fcommit-bot@chromium.org#include "SkTLazy.h" 185c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 19c3b589a24eb4d567a906189f882c259ecf5c2f58fmalitaclass SkCanvasClipVisitor; 205c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 214c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com// Because a single save/restore state can have multiple clips, this class 224c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com// stores the stack depth (fSaveCount) and clips (fDeque) separately. 234c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com// Each clip in fDeque stores the stack state to which it belongs 244c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com// (i.e., the fSaveCount in force when it was added). Restores are thus 254c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com// implemented by removing clips from fDeque that have an fSaveCount larger 264c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com// then the freshly decremented count. 277ffb1b21abcc7bbed5a0fc711f6dd7b9dbb4f577ctguil@chromium.orgclass SK_API SkClipStack { 285c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.compublic: 298a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com enum BoundsType { 308a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // The bounding box contains all the pixels that can be written to 318a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com kNormal_BoundsType, 328a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // The bounding box contains all the pixels that cannot be written to. 338a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // The real bound extends out to infinity and all the pixels outside 348a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // of the bound can be written to. Note that some of the pixels inside 358a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // the bound may also be writeable but all pixels that cannot be 368a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // written to are guaranteed to be inside. 378a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com kInsideOut_BoundsType 388a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com }; 398a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com 408a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com class Element { 418a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com public: 428a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com enum Type { 438a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com //!< This element makes the clip empty (regardless of previous elements). 448a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com kEmpty_Type, 458a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com //!< This element combines a rect with the current clip using a set operation 468a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com kRect_Type, 47e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org //!< This element combines a round-rect with the current clip using a set operation 48e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org kRRect_Type, 498a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com //!< This element combines a path with the current clip using a set operation 508a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com kPath_Type, 51b6b02526438d6839481fb40ccf610d28f7652397bsalomon 52b6b02526438d6839481fb40ccf610d28f7652397bsalomon kLastType = kPath_Type 538a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com }; 54b6b02526438d6839481fb40ccf610d28f7652397bsalomon static const int kTypeCnt = kLastType + 1; 558a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com 568a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com Element() { 578a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com this->initCommon(0, SkRegion::kReplace_Op, false); 588a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com this->setEmpty(); 598a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com } 608a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com 616f954b956fc5c36ebbcac404d93ba9349fb0355fcommit-bot@chromium.org Element(const Element&); 626f954b956fc5c36ebbcac404d93ba9349fb0355fcommit-bot@chromium.org 638a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com Element(const SkRect& rect, SkRegion::Op op, bool doAA) { 648a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com this->initRect(0, rect, op, doAA); 658a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com } 668a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com 67e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org Element(const SkRRect& rrect, SkRegion::Op op, bool doAA) { 68e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org this->initRRect(0, rrect, op, doAA); 69e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org } 70e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org 718a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com Element(const SkPath& path, SkRegion::Op op, bool doAA) { 728a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com this->initPath(0, path, op, doAA); 738a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com } 748a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com 75e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org bool operator== (const Element& element) const; 768182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com bool operator!= (const Element& element) const { return !(*this == element); } 778182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com 788a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com //!< Call to get the type of the clip element. 798a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com Type getType() const { return fType; } 808a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com 81c3b589a24eb4d567a906189f882c259ecf5c2f58fmalita //!< Call to get the save count associated with this clip element. 82c3b589a24eb4d567a906189f882c259ecf5c2f58fmalita int getSaveCount() const { return fSaveCount; } 83c3b589a24eb4d567a906189f882c259ecf5c2f58fmalita 848a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com //!< Call if getType() is kPath to get the path. 856f954b956fc5c36ebbcac404d93ba9349fb0355fcommit-bot@chromium.org const SkPath& getPath() const { SkASSERT(kPath_Type == fType); return *fPath.get(); } 86e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org 87e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org //!< Call if getType() is kRRect to get the round-rect. 88e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org const SkRRect& getRRect() const { SkASSERT(kRRect_Type == fType); return fRRect; } 898a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com 908a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com //!< Call if getType() is kRect to get the rect. 91032a52fd4ceda001e44b80ff0462b570817bfe6fcommit-bot@chromium.org const SkRect& getRect() const { 92032a52fd4ceda001e44b80ff0462b570817bfe6fcommit-bot@chromium.org SkASSERT(kRect_Type == fType && (fRRect.isRect() || fRRect.isEmpty())); 93032a52fd4ceda001e44b80ff0462b570817bfe6fcommit-bot@chromium.org return fRRect.getBounds(); 94032a52fd4ceda001e44b80ff0462b570817bfe6fcommit-bot@chromium.org } 958a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com 968a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com //!< Call if getType() is not kEmpty to get the set operation used to combine this element. 978a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com SkRegion::Op getOp() const { return fOp; } 988a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com 99e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org //!< Call to get the element as a path, regardless of its type. 100e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org void asPath(SkPath* path) const; 101e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org 1028a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com /** If getType() is not kEmpty this indicates whether the clip shape should be anti-aliased 1038a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com when it is rasterized. */ 1048a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com bool isAA() const { return fDoAA; } 1058a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com 106c6b3e48cb3a22d83ba3f4b9a614a5a35b05958a0bsalomon@google.com //!< Inverts the fill of the clip shape. Note that a kEmpty element remains kEmpty. 107c6b3e48cb3a22d83ba3f4b9a614a5a35b05958a0bsalomon@google.com void invertShapeFillType(); 108c6b3e48cb3a22d83ba3f4b9a614a5a35b05958a0bsalomon@google.com 109c6b3e48cb3a22d83ba3f4b9a614a5a35b05958a0bsalomon@google.com //!< Sets the set operation represented by the element. 1108182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com void setOp(SkRegion::Op op) { fOp = op; } 1118182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com 1128a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com /** The GenID can be used by clip stack clients to cache representations of the clip. The 1138a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com ID corresponds to the set of clip elements up to and including this element within the 1148a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com stack not to the element itself. That is the same clip path in different stacks will 1158a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com have a different ID since the elements produce different clip result in the context of 1168a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com their stacks. */ 117d3e5842db0cb169e10d6da1e62c94ba5cf182bb4commit-bot@chromium.org int32_t getGenID() const { SkASSERT(kInvalidGenID != fGenID); return fGenID; } 1188a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com 1198182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com /** 1208182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com * Gets the bounds of the clip element, either the rect or path bounds. (Whether the shape 1218182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com * is inverse filled is not considered.) 1228182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com */ 1238182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com const SkRect& getBounds() const { 1248182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com static const SkRect kEmpty = { 0, 0, 0, 0 }; 1258182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com switch (fType) { 126032a52fd4ceda001e44b80ff0462b570817bfe6fcommit-bot@chromium.org case kRect_Type: // fallthrough 127e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org case kRRect_Type: 128e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org return fRRect.getBounds(); 1298182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com case kPath_Type: 1306f954b956fc5c36ebbcac404d93ba9349fb0355fcommit-bot@chromium.org return fPath.get()->getBounds(); 1318182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com case kEmpty_Type: 1328182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com return kEmpty; 1338182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com default: 1348182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com SkDEBUGFAIL("Unexpected type."); 1358182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com return kEmpty; 1368182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com } 1378182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com } 1388182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com 1398182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com /** 1408182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com * Conservatively checks whether the clip shape contains the rect param. (Whether the shape 1418182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com * is inverse filled is not considered.) 1428182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com */ 1438182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com bool contains(const SkRect& rect) const { 1448182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com switch (fType) { 1458182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com case kRect_Type: 146032a52fd4ceda001e44b80ff0462b570817bfe6fcommit-bot@chromium.org return this->getRect().contains(rect); 147e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org case kRRect_Type: 148e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org return fRRect.contains(rect); 1498182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com case kPath_Type: 1506f954b956fc5c36ebbcac404d93ba9349fb0355fcommit-bot@chromium.org return fPath.get()->conservativelyContainsRect(rect); 1518182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com case kEmpty_Type: 1528182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com return false; 1538182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com default: 1548182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com SkDEBUGFAIL("Unexpected type."); 1558182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com return false; 1568182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com } 1578182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com } 1588182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com 1598182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com /** 1608182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com * Is the clip shape inverse filled. 1618182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com */ 1628182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com bool isInverseFilled() const { 1636f954b956fc5c36ebbcac404d93ba9349fb0355fcommit-bot@chromium.org return kPath_Type == fType && fPath.get()->isInverseFillType(); 1648182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com } 1658182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com 166c3b589a24eb4d567a906189f882c259ecf5c2f58fmalita /** 167c3b589a24eb4d567a906189f882c259ecf5c2f58fmalita * Replay this clip into the visitor. 168c3b589a24eb4d567a906189f882c259ecf5c2f58fmalita */ 169c3b589a24eb4d567a906189f882c259ecf5c2f58fmalita void replay(SkCanvasClipVisitor*) const; 170c3b589a24eb4d567a906189f882c259ecf5c2f58fmalita 171b6b02526438d6839481fb40ccf610d28f7652397bsalomon#ifdef SK_DEVELOPER 172b6b02526438d6839481fb40ccf610d28f7652397bsalomon /** 173b6b02526438d6839481fb40ccf610d28f7652397bsalomon * Dumps the element to SkDebugf. This is intended for Skia development debugging 174b6b02526438d6839481fb40ccf610d28f7652397bsalomon * Don't rely on the existence of this function or the formatting of its output. 175b6b02526438d6839481fb40ccf610d28f7652397bsalomon */ 176b6b02526438d6839481fb40ccf610d28f7652397bsalomon void dump() const; 177b6b02526438d6839481fb40ccf610d28f7652397bsalomon#endif 178b6b02526438d6839481fb40ccf610d28f7652397bsalomon 1798a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com private: 1808a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com friend class SkClipStack; 1818a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com 1826f954b956fc5c36ebbcac404d93ba9349fb0355fcommit-bot@chromium.org SkTLazy<SkPath> fPath; 183e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org SkRRect fRRect; 1848a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com int fSaveCount; // save count of stack when this element was added. 1858a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com SkRegion::Op fOp; 1868a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com Type fType; 1878a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com bool fDoAA; 1888a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com 1898a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com /* fFiniteBoundType and fFiniteBound are used to incrementally update the clip stack's 1908a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com bound. When fFiniteBoundType is kNormal_BoundsType, fFiniteBound represents the 1918a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com conservative bounding box of the pixels that aren't clipped (i.e., any pixels that can be 1928a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com drawn to are inside the bound). When fFiniteBoundType is kInsideOut_BoundsType (which 1938a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com occurs when a clip is inverse filled), fFiniteBound represents the conservative bounding 1948a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com box of the pixels that _are_ clipped (i.e., any pixels that cannot be drawn to are inside 1958a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com the bound). When fFiniteBoundType is kInsideOut_BoundsType the actual bound is the 1968a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com infinite plane. This behavior of fFiniteBoundType and fFiniteBound is required so that we 1978a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com can capture the cancelling out of the extensions to infinity when two inverse filled 1988a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com clips are Booleaned together. */ 1998a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com SkClipStack::BoundsType fFiniteBoundType; 2008a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com SkRect fFiniteBound; 201c3d7d90973528527131c72549b10c2a21300e0acskia.committer@gmail.com 2028a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // When element is applied to the previous elements in the stack is the result known to be 2038a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // equivalent to a single rect intersection? IIOW, is the clip effectively a rectangle. 2048a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com bool fIsIntersectionOfRects; 2058a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com 2068a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com int fGenID; 2078a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com 2088a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com Element(int saveCount) { 2098a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com this->initCommon(saveCount, SkRegion::kReplace_Op, false); 2108a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com this->setEmpty(); 2118a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com } 2128a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com 213e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org Element(int saveCount, const SkRRect& rrect, SkRegion::Op op, bool doAA) { 214e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org this->initRRect(saveCount, rrect, op, doAA); 215e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org } 216e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org 2178a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com Element(int saveCount, const SkRect& rect, SkRegion::Op op, bool doAA) { 2188a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com this->initRect(saveCount, rect, op, doAA); 2198a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com } 2208a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com 2218a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com Element(int saveCount, const SkPath& path, SkRegion::Op op, bool doAA) { 2228a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com this->initPath(saveCount, path, op, doAA); 2238a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com } 2248a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com 2258a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com void initCommon(int saveCount, SkRegion::Op op, bool doAA) { 2268a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com fSaveCount = saveCount; 2278a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com fOp = op; 2288a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com fDoAA = doAA; 2298a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // A default of inside-out and empty bounds means the bounds are effectively void as it 2308a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // indicates that nothing is known to be outside the clip. 2318a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com fFiniteBoundType = kInsideOut_BoundsType; 2328a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com fFiniteBound.setEmpty(); 2338a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com fIsIntersectionOfRects = false; 2348a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com fGenID = kInvalidGenID; 2358a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com } 2368a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com 2378a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com void initRect(int saveCount, const SkRect& rect, SkRegion::Op op, bool doAA) { 238032a52fd4ceda001e44b80ff0462b570817bfe6fcommit-bot@chromium.org fRRect.setRect(rect); 2398a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com fType = kRect_Type; 2408a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com this->initCommon(saveCount, op, doAA); 2418a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com } 2428a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com 243e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org void initRRect(int saveCount, const SkRRect& rrect, SkRegion::Op op, bool doAA) { 244032a52fd4ceda001e44b80ff0462b570817bfe6fcommit-bot@chromium.org SkRRect::Type type = rrect.getType(); 245032a52fd4ceda001e44b80ff0462b570817bfe6fcommit-bot@chromium.org fRRect = rrect; 246032a52fd4ceda001e44b80ff0462b570817bfe6fcommit-bot@chromium.org if (SkRRect::kRect_Type == type || SkRRect::kEmpty_Type == type) { 247e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org fType = kRect_Type; 248e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org } else { 249e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org fType = kRRect_Type; 250e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org } 2518a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com this->initCommon(saveCount, op, doAA); 2528a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com } 2538a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com 254e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org void initPath(int saveCount, const SkPath& path, SkRegion::Op op, bool doAA); 255e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org 2569cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org void setEmpty(); 2578a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com 2588a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // All Element methods below are only used within SkClipStack.cpp 2598a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com inline void checkEmpty() const; 2608a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com inline bool canBeIntersectedInPlace(int saveCount, SkRegion::Op op) const; 2618a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com /* This method checks to see if two rect clips can be safely merged into one. The issue here 262c3d7d90973528527131c72549b10c2a21300e0acskia.committer@gmail.com is that to be strictly correct all the edges of the resulting rect must have the same 2638a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com anti-aliasing. */ 2648a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com bool rectRectIntersectAllowed(const SkRect& newR, bool newAA) const; 2658a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com /** Determines possible finite bounds for the Element given the previous element of the 2668a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com stack */ 2678a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com void updateBoundAndGenID(const Element* prior); 2688a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // The different combination of fill & inverse fill when combining bounding boxes 2698a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com enum FillCombo { 2708a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com kPrev_Cur_FillCombo, 2718a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com kPrev_InvCur_FillCombo, 2728a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com kInvPrev_Cur_FillCombo, 2738a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com kInvPrev_InvCur_FillCombo 2748a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com }; 2758a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com // per-set operation functions used by updateBoundAndGenID(). 2768a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com inline void combineBoundsDiff(FillCombo combination, const SkRect& prevFinite); 2778a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com inline void combineBoundsXOR(int combination, const SkRect& prevFinite); 2788a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com inline void combineBoundsUnion(int combination, const SkRect& prevFinite); 2798a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com inline void combineBoundsIntersection(int combination, const SkRect& prevFinite); 2808a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com inline void combineBoundsRevDiff(int combination, const SkRect& prevFinite); 2818a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com }; 2828a98e3bd18f1a8914cbfe1461e1ff47f51286556bsalomon@google.com 2835c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com SkClipStack(); 2841e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org SkClipStack(const SkClipStack& b); 285cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com explicit SkClipStack(const SkRect& r); 286641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com explicit SkClipStack(const SkIRect& r); 287610f716b00f214e4899a102c1bbc1d6a323e114evandebo@chromium.org ~SkClipStack(); 2885c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 2891e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org SkClipStack& operator=(const SkClipStack& b); 2901e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org bool operator==(const SkClipStack& b) const; 2911e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org bool operator!=(const SkClipStack& b) const { return !(*this == b); } 2921e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org 2935c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com void reset(); 2945c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 2955c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com int getSaveCount() const { return fSaveCount; } 2965c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com void save(); 2975c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com void restore(); 2985c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 299607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com /** 300607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com * getBounds places the current finite bound in its first parameter. In its 301fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com * second, it indicates which kind of bound is being returned. If 3027b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com * 'canvFiniteBound' is a normal bounding box then it encloses all writeable 303fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com * pixels. If 'canvFiniteBound' is an inside out bounding box then it 304607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com * encloses all the un-writeable pixels and the true/normal bound is the 3054c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com * infinite plane. isIntersectionOfRects is an optional parameter 3067b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com * that is true if 'canvFiniteBound' resulted from an intersection of rects. 307607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com */ 308fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com void getBounds(SkRect* canvFiniteBound, 3094c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com BoundsType* boundType, 3104c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com bool* isIntersectionOfRects = NULL) const; 311607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 3123ab43d5c5b4d77f46dd0266618f92e5fefce2021bsalomon@google.com /** 3133ab43d5c5b4d77f46dd0266618f92e5fefce2021bsalomon@google.com * Takes an input rect in device space and conservatively clips it to the 3143ab43d5c5b4d77f46dd0266618f92e5fefce2021bsalomon@google.com * clip-stack. If false is returned then the rect does not intersect the 3153ab43d5c5b4d77f46dd0266618f92e5fefce2021bsalomon@google.com * clip and is unmodified. 3163ab43d5c5b4d77f46dd0266618f92e5fefce2021bsalomon@google.com */ 3173ab43d5c5b4d77f46dd0266618f92e5fefce2021bsalomon@google.com bool intersectRectWithClip(SkRect* devRect) const; 3183ab43d5c5b4d77f46dd0266618f92e5fefce2021bsalomon@google.com 3198cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org /** 3208cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org * Returns true if the input rect in device space is entirely contained 3218cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org * by the clip. A return value of false does not guarantee that the rect 3228cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org * is not contained by the clip. 3238cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org */ 3248cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org bool quickContains(const SkRect& devRect) const; 3258cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org 326115d931d2fbd3a109a21b28c8a9c5099e6c49c54reed@google.com void clipDevRect(const SkIRect& ir, SkRegion::Op op) { 3275c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com SkRect r; 3285c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com r.set(ir); 3290017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com this->clipDevRect(r, op, false); 3305c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com } 3310017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com void clipDevRect(const SkRect&, SkRegion::Op, bool doAA); 332e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org void clipDevRRect(const SkRRect&, SkRegion::Op, bool doAA); 3330017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com void clipDevPath(const SkPath&, SkRegion::Op, bool doAA); 3340557d9ea94d5435a9072c9b4141a05190d648442reed@google.com // An optimized version of clipDevRect(emptyRect, kIntersect, ...) 3350557d9ea94d5435a9072c9b4141a05190d648442reed@google.com void clipEmpty(); 3365c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 337cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com /** 338fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com * isWideOpen returns true if the clip state corresponds to the infinite 339cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com * plane (i.e., draws are not limited at all) 340cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com */ 341cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com bool isWideOpen() const; 342cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 34346f935002c2b25331e552520dc7b1a912e12dfdcrobertphillips@google.com /** 34446f935002c2b25331e552520dc7b1a912e12dfdcrobertphillips@google.com * The generation ID has three reserved values to indicate special 345e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com * (potentially ignorable) cases 34646f935002c2b25331e552520dc7b1a912e12dfdcrobertphillips@google.com */ 347d3e5842db0cb169e10d6da1e62c94ba5cf182bb4commit-bot@chromium.org static const int32_t kInvalidGenID = 0; //!< Invalid id that is never returned by 348d3e5842db0cb169e10d6da1e62c94ba5cf182bb4commit-bot@chromium.org //!< SkClipStack. Useful when caching clips 349d3e5842db0cb169e10d6da1e62c94ba5cf182bb4commit-bot@chromium.org //!< based on GenID. 35046f935002c2b25331e552520dc7b1a912e12dfdcrobertphillips@google.com static const int32_t kEmptyGenID = 1; // no pixels writeable 35146f935002c2b25331e552520dc7b1a912e12dfdcrobertphillips@google.com static const int32_t kWideOpenGenID = 2; // all pixels writeable 35246f935002c2b25331e552520dc7b1a912e12dfdcrobertphillips@google.com 35373e71023a05393ef0aa12bf3644a1c704feeec0crobertphillips@google.com int32_t getTopmostGenID() const; 35473e71023a05393ef0aa12bf3644a1c704feeec0crobertphillips@google.com 355b6b02526438d6839481fb40ccf610d28f7652397bsalomon#ifdef SK_DEVELOPER 356b6b02526438d6839481fb40ccf610d28f7652397bsalomon /** 357b6b02526438d6839481fb40ccf610d28f7652397bsalomon * Dumps the contents of the clip stack to SkDebugf. This is intended for Skia development 358b6b02526438d6839481fb40ccf610d28f7652397bsalomon * debugging. Don't rely on the existence of this function or the formatting of its output. 359b6b02526438d6839481fb40ccf610d28f7652397bsalomon */ 360b6b02526438d6839481fb40ccf610d28f7652397bsalomon void dump() const; 361b6b02526438d6839481fb40ccf610d28f7652397bsalomon#endif 362b6b02526438d6839481fb40ccf610d28f7652397bsalomon 36352cb2c7cdf87f1e7d4b5d24b3609aaa514a26c10robertphillips@google.compublic: 36452cb2c7cdf87f1e7d4b5d24b3609aaa514a26c10robertphillips@google.com class Iter { 3655c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com public: 36652cb2c7cdf87f1e7d4b5d24b3609aaa514a26c10robertphillips@google.com enum IterStart { 36780214e26c57c5fea954006400852e8999e201923robertphillips@google.com kBottom_IterStart = SkDeque::Iter::kFront_IterStart, 36880214e26c57c5fea954006400852e8999e201923robertphillips@google.com kTop_IterStart = SkDeque::Iter::kBack_IterStart 36952cb2c7cdf87f1e7d4b5d24b3609aaa514a26c10robertphillips@google.com }; 37052cb2c7cdf87f1e7d4b5d24b3609aaa514a26c10robertphillips@google.com 371d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com /** 372d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com * Creates an uninitialized iterator. Must be reset() 373d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com */ 37452cb2c7cdf87f1e7d4b5d24b3609aaa514a26c10robertphillips@google.com Iter(); 375d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com 37652cb2c7cdf87f1e7d4b5d24b3609aaa514a26c10robertphillips@google.com Iter(const SkClipStack& stack, IterStart startLoc); 3775c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 3785c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com /** 3798182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com * Return the clip element for this iterator. If next()/prev() returns NULL, then the 3808182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com * iterator is done. 3815c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com */ 3828182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com const Element* next(); 3838182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com const Element* prev(); 3845c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 385d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com /** 3868182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com * Moves the iterator to the topmost element with the specified RegionOp and returns that 3878182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com * element. If no clip element with that op is found, the first element is returned. 3885836b6dec5563e6273099fcf23984dd3818a168frobertphillips@google.com */ 3898182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com const Element* skipToTopmost(SkRegion::Op op); 3905836b6dec5563e6273099fcf23984dd3818a168frobertphillips@google.com 3915836b6dec5563e6273099fcf23984dd3818a168frobertphillips@google.com /** 392d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com * Restarts the iterator on a clip stack. 393d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com */ 39452cb2c7cdf87f1e7d4b5d24b3609aaa514a26c10robertphillips@google.com void reset(const SkClipStack& stack, IterStart startLoc); 395d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com 3965c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com private: 3975836b6dec5563e6273099fcf23984dd3818a168frobertphillips@google.com const SkClipStack* fStack; 3985836b6dec5563e6273099fcf23984dd3818a168frobertphillips@google.com SkDeque::Iter fIter; 39952cb2c7cdf87f1e7d4b5d24b3609aaa514a26c10robertphillips@google.com }; 40052cb2c7cdf87f1e7d4b5d24b3609aaa514a26c10robertphillips@google.com 401fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com /** 40280214e26c57c5fea954006400852e8999e201923robertphillips@google.com * The B2TIter iterates from the bottom of the stack to the top. 40380214e26c57c5fea954006400852e8999e201923robertphillips@google.com * It inherits privately from Iter to prevent access to reverse iteration. 40480214e26c57c5fea954006400852e8999e201923robertphillips@google.com */ 40580214e26c57c5fea954006400852e8999e201923robertphillips@google.com class B2TIter : private Iter { 40652cb2c7cdf87f1e7d4b5d24b3609aaa514a26c10robertphillips@google.com public: 40780214e26c57c5fea954006400852e8999e201923robertphillips@google.com B2TIter() {} 40852cb2c7cdf87f1e7d4b5d24b3609aaa514a26c10robertphillips@google.com 40952cb2c7cdf87f1e7d4b5d24b3609aaa514a26c10robertphillips@google.com /** 410fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com * Wrap Iter's 2 parameter ctor to force initialization to the 41180214e26c57c5fea954006400852e8999e201923robertphillips@google.com * beginning of the deque/bottom of the stack 41252cb2c7cdf87f1e7d4b5d24b3609aaa514a26c10robertphillips@google.com */ 413fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com B2TIter(const SkClipStack& stack) 41480214e26c57c5fea954006400852e8999e201923robertphillips@google.com : INHERITED(stack, kBottom_IterStart) { 41552cb2c7cdf87f1e7d4b5d24b3609aaa514a26c10robertphillips@google.com } 41652cb2c7cdf87f1e7d4b5d24b3609aaa514a26c10robertphillips@google.com 41752cb2c7cdf87f1e7d4b5d24b3609aaa514a26c10robertphillips@google.com using Iter::next; 41852cb2c7cdf87f1e7d4b5d24b3609aaa514a26c10robertphillips@google.com 41952cb2c7cdf87f1e7d4b5d24b3609aaa514a26c10robertphillips@google.com /** 420fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com * Wrap Iter::reset to force initialization to the 42180214e26c57c5fea954006400852e8999e201923robertphillips@google.com * beginning of the deque/bottom of the stack 42252cb2c7cdf87f1e7d4b5d24b3609aaa514a26c10robertphillips@google.com */ 42352cb2c7cdf87f1e7d4b5d24b3609aaa514a26c10robertphillips@google.com void reset(const SkClipStack& stack) { 42480214e26c57c5fea954006400852e8999e201923robertphillips@google.com this->INHERITED::reset(stack, kBottom_IterStart); 42552cb2c7cdf87f1e7d4b5d24b3609aaa514a26c10robertphillips@google.com } 42652cb2c7cdf87f1e7d4b5d24b3609aaa514a26c10robertphillips@google.com 42752cb2c7cdf87f1e7d4b5d24b3609aaa514a26c10robertphillips@google.com private: 42852cb2c7cdf87f1e7d4b5d24b3609aaa514a26c10robertphillips@google.com 42952cb2c7cdf87f1e7d4b5d24b3609aaa514a26c10robertphillips@google.com typedef Iter INHERITED; 4305c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com }; 4315c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 432607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com /** 433fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com * GetConservativeBounds returns a conservative bound of the current clip. 434fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com * Since this could be the infinite plane (if inverse fills were involved) the 435fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com * maxWidth and maxHeight parameters can be used to limit the returned bound 436607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com * to the expected drawing area. Similarly, the offsetX and offsetY parameters 437fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com * allow the caller to offset the returned bound to account for translated 438607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com * drawing areas (i.e., those resulting from a saveLayer). For finite bounds, 439fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com * the translation (+offsetX, +offsetY) is applied before the clamp to the 440607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com * maximum rectangle: [0,maxWidth) x [0,maxHeight). 441fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com * isIntersectionOfRects is an optional parameter that is true when 442641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com * 'devBounds' is the result of an intersection of rects. In this case 443641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com * 'devBounds' is the exact answer/clip. 444607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com */ 445607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com void getConservativeBounds(int offsetX, 446607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com int offsetY, 447607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com int maxWidth, 448607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com int maxHeight, 4497b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com SkRect* devBounds, 4504c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com bool* isIntersectionOfRects = NULL) const; 451607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 4525c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.comprivate: 45352cb2c7cdf87f1e7d4b5d24b3609aaa514a26c10robertphillips@google.com friend class Iter; 4545c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 4555c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com SkDeque fDeque; 4565c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com int fSaveCount; 45746f935002c2b25331e552520dc7b1a912e12dfdcrobertphillips@google.com 45846f935002c2b25331e552520dc7b1a912e12dfdcrobertphillips@google.com // Generation ID for the clip stack. This is incremented for each 45946f935002c2b25331e552520dc7b1a912e12dfdcrobertphillips@google.com // clipDevRect and clipDevPath call. 0 is reserved to indicate an 46046f935002c2b25331e552520dc7b1a912e12dfdcrobertphillips@google.com // invalid ID. 46146f935002c2b25331e552520dc7b1a912e12dfdcrobertphillips@google.com static int32_t gGenID; 46246f935002c2b25331e552520dc7b1a912e12dfdcrobertphillips@google.com 46346f935002c2b25331e552520dc7b1a912e12dfdcrobertphillips@google.com /** 464e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org * Helper for clipDevPath, etc. 465e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org */ 466e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org void pushElement(const Element& element); 467e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org 468e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org /** 4696fbe54c663bd0eed6f6519c31a4c8e291db2613bcommit-bot@chromium.org * Restore the stack back to the specified save count. 4706fbe54c663bd0eed6f6519c31a4c8e291db2613bcommit-bot@chromium.org */ 4716fbe54c663bd0eed6f6519c31a4c8e291db2613bcommit-bot@chromium.org void restoreTo(int saveCount); 4726fbe54c663bd0eed6f6519c31a4c8e291db2613bcommit-bot@chromium.org 4736fbe54c663bd0eed6f6519c31a4c8e291db2613bcommit-bot@chromium.org /** 47446f935002c2b25331e552520dc7b1a912e12dfdcrobertphillips@google.com * Return the next unique generation ID. 47546f935002c2b25331e552520dc7b1a912e12dfdcrobertphillips@google.com */ 47646f935002c2b25331e552520dc7b1a912e12dfdcrobertphillips@google.com static int32_t GetNextGenID(); 4775c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com}; 4785c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 4795c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com#endif 480