Flutter Engine
The Flutter Engine
Public Member Functions | Protected Member Functions | List of all members
SkDashImpl Class Reference

#include <SkDashImpl.h>

Inheritance diagram for SkDashImpl:
SkPathEffectBase SkPathEffect SkFlattenable SkRefCnt SkRefCntBase

Public Member Functions

 SkDashImpl (const SkScalar intervals[], int count, SkScalar phase)
 
- Public Member Functions inherited from SkPathEffectBase
 SkPathEffectBase ()
 
bool asPoints (PointData *results, const SkPath &src, const SkStrokeRec &, const SkMatrix &, const SkRect *cullR) const
 
SkFlattenable::Type getFlattenableType () const override
 
virtual bool onFilterPath (SkPath *, const SkPath &, SkStrokeRec *, const SkRect *, const SkMatrix &) const =0
 
virtual bool onNeedsCTM () const
 
virtual bool onAsPoints (PointData *, const SkPath &, const SkStrokeRec &, const SkMatrix &, const SkRect *) const
 
virtual DashType onAsADash (DashInfo *) const
 
virtual bool computeFastBounds (SkRect *bounds) const =0
 
- Public Member Functions inherited from SkPathEffect
DashType asADash (DashInfo *info) const
 
bool filterPath (SkPath *dst, const SkPath &src, SkStrokeRec *, const SkRect *cullR) const
 
bool filterPath (SkPath *dst, const SkPath &src, SkStrokeRec *, const SkRect *cullR, const SkMatrix &ctm) const
 
bool needsCTM () const
 
- Public Member Functions inherited from SkFlattenable
 SkFlattenable ()
 
virtual Factory getFactory () const =0
 
virtual const char * getTypeName () const =0
 
virtual void flatten (SkWriteBuffer &) const
 
virtual Type getFlattenableType () const =0
 
sk_sp< SkDataserialize (const SkSerialProcs *=nullptr) const
 
size_t serialize (void *memory, size_t memory_size, const SkSerialProcs *=nullptr) const
 
- Public Member Functions inherited from SkRefCntBase
 SkRefCntBase ()
 
virtual ~SkRefCntBase ()
 
bool unique () const
 
void ref () const
 
void unref () const
 

Protected Member Functions

 ~SkDashImpl () override
 
void flatten (SkWriteBuffer &) const override
 
bool onFilterPath (SkPath *dst, const SkPath &src, SkStrokeRec *, const SkRect *, const SkMatrix &) const override
 
bool onAsPoints (PointData *results, const SkPath &src, const SkStrokeRec &, const SkMatrix &, const SkRect *) const override
 
DashType onAsADash (DashInfo *info) const override
 

Additional Inherited Members

- Public Types inherited from SkPathEffect
enum  DashType { kNone_DashType , kDash_DashType }
 
- Public Types inherited from SkFlattenable
enum  Type {
  kSkColorFilter_Type , kSkBlender_Type , kSkDrawable_Type , kSkDrawLooper_Type ,
  kSkImageFilter_Type , kSkMaskFilter_Type , kSkPathEffect_Type , kSkShader_Type
}
 
typedef sk_sp< SkFlattenable >(* Factory) (SkReadBuffer &)
 
- Static Public Member Functions inherited from SkPathEffectBase
static sk_sp< SkPathEffectDeserialize (const void *data, size_t size, const SkDeserialProcs *procs=nullptr)
 
static void RegisterFlattenables ()
 
- Static Public Member Functions inherited from SkPathEffect
static sk_sp< SkPathEffectMakeSum (sk_sp< SkPathEffect > first, sk_sp< SkPathEffect > second)
 
static sk_sp< SkPathEffectMakeCompose (sk_sp< SkPathEffect > outer, sk_sp< SkPathEffect > inner)
 
static SkFlattenable::Type GetFlattenableType ()
 
static sk_sp< SkPathEffectDeserialize (const void *data, size_t size, const SkDeserialProcs *procs=nullptr)
 
- Static Public Member Functions inherited from SkFlattenable
static Factory NameToFactory (const char name[])
 
static const char * FactoryToName (Factory)
 
static void Register (const char name[], Factory)
 
static sk_sp< SkFlattenableDeserialize (Type, const void *data, size_t length, const SkDeserialProcs *procs=nullptr)
 

Detailed Description

Definition at line 13 of file SkDashImpl.h.

Constructor & Destructor Documentation

◆ SkDashImpl()

SkDashImpl::SkDashImpl ( const SkScalar  intervals[],
int  count,
SkScalar  phase 
)

