123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552 |
- /*
- * 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.
- */
- #ifndef SkPoint_DEFINED
- #define SkPoint_DEFINED
- #include "include/core/SkMath.h"
- #include "include/core/SkScalar.h"
- #include "include/private/SkSafe32.h"
- struct SkIPoint;
- /** SkIVector provides an alternative name for SkIPoint. SkIVector and SkIPoint
- can be used interchangeably for all purposes.
- */
- typedef SkIPoint SkIVector;
- /** \struct SkIPoint
- SkIPoint holds two 32-bit integer coordinates.
- */
- struct SkIPoint {
- int32_t fX; //!< x-axis value
- int32_t fY; //!< y-axis value
- /** Sets fX to x, fY to y.
- @param x integer x-axis value of constructed SkIPoint
- @param y integer y-axis value of constructed SkIPoint
- @return SkIPoint (x, y)
- */
- static constexpr SkIPoint Make(int32_t x, int32_t y) {
- return {x, y};
- }
- /** Returns x-axis value of SkIPoint.
- @return fX
- */
- int32_t x() const { return fX; }
- /** Returns y-axis value of SkIPoint.
- @return fY
- */
- int32_t y() const { return fY; }
- /** Returns true if fX and fY are both zero.
- @return true if fX is zero and fY is zero
- */
- bool isZero() const { return (fX | fY) == 0; }
- /** Sets fX to x and fY to y.
- @param x new value for fX
- @param y new value for fY
- */
- void set(int32_t x, int32_t y) {
- fX = x;
- fY = y;
- }
- /** Returns SkIPoint changing the signs of fX and fY.
- @return SkIPoint as (-fX, -fY)
- */
- SkIPoint operator-() const {
- return {-fX, -fY};
- }
- /** Offsets SkIPoint by ivector v. Sets SkIPoint to (fX + v.fX, fY + v.fY).
- @param v ivector to add
- */
- void operator+=(const SkIVector& v) {
- fX = Sk32_sat_add(fX, v.fX);
- fY = Sk32_sat_add(fY, v.fY);
- }
- /** Subtracts ivector v from SkIPoint. Sets SkIPoint to: (fX - v.fX, fY - v.fY).
- @param v ivector to subtract
- */
- void operator-=(const SkIVector& v) {
- fX = Sk32_sat_sub(fX, v.fX);
- fY = Sk32_sat_sub(fY, v.fY);
- }
- /** Returns true if SkIPoint is equivalent to SkIPoint constructed from (x, y).
- @param x value compared with fX
- @param y value compared with fY
- @return true if SkIPoint equals (x, y)
- */
- bool equals(int32_t x, int32_t y) const {
- return fX == x && fY == y;
- }
- /** Returns true if a is equivalent to b.
- @param a SkIPoint to compare
- @param b SkIPoint to compare
- @return true if a.fX == b.fX and a.fY == b.fY
- */
- friend bool operator==(const SkIPoint& a, const SkIPoint& b) {
- return a.fX == b.fX && a.fY == b.fY;
- }
- /** Returns true if a is not equivalent to b.
- @param a SkIPoint to compare
- @param b SkIPoint to compare
- @return true if a.fX != b.fX or a.fY != b.fY
- */
- friend bool operator!=(const SkIPoint& a, const SkIPoint& b) {
- return a.fX != b.fX || a.fY != b.fY;
- }
- /** Returns ivector from b to a; computed as (a.fX - b.fX, a.fY - b.fY).
- Can also be used to subtract ivector from ivector, returning ivector.
- @param a SkIPoint or ivector to subtract from
- @param b ivector to subtract
- @return ivector from b to a
- */
- friend SkIVector operator-(const SkIPoint& a, const SkIPoint& b) {
- return { Sk32_sat_sub(a.fX, b.fX), Sk32_sat_sub(a.fY, b.fY) };
- }
- /** Returns SkIPoint resulting from SkIPoint a offset by ivector b, computed as:
- (a.fX + b.fX, a.fY + b.fY).
- Can also be used to offset SkIPoint b by ivector a, returning SkIPoint.
- Can also be used to add ivector to ivector, returning ivector.
- @param a SkIPoint or ivector to add to
- @param b SkIPoint or ivector to add
- @return SkIPoint equal to a offset by b
- */
- friend SkIPoint operator+(const SkIPoint& a, const SkIVector& b) {
- return { Sk32_sat_add(a.fX, b.fX), Sk32_sat_add(a.fY, b.fY) };
- }
- };
- struct SkPoint;
- /** SkVector provides an alternative name for SkPoint. SkVector and SkPoint can
- be used interchangeably for all purposes.
- */
- typedef SkPoint SkVector;
- /** \struct SkPoint
- SkPoint holds two 32-bit floating point coordinates.
- */
- struct SK_API SkPoint {
- SkScalar fX; //!< x-axis value
- SkScalar fY; //!< y-axis value
- /** Sets fX to x, fY to y. Used both to set SkPoint and vector.
- @param x SkScalar x-axis value of constructed SkPoint or vector
- @param y SkScalar y-axis value of constructed SkPoint or vector
- @return SkPoint (x, y)
- */
- static constexpr SkPoint Make(SkScalar x, SkScalar y) {
- return {x, y};
- }
- /** Returns x-axis value of SkPoint or vector.
- @return fX
- */
- SkScalar x() const { return fX; }
- /** Returns y-axis value of SkPoint or vector.
- @return fY
- */
- SkScalar y() const { return fY; }
- /** Returns true if fX and fY are both zero.
- @return true if fX is zero and fY is zero
- */
- bool isZero() const { return (0 == fX) & (0 == fY); }
- /** Sets fX to x and fY to y.
- @param x new value for fX
- @param y new value for fY
- */
- void set(SkScalar x, SkScalar y) {
- fX = x;
- fY = y;
- }
- /** Sets fX to x and fY to y, promoting integers to SkScalar values.
- Assigning a large integer value directly to fX or fY may cause a compiler
- error, triggered by narrowing conversion of int to SkScalar. This safely
- casts x and y to avoid the error.
- @param x new value for fX
- @param y new value for fY
- */
- void iset(int32_t x, int32_t y) {
- fX = SkIntToScalar(x);
- fY = SkIntToScalar(y);
- }
- /** Sets fX to p.fX and fY to p.fY, promoting integers to SkScalar values.
- Assigning an SkIPoint containing a large integer value directly to fX or fY may
- cause a compiler error, triggered by narrowing conversion of int to SkScalar.
- This safely casts p.fX and p.fY to avoid the error.
- @param p SkIPoint members promoted to SkScalar
- */
- void iset(const SkIPoint& p) {
- fX = SkIntToScalar(p.fX);
- fY = SkIntToScalar(p.fY);
- }
- /** Sets fX to absolute value of pt.fX; and fY to absolute value of pt.fY.
- @param pt members providing magnitude for fX and fY
- */
- void setAbs(const SkPoint& pt) {
- fX = SkScalarAbs(pt.fX);
- fY = SkScalarAbs(pt.fY);
- }
- /** Adds offset to each SkPoint in points array with count entries.
- @param points SkPoint array
- @param count entries in array
- @param offset vector added to points
- */
- static void Offset(SkPoint points[], int count, const SkVector& offset) {
- Offset(points, count, offset.fX, offset.fY);
- }
- /** Adds offset (dx, dy) to each SkPoint in points array of length count.
- @param points SkPoint array
- @param count entries in array
- @param dx added to fX in points
- @param dy added to fY in points
- */
- static void Offset(SkPoint points[], int count, SkScalar dx, SkScalar dy) {
- for (int i = 0; i < count; ++i) {
- points[i].offset(dx, dy);
- }
- }
- /** Adds offset (dx, dy) to SkPoint.
- @param dx added to fX
- @param dy added to fY
- */
- void offset(SkScalar dx, SkScalar dy) {
- fX += dx;
- fY += dy;
- }
- /** Returns the Euclidean distance from origin, computed as:
- sqrt(fX * fX + fY * fY)
- .
- @return straight-line distance to origin
- */
- SkScalar length() const { return SkPoint::Length(fX, fY); }
- /** Returns the Euclidean distance from origin, computed as:
- sqrt(fX * fX + fY * fY)
- .
- @return straight-line distance to origin
- */
- SkScalar distanceToOrigin() const { return this->length(); }
- /** Scales (fX, fY) so that length() returns one, while preserving ratio of fX to fY,
- if possible. If prior length is nearly zero, sets vector to (0, 0) and returns
- false; otherwise returns true.
- @return true if former length is not zero or nearly zero
- */
- bool normalize();
- /** Sets vector to (x, y) scaled so length() returns one, and so that
- (fX, fY) is proportional to (x, y). If (x, y) length is nearly zero,
- sets vector to (0, 0) and returns false; otherwise returns true.
- @param x proportional value for fX
- @param y proportional value for fY
- @return true if (x, y) length is not zero or nearly zero
- */
- bool setNormalize(SkScalar x, SkScalar y);
- /** Scales vector so that distanceToOrigin() returns length, if possible. If former
- length is nearly zero, sets vector to (0, 0) and return false; otherwise returns
- true.
- @param length straight-line distance to origin
- @return true if former length is not zero or nearly zero
- */
- bool setLength(SkScalar length);
- /** Sets vector to (x, y) scaled to length, if possible. If former
- length is nearly zero, sets vector to (0, 0) and return false; otherwise returns
- true.
- @param x proportional value for fX
- @param y proportional value for fY
- @param length straight-line distance to origin
- @return true if (x, y) length is not zero or nearly zero
- */
- bool setLength(SkScalar x, SkScalar y, SkScalar length);
- /** Sets dst to SkPoint times scale. dst may be SkPoint to modify SkPoint in place.
- @param scale factor to multiply SkPoint by
- @param dst storage for scaled SkPoint
- */
- void scale(SkScalar scale, SkPoint* dst) const;
- /** Scales SkPoint in place by scale.
- @param value factor to multiply SkPoint by
- */
- void scale(SkScalar value) { this->scale(value, this); }
- /** Changes the sign of fX and fY.
- */
- void negate() {
- fX = -fX;
- fY = -fY;
- }
- /** Returns SkPoint changing the signs of fX and fY.
- @return SkPoint as (-fX, -fY)
- */
- SkPoint operator-() const {
- return {-fX, -fY};
- }
- /** Adds vector v to SkPoint. Sets SkPoint to: (fX + v.fX, fY + v.fY).
- @param v vector to add
- */
- void operator+=(const SkVector& v) {
- fX += v.fX;
- fY += v.fY;
- }
- /** Subtracts vector v from SkPoint. Sets SkPoint to: (fX - v.fX, fY - v.fY).
- @param v vector to subtract
- */
- void operator-=(const SkVector& v) {
- fX -= v.fX;
- fY -= v.fY;
- }
- /** Returns SkPoint multiplied by scale.
- @param scale scalar to multiply by
- @return SkPoint as (fX * scale, fY * scale)
- */
- SkPoint operator*(SkScalar scale) const {
- return {fX * scale, fY * scale};
- }
- /** Multiplies SkPoint by scale. Sets SkPoint to: (fX * scale, fY * scale).
- @param scale scalar to multiply by
- @return reference to SkPoint
- */
- SkPoint& operator*=(SkScalar scale) {
- fX *= scale;
- fY *= scale;
- return *this;
- }
- /** Returns true if both fX and fY are measurable values.
- @return true for values other than infinities and NaN
- */
- bool isFinite() const {
- SkScalar accum = 0;
- accum *= fX;
- accum *= fY;
- // accum is either NaN or it is finite (zero).
- SkASSERT(0 == accum || SkScalarIsNaN(accum));
- // value==value will be true iff value is not NaN
- // TODO: is it faster to say !accum or accum==accum?
- return !SkScalarIsNaN(accum);
- }
- /** Returns true if SkPoint is equivalent to SkPoint constructed from (x, y).
- @param x value compared with fX
- @param y value compared with fY
- @return true if SkPoint equals (x, y)
- */
- bool equals(SkScalar x, SkScalar y) const {
- return fX == x && fY == y;
- }
- /** Returns true if a is equivalent to b.
- @param a SkPoint to compare
- @param b SkPoint to compare
- @return true if a.fX == b.fX and a.fY == b.fY
- */
- friend bool operator==(const SkPoint& a, const SkPoint& b) {
- return a.fX == b.fX && a.fY == b.fY;
- }
- /** Returns true if a is not equivalent to b.
- @param a SkPoint to compare
- @param b SkPoint to compare
- @return true if a.fX != b.fX or a.fY != b.fY
- */
- friend bool operator!=(const SkPoint& a, const SkPoint& b) {
- return a.fX != b.fX || a.fY != b.fY;
- }
- /** Returns vector from b to a, computed as (a.fX - b.fX, a.fY - b.fY).
- Can also be used to subtract vector from SkPoint, returning SkPoint.
- Can also be used to subtract vector from vector, returning vector.
- @param a SkPoint to subtract from
- @param b SkPoint to subtract
- @return vector from b to a
- */
- friend SkVector operator-(const SkPoint& a, const SkPoint& b) {
- return {a.fX - b.fX, a.fY - b.fY};
- }
- /** Returns SkPoint resulting from SkPoint a offset by vector b, computed as:
- (a.fX + b.fX, a.fY + b.fY).
- Can also be used to offset SkPoint b by vector a, returning SkPoint.
- Can also be used to add vector to vector, returning vector.
- @param a SkPoint or vector to add to
- @param b SkPoint or vector to add
- @return SkPoint equal to a offset by b
- */
- friend SkPoint operator+(const SkPoint& a, const SkVector& b) {
- return {a.fX + b.fX, a.fY + b.fY};
- }
- /** Returns the Euclidean distance from origin, computed as:
- sqrt(x * x + y * y)
- .
- @param x component of length
- @param y component of length
- @return straight-line distance to origin
- */
- static SkScalar Length(SkScalar x, SkScalar y);
- /** Scales (vec->fX, vec->fY) so that length() returns one, while preserving ratio of vec->fX
- to vec->fY, if possible. If original length is nearly zero, sets vec to (0, 0) and returns
- zero; otherwise, returns length of vec before vec is scaled.
- Returned prior length may be SK_ScalarInfinity if it can not be represented by SkScalar.
- Note that normalize() is faster if prior length is not required.
- @param vec normalized to unit length
- @return original vec length
- */
- static SkScalar Normalize(SkVector* vec);
- /** Returns the Euclidean distance between a and b.
- @param a line end point
- @param b line end point
- @return straight-line distance from a to b
- */
- static SkScalar Distance(const SkPoint& a, const SkPoint& b) {
- return Length(a.fX - b.fX, a.fY - b.fY);
- }
- /** Returns the dot product of vector a and vector b.
- @param a left side of dot product
- @param b right side of dot product
- @return product of input magnitudes and cosine of the angle between them
- */
- static SkScalar DotProduct(const SkVector& a, const SkVector& b) {
- return a.fX * b.fX + a.fY * b.fY;
- }
- /** Returns the cross product of vector a and vector b.
- a and b form three-dimensional vectors with z-axis value equal to zero. The
- cross product is a three-dimensional vector with x-axis and y-axis values equal
- to zero. The cross product z-axis component is returned.
- @param a left side of cross product
- @param b right side of cross product
- @return area spanned by vectors signed by angle direction
- */
- static SkScalar CrossProduct(const SkVector& a, const SkVector& b) {
- return a.fX * b.fY - a.fY * b.fX;
- }
- /** Returns the cross product of vector and vec.
- Vector and vec form three-dimensional vectors with z-axis value equal to zero.
- The cross product is a three-dimensional vector with x-axis and y-axis values
- equal to zero. The cross product z-axis component is returned.
- @param vec right side of cross product
- @return area spanned by vectors signed by angle direction
- */
- SkScalar cross(const SkVector& vec) const {
- return CrossProduct(*this, vec);
- }
- /** Returns the dot product of vector and vector vec.
- @param vec right side of dot product
- @return product of input magnitudes and cosine of the angle between them
- */
- SkScalar dot(const SkVector& vec) const {
- return DotProduct(*this, vec);
- }
- };
- #endif
|