SkStrokeRec.h 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. /*
  2. * Copyright 2012 Google Inc.
  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 SkStrokeRec_DEFINED
  8. #define SkStrokeRec_DEFINED
  9. #include "include/core/SkPaint.h"
  10. #include "include/private/SkMacros.h"
  11. class SkPath;
  12. SK_BEGIN_REQUIRE_DENSE
  13. class SK_API SkStrokeRec {
  14. public:
  15. enum InitStyle {
  16. kHairline_InitStyle,
  17. kFill_InitStyle
  18. };
  19. SkStrokeRec(InitStyle style);
  20. SkStrokeRec(const SkPaint&, SkPaint::Style, SkScalar resScale = 1);
  21. explicit SkStrokeRec(const SkPaint&, SkScalar resScale = 1);
  22. enum Style {
  23. kHairline_Style,
  24. kFill_Style,
  25. kStroke_Style,
  26. kStrokeAndFill_Style
  27. };
  28. static constexpr int kStyleCount = kStrokeAndFill_Style + 1;
  29. Style getStyle() const;
  30. SkScalar getWidth() const { return fWidth; }
  31. SkScalar getMiter() const { return fMiterLimit; }
  32. SkPaint::Cap getCap() const { return (SkPaint::Cap)fCap; }
  33. SkPaint::Join getJoin() const { return (SkPaint::Join)fJoin; }
  34. bool isHairlineStyle() const {
  35. return kHairline_Style == this->getStyle();
  36. }
  37. bool isFillStyle() const {
  38. return kFill_Style == this->getStyle();
  39. }
  40. void setFillStyle();
  41. void setHairlineStyle();
  42. /**
  43. * Specify the strokewidth, and optionally if you want stroke + fill.
  44. * Note, if width==0, then this request is taken to mean:
  45. * strokeAndFill==true -> new style will be Fill
  46. * strokeAndFill==false -> new style will be Hairline
  47. */
  48. void setStrokeStyle(SkScalar width, bool strokeAndFill = false);
  49. void setStrokeParams(SkPaint::Cap cap, SkPaint::Join join, SkScalar miterLimit) {
  50. fCap = cap;
  51. fJoin = join;
  52. fMiterLimit = miterLimit;
  53. }
  54. SkScalar getResScale() const {
  55. return fResScale;
  56. }
  57. void setResScale(SkScalar rs) {
  58. SkASSERT(rs > 0 && SkScalarIsFinite(rs));
  59. fResScale = rs;
  60. }
  61. /**
  62. * Returns true if this specifes any thick stroking, i.e. applyToPath()
  63. * will return true.
  64. */
  65. bool needToApply() const {
  66. Style style = this->getStyle();
  67. return (kStroke_Style == style) || (kStrokeAndFill_Style == style);
  68. }
  69. /**
  70. * Apply these stroke parameters to the src path, returning the result
  71. * in dst.
  72. *
  73. * If there was no change (i.e. style == hairline or fill) this returns
  74. * false and dst is unchanged. Otherwise returns true and the result is
  75. * stored in dst.
  76. *
  77. * src and dst may be the same path.
  78. */
  79. bool applyToPath(SkPath* dst, const SkPath& src) const;
  80. /**
  81. * Apply these stroke parameters to a paint.
  82. */
  83. void applyToPaint(SkPaint* paint) const;
  84. /**
  85. * Gives a conservative value for the outset that should applied to a
  86. * geometries bounds to account for any inflation due to applying this
  87. * strokeRec to the geometry.
  88. */
  89. SkScalar getInflationRadius() const;
  90. /**
  91. * Equivalent to:
  92. * SkStrokeRec rec(paint, style);
  93. * rec.getInflationRadius();
  94. * This does not account for other effects on the paint (i.e. path
  95. * effect).
  96. */
  97. static SkScalar GetInflationRadius(const SkPaint&, SkPaint::Style);
  98. static SkScalar GetInflationRadius(SkPaint::Join, SkScalar miterLimit, SkPaint::Cap,
  99. SkScalar strokeWidth);
  100. /**
  101. * Compare if two SkStrokeRecs have an equal effect on a path.
  102. * Equal SkStrokeRecs produce equal paths. Equality of produced
  103. * paths does not take the ResScale parameter into account.
  104. */
  105. bool hasEqualEffect(const SkStrokeRec& other) const {
  106. if (!this->needToApply()) {
  107. return this->getStyle() == other.getStyle();
  108. }
  109. return fWidth == other.fWidth &&
  110. fMiterLimit == other.fMiterLimit &&
  111. fCap == other.fCap &&
  112. fJoin == other.fJoin &&
  113. fStrokeAndFill == other.fStrokeAndFill;
  114. }
  115. private:
  116. void init(const SkPaint&, SkPaint::Style, SkScalar resScale);
  117. SkScalar fResScale;
  118. SkScalar fWidth;
  119. SkScalar fMiterLimit;
  120. // The following three members are packed together into a single u32.
  121. // This is to avoid unnecessary padding and ensure binary equality for
  122. // hashing (because the padded areas might contain garbage values).
  123. //
  124. // fCap and fJoin are larger than needed to avoid having to initialize
  125. // any pad values
  126. uint32_t fCap : 16; // SkPaint::Cap
  127. uint32_t fJoin : 15; // SkPaint::Join
  128. uint32_t fStrokeAndFill : 1; // bool
  129. };
  130. SK_END_REQUIRE_DENSE
  131. #endif