Definition at line 34 of file SkDashPathEffect.cpp.

35 : fPhase(0)
36 , fInitialDashLength(-1)
37 , fInitialDashIndex(0)
38 , fIntervalLength(0) {
39 SkASSERT(intervals);
41
42 fIntervals = (SkScalar*)sk_malloc_throw(sizeof(SkScalar) * count);
43 fCount = count;
44 for (int i = 0; i < count; i++) {
45 fIntervals[i] = intervals[i];
46 }
47
48 // set the internal data members
49 SkDashPath::CalcDashParameters(phase, fIntervals, fCount,
50 &fInitialDashLength, &fInitialDashIndex, &fIntervalLength, &fPhase);
51}
int count
Definition: FontMgrTest.cpp:50
static constexpr bool SkIsAlign2(T x)
Definition: SkAlign.h:19
#define SkASSERT(cond)
Definition: SkAssert.h:116
static void * sk_malloc_throw(size_t size)
Definition: SkMalloc.h:67
float SkScalar
Definition: extension.cpp:12
void CalcDashParameters(SkScalar phase, const SkScalar intervals[], int32_t count, SkScalar *initialDashLength, int32_t *initialDashIndex, SkScalar *intervalLength, SkScalar *adjustedPhase=nullptr)
Definition: SkDashPath.cpp:54

◆ ~SkDashImpl()

SkDashImpl::~SkDashImpl ( )
overrideprotected

Definition at line 53 of file SkDashPathEffect.cpp.

53 {
54 sk_free(fIntervals);
55}
SK_API void sk_free(void *)

Member Function Documentation

◆ flatten()

void SkDashImpl::flatten ( SkWriteBuffer ) const
overrideprotectedvirtual

Override this if your subclass needs to record data that it will need to recreate itself from its CreateProc (returned by getFactory()).

DEPRECATED public : will move to protected ... use serialize() instead

Reimplemented from SkFlattenable.

Definition at line 386 of file SkDashPathEffect.cpp.

386 {
387 buffer.writeScalar(fPhase);
388 buffer.writeScalarArray(fIntervals, fCount);
389}
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace buffer
Definition: switches.h:126

◆ onAsADash()

SkPathEffect::DashType SkDashImpl::onAsADash ( DashInfo info) const
overrideprotectedvirtual

Reimplemented from SkPathEffectBase.

Definition at line 375 of file SkDashPathEffect.cpp.

375 {
376 if (info) {
377 if (info->fCount >= fCount && info->fIntervals) {
378 memcpy(info->fIntervals, fIntervals, fCount * sizeof(SkScalar));
379 }
380 info->fCount = fCount;
381 info->fPhase = fPhase;
382 }
383 return kDash_DashType;
384}
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: DM.cpp:213
@ kDash_DashType
fills in all of the info parameter
Definition: SkPathEffect.h:62

◆ onAsPoints()

bool SkDashImpl::onAsPoints ( PointData results,
const SkPath src,
const SkStrokeRec rec,
const SkMatrix matrix,
const SkRect cullRect 
) const
overrideprotectedvirtual

Reimplemented from SkPathEffectBase.

Definition at line 182 of file SkDashPathEffect.cpp.

