/*
|
* Copyright 2018 Google Inc.
|
*
|
* Use of this source code is governed by a BSD-style license that can be
|
* found in the LICENSE file.
|
*/
|
|
#include "SkOpPE.h"
|
#include "SkStrokeRec.h"
|
#include "SkReadBuffer.h"
|
#include "SkWriteBuffer.h"
|
|
sk_sp<SkPathEffect> SkMergePathEffect::Make(sk_sp<SkPathEffect> one, sk_sp<SkPathEffect> two,
|
SkPathOp op) {
|
return sk_sp<SkPathEffect>(new SkOpPE(std::move(one), std::move(two), op));
|
}
|
|
SkOpPE::SkOpPE(sk_sp<SkPathEffect> one, sk_sp<SkPathEffect> two, SkPathOp op)
|
: fOne(std::move(one)), fTwo(std::move(two)), fOp(op) {}
|
|
bool SkOpPE::onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec* rec,
|
const SkRect* cull) const {
|
SkPath one, two;
|
if (fOne) {
|
if (!fOne->filterPath(&one, src, rec, cull)) {
|
return false;
|
}
|
} else {
|
one = src;
|
}
|
if (fTwo) {
|
if (!fTwo->filterPath(&two, src, rec, cull)) {
|
return false;
|
}
|
} else {
|
two = src;
|
}
|
return Op(one, two, fOp, dst);
|
}
|
|
void SkOpPE::flatten(SkWriteBuffer& buffer) const {
|
buffer.writeFlattenable(fOne.get());
|
buffer.writeFlattenable(fTwo.get());
|
buffer.write32(fOp);
|
}
|
|
sk_sp<SkFlattenable> SkOpPE::CreateProc(SkReadBuffer& buffer) {
|
auto one = buffer.readPathEffect();
|
auto two = buffer.readPathEffect();
|
SkPathOp op = buffer.read32LE(kReverseDifference_SkPathOp);
|
return buffer.isValid() ? SkMergePathEffect::Make(std::move(one), std::move(two), op) : nullptr;
|
}
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////
|
|
sk_sp<SkPathEffect> SkMatrixPathEffect::MakeTranslate(SkScalar dx, SkScalar dy) {
|
if (!SkScalarsAreFinite(dx, dy)) {
|
return nullptr;
|
}
|
return sk_sp<SkPathEffect>(new SkMatrixPE(SkMatrix::MakeTrans(dx, dy)));
|
}
|
|
sk_sp<SkPathEffect> SkMatrixPathEffect::Make(const SkMatrix& matrix) {
|
if (!matrix.isFinite()) {
|
return nullptr;
|
}
|
return sk_sp<SkPathEffect>(new SkMatrixPE(matrix));
|
}
|
|
SkMatrixPE::SkMatrixPE(const SkMatrix& matrix) : fMatrix(matrix) {
|
SkASSERT(matrix.isFinite());
|
}
|
|
bool SkMatrixPE::onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, const SkRect*) const {
|
src.transform(fMatrix, dst);
|
return true;
|
}
|
|
void SkMatrixPE::flatten(SkWriteBuffer& buffer) const {
|
buffer.writeMatrix(fMatrix);
|
}
|
|
sk_sp<SkFlattenable> SkMatrixPE::CreateProc(SkReadBuffer& buffer) {
|
SkMatrix mx;
|
buffer.readMatrix(&mx);
|
return buffer.isValid() ? SkMatrixPathEffect::Make(mx) : nullptr;
|
}
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////
|
|
sk_sp<SkPathEffect> SkStrokePathEffect::Make(SkScalar width, SkPaint::Join join, SkPaint::Cap cap,
|
SkScalar miter) {
|
if (!SkScalarsAreFinite(width, miter) || width < 0 || miter < 0) {
|
return nullptr;
|
}
|
return sk_sp<SkPathEffect>(new SkStrokePE(width, join, cap, miter));
|
}
|
|
SkStrokePE::SkStrokePE(SkScalar width, SkPaint::Join join, SkPaint::Cap cap, SkScalar miter)
|
: fWidth(width), fMiter(miter), fJoin(join), fCap(cap) {}
|
|
bool SkStrokePE::onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, const SkRect*) const {
|
SkStrokeRec rec(SkStrokeRec::kFill_InitStyle);
|
rec.setStrokeStyle(fWidth);
|
rec.setStrokeParams(fCap, fJoin, fMiter);
|
return rec.applyToPath(dst, src);
|
}
|
|
void SkStrokePE::flatten(SkWriteBuffer& buffer) const {
|
buffer.writeScalar(fWidth);
|
buffer.writeScalar(fMiter);
|
buffer.write32(fJoin);
|
buffer.write32(fCap);
|
}
|
|
sk_sp<SkFlattenable> SkStrokePE::CreateProc(SkReadBuffer& buffer) {
|
SkScalar width = buffer.readScalar();
|
SkScalar miter = buffer.readScalar();
|
SkPaint::Join join = buffer.read32LE(SkPaint::kLast_Join);
|
SkPaint::Cap cap = buffer.read32LE(SkPaint::kLast_Cap);
|
return buffer.isValid() ? SkStrokePathEffect::Make(width, join, cap, miter) : nullptr;
|
}
|