123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779 |
- /*
- * Copyright 2006 The Android Open Source Project
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
- /* Generated by tools/bookmaker from include/core/SkPath.h and docs/SkPath_Reference.bmh
- on 2018-09-13 13:59:55. Additional documentation and examples can be found at:
- https://skia.org/user/api/SkPath_Reference
- You may edit either file directly. Structural changes to public interfaces require
- editing both files. After editing docs/SkPath_Reference.bmh, run:
- bookmaker -b docs -i include/core/SkPath.h -p
- to create an updated version of this file.
- */
- #ifndef SkPath_DEFINED
- #define SkPath_DEFINED
- #include "SkMatrix.h"
- #include "../private/SkPathRef.h"
- #include "../private/SkTo.h"
- #include <initializer_list>
- class SkAutoPathBoundsUpdate;
- class SkData;
- class SkRRect;
- class SkWStream;
- /** \class SkPath
- SkPath contain geometry. SkPath may be empty, or contain one or more verbs that
- outline a figure. SkPath always starts with a move verb to a Cartesian coordinate,
- and may be followed by additional verbs that add lines or curves.
- Adding a close verb makes the geometry into a continuous loop, a closed contour.
- SkPath may contain any number of contours, each beginning with a move verb.
- SkPath contours may contain only a move verb, or may also contain lines,
- quadratic beziers, conics, and cubic beziers. SkPath contours may be open or
- closed.
- When used to draw a filled area, SkPath describes whether the fill is inside or
- outside the geometry. SkPath also describes the winding rule used to fill
- overlapping contours.
- Internally, SkPath lazily computes metrics likes bounds and convexity. Call
- SkPath::updateBoundsCache to make SkPath thread safe.
- */
- class SK_API SkPath {
- public:
- /** \enum SkPath::Direction
- Direction describes whether contour is clockwise or counterclockwise.
- When SkPath contains multiple overlapping contours, Direction together with
- FillType determines whether overlaps are filled or form holes.
- Direction also determines how contour is measured. For instance, dashing
- measures along SkPath to determine where to start and stop stroke; Direction
- will change dashed results as it steps clockwise or counterclockwise.
- Closed contours like SkRect, SkRRect, circle, and oval added with
- kCW_Direction travel clockwise; the same added with kCCW_Direction
- travel counterclockwise.
- */
- enum Direction : int {
- kCW_Direction, //!< contour travels clockwise
- kCCW_Direction, //!< contour travels counterclockwise
- };
- /** Constructs an empty SkPath. By default, SkPath has no verbs, no SkPoint, and no weights.
- SkPath::FillType is set to kWinding_FillType.
- @return empty SkPath
- */
- SkPath();
- /** Constructs a copy of an existing path.
- Copy constructor makes two paths identical by value. Internally, path and
- the returned result share pointer values. The underlying verb array, SkPoint array
- and weights are copied when modified.
- Creating a SkPath copy is very efficient and never allocates memory.
- SkPath are always copied by value from the interface; the underlying shared
- pointers are not exposed.
- @param path SkPath to copy by value
- @return copy of SkPath
- */
- SkPath(const SkPath& path);
- /** Releases ownership of any shared data and deletes data if SkPath is sole owner.
- */
- ~SkPath();
- /** Constructs a copy of an existing path.
- SkPath assignment makes two paths identical by value. Internally, assignment
- shares pointer values. The underlying verb array, SkPoint array and weights
- are copied when modified.
- Copying SkPath by assignment is very efficient and never allocates memory.
- SkPath are always copied by value from the interface; the underlying shared
- pointers are not exposed.
- @param path verb array, SkPoint array, weights, and SkPath::FillType to copy
- @return SkPath copied by value
- */
- SkPath& operator=(const SkPath& path);
- /** Compares a and b; returns true if SkPath::FillType, verb array, SkPoint array, and weights
- are equivalent.
- @param a SkPath to compare
- @param b SkPath to compare
- @return true if SkPath pair are equivalent
- */
- friend SK_API bool operator==(const SkPath& a, const SkPath& b);
- /** Compares a and b; returns true if SkPath::FillType, verb array, SkPoint array, and weights
- are not equivalent.
- @param a SkPath to compare
- @param b SkPath to compare
- @return true if SkPath pair are not equivalent
- */
- friend bool operator!=(const SkPath& a, const SkPath& b) {
- return !(a == b);
- }
- /** Returns true if SkPath contain equal verbs and equal weights.
- If SkPath contain one or more conics, the weights must match.
- conicTo() may add different verbs depending on conic weight, so it is not
- trivial to interpolate a pair of SkPath containing conics with different
- conic weight values.
- @param compare SkPath to compare
- @return true if SkPath verb array and weights are equivalent
- */
- bool isInterpolatable(const SkPath& compare) const;
- /** Interpolates between SkPath with SkPoint array of equal size.
- Copy verb array and weights to out, and set out SkPoint array to a weighted
- average of this SkPoint array and ending SkPoint array, using the formula:
- (Path Point * weight) + ending Point * (1 - weight).
- weight is most useful when between zero (ending SkPoint array) and
- one (this Point_Array); will work with values outside of this
- range.
- interpolate() returns false and leaves out unchanged if SkPoint array is not
- the same size as ending SkPoint array. Call isInterpolatable() to check SkPath
- compatibility prior to calling interpolate().
- @param ending SkPoint array averaged with this SkPoint array
- @param weight contribution of this SkPoint array, and
- one minus contribution of ending SkPoint array
- @param out SkPath replaced by interpolated averages
- @return true if SkPath contain same number of SkPoint
- */
- bool interpolate(const SkPath& ending, SkScalar weight, SkPath* out) const;
- /** \enum SkPath::FillType
- FillType selects the rule used to fill SkPath. SkPath set to kWinding_FillType
- fills if the sum of contour edges is not zero, where clockwise edges add one, and
- counterclockwise edges subtract one. SkPath set to kEvenOdd_FillType fills if the
- number of contour edges is odd. Each FillType has an inverse variant that
- reverses the rule:
- kInverseWinding_FillType fills where the sum of contour edges is zero;
- kInverseEvenOdd_FillType fills where the number of contour edges is even.
- */
- enum FillType {
- kWinding_FillType, //!< is enclosed by a non-zero sum of contour directions
- kEvenOdd_FillType, //!< is enclosed by an odd number of contours
- kInverseWinding_FillType, //!< is enclosed by a zero sum of contour directions
- kInverseEvenOdd_FillType, //!< is enclosed by an even number of contours
- };
- /** Returns FillType, the rule used to fill SkPath. FillType of a new SkPath is
- kWinding_FillType.
- @return one of: kWinding_FillType, kEvenOdd_FillType, kInverseWinding_FillType,
- kInverseEvenOdd_FillType
- */
- FillType getFillType() const { return (FillType)fFillType; }
- /** Sets FillType, the rule used to fill SkPath. While there is no check
- that ft is legal, values outside of FillType are not supported.
- @param ft one of: kWinding_FillType, kEvenOdd_FillType, kInverseWinding_FillType,
- kInverseEvenOdd_FillType
- */
- void setFillType(FillType ft) {
- fFillType = SkToU8(ft);
- }
- /** Returns if FillType describes area outside SkPath geometry. The inverse fill area
- extends indefinitely.
- @return true if FillType is kInverseWinding_FillType or kInverseEvenOdd_FillType
- */
- bool isInverseFillType() const { return IsInverseFillType((FillType)fFillType); }
- /** Replaces FillType with its inverse. The inverse of FillType describes the area
- unmodified by the original FillType.
- */
- void toggleInverseFillType() {
- fFillType ^= 2;
- }
- /** \enum SkPath::Convexity
- SkPath is convex if it contains one contour and contour loops no more than
- 360 degrees, and contour angles all have same Direction. Convex SkPath
- may have better performance and require fewer resources on GPU surface.
- SkPath is concave when either at least one Direction change is clockwise and
- another is counterclockwise, or the sum of the changes in Direction is not 360
- degrees.
- Initially SkPath Convexity is kUnknown_Convexity. SkPath Convexity is computed
- if needed by destination SkSurface.
- */
- enum Convexity : uint8_t {
- kUnknown_Convexity, //!< indicates Convexity has not been determined
- kConvex_Convexity, //!< one contour made of a simple geometry without indentations
- kConcave_Convexity, //!< more than one contour, or a geometry with indentations
- };
- /** Computes SkPath::Convexity if required, and returns stored value.
- SkPath::Convexity is computed if stored value is kUnknown_Convexity,
- or if SkPath has been altered since SkPath::Convexity was computed or set.
- @return computed or stored SkPath::Convexity
- */
- Convexity getConvexity() const {
- for (Convexity convexity = fConvexity.load(); kUnknown_Convexity != convexity; ) {
- return convexity;
- }
- return this->internalGetConvexity();
- }
- /** Returns last computed SkPath::Convexity, or kUnknown_Convexity if
- SkPath has been altered since SkPath::Convexity was computed or set.
- @return stored SkPath::Convexity
- */
- Convexity getConvexityOrUnknown() const { return (Convexity)fConvexity; }
- /** Stores convexity so that it is later returned by getConvexity() or getConvexityOrUnknown().
- convexity may differ from getConvexity(), although setting an incorrect value may
- cause incorrect or inefficient drawing.
- If convexity is kUnknown_Convexity: getConvexity() will
- compute SkPath::Convexity, and getConvexityOrUnknown() will return kUnknown_Convexity.
- If convexity is kConvex_Convexity or kConcave_Convexity, getConvexity()
- and getConvexityOrUnknown() will return convexity until the path is
- altered.
- @param convexity one of: kUnknown_Convexity, kConvex_Convexity, or kConcave_Convexity
- */
- void setConvexity(Convexity convexity);
- /** Computes SkPath::Convexity if required, and returns true if value is kConvex_Convexity.
- If setConvexity() was called with kConvex_Convexity or kConcave_Convexity, and
- the path has not been altered, SkPath::Convexity is not recomputed.
- @return true if SkPath::Convexity stored or computed is kConvex_Convexity
- */
- bool isConvex() const {
- return kConvex_Convexity == this->getConvexity();
- }
- /** Returns true if this path is recognized as an oval or circle.
- bounds receives bounds of oval.
- bounds is unmodified if oval is not found.
- @param bounds storage for bounding SkRect of oval; may be nullptr
- @return true if SkPath is recognized as an oval or circle
- */
- bool isOval(SkRect* bounds) const;
- /** Returns true if path is representable as SkRRect.
- Returns false if path is representable as oval, circle, or SkRect.
- rrect receives bounds of SkRRect.
- rrect is unmodified if SkRRect is not found.
- @param rrect storage for bounding SkRect of SkRRect; may be nullptr
- @return true if SkPath contains only SkRRect
- */
- bool isRRect(SkRRect* rrect) const;
- /** Sets SkPath to its initial state.
- Removes verb array, SkPoint array, and weights, and sets FillType to kWinding_FillType.
- Internal storage associated with SkPath is released.
- @return reference to SkPath
- */
- SkPath& reset();
- /** Sets SkPath to its initial state, preserving internal storage.
- Removes verb array, SkPoint array, and weights, and sets FillType to kWinding_FillType.
- Internal storage associated with SkPath is retained.
- Use rewind() instead of reset() if SkPath storage will be reused and performance
- is critical.
- @return reference to SkPath
- */
- SkPath& rewind();
- /** Returns if SkPath is empty.
- Empty SkPath may have FillType but has no SkPoint, SkPath::Verb, or conic weight.
- SkPath() constructs empty SkPath; reset() and rewind() make SkPath empty.
- @return true if the path contains no SkPath::Verb array
- */
- bool isEmpty() const {
- SkDEBUGCODE(this->validate();)
- return 0 == fPathRef->countVerbs();
- }
- /** Returns if contour is closed.
- Contour is closed if SkPath SkPath::Verb array was last modified by close(). When stroked,
- closed contour draws SkPaint::Join instead of SkPaint::Cap at first and last SkPoint.
- @return true if the last contour ends with a kClose_Verb
- */
- bool isLastContourClosed() const;
- /** Returns true for finite SkPoint array values between negative SK_ScalarMax and
- positive SK_ScalarMax. Returns false for any SkPoint array value of
- SK_ScalarInfinity, SK_ScalarNegativeInfinity, or SK_ScalarNaN.
- @return true if all SkPoint values are finite
- */
- bool isFinite() const {
- SkDEBUGCODE(this->validate();)
- return fPathRef->isFinite();
- }
- /** Returns true if the path is volatile; it will not be altered or discarded
- by the caller after it is drawn. SkPath by default have volatile set false, allowing
- SkSurface to attach a cache of data which speeds repeated drawing. If true, SkSurface
- may not speed repeated drawing.
- @return true if caller will alter SkPath after drawing
- */
- bool isVolatile() const {
- return SkToBool(fIsVolatile);
- }
- /** Specifies whether SkPath is volatile; whether it will be altered or discarded
- by the caller after it is drawn. SkPath by default have volatile set false, allowing
- SkBaseDevice to attach a cache of data which speeds repeated drawing.
- Mark temporary paths, discarded or modified after use, as volatile
- to inform SkBaseDevice that the path need not be cached.
- Mark animating SkPath volatile to improve performance.
- Mark unchanging SkPath non-volatile to improve repeated rendering.
- raster surface SkPath draws are affected by volatile for some shadows.
- GPU surface SkPath draws are affected by volatile for some shadows and concave geometries.
- @param isVolatile true if caller will alter SkPath after drawing
- */
- void setIsVolatile(bool isVolatile) {
- fIsVolatile = isVolatile;
- }
- /** Tests if line between SkPoint pair is degenerate.
- Line with no length or that moves a very short distance is degenerate; it is
- treated as a point.
- exact changes the equality test. If true, returns true only if p1 equals p2.
- If false, returns true if p1 equals or nearly equals p2.
- @param p1 line start point
- @param p2 line end point
- @param exact if false, allow nearly equals
- @return true if line is degenerate; its length is effectively zero
- */
- static bool IsLineDegenerate(const SkPoint& p1, const SkPoint& p2, bool exact);
- /** Tests if quad is degenerate.
- Quad with no length or that moves a very short distance is degenerate; it is
- treated as a point.
- @param p1 quad start point
- @param p2 quad control point
- @param p3 quad end point
- @param exact if true, returns true only if p1, p2, and p3 are equal;
- if false, returns true if p1, p2, and p3 are equal or nearly equal
- @return true if quad is degenerate; its length is effectively zero
- */
- static bool IsQuadDegenerate(const SkPoint& p1, const SkPoint& p2,
- const SkPoint& p3, bool exact);
- /** Tests if cubic is degenerate.
- Cubic with no length or that moves a very short distance is degenerate; it is
- treated as a point.
- @param p1 cubic start point
- @param p2 cubic control point 1
- @param p3 cubic control point 2
- @param p4 cubic end point
- @param exact if true, returns true only if p1, p2, p3, and p4 are equal;
- if false, returns true if p1, p2, p3, and p4 are equal or nearly equal
- @return true if cubic is degenerate; its length is effectively zero
- */
- static bool IsCubicDegenerate(const SkPoint& p1, const SkPoint& p2,
- const SkPoint& p3, const SkPoint& p4, bool exact);
- /** Returns true if SkPath contains only one line;
- SkPath::Verb array has two entries: kMove_Verb, kLine_Verb.
- If SkPath contains one line and line is not nullptr, line is set to
- line start point and line end point.
- Returns false if SkPath is not one line; line is unaltered.
- @param line storage for line. May be nullptr
- @return true if SkPath contains exactly one line
- */
- bool isLine(SkPoint line[2]) const;
- /** Returns the number of points in SkPath.
- SkPoint count is initially zero.
- @return SkPath SkPoint array length
- */
- int countPoints() const;
- /** Returns SkPoint at index in SkPoint array. Valid range for index is
- 0 to countPoints() - 1.
- Returns (0, 0) if index is out of range.
- @param index SkPoint array element selector
- @return SkPoint array value or (0, 0)
- */
- SkPoint getPoint(int index) const;
- /** Returns number of points in SkPath. Up to max points are copied.
- points may be nullptr; then, max must be zero.
- If max is greater than number of points, excess points storage is unaltered.
- @param points storage for SkPath SkPoint array. May be nullptr
- @param max maximum to copy; must be greater than or equal to zero
- @return SkPath SkPoint array length
- */
- int getPoints(SkPoint points[], int max) const;
- /** Returns the number of verbs: kMove_Verb, kLine_Verb, kQuad_Verb, kConic_Verb,
- kCubic_Verb, and kClose_Verb; added to SkPath.
- @return length of verb array
- */
- int countVerbs() const;
- /** Returns the number of verbs in the path. Up to max verbs are copied. The
- verbs are copied as one byte per verb.
- @param verbs storage for verbs, may be nullptr
- @param max maximum number to copy into verbs
- @return the actual number of verbs in the path
- */
- int getVerbs(uint8_t verbs[], int max) const;
- /** Exchanges the verb array, SkPoint array, weights, and SkPath::FillType with other.
- Cached state is also exchanged. swap() internally exchanges pointers, so
- it is lightweight and does not allocate memory.
- swap() usage has largely been replaced by operator=(const SkPath& path).
- SkPath do not copy their content on assignment until they are written to,
- making assignment as efficient as swap().
- @param other SkPath exchanged by value
- */
- void swap(SkPath& other);
- /** Returns minimum and maximum axes values of SkPoint array.
- Returns (0, 0, 0, 0) if SkPath contains no points. Returned bounds width and height may
- be larger or smaller than area affected when SkPath is drawn.
- SkRect returned includes all SkPoint added to SkPath, including SkPoint associated with
- kMove_Verb that define empty contours.
- @return bounds of all SkPoint in SkPoint array
- */
- const SkRect& getBounds() const {
- return fPathRef->getBounds();
- }
- /** Updates internal bounds so that subsequent calls to getBounds() are instantaneous.
- Unaltered copies of SkPath may also access cached bounds through getBounds().
- For now, identical to calling getBounds() and ignoring the returned value.
- Call to prepare SkPath subsequently drawn from multiple threads,
- to avoid a race condition where each draw separately computes the bounds.
- */
- void updateBoundsCache() const {
- // for now, just calling getBounds() is sufficient
- this->getBounds();
- }
- /** Returns minimum and maximum axes values of the lines and curves in SkPath.
- Returns (0, 0, 0, 0) if SkPath contains no points.
- Returned bounds width and height may be larger or smaller than area affected
- when SkPath is drawn.
- Includes SkPoint associated with kMove_Verb that define empty
- contours.
- Behaves identically to getBounds() when SkPath contains
- only lines. If SkPath contains curves, computed bounds includes
- the maximum extent of the quad, conic, or cubic; is slower than getBounds();
- and unlike getBounds(), does not cache the result.
- @return tight bounds of curves in SkPath
- */
- SkRect computeTightBounds() const;
- /** Returns true if rect is contained by SkPath.
- May return false when rect is contained by SkPath.
- For now, only returns true if SkPath has one contour and is convex.
- rect may share points and edges with SkPath and be contained.
- Returns true if rect is empty, that is, it has zero width or height; and
- the SkPoint or line described by rect is contained by SkPath.
- @param rect SkRect, line, or SkPoint checked for containment
- @return true if rect is contained
- */
- bool conservativelyContainsRect(const SkRect& rect) const;
- /** Grows SkPath verb array and SkPoint array to contain extraPtCount additional SkPoint.
- May improve performance and use less memory by
- reducing the number and size of allocations when creating SkPath.
- @param extraPtCount number of additional SkPoint to allocate
- */
- void incReserve(int extraPtCount);
- /** Shrinks SkPath verb array and SkPoint array storage to discard unused capacity.
- May reduce the heap overhead for SkPath known to be fully constructed.
- */
- void shrinkToFit();
- /** Adds beginning of contour at SkPoint (x, y).
- @param x x-axis value of contour start
- @param y y-axis value of contour start
- @return reference to SkPath
- */
- SkPath& moveTo(SkScalar x, SkScalar y);
- /** Adds beginning of contour at SkPoint p.
- @param p contour start
- @return reference to SkPath
- */
- SkPath& moveTo(const SkPoint& p) {
- return this->moveTo(p.fX, p.fY);
- }
- /** Adds beginning of contour relative to last point.
- If SkPath is empty, starts contour at (dx, dy).
- Otherwise, start contour at last point offset by (dx, dy).
- Function name stands for "relative move to".
- @param dx offset from last point to contour start on x-axis
- @param dy offset from last point to contour start on y-axis
- @return reference to SkPath
- */
- SkPath& rMoveTo(SkScalar dx, SkScalar dy);
- /** Adds line from last point to (x, y). If SkPath is empty, or last SkPath::Verb is
- kClose_Verb, last point is set to (0, 0) before adding line.
- lineTo() appends kMove_Verb to verb array and (0, 0) to SkPoint array, if needed.
- lineTo() then appends kLine_Verb to verb array and (x, y) to SkPoint array.
- @param x end of added line on x-axis
- @param y end of added line on y-axis
- @return reference to SkPath
- */
- SkPath& lineTo(SkScalar x, SkScalar y);
- /** Adds line from last point to SkPoint p. If SkPath is empty, or last SkPath::Verb is
- kClose_Verb, last point is set to (0, 0) before adding line.
- lineTo() first appends kMove_Verb to verb array and (0, 0) to SkPoint array, if needed.
- lineTo() then appends kLine_Verb to verb array and SkPoint p to SkPoint array.
- @param p end SkPoint of added line
- @return reference to SkPath
- */
- SkPath& lineTo(const SkPoint& p) {
- return this->lineTo(p.fX, p.fY);
- }
- /** Adds line from last point to vector (dx, dy). If SkPath is empty, or last SkPath::Verb is
- kClose_Verb, last point is set to (0, 0) before adding line.
- Appends kMove_Verb to verb array and (0, 0) to SkPoint array, if needed;
- then appends kLine_Verb to verb array and line end to SkPoint array.
- Line end is last point plus vector (dx, dy).
- Function name stands for "relative line to".
- @param dx offset from last point to line end on x-axis
- @param dy offset from last point to line end on y-axis
- @return reference to SkPath
- */
- SkPath& rLineTo(SkScalar dx, SkScalar dy);
- /** Adds quad from last point towards (x1, y1), to (x2, y2).
- If SkPath is empty, or last SkPath::Verb is kClose_Verb, last point is set to (0, 0)
- before adding quad.
- Appends kMove_Verb to verb array and (0, 0) to SkPoint array, if needed;
- then appends kQuad_Verb to verb array; and (x1, y1), (x2, y2)
- to SkPoint array.
- @param x1 control SkPoint of quad on x-axis
- @param y1 control SkPoint of quad on y-axis
- @param x2 end SkPoint of quad on x-axis
- @param y2 end SkPoint of quad on y-axis
- @return reference to SkPath
- */
- SkPath& quadTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2);
- /** Adds quad from last point towards SkPoint p1, to SkPoint p2.
- If SkPath is empty, or last SkPath::Verb is kClose_Verb, last point is set to (0, 0)
- before adding quad.
- Appends kMove_Verb to verb array and (0, 0) to SkPoint array, if needed;
- then appends kQuad_Verb to verb array; and SkPoint p1, p2
- to SkPoint array.
- @param p1 control SkPoint of added quad
- @param p2 end SkPoint of added quad
- @return reference to SkPath
- */
- SkPath& quadTo(const SkPoint& p1, const SkPoint& p2) {
- return this->quadTo(p1.fX, p1.fY, p2.fX, p2.fY);
- }
- /** Adds quad from last point towards vector (dx1, dy1), to vector (dx2, dy2).
- If SkPath is empty, or last SkPath::Verb
- is kClose_Verb, last point is set to (0, 0) before adding quad.
- Appends kMove_Verb to verb array and (0, 0) to SkPoint array,
- if needed; then appends kQuad_Verb to verb array; and appends quad
- control and quad end to SkPoint array.
- Quad control is last point plus vector (dx1, dy1).
- Quad end is last point plus vector (dx2, dy2).
- Function name stands for "relative quad to".
- @param dx1 offset from last point to quad control on x-axis
- @param dy1 offset from last point to quad control on y-axis
- @param dx2 offset from last point to quad end on x-axis
- @param dy2 offset from last point to quad end on y-axis
- @return reference to SkPath
- */
- SkPath& rQuadTo(SkScalar dx1, SkScalar dy1, SkScalar dx2, SkScalar dy2);
- /** Adds conic from last point towards (x1, y1), to (x2, y2), weighted by w.
- If SkPath is empty, or last SkPath::Verb is kClose_Verb, last point is set to (0, 0)
- before adding conic.
- Appends kMove_Verb to verb array and (0, 0) to SkPoint array, if needed.
- If w is finite and not one, appends kConic_Verb to verb array;
- and (x1, y1), (x2, y2) to SkPoint array; and w to conic weights.
- If w is one, appends kQuad_Verb to verb array, and
- (x1, y1), (x2, y2) to SkPoint array.
- If w is not finite, appends kLine_Verb twice to verb array, and
- (x1, y1), (x2, y2) to SkPoint array.
- @param x1 control SkPoint of conic on x-axis
- @param y1 control SkPoint of conic on y-axis
- @param x2 end SkPoint of conic on x-axis
- @param y2 end SkPoint of conic on y-axis
- @param w weight of added conic
- @return reference to SkPath
- */
- SkPath& conicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2,
- SkScalar w);
- /** Adds conic from last point towards SkPoint p1, to SkPoint p2, weighted by w.
- If SkPath is empty, or last SkPath::Verb is kClose_Verb, last point is set to (0, 0)
- before adding conic.
- Appends kMove_Verb to verb array and (0, 0) to SkPoint array, if needed.
- If w is finite and not one, appends kConic_Verb to verb array;
- and SkPoint p1, p2 to SkPoint array; and w to conic weights.
- If w is one, appends kQuad_Verb to verb array, and SkPoint p1, p2
- to SkPoint array.
- If w is not finite, appends kLine_Verb twice to verb array, and
- SkPoint p1, p2 to SkPoint array.
- @param p1 control SkPoint of added conic
- @param p2 end SkPoint of added conic
- @param w weight of added conic
- @return reference to SkPath
- */
- SkPath& conicTo(const SkPoint& p1, const SkPoint& p2, SkScalar w) {
- return this->conicTo(p1.fX, p1.fY, p2.fX, p2.fY, w);
- }
- /** Adds conic from last point towards vector (dx1, dy1), to vector (dx2, dy2),
- weighted by w. If SkPath is empty, or last SkPath::Verb
- is kClose_Verb, last point is set to (0, 0) before adding conic.
- Appends kMove_Verb to verb array and (0, 0) to SkPoint array,
- if needed.
- If w is finite and not one, next appends kConic_Verb to verb array,
- and w is recorded as conic weight; otherwise, if w is one, appends
- kQuad_Verb to verb array; or if w is not finite, appends kLine_Verb
- twice to verb array.
- In all cases appends SkPoint control and end to SkPoint array.
- control is last point plus vector (dx1, dy1).
- end is last point plus vector (dx2, dy2).
- Function name stands for "relative conic to".
- @param dx1 offset from last point to conic control on x-axis
- @param dy1 offset from last point to conic control on y-axis
- @param dx2 offset from last point to conic end on x-axis
- @param dy2 offset from last point to conic end on y-axis
- @param w weight of added conic
- @return reference to SkPath
- */
- SkPath& rConicTo(SkScalar dx1, SkScalar dy1, SkScalar dx2, SkScalar dy2,
- SkScalar w);
- /** Adds cubic from last point towards (x1, y1), then towards (x2, y2), ending at
- (x3, y3). If SkPath is empty, or last SkPath::Verb is kClose_Verb, last point is set to
- (0, 0) before adding cubic.
- Appends kMove_Verb to verb array and (0, 0) to SkPoint array, if needed;
- then appends kCubic_Verb to verb array; and (x1, y1), (x2, y2), (x3, y3)
- to SkPoint array.
- @param x1 first control SkPoint of cubic on x-axis
- @param y1 first control SkPoint of cubic on y-axis
- @param x2 second control SkPoint of cubic on x-axis
- @param y2 second control SkPoint of cubic on y-axis
- @param x3 end SkPoint of cubic on x-axis
- @param y3 end SkPoint of cubic on y-axis
- @return reference to SkPath
- */
- SkPath& cubicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2,
- SkScalar x3, SkScalar y3);
- /** Adds cubic from last point towards SkPoint p1, then towards SkPoint p2, ending at
- SkPoint p3. If SkPath is empty, or last SkPath::Verb is kClose_Verb, last point is set to
- (0, 0) before adding cubic.
- Appends kMove_Verb to verb array and (0, 0) to SkPoint array, if needed;
- then appends kCubic_Verb to verb array; and SkPoint p1, p2, p3
- to SkPoint array.
- @param p1 first control SkPoint of cubic
- @param p2 second control SkPoint of cubic
- @param p3 end SkPoint of cubic
- @return reference to SkPath
- */
- SkPath& cubicTo(const SkPoint& p1, const SkPoint& p2, const SkPoint& p3) {
- return this->cubicTo(p1.fX, p1.fY, p2.fX, p2.fY, p3.fX, p3.fY);
- }
- /** Adds cubic from last point towards vector (dx1, dy1), then towards
- vector (dx2, dy2), to vector (dx3, dy3).
- If SkPath is empty, or last SkPath::Verb
- is kClose_Verb, last point is set to (0, 0) before adding cubic.
- Appends kMove_Verb to verb array and (0, 0) to SkPoint array,
- if needed; then appends kCubic_Verb to verb array; and appends cubic
- control and cubic end to SkPoint array.
- Cubic control is last point plus vector (dx1, dy1).
- Cubic end is last point plus vector (dx2, dy2).
- Function name stands for "relative cubic to".
- @param dx1 offset from last point to first cubic control on x-axis
- @param dy1 offset from last point to first cubic control on y-axis
- @param dx2 offset from last point to second cubic control on x-axis
- @param dy2 offset from last point to second cubic control on y-axis
- @param dx3 offset from last point to cubic end on x-axis
- @param dy3 offset from last point to cubic end on y-axis
- @return reference to SkPath
- */
- SkPath& rCubicTo(SkScalar dx1, SkScalar dy1, SkScalar dx2, SkScalar dy2,
- SkScalar dx3, SkScalar dy3);
- /** Appends arc to SkPath. Arc added is part of ellipse
- bounded by oval, from startAngle through sweepAngle. Both startAngle and
- sweepAngle are measured in degrees, where zero degrees is aligned with the
- positive x-axis, and positive sweeps extends arc clockwise.
- arcTo() adds line connecting SkPath last SkPoint to initial arc SkPoint if forceMoveTo
- is false and SkPath is not empty. Otherwise, added contour begins with first point
- of arc. Angles greater than -360 and less than 360 are treated modulo 360.
- @param oval bounds of ellipse containing arc
- @param startAngle starting angle of arc in degrees
- @param sweepAngle sweep, in degrees. Positive is clockwise; treated modulo 360
- @param forceMoveTo true to start a new contour with arc
- @return reference to SkPath
- */
- SkPath& arcTo(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle, bool forceMoveTo);
- /** Appends arc to SkPath, after appending line if needed. Arc is implemented by conic
- weighted to describe part of circle. Arc is contained by tangent from
- last SkPath point to (x1, y1), and tangent from (x1, y1) to (x2, y2). Arc
- is part of circle sized to radius, positioned so it touches both tangent lines.
- If last Path Point does not start Arc, arcTo appends connecting Line to Path.
- The length of Vector from (x1, y1) to (x2, y2) does not affect Arc.
- Arc sweep is always less than 180 degrees. If radius is zero, or if
- tangents are nearly parallel, arcTo appends Line from last Path Point to (x1, y1).
- arcTo appends at most one Line and one conic.
- arcTo implements the functionality of PostScript arct and HTML Canvas arcTo.
- @param x1 x-axis value common to pair of tangents
- @param y1 y-axis value common to pair of tangents
- @param x2 x-axis value end of second tangent
- @param y2 y-axis value end of second tangent
- @param radius distance from arc to circle center
- @return reference to SkPath
- */
- SkPath& arcTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2, SkScalar radius);
- /** Appends arc to SkPath, after appending line if needed. Arc is implemented by conic
- weighted to describe part of circle. Arc is contained by tangent from
- last SkPath point to p1, and tangent from p1 to p2. Arc
- is part of circle sized to radius, positioned so it touches both tangent lines.
- If last SkPath SkPoint does not start arc, arcTo() appends connecting line to SkPath.
- The length of vector from p1 to p2 does not affect arc.
- Arc sweep is always less than 180 degrees. If radius is zero, or if
- tangents are nearly parallel, arcTo() appends line from last SkPath SkPoint to p1.
- arcTo() appends at most one line and one conic.
- arcTo() implements the functionality of PostScript arct and HTML Canvas arcTo.
- @param p1 SkPoint common to pair of tangents
- @param p2 end of second tangent
- @param radius distance from arc to circle center
- @return reference to SkPath
- */
- SkPath& arcTo(const SkPoint p1, const SkPoint p2, SkScalar radius) {
- return this->arcTo(p1.fX, p1.fY, p2.fX, p2.fY, radius);
- }
- /** \enum SkPath::ArcSize
- Four oval parts with radii (rx, ry) start at last SkPath SkPoint and ends at (x, y).
- ArcSize and Direction select one of the four oval parts.
- */
- enum ArcSize {
- kSmall_ArcSize, //!< smaller of arc pair
- kLarge_ArcSize, //!< larger of arc pair
- };
- /** Appends arc to SkPath. Arc is implemented by one or more conics weighted to
- describe part of oval with radii (rx, ry) rotated by xAxisRotate degrees. Arc
- curves from last SkPath SkPoint to (x, y), choosing one of four possible routes:
- clockwise or counterclockwise, and smaller or larger.
- Arc sweep is always less than 360 degrees. arcTo() appends line to (x, y) if
- either radii are zero, or if last SkPath SkPoint equals (x, y). arcTo() scales radii
- (rx, ry) to fit last SkPath SkPoint and (x, y) if both are greater than zero but
- too small.
- arcTo() appends up to four conic curves.
- arcTo() implements the functionality of SVG arc, although SVG sweep-flag value
- is opposite the integer value of sweep; SVG sweep-flag uses 1 for clockwise,
- while kCW_Direction cast to int is zero.
- @param rx radius on x-axis before x-axis rotation
- @param ry radius on y-axis before x-axis rotation
- @param xAxisRotate x-axis rotation in degrees; positive values are clockwise
- @param largeArc chooses smaller or larger arc
- @param sweep chooses clockwise or counterclockwise arc
- @param x end of arc
- @param y end of arc
- @return reference to SkPath
- */
- SkPath& arcTo(SkScalar rx, SkScalar ry, SkScalar xAxisRotate, ArcSize largeArc,
- Direction sweep, SkScalar x, SkScalar y);
- /** Appends arc to SkPath. Arc is implemented by one or more conic weighted to describe
- part of oval with radii (r.fX, r.fY) rotated by xAxisRotate degrees. Arc curves
- from last SkPath SkPoint to (xy.fX, xy.fY), choosing one of four possible routes:
- clockwise or counterclockwise,
- and smaller or larger.
- Arc sweep is always less than 360 degrees. arcTo() appends line to xy if either
- radii are zero, or if last SkPath SkPoint equals (xy.fX, xy.fY). arcTo() scales radii r to
- fit last SkPath SkPoint and xy if both are greater than zero but too small to describe
- an arc.
- arcTo() appends up to four conic curves.
- arcTo() implements the functionality of SVG arc, although SVG sweep-flag value is
- opposite the integer value of sweep; SVG sweep-flag uses 1 for clockwise, while
- kCW_Direction cast to int is zero.
- @param r radii on axes before x-axis rotation
- @param xAxisRotate x-axis rotation in degrees; positive values are clockwise
- @param largeArc chooses smaller or larger arc
- @param sweep chooses clockwise or counterclockwise arc
- @param xy end of arc
- @return reference to SkPath
- */
- SkPath& arcTo(const SkPoint r, SkScalar xAxisRotate, ArcSize largeArc, Direction sweep,
- const SkPoint xy) {
- return this->arcTo(r.fX, r.fY, xAxisRotate, largeArc, sweep, xy.fX, xy.fY);
- }
- /** Appends arc to SkPath, relative to last SkPath SkPoint. Arc is implemented by one or
- more conic, weighted to describe part of oval with radii (rx, ry) rotated by
- xAxisRotate degrees. Arc curves from last SkPath SkPoint to relative end SkPoint:
- (dx, dy), choosing one of four possible routes: clockwise or
- counterclockwise, and smaller or larger. If SkPath is empty, the start arc SkPoint
- is (0, 0).
- Arc sweep is always less than 360 degrees. arcTo() appends line to end SkPoint
- if either radii are zero, or if last SkPath SkPoint equals end SkPoint.
- arcTo() scales radii (rx, ry) to fit last SkPath SkPoint and end SkPoint if both are
- greater than zero but too small to describe an arc.
- arcTo() appends up to four conic curves.
- arcTo() implements the functionality of svg arc, although SVG "sweep-flag" value is
- opposite the integer value of sweep; SVG "sweep-flag" uses 1 for clockwise, while
- kCW_Direction cast to int is zero.
- @param rx radius before x-axis rotation
- @param ry radius before x-axis rotation
- @param xAxisRotate x-axis rotation in degrees; positive values are clockwise
- @param largeArc chooses smaller or larger arc
- @param sweep chooses clockwise or counterclockwise arc
- @param dx x-axis offset end of arc from last SkPath SkPoint
- @param dy y-axis offset end of arc from last SkPath SkPoint
- @return reference to SkPath
- */
- SkPath& rArcTo(SkScalar rx, SkScalar ry, SkScalar xAxisRotate, ArcSize largeArc,
- Direction sweep, SkScalar dx, SkScalar dy);
- /** Appends kClose_Verb to SkPath. A closed contour connects the first and last SkPoint
- with line, forming a continuous loop. Open and closed contour draw the same
- with SkPaint::kFill_Style. With SkPaint::kStroke_Style, open contour draws
- SkPaint::Cap at contour start and end; closed contour draws
- SkPaint::Join at contour start and end.
- close() has no effect if SkPath is empty or last SkPath SkPath::Verb is kClose_Verb.
- @return reference to SkPath
- */
- SkPath& close();
- /** Returns true if fill is inverted and SkPath with fill represents area outside
- of its geometric bounds.
- @param fill one of: kWinding_FillType, kEvenOdd_FillType,
- kInverseWinding_FillType, kInverseEvenOdd_FillType
- @return true if SkPath fills outside its bounds
- */
- static bool IsInverseFillType(FillType fill) {
- static_assert(0 == kWinding_FillType, "fill_type_mismatch");
- static_assert(1 == kEvenOdd_FillType, "fill_type_mismatch");
- static_assert(2 == kInverseWinding_FillType, "fill_type_mismatch");
- static_assert(3 == kInverseEvenOdd_FillType, "fill_type_mismatch");
- return (fill & 2) != 0;
- }
- /** Returns equivalent SkPath::FillType representing SkPath fill inside its bounds.
- .
- @param fill one of: kWinding_FillType, kEvenOdd_FillType,
- kInverseWinding_FillType, kInverseEvenOdd_FillType
- @return fill, or kWinding_FillType or kEvenOdd_FillType if fill is inverted
- */
- static FillType ConvertToNonInverseFillType(FillType fill) {
- static_assert(0 == kWinding_FillType, "fill_type_mismatch");
- static_assert(1 == kEvenOdd_FillType, "fill_type_mismatch");
- static_assert(2 == kInverseWinding_FillType, "fill_type_mismatch");
- static_assert(3 == kInverseEvenOdd_FillType, "fill_type_mismatch");
- return (FillType)(fill & 1);
- }
- /** Approximates conic with quad array. Conic is constructed from start SkPoint p0,
- control SkPoint p1, end SkPoint p2, and weight w.
- Quad array is stored in pts; this storage is supplied by caller.
- Maximum quad count is 2 to the pow2.
- Every third point in array shares last SkPoint of previous quad and first SkPoint of
- next quad. Maximum pts storage size is given by:
- (1 + 2 * (1 << pow2)) * sizeof(SkPoint).
- Returns quad count used the approximation, which may be smaller
- than the number requested.
- conic weight determines the amount of influence conic control point has on the curve.
- w less than one represents an elliptical section. w greater than one represents
- a hyperbolic section. w equal to one represents a parabolic section.
- Two quad curves are sufficient to approximate an elliptical conic with a sweep
- of up to 90 degrees; in this case, set pow2 to one.
- @param p0 conic start SkPoint
- @param p1 conic control SkPoint
- @param p2 conic end SkPoint
- @param w conic weight
- @param pts storage for quad array
- @param pow2 quad count, as power of two, normally 0 to 5 (1 to 32 quad curves)
- @return number of quad curves written to pts
- */
- static int ConvertConicToQuads(const SkPoint& p0, const SkPoint& p1, const SkPoint& p2,
- SkScalar w, SkPoint pts[], int pow2);
- /** Returns true if SkPath is equivalent to SkRect when filled.
- If false: rect, isClosed, and direction are unchanged.
- If true: rect, isClosed, and direction are written to if not nullptr.
- rect may be smaller than the SkPath bounds. SkPath bounds may include kMove_Verb points
- that do not alter the area drawn by the returned rect.
- @param rect storage for bounds of SkRect; may be nullptr
- @param isClosed storage set to true if SkPath is closed; may be nullptr
- @param direction storage set to SkRect direction; may be nullptr
- @return true if SkPath contains SkRect
- */
- bool isRect(SkRect* rect, bool* isClosed = nullptr, Direction* direction = nullptr) const;
- /** Returns true if SkPath is equivalent to nested SkRect pair when filled.
- If false, rect and dirs are unchanged.
- If true, rect and dirs are written to if not nullptr:
- setting rect[0] to outer SkRect, and rect[1] to inner SkRect;
- setting dirs[0] to SkPath::Direction of outer SkRect, and dirs[1] to SkPath::Direction of
- inner SkRect.
- @param rect storage for SkRect pair; may be nullptr
- @param dirs storage for SkPath::Direction pair; may be nullptr
- @return true if SkPath contains nested SkRect pair
- */
- bool isNestedFillRects(SkRect rect[2], Direction dirs[2] = nullptr) const;
- /** Adds SkRect to SkPath, appending kMove_Verb, three kLine_Verb, and kClose_Verb,
- starting with top-left corner of SkRect; followed by top-right, bottom-right,
- and bottom-left if dir is kCW_Direction; or followed by bottom-left,
- bottom-right, and top-right if dir is kCCW_Direction.
- @param rect SkRect to add as a closed contour
- @param dir SkPath::Direction to wind added contour
- @return reference to SkPath
- */
- SkPath& addRect(const SkRect& rect, Direction dir = kCW_Direction);
- /** Adds SkRect to SkPath, appending kMove_Verb, three kLine_Verb, and kClose_Verb.
- If dir is kCW_Direction, SkRect corners are added clockwise; if dir is
- kCCW_Direction, SkRect corners are added counterclockwise.
- start determines the first corner added.
- @param rect SkRect to add as a closed contour
- @param dir SkPath::Direction to wind added contour
- @param start initial corner of SkRect to add
- @return reference to SkPath
- */
- SkPath& addRect(const SkRect& rect, Direction dir, unsigned start);
- /** Adds SkRect (left, top, right, bottom) to SkPath,
- appending kMove_Verb, three kLine_Verb, and kClose_Verb,
- starting with top-left corner of SkRect; followed by top-right, bottom-right,
- and bottom-left if dir is kCW_Direction; or followed by bottom-left,
- bottom-right, and top-right if dir is kCCW_Direction.
- @param left smaller x-axis value of SkRect
- @param top smaller y-axis value of SkRect
- @param right larger x-axis value of SkRect
- @param bottom larger y-axis value of SkRect
- @param dir SkPath::Direction to wind added contour
- @return reference to SkPath
- */
- SkPath& addRect(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom,
- Direction dir = kCW_Direction);
- /** Adds oval to path, appending kMove_Verb, four kConic_Verb, and kClose_Verb.
- Oval is upright ellipse bounded by SkRect oval with radii equal to half oval width
- and half oval height. Oval begins at (oval.fRight, oval.centerY()) and continues
- clockwise if dir is kCW_Direction, counterclockwise if dir is kCCW_Direction.
- @param oval bounds of ellipse added
- @param dir SkPath::Direction to wind ellipse
- @return reference to SkPath
- */
- SkPath& addOval(const SkRect& oval, Direction dir = kCW_Direction);
- /** Adds oval to SkPath, appending kMove_Verb, four kConic_Verb, and kClose_Verb.
- Oval is upright ellipse bounded by SkRect oval with radii equal to half oval width
- and half oval height. Oval begins at start and continues
- clockwise if dir is kCW_Direction, counterclockwise if dir is kCCW_Direction.
- @param oval bounds of ellipse added
- @param dir SkPath::Direction to wind ellipse
- @param start index of initial point of ellipse
- @return reference to SkPath
- */
- SkPath& addOval(const SkRect& oval, Direction dir, unsigned start);
- /** Adds circle centered at (x, y) of size radius to SkPath, appending kMove_Verb,
- four kConic_Verb, and kClose_Verb. Circle begins at: (x + radius, y), continuing
- clockwise if dir is kCW_Direction, and counterclockwise if dir is kCCW_Direction.
- Has no effect if radius is zero or negative.
- @param x center of circle
- @param y center of circle
- @param radius distance from center to edge
- @param dir SkPath::Direction to wind circle
- @return reference to SkPath
- */
- SkPath& addCircle(SkScalar x, SkScalar y, SkScalar radius,
- Direction dir = kCW_Direction);
- /** Appends arc to SkPath, as the start of new contour. Arc added is part of ellipse
- bounded by oval, from startAngle through sweepAngle. Both startAngle and
- sweepAngle are measured in degrees, where zero degrees is aligned with the
- positive x-axis, and positive sweeps extends arc clockwise.
- If sweepAngle <= -360, or sweepAngle >= 360; and startAngle modulo 90 is nearly
- zero, append oval instead of arc. Otherwise, sweepAngle values are treated
- modulo 360, and arc may or may not draw depending on numeric rounding.
- @param oval bounds of ellipse containing arc
- @param startAngle starting angle of arc in degrees
- @param sweepAngle sweep, in degrees. Positive is clockwise; treated modulo 360
- @return reference to SkPath
- */
- SkPath& addArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle);
- /** Appends SkRRect to SkPath, creating a new closed contour. SkRRect has bounds
- equal to rect; each corner is 90 degrees of an ellipse with radii (rx, ry). If
- dir is kCW_Direction, SkRRect starts at top-left of the lower-left corner and
- winds clockwise. If dir is kCCW_Direction, SkRRect starts at the bottom-left
- of the upper-left corner and winds counterclockwise.
- If either rx or ry is too large, rx and ry are scaled uniformly until the
- corners fit. If rx or ry is less than or equal to zero, addRoundRect() appends
- SkRect rect to SkPath.
- After appending, SkPath may be empty, or may contain: SkRect, oval, or SkRRect.
- @param rect bounds of SkRRect
- @param rx x-axis radius of rounded corners on the SkRRect
- @param ry y-axis radius of rounded corners on the SkRRect
- @param dir SkPath::Direction to wind SkRRect
- @return reference to SkPath
- */
- SkPath& addRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry,
- Direction dir = kCW_Direction);
- /** Appends SkRRect to SkPath, creating a new closed contour. SkRRect has bounds
- equal to rect; each corner is 90 degrees of an ellipse with radii from the
- array.
- @param rect bounds of SkRRect
- @param radii array of 8 SkScalar values, a radius pair for each corner
- @param dir SkPath::Direction to wind SkRRect
- @return reference to SkPath
- */
- SkPath& addRoundRect(const SkRect& rect, const SkScalar radii[],
- Direction dir = kCW_Direction);
- /** Adds rrect to SkPath, creating a new closed contour. If
- dir is kCW_Direction, rrect starts at top-left of the lower-left corner and
- winds clockwise. If dir is kCCW_Direction, rrect starts at the bottom-left
- of the upper-left corner and winds counterclockwise.
- After appending, SkPath may be empty, or may contain: SkRect, oval, or SkRRect.
- @param rrect bounds and radii of rounded rectangle
- @param dir SkPath::Direction to wind SkRRect
- @return reference to SkPath
- */
- SkPath& addRRect(const SkRRect& rrect, Direction dir = kCW_Direction);
- /** Adds rrect to SkPath, creating a new closed contour. If dir is kCW_Direction, rrect
- winds clockwise; if dir is kCCW_Direction, rrect winds counterclockwise.
- start determines the first point of rrect to add.
- @param rrect bounds and radii of rounded rectangle
- @param dir SkPath::Direction to wind SkRRect
- @param start index of initial point of SkRRect
- @return reference to SkPath
- */
- SkPath& addRRect(const SkRRect& rrect, Direction dir, unsigned start);
- /** Adds contour created from line array, adding (count - 1) line segments.
- Contour added starts at pts[0], then adds a line for every additional SkPoint
- in pts array. If close is true, appends kClose_Verb to SkPath, connecting
- pts[count - 1] and pts[0].
- If count is zero, append kMove_Verb to path.
- Has no effect if count is less than one.
- @param pts array of line sharing end and start SkPoint
- @param count length of SkPoint array
- @param close true to add line connecting contour end and start
- @return reference to SkPath
- */
- SkPath& addPoly(const SkPoint pts[], int count, bool close);
- /** Adds contour created from list. Contour added starts at list[0], then adds a line
- for every additional SkPoint in list. If close is true, appends kClose_Verb to SkPath,
- connecting last and first SkPoint in list.
- If list is empty, append kMove_Verb to path.
- @param list array of SkPoint
- @param close true to add line connecting contour end and start
- @return reference to SkPath
- */
- SkPath& addPoly(const std::initializer_list<SkPoint>& list, bool close) {
- return this->addPoly(list.begin(), SkToInt(list.size()), close);
- }
- /** \enum SkPath::AddPathMode
- AddPathMode chooses how addPath() appends. Adding one SkPath to another can extend
- the last contour or start a new contour.
- */
- enum AddPathMode {
- kAppend_AddPathMode, //!< appended to destination unaltered
- kExtend_AddPathMode, //!< add line if prior contour is not closed
- };
- /** Appends src to SkPath, offset by (dx, dy).
- If mode is kAppend_AddPathMode, src verb array, SkPoint array, and conic weights are
- added unaltered. If mode is kExtend_AddPathMode, add line before appending
- verbs, SkPoint, and conic weights.
- @param src SkPath verbs, SkPoint, and conic weights to add
- @param dx offset added to src SkPoint array x-axis coordinates
- @param dy offset added to src SkPoint array y-axis coordinates
- @param mode kAppend_AddPathMode or kExtend_AddPathMode
- @return reference to SkPath
- */
- SkPath& addPath(const SkPath& src, SkScalar dx, SkScalar dy,
- AddPathMode mode = kAppend_AddPathMode);
- /** Appends src to SkPath.
- If mode is kAppend_AddPathMode, src verb array, SkPoint array, and conic weights are
- added unaltered. If mode is kExtend_AddPathMode, add line before appending
- verbs, SkPoint, and conic weights.
- @param src SkPath verbs, SkPoint, and conic weights to add
- @param mode kAppend_AddPathMode or kExtend_AddPathMode
- @return reference to SkPath
- */
- SkPath& addPath(const SkPath& src, AddPathMode mode = kAppend_AddPathMode) {
- SkMatrix m;
- m.reset();
- return this->addPath(src, m, mode);
- }
- /** Appends src to SkPath, transformed by matrix. Transformed curves may have different
- verbs, SkPoint, and conic weights.
- If mode is kAppend_AddPathMode, src verb array, SkPoint array, and conic weights are
- added unaltered. If mode is kExtend_AddPathMode, add line before appending
- verbs, SkPoint, and conic weights.
- @param src SkPath verbs, SkPoint, and conic weights to add
- @param matrix transform applied to src
- @param mode kAppend_AddPathMode or kExtend_AddPathMode
- @return reference to SkPath
- */
- SkPath& addPath(const SkPath& src, const SkMatrix& matrix,
- AddPathMode mode = kAppend_AddPathMode);
- /** Appends src to SkPath, from back to front.
- Reversed src always appends a new contour to SkPath.
- @param src SkPath verbs, SkPoint, and conic weights to add
- @return reference to SkPath
- */
- SkPath& reverseAddPath(const SkPath& src);
- /** Offsets SkPoint array by (dx, dy). Offset SkPath replaces dst.
- If dst is nullptr, SkPath is replaced by offset data.
- @param dx offset added to SkPoint array x-axis coordinates
- @param dy offset added to SkPoint array y-axis coordinates
- @param dst overwritten, translated copy of SkPath; may be nullptr
- */
- void offset(SkScalar dx, SkScalar dy, SkPath* dst) const;
- /** Offsets SkPoint array by (dx, dy). SkPath is replaced by offset data.
- @param dx offset added to SkPoint array x-axis coordinates
- @param dy offset added to SkPoint array y-axis coordinates
- */
- void offset(SkScalar dx, SkScalar dy) {
- this->offset(dx, dy, this);
- }
- /** Transforms verb array, SkPoint array, and weight by matrix.
- transform may change verbs and increase their number.
- Transformed SkPath replaces dst; if dst is nullptr, original data
- is replaced.
- @param matrix SkMatrix to apply to SkPath
- @param dst overwritten, transformed copy of SkPath; may be nullptr
- */
- void transform(const SkMatrix& matrix, SkPath* dst) const;
- /** Transforms verb array, SkPoint array, and weight by matrix.
- transform may change verbs and increase their number.
- SkPath is replaced by transformed data.
- @param matrix SkMatrix to apply to SkPath
- */
- void transform(const SkMatrix& matrix) {
- this->transform(matrix, this);
- }
- /** Returns last point on SkPath in lastPt. Returns false if SkPoint array is empty,
- storing (0, 0) if lastPt is not nullptr.
- @param lastPt storage for final SkPoint in SkPoint array; may be nullptr
- @return true if SkPoint array contains one or more SkPoint
- */
- bool getLastPt(SkPoint* lastPt) const;
- /** Sets last point to (x, y). If SkPoint array is empty, append kMove_Verb to
- verb array and append (x, y) to SkPoint array.
- @param x set x-axis value of last point
- @param y set y-axis value of last point
- */
- void setLastPt(SkScalar x, SkScalar y);
- /** Sets the last point on the path. If SkPoint array is empty, append kMove_Verb to
- verb array and append p to SkPoint array.
- @param p set value of last point
- */
- void setLastPt(const SkPoint& p) {
- this->setLastPt(p.fX, p.fY);
- }
- /** \enum SkPath::SegmentMask
- SegmentMask constants correspond to each drawing Verb type in SkPath; for
- instance, if SkPath only contains lines, only the kLine_SegmentMask bit is set.
- */
- enum SegmentMask {
- kLine_SegmentMask = 1 << 0, //!< contains one or more lines
- kQuad_SegmentMask = 1 << 1, //!< contains one or more quads
- kConic_SegmentMask = 1 << 2, //!< contains one or more conics
- kCubic_SegmentMask = 1 << 3, //!< contains one or more cubics
- };
- /** Returns a mask, where each set bit corresponds to a SegmentMask constant
- if SkPath contains one or more verbs of that type.
- Returns zero if SkPath contains no lines, or curves: quads, conics, or cubics.
- getSegmentMasks() returns a cached result; it is very fast.
- @return SegmentMask bits or zero
- */
- uint32_t getSegmentMasks() const { return fPathRef->getSegmentMasks(); }
- /** \enum SkPath::Verb
- Verb instructs SkPath how to interpret one or more SkPoint and optional conic weight;
- manage contour, and terminate SkPath.
- */
- enum Verb {
- kMove_Verb, //!< starts new contour at next SkPoint
- kLine_Verb, //!< adds line from last point to next SkPoint
- kQuad_Verb, //!< adds quad from last point
- kConic_Verb, //!< adds conic from last point
- kCubic_Verb, //!< adds cubic from last point
- kClose_Verb, //!< closes contour
- kDone_Verb, //!< terminates SkPath
- };
- /** \class SkPath::Iter
- Iterates through verb array, and associated SkPoint array and conic weight.
- Provides options to treat open contours as closed, and to ignore
- degenerate data.
- */
- class SK_API Iter {
- public:
- /** Initializes SkPath::Iter with an empty SkPath. next() on SkPath::Iter returns
- kDone_Verb.
- Call setPath to initialize SkPath::Iter at a later time.
- @return SkPath::Iter of empty SkPath
- */
- Iter();
- /** Sets SkPath::Iter to return elements of verb array, SkPoint array, and conic weight in
- path. If forceClose is true, SkPath::Iter will add kLine_Verb and kClose_Verb after each
- open contour. path is not altered.
- @param path SkPath to iterate
- @param forceClose true if open contours generate kClose_Verb
- @return SkPath::Iter of path
- */
- Iter(const SkPath& path, bool forceClose);
- /** Sets SkPath::Iter to return elements of verb array, SkPoint array, and conic weight in
- path. If forceClose is true, SkPath::Iter will add kLine_Verb and kClose_Verb after each
- open contour. path is not altered.
- @param path SkPath to iterate
- @param forceClose true if open contours generate kClose_Verb
- */
- void setPath(const SkPath& path, bool forceClose);
- /** Returns next SkPath::Verb in verb array, and advances SkPath::Iter.
- When verb array is exhausted, returns kDone_Verb.
- Zero to four SkPoint are stored in pts, depending on the returned SkPath::Verb.
- If doConsumeDegenerates is true, skip consecutive kMove_Verb entries, returning
- only the last in the series; and skip very small lines, quads, and conics; and
- skip kClose_Verb following kMove_Verb.
- if doConsumeDegenerates is true and exact is true, only skip lines, quads, and
- conics with zero lengths.
- @param pts storage for SkPoint data describing returned SkPath::Verb
- @param doConsumeDegenerates if true, skip degenerate verbs
- @param exact skip zero length curves
- @return next SkPath::Verb from verb array
- */
- Verb next(SkPoint pts[4], bool doConsumeDegenerates = true, bool exact = false) {
- if (doConsumeDegenerates) {
- this->consumeDegenerateSegments(exact);
- }
- return this->doNext(pts);
- }
- /** Returns conic weight if next() returned kConic_Verb.
- If next() has not been called, or next() did not return kConic_Verb,
- result is undefined.
- @return conic weight for conic SkPoint returned by next()
- */
- SkScalar conicWeight() const { return *fConicWeights; }
- /** Returns true if last kLine_Verb returned by next() was generated
- by kClose_Verb. When true, the end point returned by next() is
- also the start point of contour.
- If next() has not been called, or next() did not return kLine_Verb,
- result is undefined.
- @return true if last kLine_Verb was generated by kClose_Verb
- */
- bool isCloseLine() const { return SkToBool(fCloseLine); }
- /** Returns true if subsequent calls to next() return kClose_Verb before returning
- kMove_Verb. if true, contour SkPath::Iter is processing may end with kClose_Verb, or
- SkPath::Iter may have been initialized with force close set to true.
- @return true if contour is closed
- */
- bool isClosedContour() const;
- private:
- const SkPoint* fPts;
- const uint8_t* fVerbs;
- const uint8_t* fVerbStop;
- const SkScalar* fConicWeights;
- SkPoint fMoveTo;
- SkPoint fLastPt;
- bool fForceClose;
- bool fNeedClose;
- bool fCloseLine;
- enum SegmentState : uint8_t {
- /** The current contour is empty. Starting processing or have just closed a contour. */
- kEmptyContour_SegmentState,
- /** Have seen a move, but nothing else. */
- kAfterMove_SegmentState,
- /** Have seen a primitive but not yet closed the path. Also the initial state. */
- kAfterPrimitive_SegmentState
- };
- SegmentState fSegmentState;
- inline const SkPoint& cons_moveTo();
- Verb autoClose(SkPoint pts[2]);
- void consumeDegenerateSegments(bool exact);
- Verb doNext(SkPoint pts[4]);
- };
- /** \class SkPath::RawIter
- Iterates through verb array, and associated SkPoint array and conic weight.
- verb array, SkPoint array, and conic weight are returned unaltered.
- */
- class SK_API RawIter {
- public:
- /** Initializes RawIter with an empty SkPath. next() on RawIter returns kDone_Verb.
- Call setPath to initialize SkPath::Iter at a later time.
- @return RawIter of empty SkPath
- */
- RawIter() {}
- /** Sets RawIter to return elements of verb array, SkPoint array, and conic weight in path.
- @param path SkPath to iterate
- @return RawIter of path
- */
- RawIter(const SkPath& path) {
- setPath(path);
- }
- /** Sets SkPath::Iter to return elements of verb array, SkPoint array, and conic weight in
- path.
- @param path SkPath to iterate
- */
- void setPath(const SkPath& path) {
- fRawIter.setPathRef(*path.fPathRef.get());
- }
- /** Returns next SkPath::Verb in verb array, and advances RawIter.
- When verb array is exhausted, returns kDone_Verb.
- Zero to four SkPoint are stored in pts, depending on the returned SkPath::Verb.
- @param pts storage for SkPoint data describing returned SkPath::Verb
- @return next SkPath::Verb from verb array
- */
- Verb next(SkPoint pts[4]) {
- return (Verb) fRawIter.next(pts);
- }
- /** Returns next SkPath::Verb, but does not advance RawIter.
- @return next SkPath::Verb from verb array
- */
- Verb peek() const {
- return (Verb) fRawIter.peek();
- }
- /** Returns conic weight if next() returned kConic_Verb.
- If next() has not been called, or next() did not return kConic_Verb,
- result is undefined.
- @return conic weight for conic SkPoint returned by next()
- */
- SkScalar conicWeight() const {
- return fRawIter.conicWeight();
- }
- private:
- SkPathRef::Iter fRawIter;
- friend class SkPath;
- };
- /** Returns true if the point (x, y) is contained by SkPath, taking into
- account FillType.
- @param x x-axis value of containment test
- @param y y-axis value of containment test
- @return true if SkPoint is in SkPath
- */
- bool contains(SkScalar x, SkScalar y) const;
- /** Writes text representation of SkPath to stream. If stream is nullptr, writes to
- standard output. Set forceClose to true to get edges used to fill SkPath.
- Set dumpAsHex true to generate exact binary representations
- of floating point numbers used in SkPoint array and conic weights.
- @param stream writable SkWStream receiving SkPath text representation; may be nullptr
- @param forceClose true if missing kClose_Verb is output
- @param dumpAsHex true if SkScalar values are written as hexadecimal
- */
- void dump(SkWStream* stream, bool forceClose, bool dumpAsHex) const;
- /** Writes text representation of SkPath to standard output. The representation may be
- directly compiled as C++ code. Floating point values are written
- with limited precision; it may not be possible to reconstruct original SkPath
- from output.
- */
- void dump() const;
- /** Writes text representation of SkPath to standard output. The representation may be
- directly compiled as C++ code. Floating point values are written
- in hexadecimal to preserve their exact bit pattern. The output reconstructs the
- original SkPath.
- Use instead of dump() when submitting
- */
- void dumpHex() const;
- /** Writes SkPath to buffer, returning the number of bytes written.
- Pass nullptr to obtain the storage size.
- Writes SkPath::FillType, verb array, SkPoint array, conic weight, and
- additionally writes computed information like SkPath::Convexity and bounds.
- Use only be used in concert with readFromMemory();
- the format used for SkPath in memory is not guaranteed.
- @param buffer storage for SkPath; may be nullptr
- @return size of storage required for SkPath; always a multiple of 4
- */
- size_t writeToMemory(void* buffer) const;
- /** Writes SkPath to buffer, returning the buffer written to, wrapped in SkData.
- serialize() writes SkPath::FillType, verb array, SkPoint array, conic weight, and
- additionally writes computed information like SkPath::Convexity and bounds.
- serialize() should only be used in concert with readFromMemory().
- The format used for SkPath in memory is not guaranteed.
- @return SkPath data wrapped in SkData buffer
- */
- sk_sp<SkData> serialize() const;
- /** Initializes SkPath from buffer of size length. Returns zero if the buffer is
- data is inconsistent, or the length is too small.
- Reads SkPath::FillType, verb array, SkPoint array, conic weight, and
- additionally reads computed information like SkPath::Convexity and bounds.
- Used only in concert with writeToMemory();
- the format used for SkPath in memory is not guaranteed.
- @param buffer storage for SkPath
- @param length buffer size in bytes; must be multiple of 4
- @return number of bytes read, or zero on failure
- */
- size_t readFromMemory(const void* buffer, size_t length);
- /** (See Skia bug 1762.)
- Returns a non-zero, globally unique value. A different value is returned
- if verb array, SkPoint array, or conic weight changes.
- Setting SkPath::FillType does not change generation identifier.
- Each time the path is modified, a different generation identifier will be returned.
- SkPath::FillType does affect generation identifier on Android framework.
- @return non-zero, globally unique value
- */
- uint32_t getGenerationID() const;
- #ifdef SK_SUPPORT_DIRECT_PATHREF_VALIDATION
- /** Returns if SkPath data is consistent. Corrupt SkPath data is detected if
- internal values are out of range or internal storage does not match
- array dimensions.
- @return true if SkPath data is consistent
- */
- bool isValid() const { return this->isValidImpl() && fPathRef->isValid(); }
- #else
- /** Deprecated.
- */
- bool isValid() const { return this->isValidImpl(); }
- /** Deprecated.
- */
- bool pathRefIsValid() const { return fPathRef->isValid(); }
- #endif
- private:
- sk_sp<SkPathRef> fPathRef;
- int fLastMoveToIndex;
- mutable SkAtomic<Convexity, sk_memory_order_relaxed> fConvexity; // SkPath::Convexity
- mutable SkAtomic<uint8_t, sk_memory_order_relaxed> fFirstDirection; // SkPathPriv::FirstDirection
- uint8_t fFillType : 2;
- uint8_t fIsVolatile : 1;
- uint8_t fIsBadForDAA : 1;
- /** Resets all fields other than fPathRef to their initial 'empty' values.
- * Assumes the caller has already emptied fPathRef.
- * On Android increments fGenerationID without reseting it.
- */
- void resetFields();
- /** Sets all fields other than fPathRef to the values in 'that'.
- * Assumes the caller has already set fPathRef.
- * Doesn't change fGenerationID or fSourcePath on Android.
- */
- void copyFields(const SkPath& that);
- size_t writeToMemoryAsRRect(void* buffer) const;
- size_t readAsRRect(const void*, size_t);
- size_t readFromMemory_LE3(const void*, size_t);
- size_t readFromMemory_EQ4(const void*, size_t);
- friend class Iter;
- friend class SkPathPriv;
- friend class SkPathStroker;
- /* Append, in reverse order, the first contour of path, ignoring path's
- last point. If no moveTo() call has been made for this contour, the
- first point is automatically set to (0,0).
- */
- SkPath& reversePathTo(const SkPath&);
- // called before we add points for lineTo, quadTo, cubicTo, checking to see
- // if we need to inject a leading moveTo first
- //
- // SkPath path; path.lineTo(...); <--- need a leading moveTo(0, 0)
- // SkPath path; ... path.close(); path.lineTo(...) <-- need a moveTo(previous moveTo)
- //
- inline void injectMoveToIfNeeded();
- inline bool hasOnlyMoveTos() const;
- Convexity internalGetConvexity() const;
- /** Asserts if SkPath data is inconsistent.
- Debugging check intended for internal use only.
- */
- SkDEBUGCODE(void validate() const { SkASSERT(this->isValidImpl()); } )
- bool isValidImpl() const;
- SkDEBUGCODE(void validateRef() const { fPathRef->validate(); } )
- bool isRectContour(bool allowPartial, int* currVerb, const SkPoint** pts,
- bool* isClosed, Direction* direction, SkRect* rect) const;
- // called by stroker to see if all points (in the last contour) are equal and worthy of a cap
- bool isZeroLengthSincePoint(int startPtIndex) const;
- /** Returns if the path can return a bound at no cost (true) or will have to
- perform some computation (false).
- */
- bool hasComputedBounds() const {
- SkDEBUGCODE(this->validate();)
- return fPathRef->hasComputedBounds();
- }
- // 'rect' needs to be sorted
- void setBounds(const SkRect& rect) {
- SkPathRef::Editor ed(&fPathRef);
- ed.setBounds(rect);
- }
- void setPt(int index, SkScalar x, SkScalar y);
- friend class SkAutoPathBoundsUpdate;
- friend class SkAutoDisableOvalCheck;
- friend class SkAutoDisableDirectionCheck;
- friend class SkPathWriter;
- friend class SkOpBuilder;
- friend class SkBench_AddPathTest; // perf test reversePathTo
- friend class PathTest_Private; // unit test reversePathTo
- friend class ForceIsRRect_Private; // unit test isRRect
- friend class FuzzPath; // for legacy access to validateRef
- };
- #endif
|