183 {
184 // width < 0 -> fill && width == 0 -> hairline so requiring width > 0 rules both out
185 if (0 >= rec.getWidth()) {
186 return false;
187 }
188
189 // TODO: this next test could be eased up. We could allow any number of
190 // intervals as long as all the ons match and all the offs match.
191 // Additionally, they do not necessarily need to be integers.
192 // We cannot allow arbitrary intervals since we want the returned points
193 // to be uniformly sized.
194 if (fCount != 2 ||
195 !SkScalarNearlyEqual(fIntervals[0], fIntervals[1]) ||
196 !SkScalarIsInt(fIntervals[0]) ||
197 !SkScalarIsInt(fIntervals[1])) {
198 return false;
199 }
200
201 SkPoint pts[2];
202
203 if (!src.isLine(pts)) {
204 return false;
205 }
206
207 // TODO: this test could be eased up to allow circles
208 if (SkPaint::kButt_Cap != rec.getCap()) {
209 return false;
210 }
211
212 // TODO: this test could be eased up for circles. Rotations could be allowed.
213 if (!matrix.rectStaysRect()) {
214 return false;
215 }
216
217 // See if the line can be limited to something plausible.
218 if (!cull_line(pts, rec, matrix, cullRect, fIntervalLength)) {
219 return false;
220 }
221
222 SkScalar length = SkPoint::Distance(pts[1], pts[0]);
223
224 SkVector tangent = pts[1] - pts[0];
225 if (tangent.isZero()) {
226 return false;
227 }
228
229 tangent.scale(SkScalarInvert(length));
230
231 // TODO: make this test for horizontal & vertical lines more robust
232 bool isXAxis = true;
233 if (SkScalarNearlyEqual(SK_Scalar1, tangent.fX) ||
234 SkScalarNearlyEqual(-SK_Scalar1, tangent.fX)) {
235 results->fSize.set(SkScalarHalf(fIntervals[0]), SkScalarHalf(rec.getWidth()));
236 } else if (SkScalarNearlyEqual(SK_Scalar1, tangent.fY) ||
237 SkScalarNearlyEqual(-SK_Scalar1, tangent.fY)) {
238 results->fSize.set(SkScalarHalf(rec.getWidth()), SkScalarHalf(fIntervals[0]));
239 isXAxis = false;
240 } else if (SkPaint::kRound_Cap != rec.getCap()) {
241 // Angled lines don't have axis-aligned boxes.
242 return false;
243 }
244
245 if (results) {
246 results->fFlags = 0;
247 SkScalar clampedInitialDashLength = std::min(length, fInitialDashLength);
248
249 if (SkPaint::kRound_Cap == rec.getCap()) {
250 results->fFlags |= PointData::kCircles_PointFlag;
251 }
252
253 results->fNumPoints = 0;
254 SkScalar len2 = length;
255 if (clampedInitialDashLength > 0 || 0 == fInitialDashIndex) {
256 SkASSERT(len2 >= clampedInitialDashLength);
257 if (0 == fInitialDashIndex) {
258 if (clampedInitialDashLength > 0) {
259 if (clampedInitialDashLength >= fIntervals[0]) {
260 ++results->fNumPoints; // partial first dash
261 }
262 len2 -= clampedInitialDashLength;
263 }
264 len2 -= fIntervals[1]; // also skip first space
265 if (len2 < 0) {
266 len2 = 0;
267 }
268 } else {
269 len2 -= clampedInitialDashLength; // skip initial partial empty
270 }
271 }
272 // Too many midpoints can cause results->fNumPoints to overflow or
273 // otherwise cause the results->fPoints allocation below to OOM.
274 // Cap it to a sane value.
275 SkScalar numIntervals = len2 / fIntervalLength;
276 if (!SkIsFinite(numIntervals) || numIntervals > SkDashPath::kMaxDashCount) {
277 return false;
278 }
279 int numMidPoints = SkScalarFloorToInt(numIntervals);
280 results->fNumPoints += numMidPoints;
281 len2 -= numMidPoints * fIntervalLength;
282 bool partialLast = false;
283 if (len2 > 0) {
284 if (len2 < fIntervals[0]) {
285 partialLast = true;
286 } else {
287 ++numMidPoints;
288 ++results->fNumPoints;
289 }
290 }
291
292 results->fPoints = new SkPoint[results->fNumPoints];
293
294 SkScalar distance = 0;
295 int curPt = 0;
296
297 if (clampedInitialDashLength > 0 || 0 == fInitialDashIndex) {
298 SkASSERT(clampedInitialDashLength <= length);
299
300 if (0 == fInitialDashIndex) {
301 if (clampedInitialDashLength > 0) {
302 // partial first block
303 SkASSERT(SkPaint::kRound_Cap != rec.getCap()); // can't handle partial circles
304 SkScalar x = pts[0].fX + tangent.fX * SkScalarHalf(clampedInitialDashLength);
305 SkScalar y = pts[0].fY + tangent.fY * SkScalarHalf(clampedInitialDashLength);
306 SkScalar halfWidth, halfHeight;
307 if (isXAxis) {
308 halfWidth = SkScalarHalf(clampedInitialDashLength);
309 halfHeight = SkScalarHalf(rec.getWidth());
310 } else {
311 halfWidth = SkScalarHalf(rec.getWidth());
312 halfHeight = SkScalarHalf(clampedInitialDashLength);
313 }
314 if (clampedInitialDashLength < fIntervals[0]) {
315 // This one will not be like the others
316 results->fFirst.addRect(x - halfWidth, y - halfHeight,
317 x + halfWidth, y + halfHeight);
318 } else {
319 SkASSERT(curPt < results->fNumPoints);
320 results->fPoints[curPt].set(x, y);
321 ++curPt;
322 }
323
324 distance += clampedInitialDashLength;
325 }
326
327 distance += fIntervals[1]; // skip over the next blank block too
328 } else {
329 distance += clampedInitialDashLength;
330 }
331 }
332
333 if (0 != numMidPoints) {
334 distance += SkScalarHalf(fIntervals[0]);
335
336 for (int i = 0; i < numMidPoints; ++i) {
337 SkScalar x = pts[0].fX + tangent.fX * distance;
338 SkScalar y = pts[0].fY + tangent.fY * distance;
339
340 SkASSERT(curPt < results->fNumPoints);
341 results->fPoints[curPt].set(x, y);
342 ++curPt;
343
344 distance += fIntervalLength;
345 }
346
347 distance -= SkScalarHalf(fIntervals[0]);
348 }
349
350 if (partialLast) {
351 // partial final block
352 SkASSERT(SkPaint::kRound_Cap != rec.getCap()); // can't handle partial circles
353 SkScalar temp = length - distance;
354 SkASSERT(temp < fIntervals[0]);
355 SkScalar x = pts[0].fX + tangent.fX * (distance + SkScalarHalf(temp));
356 SkScalar y = pts[0].fY + tangent.fY * (distance + SkScalarHalf(temp));
357 SkScalar halfWidth, halfHeight;
358 if (isXAxis) {
359 halfWidth = SkScalarHalf(temp);
360 halfHeight = SkScalarHalf(rec.getWidth());
361 } else {
362 halfWidth = SkScalarHalf(rec.getWidth());
363 halfHeight = SkScalarHalf(temp);
364 }
365 results->fLast.addRect(x - halfWidth, y - halfHeight,
366 x + halfWidth, y + halfHeight);
367 }
368
369 SkASSERT(curPt == results->fNumPoints);
370 }
371
372 return true;
373}
static bool cull_line(SkPoint *pts, const SkStrokeRec &rec, const SkMatrix &ctm, const SkRect *cullRect, const SkScalar intervalLength)
static bool SkIsFinite(T x, Pack... values)
#define SkScalarInvert(x)
Definition: SkScalar.h:73
static bool SkScalarNearlyEqual(SkScalar x, SkScalar y, SkScalar tolerance=SK_ScalarNearlyZero)
Definition: SkScalar.h:107
#define SK_Scalar1
Definition: SkScalar.h:18
#define SkScalarHalf(a)
Definition: SkScalar.h:75
static bool SkScalarIsInt(SkScalar x)
Definition: SkScalar.h:80
#define SkScalarFloorToInt(x)
Definition: SkScalar.h:35
@ kRound_Cap
adds circle
Definition: SkPaint.h:335
@ kButt_Cap
no stroke extension
Definition: SkPaint.h:334
SkScalar getWidth() const
Definition: SkStrokeRec.h:42
SkPaint::Cap getCap() const
Definition: SkStrokeRec.h:44
static float min(float r, float g, float b)
Definition: hsl.cpp:48
size_t length
double y
double x
const SkScalar kMaxDashCount
unsigned useCenter Optional< SkMatrix > matrix
Definition: SkRecords.h:258
bool isZero() const
Definition: SkPoint_impl.h:193
float fX
x-axis value
Definition: SkPoint_impl.h:164
static float Distance(const SkPoint &a, const SkPoint &b)
Definition: SkPoint_impl.h:508
void scale(float scale, SkPoint *dst) const
Definition: SkPoint.cpp:17
float fY
y-axis value
Definition: SkPoint_impl.h:165

◆ onFilterPath()

bool SkDashImpl::onFilterPath ( SkPath ,
const SkPath ,
SkStrokeRec ,
const SkRect ,
const SkMatrix  
) const
overrideprotectedvirtual

Filter the input path.

The CTM parameter is provided for path effects that can use the information. The output of path effects must always be in the original (input) coordinate system, regardless of whether the path effect uses the CTM or not.

Implements SkPathEffectBase.

Definition at line 57 of file SkDashPathEffect.cpp.

58 {
59 return SkDashPath::InternalFilter(dst, src, rec, cullRect, fIntervals, fCount,
60 fInitialDashLength, fInitialDashIndex, fIntervalLength,
61 fPhase);
62}
bool InternalFilter(SkPath *dst, const SkPath &src, SkStrokeRec *rec, const SkRect *cullRect, const SkScalar aIntervals[], int32_t count, SkScalar initialDashLength, int32_t initialDashIndex, SkScalar intervalLength, SkScalar startPhase, StrokeRecApplication=StrokeRecApplication::kAllow)
Definition: SkDashPath.cpp:309
dst
Definition: cp.py:12

The documentation for this class was generated from the following files: