some utils for rect and matrix

BUG=skia:

Review URL: https://codereview.chromium.org/1003813003
This commit is contained in:
reed 2015-03-13 06:08:28 -07:00 committed by Commit bot
parent d1f7f990a1
commit 11fa2247b7
10 changed files with 56 additions and 42 deletions

View File

@ -457,6 +457,12 @@ public:
this->getMapXYProc()(*this, x, y, result);
}
SkPoint mapXY(SkScalar x, SkScalar y) const {
SkPoint result;
this->getMapXYProc()(*this, x, y, &result);
return result;
}
/** Apply this matrix to the array of vectors specified by src, and write
the transformed vectors into the array of vectors specified by dst.
This is similar to mapPoints, but ignores any translation in the matrix.
@ -480,6 +486,17 @@ public:
this->mapVectors(vecs, vecs, count);
}
void mapVector(SkScalar dx, SkScalar dy, SkVector* result) const {
SkVector vec = { dx, dy };
this->mapVectors(result, &vec, 1);
}
SkVector mapVector(SkScalar dx, SkScalar dy) const {
SkVector vec = { dx, dy };
this->mapVectors(&vec, &vec, 1);
return vec;
}
/** Apply this matrix to the src rectangle, and write the transformed
rectangle into dst. This is accomplished by transforming the 4 corners
of src, and then setting dst to the bounds of those points.

View File

@ -162,17 +162,24 @@ struct SK_API SkIRect {
/**
* Return a new IRect, built as an offset of this rect.
*/
SkIRect makeOffset(int dx, int dy) const {
SkIRect makeOffset(int32_t dx, int32_t dy) const {
return MakeLTRB(fLeft + dx, fTop + dy, fRight + dx, fBottom + dy);
}
/**
* Return a new IRect, built as an inset of this rect.
*/
SkIRect makeInset(int dx, int dy) const {
SkIRect makeInset(int32_t dx, int32_t dy) const {
return MakeLTRB(fLeft + dx, fTop + dy, fRight - dx, fBottom - dy);
}
/**
* Return a new Rect, built as an outset of this rect.
*/
SkIRect makeOutset(int32_t dx, int32_t dy) const {
return MakeLTRB(fLeft - dx, fTop - dy, fRight + dx, fBottom + dy);
}
/** Offset set the rectangle by adding dx to its left and right,
and adding dy to its top and bottom.
*/
@ -608,7 +615,7 @@ struct SK_API SkRect {
SkRect makeOffset(SkScalar dx, SkScalar dy) const {
return MakeLTRB(fLeft + dx, fTop + dy, fRight + dx, fBottom + dy);
}
/**
* Return a new Rect, built as an inset of this rect.
*/
@ -616,6 +623,13 @@ struct SK_API SkRect {
return MakeLTRB(fLeft + dx, fTop + dy, fRight - dx, fBottom - dy);
}
/**
* Return a new Rect, built as an outset of this rect.
*/
SkRect makeOutset(SkScalar dx, SkScalar dy) const {
return MakeLTRB(fLeft - dx, fTop - dy, fRight + dx, fBottom + dy);
}
/** Offset set the rectangle by adding dx to its left and right,
and adding dy to its top and bottom.
*/

View File

@ -125,7 +125,7 @@ public:
static inline SkMatrix MakeDivByTextureWHMatrix(const GrTexture* texture) {
SkASSERT(texture);
SkMatrix mat;
mat.setIDiv(texture->width(), texture->height());
(void)mat.setIDiv(texture->width(), texture->height());
return mat;
}

View File

@ -2181,11 +2181,7 @@ static bool compute_bounds(const SkPath& devPath, const SkIRect* clipBounds,
}
// init our bounds from the path
{
SkRect pathBounds = devPath.getBounds();
pathBounds.inset(-SK_ScalarHalf, -SK_ScalarHalf);
pathBounds.roundOut(bounds);
}
*bounds = devPath.getBounds().makeOutset(SK_ScalarHalf, SK_ScalarHalf).roundOut();
SkIPoint margin = SkIPoint::Make(0, 0);
if (filter) {
@ -2204,7 +2200,6 @@ static bool compute_bounds(const SkPath& devPath, const SkIRect* clipBounds,
// (possibly) trim the bounds to reflect the clip
// (plus whatever slop the filter needs)
if (clipBounds) {
SkIRect tmp = *clipBounds;
// Ugh. Guard against gigantic margins from wacky filters. Without this
// check we can request arbitrary amounts of slop beyond our visible
// clip, and bring down the renderer (at least on finite RAM machines
@ -2212,9 +2207,8 @@ static bool compute_bounds(const SkPath& devPath, const SkIRect* clipBounds,
// quality of large filters like blurs, and the corresponding memory
// requests.
static const int MAX_MARGIN = 128;
tmp.inset(-SkMin32(margin.fX, MAX_MARGIN),
-SkMin32(margin.fY, MAX_MARGIN));
if (!bounds->intersect(tmp)) {
if (!bounds->intersect(clipBounds->makeOutset(SkMin32(margin.fX, MAX_MARGIN),
SkMin32(margin.fY, MAX_MARGIN)))) {
return false;
}
}

View File

@ -453,9 +453,8 @@ bool SkRRect::transform(const SkMatrix& matrix, SkRRect* dst) const {
///////////////////////////////////////////////////////////////////////////////
void SkRRect::inset(SkScalar dx, SkScalar dy, SkRRect* dst) const {
SkRect r = fRect;
const SkRect r = fRect.makeInset(dx, dy);
r.inset(dx, dy);
if (r.isEmpty()) {
dst->setEmpty();
return;

View File

@ -27,8 +27,7 @@ bool SkRasterizer::rasterize(const SkPath& fillPath, const SkMatrix& matrix,
if (!filter->filterMask(&dstM, srcM, matrix, &margin)) {
return false;
}
storage = *clipBounds;
storage.inset(-margin.fX, -margin.fY);
storage = clipBounds->makeOutset(margin.fX, margin.fY);
clipBounds = &storage;
}

View File

@ -625,7 +625,7 @@ void SkScan::AntiHairLineRgn(const SkPoint& pt0, const SkPoint& pt1,
since the 1/2 pixel boundary is important to the antihair blitter,
we don't want to risk numerical fate by chopping on that edge.
*/
clipBounds.inset(-SK_Scalar1, -SK_Scalar1);
clipBounds.outset(SK_Scalar1, SK_Scalar1);
if (!SkLineClipper::IntersectLine(pts, clipBounds, pts)) {
return;

View File

@ -267,9 +267,7 @@ static void hair_path(const SkPath& path, const SkRasterClip& rclip,
const SkRegion* clip = NULL;
{
SkIRect ibounds;
path.getBounds().roundOut(&ibounds);
ibounds.inset(-1, -1);
const SkIRect ibounds = path.getBounds().roundOut().makeOutset(1, 1);
if (rclip.quickReject(ibounds)) {
return;
@ -379,7 +377,7 @@ void SkScan::HairLine(const SkPoint& p0, const SkPoint& p1,
SkRect r;
r.set(p0.fX, p0.fY, p1.fX, p1.fY);
r.sort();
r.inset(-SK_ScalarHalf, -SK_ScalarHalf);
r.outset(SK_ScalarHalf, SK_ScalarHalf);
SkAAClipBlitterWrapper wrap;
if (!clip.quickContains(r.roundOut())) {
@ -398,14 +396,11 @@ void SkScan::AntiHairLine(const SkPoint& p0, const SkPoint& p1,
} else {
const SkRegion* clipRgn = NULL;
SkRect r;
SkIRect ir;
r.set(p0.fX, p0.fY, p1.fX, p1.fY);
r.sort();
r.roundOut(&ir);
ir.inset(-1, -1);
SkAAClipBlitterWrapper wrap;
if (!clip.quickContains(ir)) {
if (!clip.quickContains(r.roundOut().makeOutset(1, 1))) {
wrap.init(clip, blitter);
blitter = wrap.getBlitter();
clipRgn = &wrap.getRgn();

View File

@ -78,16 +78,14 @@ struct SkPerlinNoiseShader::PaintingData {
SkScalar baseFrequencyX, SkScalar baseFrequencyY,
const SkMatrix& matrix)
{
SkVector wavelength = SkVector::Make(SkScalarInvert(baseFrequencyX),
SkScalarInvert(baseFrequencyY));
matrix.mapVectors(&wavelength, 1);
fBaseFrequency.fX = SkScalarInvert(wavelength.fX);
fBaseFrequency.fY = SkScalarInvert(wavelength.fY);
SkVector sizeVec = SkVector::Make(SkIntToScalar(tileSize.fWidth),
SkIntToScalar(tileSize.fHeight));
matrix.mapVectors(&sizeVec, 1);
fTileSize.fWidth = SkScalarRoundToInt(sizeVec.fX);
fTileSize.fHeight = SkScalarRoundToInt(sizeVec.fY);
SkVector vec[2] = {
{ SkScalarInvert(baseFrequencyX), SkScalarInvert(baseFrequencyY) },
{ SkIntToScalar(tileSize.fWidth), SkIntToScalar(tileSize.fHeight) },
};
matrix.mapVectors(vec, 2);
fBaseFrequency.set(SkScalarInvert(vec[0].fX), SkScalarInvert(vec[0].fY));
fTileSize.set(SkScalarRoundToInt(vec[1].fX), SkScalarRoundToInt(vec[1].fY));
this->init(seed);
if (!fTileSize.isEmpty()) {
this->stitch();

View File

@ -214,9 +214,8 @@ protected:
void generateAdvance(SkGlyph* glyph) SK_OVERRIDE {
fFace->getAdvance(glyph);
SkVector advance;
fMatrix.mapXY(SkFixedToScalar(glyph->fAdvanceX),
SkFixedToScalar(glyph->fAdvanceY), &advance);
const SkVector advance = fMatrix.mapXY(SkFixedToScalar(glyph->fAdvanceX),
SkFixedToScalar(glyph->fAdvanceY));
glyph->fAdvanceX = SkScalarToFixed(advance.fX);
glyph->fAdvanceY = SkScalarToFixed(advance.fY);
}
@ -224,9 +223,8 @@ protected:
void generateMetrics(SkGlyph* glyph) SK_OVERRIDE {
fFace->getMetrics(glyph);
SkVector advance;
fMatrix.mapXY(SkFixedToScalar(glyph->fAdvanceX),
SkFixedToScalar(glyph->fAdvanceY), &advance);
const SkVector advance = fMatrix.mapXY(SkFixedToScalar(glyph->fAdvanceX),
SkFixedToScalar(glyph->fAdvanceY));
glyph->fAdvanceX = SkScalarToFixed(advance.fX);
glyph->fAdvanceY = SkScalarToFixed(advance.fY);