tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

SVGPathData.h (6912B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #ifndef DOM_SVG_SVGPATHDATA_H_
      8 #define DOM_SVG_SVGPATHDATA_H_
      9 
     10 #include <string.h>
     11 
     12 #include "mozilla/MemoryReporting.h"
     13 #include "mozilla/ServoStyleConsts.h"
     14 #include "mozilla/dom/SVGElement.h"
     15 #include "mozilla/gfx/2D.h"
     16 #include "mozilla/gfx/Types.h"
     17 #include "nsCOMPtr.h"
     18 #include "nsDebug.h"
     19 #include "nsIContent.h"
     20 #include "nsINode.h"
     21 #include "nsIWeakReferenceUtils.h"
     22 #include "nsTArray.h"
     23 
     24 namespace mozilla {
     25 
     26 struct SVGMark;
     27 enum class StyleStrokeLinecap : uint8_t;
     28 namespace dom {
     29 class SVGPathElement;
     30 class SVGPathSegment;
     31 }  // namespace dom
     32 
     33 class SVGPathData {
     34  friend class SVGAnimatedPathSegList;
     35  friend class SVGPathDataAndInfo;
     36  friend class SVGPathSegListSMILType;
     37 
     38  using DrawTarget = gfx::DrawTarget;
     39  using Path = gfx::Path;
     40  using PathBuilder = gfx::PathBuilder;
     41  using FillRule = gfx::FillRule;
     42  using Float = gfx::Float;
     43  using CapStyle = gfx::CapStyle;
     44 
     45 public:
     46  SVGPathData() = default;
     47  ~SVGPathData() = default;
     48 
     49  explicit SVGPathData(const nsACString& aString) {
     50    SetValueFromString(aString);
     51  }
     52 
     53  SVGPathData& operator=(const SVGPathData&) = default;
     54  SVGPathData(const SVGPathData&) = default;
     55  SVGPathData& operator=(SVGPathData&&) = default;
     56  SVGPathData(SVGPathData&&) = default;
     57 
     58  // Used by SMILCompositor to check if the cached base val is out of date
     59  bool operator==(const SVGPathData& rhs) const { return mData == rhs.mData; }
     60 
     61  // Only methods that don't make/permit modification to this list are public.
     62  // Only our friend classes can access methods that may change us.
     63 
     64  /// This may return an incomplete string on OOM, but that's acceptable.
     65  void GetValueAsString(nsACString& aValue) const;
     66 
     67  Span<const StylePathCommand> AsSpan() const { return mData._0.AsSpan(); }
     68  bool IsEmpty() const { return AsSpan().IsEmpty(); }
     69 
     70  const StyleSVGPathData& RawData() const { return mData; }
     71 
     72  static already_AddRefed<dom::SVGPathSegment> GetPathSegmentAtLength(
     73      dom::SVGPathElement* aPathElement, Span<const StylePathCommand> aPath,
     74      float aDistance);
     75 
     76  void GetMarkerPositioningData(float aZoom, nsTArray<SVGMark>* aMarks) const;
     77 
     78  static void GetMarkerPositioningData(Span<const StylePathCommand> aPath,
     79                                       float aZoom, nsTArray<SVGMark>* aMarks);
     80  /**
     81   * Returns true, except on OOM, in which case returns false.
     82   */
     83  bool GetDistancesFromOriginToEndsOfVisibleSegments(
     84      FallibleTArray<double>* aOutput) const;
     85 
     86  /**
     87   * This is identical to the above one but accepts StylePathCommand.
     88   */
     89  static bool GetDistancesFromOriginToEndsOfVisibleSegments(
     90      Span<const StylePathCommand> aPath, FallibleTArray<double>* aOutput);
     91 
     92  /**
     93   * This returns a path without the extra little line segments that
     94   * ApproximateZeroLengthSubpathSquareCaps can insert if we have square-caps.
     95   * See the comment for that function for more info on that.
     96   */
     97  already_AddRefed<Path> BuildPathForMeasuring(float aZoom) const;
     98 
     99  already_AddRefed<Path> BuildPath(PathBuilder* aBuilder,
    100                                   StyleStrokeLinecap aStrokeLineCap,
    101                                   Float aStrokeWidth, float aZoom) const;
    102 
    103  static already_AddRefed<Path> BuildPathForMeasuring(
    104      Span<const StylePathCommand> aPath, float aZoom);
    105 
    106  /**
    107   * This function tries to build the path from an array of GenericShapeCommand,
    108   * which is generated by cbindgen from Rust (see ServoStyleConsts.h).
    109   * Basically, this is a variant of the above BuildPath() functions.
    110   * Note: |StylePathCommand| doesn't accept percentage values, so its |aBasis|
    111   * is empty by default.
    112   */
    113  static already_AddRefed<Path> BuildPath(Span<const StylePathCommand> aPath,
    114                                          PathBuilder* aBuilder,
    115                                          StyleStrokeLinecap aStrokeLineCap,
    116                                          Float aStrokeWidth,
    117                                          const CSSSize& aBasis = {},
    118                                          const gfx::Point& aOffset = {},
    119                                          float aZoomFactor = 1.0);
    120  static already_AddRefed<Path> BuildPath(
    121      Span<const StyleShapeCommand> aShape, PathBuilder* aBuilder,
    122      StyleStrokeLinecap aStrokeLineCap, Float aStrokeWidth,
    123      const CSSSize& aBasis, const gfx::Point& aOffset = gfx::Point(),
    124      float aZoomFactor = 1.0);
    125 
    126  // memory reporting methods
    127  size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
    128  size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
    129 
    130 protected:
    131  nsresult SetValueFromString(const nsACString& aValue);
    132 
    133  void Clear() { mData = {}; }
    134 
    135  StyleSVGPathData& RawData() { return mData; }
    136 
    137  mozilla::StyleSVGPathData mData;
    138 };
    139 
    140 /**
    141 * This SVGPathData subclass is for SVGPathSegListSMILType which needs to
    142 * have write access to the lists it works with.
    143 *
    144 * Instances of this class do not have DOM wrappers that need to be kept in
    145 * sync, so we can safely expose any protected base class methods required by
    146 * the SMIL code.
    147 */
    148 class SVGPathDataAndInfo final : public SVGPathData {
    149 public:
    150  explicit SVGPathDataAndInfo(dom::SVGElement* aElement = nullptr)
    151      : mElement(do_GetWeakReference(static_cast<nsINode*>(aElement))) {}
    152 
    153  void SetElement(dom::SVGElement* aElement) {
    154    mElement = do_GetWeakReference(static_cast<nsINode*>(aElement));
    155  }
    156 
    157  dom::SVGElement* Element() const {
    158    nsCOMPtr<nsIContent> e = do_QueryReferent(mElement);
    159    return static_cast<dom::SVGElement*>(e.get());
    160  }
    161 
    162  // If you use this, you need to call SetElement manually.
    163  void CopyFrom(const SVGPathData& aOther) { mData = aOther.mData; }
    164  void CopyFrom(const SVGPathDataAndInfo& aOther) {
    165    CopyFrom(static_cast<const SVGPathData&>(aOther));
    166    mElement = aOther.mElement;
    167  }
    168 
    169  /**
    170   * Returns true if this object is an "identity" value, from the perspective
    171   * of SMIL. In other words, returns true until the initial value set up in
    172   * SVGPathSegListSMILType::InitValue() has been changed with a SetElement()
    173   * call.
    174   */
    175  bool IsIdentity() const {
    176    if (!mElement) {
    177      MOZ_ASSERT(IsEmpty(), "target element propagation failure");
    178      return true;
    179    }
    180    return false;
    181  }
    182 
    183 private:
    184  // We must keep a weak reference to our element because we may belong to a
    185  // cached baseVal SMILValue. See the comments starting at:
    186  // https://bugzilla.mozilla.org/show_bug.cgi?id=515116#c15
    187  // See also https://bugzilla.mozilla.org/show_bug.cgi?id=653497
    188  nsWeakPtr mElement;
    189 };
    190 
    191 }  // namespace mozilla
    192 
    193 #endif  // DOM_SVG_SVGPATHDATA_H_