Core skia changes to prepare for Gr AA Hairline renderer
Review URL: http://codereview.appspot.com/4940045/ git-svn-id: http://skia.googlecode.com/svn/trunk@2160 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
8214587a79
commit
647a804c3d
@ -105,7 +105,11 @@ void SkEvalCubicAt(const SkPoint src[4], SkScalar t, SkPoint* locOrNull,
|
||||
dst[0..3] and dst[3..6]
|
||||
*/
|
||||
void SkChopCubicAt(const SkPoint src[4], SkPoint dst[7], SkScalar t);
|
||||
void SkChopCubicAt(const SkPoint src[4], SkPoint dst[7], const SkScalar t[],
|
||||
/** Given a src cubic bezier, chop it at the specified t values,
|
||||
where 0 < t < 1, and return the new cubics in dst:
|
||||
dst[0..3],dst[3..6],...,dst[3*t_count..3*(t_count+1)]
|
||||
*/
|
||||
void SkChopCubicAt(const SkPoint src[4], SkPoint dst[], const SkScalar t[],
|
||||
int t_count);
|
||||
|
||||
/** Given a src cubic bezier, chop it at the specified t == 1/2,
|
||||
@ -141,8 +145,8 @@ int SkChopCubicAtXExtrema(const SkPoint src[4], SkPoint dst[10]);
|
||||
*/
|
||||
int SkFindCubicInflections(const SkPoint src[4], SkScalar tValues[2]);
|
||||
|
||||
/** Return 1 for no chop, or 2 for having chopped the cubic at its
|
||||
inflection point.
|
||||
/** Return 1 for no chop, 2 for having chopped the cubic at a single
|
||||
inflection point, 3 for having chopped at 2 inflection points.
|
||||
*/
|
||||
int SkChopCubicAtInflections(const SkPoint src[4], SkPoint dst[10]);
|
||||
|
||||
|
@ -364,6 +364,31 @@ public:
|
||||
this->mapPoints(pts, pts, count);
|
||||
}
|
||||
|
||||
/** Like mapPoints but with custom byte stride between the points. Stride
|
||||
* should be a multiple of sizeof(SkScalar).
|
||||
*/
|
||||
void mapPointsWithStride(SkPoint pts[], size_t stride, int count) const {
|
||||
SkASSERT(stride >= sizeof(SkPoint));
|
||||
SkASSERT(0 == stride % sizeof(SkScalar));
|
||||
for (int i = 0; i < count; ++i) {
|
||||
this->mapPoints(pts, pts, 1);
|
||||
pts = (SkPoint*)((intptr_t)pts + stride);
|
||||
}
|
||||
}
|
||||
|
||||
/** Like mapPoints but with custom byte stride between the points.
|
||||
*/
|
||||
void mapPointsWithStride(SkPoint dst[], SkPoint src[],
|
||||
size_t stride, int count) const {
|
||||
SkASSERT(stride >= sizeof(SkPoint));
|
||||
SkASSERT(0 == stride % sizeof(SkScalar));
|
||||
for (int i = 0; i < count; ++i) {
|
||||
this->mapPoints(dst, src, 1);
|
||||
src = (SkPoint*)((intptr_t)src + stride);
|
||||
dst = (SkPoint*)((intptr_t)dst + stride);
|
||||
}
|
||||
}
|
||||
|
||||
void mapXY(SkScalar x, SkScalar y, SkPoint* result) const {
|
||||
SkASSERT(result);
|
||||
this->getMapXYProc()(*this, x, y, result);
|
||||
@ -411,13 +436,6 @@ public:
|
||||
return this->mapRect(rect, *rect);
|
||||
}
|
||||
|
||||
void mapPointsWithStride(SkPoint pts[], size_t stride, int count) const {
|
||||
for (int i = 0; i < count; ++i) {
|
||||
this->mapPoints(pts, pts, 1);
|
||||
pts = (SkPoint*)((intptr_t)pts + stride);
|
||||
}
|
||||
}
|
||||
|
||||
/** Return the mean radius of a circle after it has been mapped by
|
||||
this matrix. NOTE: in perspective this value assumes the circle
|
||||
has its center at the origin.
|
||||
|
@ -361,14 +361,68 @@ struct SK_API SkPoint {
|
||||
SkScalar dy = fY - pt.fY;
|
||||
return SkScalarMul(dx, dx) + SkScalarMul(dy, dy);
|
||||
}
|
||||
|
||||
SkScalar distanceToLineSegmentBetweenSqd(const SkPoint& a,
|
||||
|
||||
/**
|
||||
* The side of a point relative to a line. If the line is from a to b then
|
||||
* the values are consistent with the sign of (b-a) cross (pt-a)
|
||||
*/
|
||||
enum Side {
|
||||
kLeft_Side = -1,
|
||||
kOn_Side = 0,
|
||||
kRight_Side = 1
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the squared distance to the infinite line between two pts. Also
|
||||
* optionally returns the side of the line that the pt falls on (looking
|
||||
* along line from a to b)
|
||||
*/
|
||||
SkScalar distanceToLineBetweenSqd(const SkPoint& a,
|
||||
const SkPoint& b,
|
||||
Side* side = NULL) const;
|
||||
|
||||
/**
|
||||
* Returns the distance to the infinite line between two pts. Also
|
||||
* optionally returns the side of the line that the pt falls on (looking
|
||||
* along the line from a to b)
|
||||
*/
|
||||
SkScalar distanceToLineBetween(const SkPoint& a,
|
||||
const SkPoint& b,
|
||||
Side* side = NULL) const {
|
||||
return SkScalarSqrt(this->distanceToLineBetweenSqd(a, b, side));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the squared distance to the line segment between pts a and b
|
||||
*/
|
||||
SkScalar distanceToLineSegmentBetweenSqd(const SkPoint& a,
|
||||
const SkPoint& b) const;
|
||||
|
||||
SkScalar distanceToLineSegmentBetween(const SkPoint& a,
|
||||
|
||||
/**
|
||||
* Returns the distance to the line segment between pts a and b.
|
||||
*/
|
||||
SkScalar distanceToLineSegmentBetween(const SkPoint& a,
|
||||
const SkPoint& b) const {
|
||||
return SkScalarSqrt(this->distanceToLineSegmentBetweenSqd(a, b));
|
||||
}
|
||||
|
||||
/**
|
||||
* Make this vector be orthogonal to vec. Looking down vec the
|
||||
* new vector will point in direction indicated by side (which
|
||||
* must be kLeft_Side or kRight_Side).
|
||||
*/
|
||||
void setOrthog(const SkPoint& vec, Side side = kLeft_Side) {
|
||||
// vec could be this
|
||||
SkScalar tmp = vec.fX;
|
||||
if (kLeft_Side == side) {
|
||||
fX = -vec.fY;
|
||||
fY = tmp;
|
||||
} else {
|
||||
SkASSERT(kRight_Side == side);
|
||||
fX = vec.fY;
|
||||
fY = -tmp;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
typedef SkPoint SkVector;
|
||||
|
@ -429,9 +429,10 @@ struct SK_API SkRect {
|
||||
this->offset(delta.fX, delta.fY);
|
||||
}
|
||||
|
||||
/** Inset the rectangle by (dx,dy). If dx is positive, then the sides are moved inwards,
|
||||
making the rectangle narrower. If dx is negative, then the sides are moved outwards,
|
||||
making the rectangle wider. The same hods true for dy and the top and bottom.
|
||||
/** Inset the rectangle by (dx,dy). If dx is positive, then the sides are
|
||||
moved inwards, making the rectangle narrower. If dx is negative, then
|
||||
the sides are moved outwards, making the rectangle wider. The same holds
|
||||
true for dy and the top and bottom.
|
||||
*/
|
||||
void inset(SkScalar dx, SkScalar dy) {
|
||||
fLeft += dx;
|
||||
@ -440,6 +441,13 @@ struct SK_API SkRect {
|
||||
fBottom -= dy;
|
||||
}
|
||||
|
||||
/** Outset the rectangle by (dx,dy). If dx is positive, then the sides are
|
||||
moved outwards, making the rectangle wider. If dx is negative, then the
|
||||
sides are moved inwards, making the rectangle narrower. The same hods
|
||||
true for dy and the top and bottom.
|
||||
*/
|
||||
void outset(SkScalar dx, SkScalar dy) { this->inset(-dx, -dy); }
|
||||
|
||||
/** If this rectangle intersects r, return true and set this rectangle to that
|
||||
intersection, otherwise return false and do not change this rectangle.
|
||||
If either rectangle is empty, do nothing and return false.
|
||||
|
@ -288,6 +288,20 @@
|
||||
#define SkScalarCeil(x) SkScalarCeilToInt(x)
|
||||
#define SkScalarRound(x) SkScalarRoundToInt(x)
|
||||
|
||||
/**
|
||||
* Returns -1 || 0 || 1 depending on the sign of value:
|
||||
* -1 if x < 0
|
||||
* 0 if x == 0
|
||||
* 1 if x > 0
|
||||
*/
|
||||
static inline int SkScalarSignAsInt(SkScalar x) {
|
||||
return x < 0 ? -1 : (x > 0);
|
||||
}
|
||||
|
||||
// Scalar result version of above
|
||||
static inline SkScalar SkScalarSignAsScalar(SkScalar x) {
|
||||
return x < 0 ? -SK_Scalar1 : ((x > 0) ? SK_Scalar1 : 0);
|
||||
}
|
||||
|
||||
#define SK_ScalarNearlyZero (SK_Scalar1 / (1 << 12))
|
||||
|
||||
|
@ -1419,21 +1419,11 @@ void SkPath::validate() const {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Returns -1 || 0 || 1 depending on the sign of value:
|
||||
* -1 if value < 0
|
||||
* 0 if vlaue == 0
|
||||
* 1 if value > 0
|
||||
*/
|
||||
static int SkScalarSign(SkScalar value) {
|
||||
return value < 0 ? -1 : (value > 0);
|
||||
}
|
||||
|
||||
static int sign(SkScalar x) { return x < 0; }
|
||||
#define kValueNeverReturnedBySign 2
|
||||
|
||||
static int CrossProductSign(const SkVector& a, const SkVector& b) {
|
||||
return SkScalarSign(SkPoint::CrossProduct(a, b));
|
||||
return SkScalarSignAsInt(SkPoint::CrossProduct(a, b));
|
||||
}
|
||||
|
||||
// only valid for a single contour
|
||||
|
@ -359,7 +359,25 @@ bool SkPoint::setLength(SkFixed ox, SkFixed oy, SkFixed length) {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SkScalar SkPoint::distanceToLineSegmentBetweenSqd(const SkPoint& a,
|
||||
SkScalar SkPoint::distanceToLineBetweenSqd(const SkPoint& a,
|
||||
const SkPoint& b,
|
||||
Side* side) const {
|
||||
|
||||
SkVector u = b - a;
|
||||
SkVector v = *this - a;
|
||||
|
||||
SkScalar uLengthSqd = u.lengthSqd();
|
||||
SkScalar det = u.cross(v);
|
||||
if (NULL != side) {
|
||||
SkASSERT(-1 == SkPoint::kLeft_Side &&
|
||||
0 == SkPoint::kOn_Side &&
|
||||
1 == kRight_Side);
|
||||
*side = (Side) SkScalarSignAsInt(det);
|
||||
}
|
||||
return SkScalarMulDiv(det, det, uLengthSqd);
|
||||
}
|
||||
|
||||
SkScalar SkPoint::distanceToLineSegmentBetweenSqd(const SkPoint& a,
|
||||
const SkPoint& b) const {
|
||||
// See comments to distanceToLineBetweenSqd. If the projection of c onto
|
||||
// u is between a and b then this returns the same result as that
|
||||
|
@ -28,8 +28,8 @@ static double getseconds() {
|
||||
}
|
||||
|
||||
// returns +1 or -1, depending on the sign of x
|
||||
// returns +1 if x is zero
|
||||
static SkScalar SkScalarSign(SkScalar x) {
|
||||
// returns +1 if z is zero
|
||||
static SkScalar SkScalarSignNonZero(SkScalar x) {
|
||||
SkScalar sign = SK_Scalar1;
|
||||
if (x < 0) {
|
||||
sign = -sign;
|
||||
@ -41,9 +41,9 @@ static void unit_axis_align(SkVector* unit) {
|
||||
const SkScalar TOLERANCE = SkDoubleToScalar(0.15);
|
||||
if (SkScalarAbs(unit->fX) < TOLERANCE) {
|
||||
unit->fX = 0;
|
||||
unit->fY = SkScalarSign(unit->fY);
|
||||
unit->fY = SkScalarSignNonZero(unit->fY);
|
||||
} else if (SkScalarAbs(unit->fY) < TOLERANCE) {
|
||||
unit->fX = SkScalarSign(unit->fX);
|
||||
unit->fX = SkScalarSignNonZero(unit->fX);
|
||||
unit->fY = 0;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user