tor-browser

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

PathRecording.h (7854B)


      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 MOZILLA_GFX_PATHRECORDING_H_
      8 #define MOZILLA_GFX_PATHRECORDING_H_
      9 
     10 #include "2D.h"
     11 #include <vector>
     12 #include <ostream>
     13 
     14 #include "PathHelpers.h"
     15 #include "RecordingTypes.h"
     16 
     17 namespace mozilla {
     18 namespace gfx {
     19 
     20 struct Circle {
     21  Point origin;
     22  float radius;
     23  bool closed = false;
     24 };
     25 
     26 struct Line {
     27  Point origin;
     28  Point destination;
     29 };
     30 
     31 class PathOps {
     32 public:
     33  PathOps() = default;
     34 
     35  template <class S>
     36  explicit PathOps(S& aStream);
     37 
     38  PathOps(const PathOps& aOther) = default;
     39  PathOps& operator=(const PathOps&) = delete;  // assign using std::move()!
     40 
     41  PathOps(PathOps&& aOther) = default;
     42  PathOps& operator=(PathOps&& aOther) = default;
     43 
     44  template <class S>
     45  void Record(S& aStream) const;
     46 
     47  bool StreamToSink(PathSink& aPathSink) const;
     48 
     49  bool CheckedStreamToSink(PathSink& aPathSink) const;
     50 
     51  PathOps TransformedCopy(const Matrix& aTransform) const;
     52 
     53  void TransformInPlace(const Matrix& aTransform);
     54 
     55  size_t NumberOfOps() const;
     56 
     57 private:
     58  enum class OpType : uint32_t {
     59    OP_MOVETO = 0,
     60    OP_LINETO,
     61    OP_BEZIERTO,
     62    OP_QUADRATICBEZIERTO,
     63    OP_ARC_CW,
     64    OP_ARC_CCW,
     65    OP_CLOSE,
     66    OP_INVALID
     67  };
     68 
     69  template <typename T>
     70  void AppendPathOp(const T& aOpData) {
     71    mPathData.insert(mPathData.end(), (const uint8_t*)(&aOpData),
     72                     (const uint8_t*)(&aOpData + 1));
     73  }
     74 
     75  template <typename T>
     76  void AppendPathOp(const OpType& aOpType, const T& aOpParams) {
     77    AppendPathOp(aOpType);
     78    AppendPathOp(aOpParams);
     79  }
     80 
     81  struct TwoPoints {
     82    Point p1;
     83    Point p2;
     84  };
     85 
     86  struct ThreePoints {
     87    Point p1;
     88    Point p2;
     89    Point p3;
     90  };
     91 
     92  struct ArcParams {
     93    Matrix transform;
     94    float startAngle;
     95    float endAngle;
     96 
     97    Point GetOrigin() const { return transform.GetTranslation(); }
     98    Maybe<float> GetRadius() const;
     99 
    100    void ToSink(PathSink& aPathSink, bool aAntiClockwise) const;
    101  };
    102 
    103 public:
    104  void MoveTo(const Point& aPoint) { AppendPathOp(OpType::OP_MOVETO, aPoint); }
    105 
    106  void LineTo(const Point& aPoint) { AppendPathOp(OpType::OP_LINETO, aPoint); }
    107 
    108  void BezierTo(const Point& aCP1, const Point& aCP2, const Point& aCP3) {
    109    AppendPathOp(OpType::OP_BEZIERTO, ThreePoints{aCP1, aCP2, aCP3});
    110  }
    111 
    112  void QuadraticBezierTo(const Point& aCP1, const Point& aCP2) {
    113    AppendPathOp(OpType::OP_QUADRATICBEZIERTO, TwoPoints{aCP1, aCP2});
    114  }
    115 
    116  void Arc(const Matrix& aTransform, float aStartAngle, float aEndAngle,
    117           bool aAntiClockwise) {
    118    AppendPathOp(aAntiClockwise ? OpType::OP_ARC_CCW : OpType::OP_ARC_CW,
    119                 ArcParams{aTransform, aStartAngle, aEndAngle});
    120  }
    121 
    122  void Arc(const Point& aOrigin, float aRadius, float aStartAngle,
    123           float aEndAngle, bool aAntiClockwise) {
    124    Arc(Matrix(aRadius, 0.0f, 0.0f, aRadius, aOrigin.x, aOrigin.y), aStartAngle,
    125        aEndAngle, aAntiClockwise);
    126  }
    127 
    128  void Close() { AppendPathOp(OpType::OP_CLOSE); }
    129 
    130  Maybe<Circle> AsCircle() const;
    131  Maybe<Line> AsLine() const;
    132 
    133  bool IsActive() const { return !mPathData.empty(); }
    134 
    135  bool IsEmpty() const;
    136 
    137 private:
    138  std::vector<uint8_t> mPathData;
    139 };
    140 
    141 template <class S>
    142 PathOps::PathOps(S& aStream) {
    143  ReadVector(aStream, mPathData);
    144 }
    145 
    146 template <class S>
    147 inline void PathOps::Record(S& aStream) const {
    148  WriteVector(aStream, mPathData);
    149 }
    150 
    151 class PathRecording;
    152 class DrawEventRecorderPrivate;
    153 
    154 class PathBuilderRecording final : public PathBuilder {
    155 public:
    156  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PathBuilderRecording, override)
    157 
    158  PathBuilderRecording(BackendType aBackend, FillRule aFillRule)
    159      : mBackendType(aBackend), mFillRule(aFillRule) {}
    160 
    161  PathBuilderRecording(BackendType aBackend, PathOps&& aPathOps,
    162                       FillRule aFillRule)
    163      : mBackendType(aBackend),
    164        mFillRule(aFillRule),
    165        mPathOps(std::move(aPathOps)) {}
    166 
    167  /* Move the current point in the path, any figure currently being drawn will
    168   * be considered closed during fill operations, however when stroking the
    169   * closing line segment will not be drawn.
    170   */
    171  void MoveTo(const Point& aPoint) final;
    172 
    173  /* Add a linesegment to the current figure */
    174  void LineTo(const Point& aPoint) final;
    175 
    176  /* Add a cubic bezier curve to the current figure */
    177  void BezierTo(const Point& aCP1, const Point& aCP2, const Point& aCP3) final;
    178 
    179  /* Add a quadratic bezier curve to the current figure */
    180  void QuadraticBezierTo(const Point& aCP1, const Point& aCP2) final;
    181 
    182  /* Close the current figure, this will essentially generate a line segment
    183   * from the current point to the starting point for the current figure
    184   */
    185  void Close() final;
    186 
    187  /* Add an arc to the current figure */
    188  void Arc(const Point& aOrigin, float aRadius, float aStartAngle,
    189           float aEndAngle, bool aAntiClockwise) final;
    190 
    191  already_AddRefed<Path> Finish() final;
    192 
    193  BackendType GetBackendType() const final { return BackendType::RECORDING; }
    194 
    195  bool IsActive() const final { return mPathOps.IsActive(); }
    196 
    197 private:
    198  BackendType mBackendType;
    199  FillRule mFillRule;
    200  PathOps mPathOps;
    201 };
    202 
    203 class PathRecording final : public Path {
    204 public:
    205  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PathRecording, override)
    206 
    207  PathRecording(BackendType aBackend, PathOps&& aOps, FillRule aFillRule,
    208                const Point& aCurrentPoint, const Point& aBeginPoint);
    209 
    210  ~PathRecording();
    211 
    212  BackendType GetBackendType() const final { return BackendType::RECORDING; }
    213  already_AddRefed<PathBuilder> CopyToBuilder(FillRule aFillRule) const final;
    214  already_AddRefed<PathBuilder> TransformedCopyToBuilder(
    215      const Matrix& aTransform, FillRule aFillRule) const final;
    216  already_AddRefed<PathBuilder> MoveToBuilder(FillRule aFillRule) final;
    217  already_AddRefed<PathBuilder> TransformedMoveToBuilder(
    218      const Matrix& aTransform, FillRule aFillRule) final;
    219 
    220  bool ContainsPoint(const Point& aPoint,
    221                     const Matrix& aTransform) const final {
    222    EnsurePath();
    223    return mPath->ContainsPoint(aPoint, aTransform);
    224  }
    225  bool StrokeContainsPoint(const StrokeOptions& aStrokeOptions,
    226                           const Point& aPoint,
    227                           const Matrix& aTransform) const final {
    228    EnsurePath();
    229    return mPath->StrokeContainsPoint(aStrokeOptions, aPoint, aTransform);
    230  }
    231 
    232  Rect GetBounds(const Matrix& aTransform = Matrix()) const final {
    233    EnsurePath();
    234    return mPath->GetBounds(aTransform);
    235  }
    236 
    237  Rect GetStrokedBounds(const StrokeOptions& aStrokeOptions,
    238                        const Matrix& aTransform = Matrix()) const final {
    239    EnsurePath();
    240    return mPath->GetStrokedBounds(aStrokeOptions, aTransform);
    241  }
    242 
    243  Maybe<Rect> AsRect() const final {
    244    EnsurePath();
    245    return mPath->AsRect();
    246  }
    247 
    248  Maybe<Circle> AsCircle() const { return mPathOps.AsCircle(); }
    249  Maybe<Line> AsLine() const { return mPathOps.AsLine(); }
    250 
    251  void StreamToSink(PathSink* aSink) const final {
    252    mPathOps.StreamToSink(*aSink);
    253  }
    254 
    255  FillRule GetFillRule() const final { return mFillRule; }
    256 
    257  bool IsEmpty() const final { return mPathOps.IsEmpty(); }
    258 
    259 private:
    260  friend class DrawTargetWrapAndRecord;
    261  friend class DrawTargetRecording;
    262  friend class RecordedPathCreation;
    263 
    264  void EnsurePath() const;
    265 
    266  BackendType mBackendType;
    267  mutable RefPtr<Path> mPath;
    268  PathOps mPathOps;
    269  FillRule mFillRule;
    270  Point mCurrentPoint;
    271  Point mBeginPoint;
    272 
    273  // Event recorders that have this path in their event stream.
    274  std::vector<RefPtr<DrawEventRecorderPrivate>> mStoredRecorders;
    275 };
    276 
    277 }  // namespace gfx
    278 }  // namespace mozilla
    279 
    280 #endif /* MOZILLA_GFX_PATHRECORDING_H_ */