SkPathEffect.h 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. /*
  2. * Copyright 2006 The Android Open Source Project
  3. *
  4. * Use of this source code is governed by a BSD-style license that can be
  5. * found in the LICENSE file.
  6. */
  7. #ifndef SkPathEffect_DEFINED
  8. #define SkPathEffect_DEFINED
  9. #include "SkFlattenable.h"
  10. #include "SkPath.h"
  11. #include "SkPoint.h"
  12. #include "SkRect.h"
  13. class SkPath;
  14. class SkStrokeRec;
  15. /** \class SkPathEffect
  16. SkPathEffect is the base class for objects in the SkPaint that affect
  17. the geometry of a drawing primitive before it is transformed by the
  18. canvas' matrix and drawn.
  19. Dashing is implemented as a subclass of SkPathEffect.
  20. */
  21. class SK_API SkPathEffect : public SkFlattenable {
  22. public:
  23. /**
  24. * Returns a patheffect that apples each effect (first and second) to the original path,
  25. * and returns a path with the sum of these.
  26. *
  27. * result = first(path) + second(path)
  28. *
  29. */
  30. static sk_sp<SkPathEffect> MakeSum(sk_sp<SkPathEffect> first, sk_sp<SkPathEffect> second);
  31. /**
  32. * Returns a patheffect that applies the inner effect to the path, and then applies the
  33. * outer effect to the result of the inner's.
  34. *
  35. * result = outer(inner(path))
  36. */
  37. static sk_sp<SkPathEffect> MakeCompose(sk_sp<SkPathEffect> outer, sk_sp<SkPathEffect> inner);
  38. /**
  39. * Given a src path (input) and a stroke-rec (input and output), apply
  40. * this effect to the src path, returning the new path in dst, and return
  41. * true. If this effect cannot be applied, return false and ignore dst
  42. * and stroke-rec.
  43. *
  44. * The stroke-rec specifies the initial request for stroking (if any).
  45. * The effect can treat this as input only, or it can choose to change
  46. * the rec as well. For example, the effect can decide to change the
  47. * stroke's width or join, or the effect can change the rec from stroke
  48. * to fill (or fill to stroke) in addition to returning a new (dst) path.
  49. *
  50. * If this method returns true, the caller will apply (as needed) the
  51. * resulting stroke-rec to dst and then draw.
  52. */
  53. bool filterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, const SkRect* cullR) const;
  54. /**
  55. * Compute a conservative bounds for its effect, given the src bounds.
  56. * The baseline implementation just assigns src to dst.
  57. */
  58. void computeFastBounds(SkRect* dst, const SkRect& src) const;
  59. /** \class PointData
  60. PointData aggregates all the information needed to draw the point
  61. primitives returned by an 'asPoints' call.
  62. */
  63. class PointData {
  64. public:
  65. PointData()
  66. : fFlags(0)
  67. , fPoints(nullptr)
  68. , fNumPoints(0) {
  69. fSize.set(SK_Scalar1, SK_Scalar1);
  70. // 'asPoints' needs to initialize/fill-in 'fClipRect' if it sets
  71. // the kUseClip flag
  72. }
  73. ~PointData() {
  74. delete [] fPoints;
  75. }
  76. // TODO: consider using passed-in flags to limit the work asPoints does.
  77. // For example, a kNoPath flag could indicate don't bother generating
  78. // stamped solutions.
  79. // Currently none of these flags are supported.
  80. enum PointFlags {
  81. kCircles_PointFlag = 0x01, // draw points as circles (instead of rects)
  82. kUsePath_PointFlag = 0x02, // draw points as stamps of the returned path
  83. kUseClip_PointFlag = 0x04, // apply 'fClipRect' before drawing the points
  84. };
  85. uint32_t fFlags; // flags that impact the drawing of the points
  86. SkPoint* fPoints; // the center point of each generated point
  87. int fNumPoints; // number of points in fPoints
  88. SkVector fSize; // the size to draw the points
  89. SkRect fClipRect; // clip required to draw the points (if kUseClip is set)
  90. SkPath fPath; // 'stamp' to be used at each point (if kUsePath is set)
  91. SkPath fFirst; // If not empty, contains geometry for first point
  92. SkPath fLast; // If not empty, contains geometry for last point
  93. };
  94. /**
  95. * Does applying this path effect to 'src' yield a set of points? If so,
  96. * optionally return the points in 'results'.
  97. */
  98. bool asPoints(PointData* results, const SkPath& src,
  99. const SkStrokeRec&, const SkMatrix&,
  100. const SkRect* cullR) const;
  101. /**
  102. * If the PathEffect can be represented as a dash pattern, asADash will return kDash_DashType
  103. * and None otherwise. If a non NULL info is passed in, the various DashInfo will be filled
  104. * in if the PathEffect can be a dash pattern. If passed in info has an fCount equal or
  105. * greater to that of the effect, it will memcpy the values of the dash intervals into the
  106. * info. Thus the general approach will be call asADash once with default info to get DashType
  107. * and fCount. If effect can be represented as a dash pattern, allocate space for the intervals
  108. * in info, then call asADash again with the same info and the intervals will get copied in.
  109. */
  110. enum DashType {
  111. kNone_DashType, //!< ignores the info parameter
  112. kDash_DashType, //!< fills in all of the info parameter
  113. };
  114. struct DashInfo {
  115. DashInfo() : fIntervals(nullptr), fCount(0), fPhase(0) {}
  116. DashInfo(SkScalar* intervals, int32_t count, SkScalar phase)
  117. : fIntervals(intervals), fCount(count), fPhase(phase) {}
  118. SkScalar* fIntervals; //!< Length of on/off intervals for dashed lines
  119. // Even values represent ons, and odds offs
  120. int32_t fCount; //!< Number of intervals in the dash. Should be even number
  121. SkScalar fPhase; //!< Offset into the dashed interval pattern
  122. // mod the sum of all intervals
  123. };
  124. DashType asADash(DashInfo* info) const;
  125. static void RegisterFlattenables();
  126. static SkFlattenable::Type GetFlattenableType() {
  127. return kSkPathEffect_Type;
  128. }
  129. SkFlattenable::Type getFlattenableType() const override {
  130. return kSkPathEffect_Type;
  131. }
  132. static sk_sp<SkPathEffect> Deserialize(const void* data, size_t size,
  133. const SkDeserialProcs* procs = nullptr) {
  134. return sk_sp<SkPathEffect>(static_cast<SkPathEffect*>(
  135. SkFlattenable::Deserialize(
  136. kSkPathEffect_Type, data, size, procs).release()));
  137. }
  138. protected:
  139. SkPathEffect() {}
  140. virtual bool onFilterPath(SkPath*, const SkPath&, SkStrokeRec*, const SkRect*) const = 0;
  141. virtual SkRect onComputeFastBounds(const SkRect& src) const {
  142. return src;
  143. }
  144. virtual bool onAsPoints(PointData*, const SkPath&, const SkStrokeRec&, const SkMatrix&,
  145. const SkRect*) const {
  146. return false;
  147. }
  148. virtual DashType onAsADash(DashInfo*) const {
  149. return kNone_DashType;
  150. }
  151. private:
  152. // illegal
  153. SkPathEffect(const SkPathEffect&);
  154. SkPathEffect& operator=(const SkPathEffect&);
  155. typedef SkFlattenable INHERITED;
  156. };
  157. #endif