Unify implementations of stroking radius calculationsns

GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1928133002

Review-Url: https://codereview.chromium.org/1928133002
This commit is contained in:
bsalomon 2016-04-29 07:07:03 -07:00 committed by Commit bot
parent 24e9128694
commit 5668648e87
4 changed files with 48 additions and 26 deletions

View File

@ -98,6 +98,22 @@ public:
*/
void applyToPaint(SkPaint* paint) const;
/**
* Gives a conservative value for the outset that should applied to a
* geometries bounds to account for any inflation due to applying this
* strokeRec to the geometry.
*/
SkScalar getInflationRadius() const;
/**
* Equivalent to:
* SkStrokeRec rec(paint, style);
* rec.getInflationRadius();
* This does not account for other effects on the paint (i.e. path
* effect).
*/
static SkScalar GetInflationRadius(const SkPaint&, SkPaint::Style);
/**
* Compare if two SkStrokeRecs have an equal effect on a path.
* Equal SkStrokeRecs produce equal paths. Equality of produced

View File

@ -2025,22 +2025,8 @@ const SkRect& SkPaint::doComputeFastBounds(const SkRect& origSrc,
src = &tmpSrc;
}
if (kFill_Style != style) {
// since we're stroked, outset the rect by the radius (and join type)
SkScalar radius = SkScalarHalf(this->getStrokeWidth());
if (0 == radius) { // hairline
radius = SK_Scalar1;
} else if (this->getStrokeJoin() == SkPaint::kMiter_Join) {
SkScalar scale = this->getStrokeMiter();
if (scale > SK_Scalar1) {
radius = SkScalarMul(radius, scale);
}
}
storage->set(src->fLeft - radius, src->fTop - radius,
src->fRight + radius, src->fBottom + radius);
} else {
*storage = *src;
}
SkScalar radius = SkStrokeRec::GetInflationRadius(*this, style);
*storage = src->makeOutset(radius, radius);
if (this->getMaskFilter()) {
this->getMaskFilter()->computeFastBounds(*storage, storage);

View File

@ -134,3 +134,31 @@ void SkStrokeRec::applyToPaint(SkPaint* paint) const {
paint->setStrokeCap((SkPaint::Cap)fCap);
paint->setStrokeJoin((SkPaint::Join)fJoin);
}
static inline SkScalar get_inflation_bounds(SkPaint::Join join,
SkScalar strokeWidth,
SkScalar miterLimit) {
if (strokeWidth < 0) { // fill
return 0;
} else if (0 == strokeWidth) {
return SK_Scalar1;
}
// since we're stroked, outset the rect by the radius (and join type)
SkScalar radius = SkScalarHalf(strokeWidth);
if (SkPaint::kMiter_Join == join) {
if (miterLimit > SK_Scalar1) {
radius = SkScalarMul(miterLimit, radius);
}
}
return radius;
}
SkScalar SkStrokeRec::getInflationRadius() const {
return get_inflation_bounds((SkPaint::Join)fJoin, fWidth, fMiterLimit);
}
SkScalar SkStrokeRec::GetInflationRadius(const SkPaint& paint, SkPaint::Style style) {
SkScalar width = SkPaint::kFill_Style == style ? -SK_Scalar1 : paint.getStrokeWidth();
return get_inflation_bounds(paint.getStrokeJoin(), width, paint.getStrokeMiter());
}

View File

@ -258,16 +258,8 @@ private:
} else {
fBounds = path.getBounds();
}
if (!stroke.isFillStyle()) {
SkScalar radius = SkScalarHalf(stroke.getWidth());
if (stroke.getJoin() == SkPaint::kMiter_Join) {
SkScalar scale = stroke.getMiter();
if (scale > SK_Scalar1) {
radius = SkScalarMul(radius, scale);
}
}
fBounds.outset(radius, radius);
}
SkScalar radius = stroke.getInflationRadius();
fBounds.outset(radius, radius);
viewMatrix.mapRect(&fBounds);
}