blob: a893e72a21797fd09ccf244b1fdfea7fdb1943e9 [file] [log] [blame]
/*
* Copyright 2022 Google LLC
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "include/core/SkPathUtils.h"
#include "include/core/SkMatrix.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPath.h"
#include "include/core/SkPathBuilder.h"
#include "include/core/SkPathEffect.h"
#include "include/core/SkScalar.h"
#include "include/core/SkStrokeRec.h"
#include "src/core/SkMatrixPriv.h"
namespace skpathutils {
#ifdef SK_SUPPORT_MUTABLE_PATHEFFECT
bool FillPathWithPaint(const SkPath& src, const SkPaint& paint, SkPath* dst) {
return skpathutils::FillPathWithPaint(src, paint, dst, nullptr, 1);
}
bool FillPathWithPaint(const SkPath& src, const SkPaint& paint, SkPath* dst,
const SkRect* cullRect, SkScalar resScale) {
return skpathutils::FillPathWithPaint(src, paint, dst, cullRect,
SkMatrix::Scale(resScale, resScale));
}
bool FillPathWithPaint(const SkPath& src, const SkPaint& paint, SkPath* dst,
const SkRect* cullRect, const SkMatrix& ctm) {
SkPathBuilder builder;
bool isFilled = FillPathWithPaint(src, paint, &builder, cullRect, ctm);
*dst = builder.detach();
return isFilled;
}
#endif
bool FillPathWithPaint(const SkPath& origSrc, const SkPaint& paint, SkPathBuilder* builder,
const SkRect* cullRect, const SkMatrix& ctm) {
builder->reset();
if (!origSrc.isFinite()) {
return false;
}
const SkScalar resScale = SkMatrixPriv::ComputeResScaleForStroking(ctm);
SkStrokeRec rec(paint, resScale);
#if defined(SK_BUILD_FOR_FUZZER)
// Prevent lines with small widths from timing out.
if (rec.getStyle() == SkStrokeRec::Style::kStroke_Style && rec.getWidth() < 0.001) {
return false;
}
#endif
const SkPath* srcPtr = &origSrc;
SkPath pathStorage;
SkPathEffect* pe = paint.getPathEffect();
if (pe && pe->filterPath(builder, origSrc, &rec, cullRect, ctm)) {
pathStorage = builder->detach();
srcPtr = &pathStorage;
}
if (!rec.applyToPath(builder, *srcPtr)) {
*builder = *srcPtr;
}
if (!builder->isFinite()) {
builder->reset();
}
return !rec.isHairlineStyle();
}
bool FillPathWithPaint(const SkPath& src, const SkPaint& paint, SkPathBuilder* dst) {
return FillPathWithPaint(src, paint, dst, nullptr, SkMatrix::I());
}
SkPath FillPathWithPaint(const SkPath& src, const SkPaint& paint, bool* isFillPtr) {
SkPathBuilder builder;
bool isFill = FillPathWithPaint(src, paint, &builder);
if (isFillPtr) {
*isFillPtr = isFill;
}
return builder.detach();
}
} // namespace skpathutils