nsSVGPathGeometryElement.h 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this
  4. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. #ifndef __NS_SVGPATHGEOMETRYELEMENT_H__
  6. #define __NS_SVGPATHGEOMETRYELEMENT_H__
  7. #include "mozilla/gfx/2D.h"
  8. #include "SVGGraphicsElement.h"
  9. struct nsSVGMark {
  10. enum Type {
  11. eStart,
  12. eMid,
  13. eEnd,
  14. eTypeCount
  15. };
  16. float x, y, angle;
  17. Type type;
  18. nsSVGMark(float aX, float aY, float aAngle, Type aType) :
  19. x(aX), y(aY), angle(aAngle), type(aType) {}
  20. };
  21. typedef mozilla::dom::SVGGraphicsElement nsSVGPathGeometryElementBase;
  22. class nsSVGPathGeometryElement : public nsSVGPathGeometryElementBase
  23. {
  24. protected:
  25. typedef mozilla::gfx::CapStyle CapStyle;
  26. typedef mozilla::gfx::DrawTarget DrawTarget;
  27. typedef mozilla::gfx::FillRule FillRule;
  28. typedef mozilla::gfx::Float Float;
  29. typedef mozilla::gfx::Matrix Matrix;
  30. typedef mozilla::gfx::Path Path;
  31. typedef mozilla::gfx::Point Point;
  32. typedef mozilla::gfx::PathBuilder PathBuilder;
  33. typedef mozilla::gfx::Rect Rect;
  34. typedef mozilla::gfx::StrokeOptions StrokeOptions;
  35. public:
  36. explicit nsSVGPathGeometryElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
  37. virtual nsresult AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName,
  38. const nsAttrValue* aValue,
  39. const nsAttrValue* aOldValue,
  40. bool aNotify) override;
  41. /**
  42. * Causes this element to discard any Path object that GetOrBuildPath may
  43. * have cached.
  44. */
  45. virtual void ClearAnyCachedPath() override final {
  46. mCachedPath = nullptr;
  47. }
  48. virtual bool AttributeDefinesGeometry(const nsIAtom *aName);
  49. /**
  50. * Returns true if this element's geometry depends on the width or height of its
  51. * coordinate context (typically the viewport established by its nearest <svg>
  52. * ancestor). In other words, returns true if one of the attributes for which
  53. * AttributeDefinesGeometry returns true has a percentage value.
  54. *
  55. * This could be moved up to a more general class so it can be used for non-leaf
  56. * elements, but that would require care and for now there's no need.
  57. */
  58. bool GeometryDependsOnCoordCtx();
  59. virtual bool IsMarkable();
  60. virtual void GetMarkPoints(nsTArray<nsSVGMark> *aMarks);
  61. /**
  62. * A method that can be faster than using a Moz2D Path and calling GetBounds/
  63. * GetStrokedBounds on it. It also helps us avoid rounding error for simple
  64. * shapes and simple transforms where the Moz2D Path backends can fail to
  65. * produce the clean integer bounds that content authors expect in some cases.
  66. *
  67. * If |aToNonScalingStrokeSpace| is non-null then |aBounds|, which is computed
  68. * in bounds space, has the property that it's the smallest (axis-aligned)
  69. * rectangular bound containing the image of this shape as stroked in
  70. * non-scaling-stroke space. (When all transforms involved are rectilinear
  71. * the bounds of the image of |aBounds| in non-scaling-stroke space will be
  72. * tight, but if there are non-rectilinear transforms involved then that may
  73. * be impossible and this method will return false).
  74. *
  75. * If |aToNonScalingStrokeSpace| is non-null then |*aToNonScalingStrokeSpace|
  76. * must be non-singular.
  77. */
  78. virtual bool GetGeometryBounds(Rect* aBounds, const StrokeOptions& aStrokeOptions,
  79. const Matrix& aToBoundsSpace,
  80. const Matrix* aToNonScalingStrokeSpace = nullptr) {
  81. return false;
  82. }
  83. /**
  84. * For use with GetAsSimplePath.
  85. */
  86. class SimplePath
  87. {
  88. public:
  89. SimplePath()
  90. : mType(NONE)
  91. {}
  92. bool IsPath() const {
  93. return mType != NONE;
  94. }
  95. void SetRect(Float x, Float y, Float width, Float height) {
  96. mX = x; mY = y, mWidthOrX2 = width, mHeightOrY2 = height;
  97. mType = RECT;
  98. }
  99. Rect AsRect() const {
  100. MOZ_ASSERT(mType == RECT);
  101. return Rect(mX, mY, mWidthOrX2, mHeightOrY2);
  102. }
  103. bool IsRect() const {
  104. return mType == RECT;
  105. }
  106. void SetLine(Float x1, Float y1, Float x2, Float y2) {
  107. mX = x1, mY = y1, mWidthOrX2 = x2, mHeightOrY2 = y2;
  108. mType = LINE;
  109. }
  110. Point Point1() const {
  111. MOZ_ASSERT(mType == LINE);
  112. return Point(mX, mY);
  113. }
  114. Point Point2() const {
  115. MOZ_ASSERT(mType == LINE);
  116. return Point(mWidthOrX2, mHeightOrY2);
  117. }
  118. bool IsLine() const {
  119. return mType == LINE;
  120. }
  121. void Reset() {
  122. mType = NONE;
  123. }
  124. private:
  125. enum Type {
  126. NONE, RECT, LINE
  127. };
  128. Float mX, mY, mWidthOrX2, mHeightOrY2;
  129. Type mType;
  130. };
  131. /**
  132. * For some platforms there is significant overhead to creating and painting
  133. * a Moz2D Path object. For Rects and lines it is better to get the path data
  134. * using this method and then use the optimized DrawTarget methods for
  135. * filling/stroking rects and lines.
  136. */
  137. virtual void GetAsSimplePath(SimplePath* aSimplePath) {
  138. aSimplePath->Reset();
  139. }
  140. /**
  141. * Returns a Path that can be used to paint, hit-test or calculate bounds for
  142. * this element. May return nullptr if there is no [valid] path. The path
  143. * that is created may be cached and returned on subsequent calls.
  144. */
  145. virtual already_AddRefed<Path> GetOrBuildPath(const DrawTarget& aDrawTarget,
  146. FillRule fillRule);
  147. /**
  148. * The same as GetOrBuildPath, but bypasses the cache (neither returns any
  149. * previously cached Path, nor caches the Path that in does return).
  150. * this element. May return nullptr if there is no [valid] path.
  151. */
  152. virtual already_AddRefed<Path> BuildPath(PathBuilder* aBuilder) = 0;
  153. /**
  154. * Returns a Path that can be used to measure the length of this elements
  155. * path, or to find the position at a given distance along it.
  156. *
  157. * This is currently equivalent to calling GetOrBuildPath, but it may not be
  158. * in the future. The reason for this function to be separate from
  159. * GetOrBuildPath is because SVGPathData::BuildPath inserts small lines into
  160. * the path if zero length subpaths are encountered, in order to implement
  161. * the SVG specifications requirements that zero length subpaths should
  162. * render circles/squares if stroke-linecap is round/square, respectively.
  163. * In principle these inserted lines could interfere with path measurement,
  164. * so we keep callers that are looking to do measurement separate in case we
  165. * run into problems with the inserted lines negatively affecting measuring
  166. * for content.
  167. */
  168. virtual already_AddRefed<Path> GetOrBuildPathForMeasuring();
  169. /**
  170. * Returns the current computed value of the CSS property 'fill-rule' for
  171. * this element.
  172. */
  173. FillRule GetFillRule();
  174. protected:
  175. mutable RefPtr<Path> mCachedPath;
  176. };
  177. #endif