Quelle Sk2DPathEffect.cpp
Sprache: C
/*
* Copyright 2006 The Android Open Source Project
*
* Use of this source code is governed by a BSD - style license that can be
* found in the LICENSE file .
*/
#include "include/effects/Sk2DPathEffect.h"
#include "include/core/SkFlattenable.h"
#include "include/core/SkMatrix.h"
#include "include/core/SkPath.h"
#include "include/core/SkPathBuilder.h"
#include "include/core/SkPathEffect.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkRegion.h"
#include "include/core/SkScalar.h"
#include "include/core/SkStrokeRec.h"
#include "include/core/SkTypes.h"
#include "src/core/SkPathEffectBase.h"
#include "src/core/SkReadBuffer.h"
#include "src/core/SkWriteBuffer.h"
class Sk2DPathEffect : public SkPathEffectBase {
public :
Sk2DPathEffect(const SkMatrix& mat) : fMatrix(mat) {
// Calling invert will set the type mask on both matrices, making them thread safe.
fMatrixIsInvertible = fMatrix.invert(&fInverse);
}
protected :
/** New virtual, to be overridden by subclasses.
This is called once from filterPath , and provides the
uv parameter bounds for the path . Subsequent calls to
next ( ) will receive u and v values within these bounds ,
and then a call to end ( ) will signal the end of processing .
*/
virtual void begin(const SkIRect& uvBounds, SkPathBuilder* dst) const {}
virtual void next(const SkPoint& loc, int u, int v, SkPathBuilder* dst) const {}
virtual void end(SkPathBuilder* dst) const {}
/** Low-level virtual called per span of locations in the u-direction.
The default implementation calls next ( ) repeatedly with each
location .
*/
virtual void nextSpan(int x, int y, int ucount, SkPathBuilder* builder) const {
if (!fMatrixIsInvertible) {
return ;
}
#if defined (SK_BUILD_FOR_FUZZER)
if (ucount > 100 ) {
return ;
}
#endif
const SkMatrix& mat = this ->getMatrix();
SkPoint src, dst;
src.set(SkIntToScalar(x) + SK_ScalarHalf, SkIntToScalar(y) + SK_ScalarHalf);
do {
dst = mat.mapPoint(src);
this ->next(dst, x++, y, builder);
src.fX += SK_Scalar1;
} while (--ucount > 0 );
}
const SkMatrix& getMatrix() const { return fMatrix; }
void flatten(SkWriteBuffer& buffer) const override {
buffer.writeMatrix(fMatrix);
}
bool onFilterPath(SkPathBuilder* dst, const SkPath& src, SkStrokeRec* rec,
const SkRect* cullRect, const SkMatrix&) const override {
if (!fMatrixIsInvertible) {
return false ;
}
SkPath tmp = src.makeTransform(fInverse);
SkIRect ir = tmp.getBounds().round();
if (!ir.isEmpty()) {
this ->begin(ir, dst);
SkRegion rgn;
rgn.setPath(tmp, SkRegion(ir));
SkRegion::Iterator iter(rgn);
for (; !iter.done(); iter.next()) {
const SkIRect& rect = iter.rect();
#if defined (SK_BUILD_FOR_FUZZER)
if (rect.height() > 100 ) {
continue ;
}
#endif
for (int y = rect.fTop; y < rect.fBottom; ++y) {
this ->nextSpan(rect.fLeft, y, rect.width(), dst);
}
}
this ->end(dst);
}
return true ;
}
private :
SkMatrix fMatrix, fInverse;
bool fMatrixIsInvertible;
// For simplicity, assume fast bounds cannot be computed
bool computeFastBounds(SkRect*) const override { return false ; }
friend class Sk2DPathEffectBlitter;
};
///////////////////////////////////////////////////////////////////////////////
class SkLine2DPathEffectImpl : public Sk2DPathEffect {
public :
SkLine2DPathEffectImpl(SkScalar width, const SkMatrix& matrix)
: Sk2DPathEffect(matrix)
, fWidth(width)
{
SkASSERT(width >= 0 );
}
bool onFilterPath(SkPathBuilder* dst, const SkPath& src, SkStrokeRec* rec,
const SkRect* cullRect, const SkMatrix& ctm) const override {
if (this ->INHERITED::onFilterPath(dst, src, rec, cullRect, ctm)) {
rec->setStrokeStyle(fWidth);
return true ;
}
return false ;
}
void nextSpan(int u, int v, int ucount, SkPathBuilder* dst) const override {
if (ucount > 1 ) {
SkPoint src[2 ], dstP[2 ];
src[0 ].set(SkIntToScalar(u) + SK_ScalarHalf, SkIntToScalar(v) + SK_ScalarHalf);
src[1 ].set(SkIntToScalar(u+ucount) + SK_ScalarHalf, SkIntToScalar(v) + SK_ScalarHalf);
this ->getMatrix().mapPoints(dstP, src);
dst->moveTo(dstP[0 ]);
dst->lineTo(dstP[1 ]);
}
}
static sk_sp<SkFlattenable> CreateProc(SkReadBuffer& buffer) {
SkMatrix matrix;
buffer.readMatrix(&matrix);
SkScalar width = buffer.readScalar();
return SkLine2DPathEffect::Make(width, matrix);
}
void flatten(SkWriteBuffer &buffer) const override {
buffer.writeMatrix(this ->getMatrix());
buffer.writeScalar(fWidth);
}
Factory getFactory() const override { return CreateProc; }
const char * getTypeName() const override { return "SkLine2DPathEffect" ; }
private :
SkScalar fWidth;
using INHERITED = Sk2DPathEffect;
};
/////////////////////////////////////////////////////////////////////////////////////////////////
class SkPath2DPathEffectImpl : public Sk2DPathEffect {
public :
SkPath2DPathEffectImpl(const SkMatrix& m, const SkPath& p) : INHERITED(m), fPath(p) {}
void next(const SkPoint& loc, int u, int v, SkPathBuilder* dst) const override {
dst->addPath(fPath, loc.fX, loc.fY);
}
static sk_sp<SkFlattenable> CreateProc(SkReadBuffer& buffer) {
SkMatrix matrix;
buffer.readMatrix(&matrix);
if (auto path = buffer.readPath()) {
return SkPath2DPathEffect::Make(matrix, *path);
}
return nullptr;
}
void flatten(SkWriteBuffer& buffer) const override {
buffer.writeMatrix(this ->getMatrix());
buffer.writePath(fPath);
}
Factory getFactory() const override { return CreateProc; }
const char * getTypeName() const override { return "SkPath2DPathEffect" ; }
private :
SkPath fPath;
using INHERITED = Sk2DPathEffect;
};
//////////////////////////////////////////////////////////////////////////////////////////////////
sk_sp<SkPathEffect> SkLine2DPathEffect::Make(SkScalar width, const SkMatrix& matrix) {
if (!(width >= 0 )) {
return nullptr;
}
return sk_sp<SkPathEffect>(new SkLine2DPathEffectImpl(width, matrix));
}
sk_sp<SkPathEffect> SkPath2DPathEffect::Make(const SkMatrix& matrix, const SkPath& path) {
return sk_sp<SkPathEffect>(new SkPath2DPathEffectImpl(matrix, path));
}
void SkLine2DPathEffect::RegisterFlattenables() {
SK_REGISTER_FLATTENABLE(SkLine2DPathEffectImpl);
}
void SkPath2DPathEffect::RegisterFlattenables() {
SK_REGISTER_FLATTENABLE(SkPath2DPathEffectImpl);
}
Messung V0.5 in Prozent C=97 H=95 G=95
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet am 2026-09-30)
¤
*© Formatika GbR, Deutschland
2026-10-10
Neuigkeiten
Aktuelles
Motto des Tages
Open Source Software
Jenseits des Üblichen ....
Besucherstatistik
Statistik
#Sources=1126864
#Domains=1897691