#include "include/core/SkStrokeRec.h"
#include "src/core/SkPaintDefaults.h"
#include "src/core/SkStroke.h"
namespace pk {
#define kStrokeRec_FillStyleWidth (-PK_Scalar1)
SkStrokeRec::SkStrokeRec(InitStyle s) {
fResScale = 1;
fWidth = (kFill_InitStyle == s) ? kStrokeRec_FillStyleWidth : 0;
fMiterLimit = PkPaintDefaults_MiterLimit;
fCap = SkPaint::kDefault_Cap;
fJoin = SkPaint::kDefault_Join;
fStrokeAndFill = false;
}
SkStrokeRec::SkStrokeRec(const SkPaint& paint, SkScalar resScale) {
this->init(paint, paint.getStyle(), resScale);
}
SkStrokeRec::SkStrokeRec(const SkPaint& paint, SkPaint::Style styleOverride, SkScalar resScale) {
this->init(paint, styleOverride, resScale);
}
void SkStrokeRec::init(const SkPaint& paint, SkPaint::Style style, SkScalar resScale) {
fResScale = resScale;
switch (style) {
case SkPaint::kFill_Style:
fWidth = kStrokeRec_FillStyleWidth;
fStrokeAndFill = false;
break;
case SkPaint::kStroke_Style:
fWidth = paint.getStrokeWidth();
fStrokeAndFill = false;
break;
case SkPaint::kStrokeAndFill_Style:
if (0 == paint.getStrokeWidth()) {
fWidth = kStrokeRec_FillStyleWidth;
fStrokeAndFill = false;
} else {
fWidth = paint.getStrokeWidth();
fStrokeAndFill = true;
}
break;
default:
PkDEBUGFAIL("unknown paint style");
fWidth = kStrokeRec_FillStyleWidth;
fStrokeAndFill = false;
break;
}
fMiterLimit = paint.getStrokeMiter();
fCap = paint.getStrokeCap();
fJoin = paint.getStrokeJoin();
}
SkStrokeRec::Style SkStrokeRec::getStyle() const {
if (fWidth < 0) {
return kFill_Style;
} else if (0 == fWidth) {
return kHairline_Style;
} else {
return fStrokeAndFill ? kStrokeAndFill_Style : kStroke_Style;
}
}
void SkStrokeRec::setFillStyle() {
fWidth = kStrokeRec_FillStyleWidth;
fStrokeAndFill = false;
}
void SkStrokeRec::setHairlineStyle() {
fWidth = 0;
fStrokeAndFill = false;
}
void SkStrokeRec::setStrokeStyle(SkScalar width, bool strokeAndFill) {
if (strokeAndFill && (0 == width)) {
this->setFillStyle();
} else {
fWidth = width;
fStrokeAndFill = strokeAndFill;
}
}
bool SkStrokeRec::applyToPath(SkPath* dst, const SkPath& src) const {
if (fWidth <= 0) { return false;
}
SkStroke stroker;
stroker.setCap((SkPaint::Cap)fCap);
stroker.setJoin((SkPaint::Join)fJoin);
stroker.setMiterLimit(fMiterLimit);
stroker.setWidth(fWidth);
stroker.setDoFill(fStrokeAndFill);
stroker.setResScale(fResScale);
stroker.strokePath(src, dst);
return true;
}
void SkStrokeRec::applyToPaint(SkPaint* paint) const {
if (fWidth < 0) { paint->setStyle(SkPaint::kFill_Style);
return;
}
paint->setStyle(fStrokeAndFill ? SkPaint::kStrokeAndFill_Style : SkPaint::kStroke_Style);
paint->setStrokeWidth(fWidth);
paint->setStrokeMiter(fMiterLimit);
paint->setStrokeCap((SkPaint::Cap)fCap);
paint->setStrokeJoin((SkPaint::Join)fJoin);
}
SkScalar SkStrokeRec::getInflationRadius() const {
return GetInflationRadius((SkPaint::Join)fJoin, fMiterLimit, (SkPaint::Cap)fCap, fWidth);
}
SkScalar SkStrokeRec::GetInflationRadius(const SkPaint& paint, SkPaint::Style style) {
SkScalar width = SkPaint::kFill_Style == style ? -PK_Scalar1 : paint.getStrokeWidth();
return GetInflationRadius(
paint.getStrokeJoin(), paint.getStrokeMiter(), paint.getStrokeCap(), width);
}
SkScalar SkStrokeRec::GetInflationRadius(SkPaint::Join join,
SkScalar miterLimit,
SkPaint::Cap cap,
SkScalar strokeWidth) {
if (strokeWidth < 0) { return 0;
} else if (0 == strokeWidth) {
return PK_Scalar1;
}
SkScalar multiplier = PK_Scalar1;
if (SkPaint::kMiter_Join == join) {
multiplier = std::max(multiplier, miterLimit);
}
if (SkPaint::kSquare_Cap == cap) {
multiplier = std::max(multiplier, PK_ScalarSqrt2);
}
return strokeWidth / 2 * multiplier;
}
}