// Because a single save/restore state can have multiple clips, this class // stores the stack depth (fSaveCount) and clips (fDeque) separately. // Each clip in fDeque stores the stack state to which it belongs // (i.e., the fSaveCount in force when it was added). Restores are thus // implemented by removing clips from fDeque that have an fSaveCount larger // then the freshly decremented count. class SkClipStack {
public: enum BoundsType { // The bounding box contains all the pixels that can be written to
kNormal_BoundsType, // The bounding box contains all the pixels that cannot be written to. // The real bound extends out to infinity and all the pixels outside // of the bound can be written to. Note that some of the pixels inside // the bound may also be writeable but all pixels that cannot be // written to are guaranteed to be inside.
kInsideOut_BoundsType
};
/** *Anelementoftheclipstack.Itrepresentsashapecombinedwiththeprevoiusclipusinga *setoperator.Eachelementcanbeantialiasedornot.
*/ class Element {
public: /** This indicates the shape type of the clip element in device space. */ enumclass DeviceSpaceType { //!< This element makes the clip empty (regardless of previous elements).
kEmpty, //!< This element combines a device space rect with the current clip.
kRect, //!< This element combines a device space round-rect with the current clip.
kRRect, //!< This element combines a device space path with the current clip.
kPath, //!< This element does not have geometry, but applies a shader to the clip
kShader,
//!< Call to get the type of the clip element.
DeviceSpaceType getDeviceSpaceType() const { return fDeviceSpaceType; }
//!< Call to get the save count associated with this clip element. int getSaveCount() const { return fSaveCount; }
//!< Call if getDeviceSpaceType() is kPath to get the path. const SkPath& getDeviceSpacePath() const {
SkASSERT(DeviceSpaceType::kPath == fDeviceSpaceType); return *fDeviceSpacePath;
}
//!< Call if getDeviceSpaceType() is kRRect to get the round-rect. const SkRRect& getDeviceSpaceRRect() const {
SkASSERT(DeviceSpaceType::kRRect == fDeviceSpaceType); return fDeviceSpaceRRect;
}
//!< Call if getDeviceSpaceType() is kRect to get the rect. const SkRect& getDeviceSpaceRect() const {
SkASSERT(DeviceSpaceType::kRect == fDeviceSpaceType &&
(fDeviceSpaceRRect.isRect() || fDeviceSpaceRRect.isEmpty())); return fDeviceSpaceRRect.getBounds();
}
//!<Call if getDeviceSpaceType() is kShader to get a reference to the clip shader.
sk_sp<SkShader> refShader() const { return fShader;
} const SkShader* getShader() const { return fShader.get();
}
//!< Call if getDeviceSpaceType() is not kEmpty to get the set operation used to combine //!< this element.
SkClipOp getOp() const { return fOp; } // Augments getOps()'s behavior by requiring a clip reset before the op is applied. bool isReplaceOp() const { return fIsReplace; }
//!< Call to get the element as a path, regardless of its type.
SkPath asDeviceSpacePath() const;
//!< Call if getType() is not kPath to get the element as a round rect. const SkRRect& asDeviceSpaceRRect() const {
SkASSERT(DeviceSpaceType::kPath != fDeviceSpaceType); return fDeviceSpaceRRect;
}
/** If getType() is not kEmpty this indicates whether the clip shape should be anti-aliased
when it is rasterized. */ bool isAA() const { return fDoAA; }
/** The GenID can be used by clip stack clients to cache representations of the clip. The IDcorrespondstothesetofclipelementsuptoandincludingthiselementwithinthe stacknottotheelementitself.Thatisthesameclippathindifferentstackswill haveadifferentIDsincetheelementsproducedifferentclipresultinthecontextof
their stacks. */
uint32_t getGenID() const { SkASSERT(kInvalidGenID != fGenID); return fGenID; }
std::optional<SkPath> fDeviceSpacePath;
SkRRect fDeviceSpaceRRect;
sk_sp<SkShader> fShader; int fSaveCount; // save count of stack when this element was added.
SkClipOp fOp;
DeviceSpaceType fDeviceSpaceType; bool fDoAA; bool fIsReplace;
/* fFiniteBoundType and fFiniteBound are used to incrementally update the clip stack's bound.WhenfFiniteBoundTypeiskNormal_BoundsType,fFiniteBoundrepresentsthe conservativeboundingboxofthepixelsthataren'tclipped(i.e.,anypixelsthatcanbe drawntoareinsidethebound).WhenfFiniteBoundTypeiskInsideOut_BoundsType(which occurswhenaclipisinversefilled),fFiniteBoundrepresentstheconservativebounding boxofthepixelsthat_are_clipped(i.e.,anypixelsthatcannotbedrawntoareinside thebound).WhenfFiniteBoundTypeiskInsideOut_BoundsTypetheactualboundisthe infiniteplane.ThisbehavioroffFiniteBoundTypeandfFiniteBoundisrequiredsothatwe cancapturethecancellingoutoftheextensionstoinfinitywhentwoinversefilled
clips are Booleaned together. */
SkClipStack::BoundsType fFiniteBoundType;
SkRect fFiniteBound;
// When element is applied to the previous elements in the stack is the result known to be // equivalent to a single rect intersection? IIOW, is the clip effectively a rectangle. bool fIsIntersectionOfRects;
// All Element methods below are only used within SkClipStack.cpp inlinevoid checkEmpty() const; inlinebool canBeIntersectedInPlace(int saveCount, SkClipOp op) const; /* This method checks to see if two rect clips can be safely merged into one. The issue here isthattobestrictlycorrectalltheedgesoftheresultingrectmusthavethesame
anti-aliasing. */ bool rectRectIntersectAllowed(const SkRect& newR, bool newAA) const; /** Determines possible finite bounds for the Element given the previous element of the
stack */ void updateBoundAndGenID(const Element* prior); // The different combination of fill & inverse fill when combining bounding boxes enum FillCombo {
kPrev_Cur_FillCombo,
kPrev_InvCur_FillCombo,
kInvPrev_Cur_FillCombo,
kInvPrev_InvCur_FillCombo
}; // per-set operation functions used by updateBoundAndGenID(). inlinevoid combineBoundsDiff(FillCombo combination, const SkRect& prevFinite); inlinevoid combineBoundsIntersection(int combination, const SkRect& prevFinite);
};
/** *ThegenerationIDhasthreereservedvaluestoindicatespecial *(potentiallyignorable)cases
*/ staticconst uint32_t kInvalidGenID = 0; //!< Invalid id that is never returned by //!< SkClipStack. Useful when caching clips //!< based on GenID. staticconst uint32_t kEmptyGenID = 1; // no pixels writeable staticconst uint32_t kWideOpenGenID = 2; // all pixels writeable
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.