tor-browser

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

nsStyleTransformMatrix.h (6783B)


      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 /*
      8 * A class representing three matrices that can be used for style transforms.
      9 */
     10 
     11 #ifndef nsStyleTransformMatrix_h_
     12 #define nsStyleTransformMatrix_h_
     13 
     14 #include "Units.h"  // for CSSPoint
     15 #include "mozilla/ServoStyleConsts.h"
     16 #include "mozilla/gfx/Matrix.h"
     17 #include "nsSize.h"
     18 
     19 class nsIFrame;
     20 class nsPresContext;
     21 struct gfxQuaternion;
     22 struct nsRect;
     23 
     24 namespace mozilla {
     25 struct ResolvedMotionPathData;
     26 }  // namespace mozilla
     27 
     28 /**
     29 * A helper to generate gfxMatrixes from css transform functions.
     30 */
     31 namespace nsStyleTransformMatrix {
     32 // The operator passed to Servo backend.
     33 enum class MatrixTransformOperator : uint8_t { Interpolate, Accumulate };
     34 
     35 /**
     36 * This class provides on-demand access to the 'reference box' for CSS
     37 * transforms (needed to resolve percentage values in 'transform',
     38 * 'transform-origin', etc.):
     39 *
     40 *    http://dev.w3.org/csswg/css-transforms/#reference-box
     41 *
     42 * This class helps us to avoid calculating the reference box unless and
     43 * until it is actually needed. This is important for performance when
     44 * transforms are applied to SVG elements since the reference box for SVG is
     45 * much more expensive to calculate (than for elements with a CSS layout box
     46 * where we can use the nsIFrame's cached mRect), much more common (than on
     47 * HTML), and yet very rarely have percentage values that require the
     48 * reference box to be resolved. We also don't want to cause SVG frames to
     49 * cache lots of ObjectBoundingBoxProperty objects that aren't needed.
     50 *
     51 * If UNIFIED_CONTINUATIONS (experimental, and currently broke) is defined,
     52 * we consider the reference box for non-SVG frames to be the smallest
     53 * rectangle containing a frame and all of its continuations.  For example,
     54 * if there is a <span> element with several continuations split over
     55 * several lines, this function will return the rectangle containing all of
     56 * those continuations. (This behavior is not currently in a spec.)
     57 */
     58 class MOZ_STACK_CLASS TransformReferenceBox final {
     59 public:
     60  typedef nscoord (TransformReferenceBox::*DimensionGetter)();
     61 
     62  TransformReferenceBox() = default;
     63 
     64  explicit TransformReferenceBox(const nsIFrame* aFrame) : mFrame(aFrame) {
     65    MOZ_ASSERT(mFrame);
     66  }
     67 
     68  TransformReferenceBox(const nsIFrame* aFrame,
     69                        const nsRect& aFallbackDimensions) {
     70    mFrame = aFrame;
     71    if (!mFrame) {
     72      Init(aFallbackDimensions);
     73    }
     74  }
     75 
     76  void Init(const nsIFrame* aFrame) {
     77    MOZ_ASSERT(!mFrame && !mIsCached);
     78    mFrame = aFrame;
     79  }
     80 
     81  void Init(const nsRect& aDimensions) {
     82    MOZ_ASSERT(!mFrame && !mIsCached);
     83    mBox = aDimensions;
     84    mIsCached = true;
     85  }
     86 
     87  /**
     88   * The offset of the reference box from the nsIFrame's TopLeft(). This
     89   * is non-zero only in the case of SVG content. If we can successfully
     90   * implement UNIFIED_CONTINUATIONS at some point in the future then it
     91   * may also be non-zero for non-SVG content.
     92   */
     93  nscoord X() {
     94    EnsureDimensionsAreCached();
     95    return mBox.X();
     96  }
     97  nscoord Y() {
     98    EnsureDimensionsAreCached();
     99    return mBox.Y();
    100  }
    101 
    102  /**
    103   * The size of the reference box.
    104   */
    105  nscoord Width() {
    106    EnsureDimensionsAreCached();
    107    return mBox.Width();
    108  }
    109  nscoord Height() {
    110    EnsureDimensionsAreCached();
    111    return mBox.Height();
    112  }
    113 
    114  bool IsEmpty() { return !mFrame; }
    115 
    116 private:
    117  // We don't really need to prevent copying, but since none of our consumers
    118  // currently need to copy, preventing copying may allow us to catch some
    119  // cases where we use pass-by-value instead of pass-by-reference.
    120  TransformReferenceBox(const TransformReferenceBox&) = delete;
    121 
    122  void EnsureDimensionsAreCached();
    123 
    124  const nsIFrame* mFrame = nullptr;
    125  nsRect mBox;
    126  bool mIsCached = false;
    127 };
    128 
    129 float ProcessTranslatePart(
    130    const mozilla::LengthPercentage& aValue, TransformReferenceBox* aRefBox,
    131    TransformReferenceBox::DimensionGetter aDimensionGetter = nullptr);
    132 
    133 void ProcessInterpolateMatrix(mozilla::gfx::Matrix4x4& aMatrix,
    134                              const mozilla::StyleTransformOperation& aOp,
    135                              TransformReferenceBox& aBounds);
    136 
    137 void ProcessAccumulateMatrix(mozilla::gfx::Matrix4x4& aMatrix,
    138                             const mozilla::StyleTransformOperation& aOp,
    139                             TransformReferenceBox& aBounds);
    140 
    141 /**
    142 * Given a StyleTransform containing transform functions, returns a matrix
    143 * containing the value of those functions.
    144 *
    145 * @param aList the transform operation list.
    146 * @param aBounds The frame's bounding rectangle.
    147 * @param aAppUnitsPerMatrixUnit The number of app units per device pixel.
    148 */
    149 mozilla::gfx::Matrix4x4 ReadTransforms(const mozilla::StyleTransform& aList,
    150                                       TransformReferenceBox& aBounds,
    151                                       float aAppUnitsPerMatrixUnit);
    152 
    153 // Generate the gfx::Matrix for CSS Transform Module Level 2.
    154 // https://drafts.csswg.org/css-transforms-2/#ctm
    155 mozilla::gfx::Matrix4x4 ReadTransforms(
    156    const mozilla::StyleTranslate&, const mozilla::StyleRotate&,
    157    const mozilla::StyleScale&, const mozilla::ResolvedMotionPathData* aMotion,
    158    const mozilla::StyleTransform&, TransformReferenceBox& aRefBox,
    159    float aAppUnitsPerMatrixUnit);
    160 
    161 /**
    162 * Given the x and y values, compute the 2d position with respect to the given
    163 * a reference box size that these values describe, in CSS pixels.
    164 */
    165 mozilla::CSSPoint Convert2DPosition(const mozilla::LengthPercentage& aX,
    166                                    const mozilla::LengthPercentage& aY,
    167                                    const mozilla::CSSSize& aSize);
    168 
    169 /**
    170 * Given the x and y values, compute the 2d position with respect to the given
    171 * TransformReferenceBox that these values describe, in CSS pixels.
    172 */
    173 mozilla::CSSPoint Convert2DPosition(const mozilla::LengthPercentage& aX,
    174                                    const mozilla::LengthPercentage& aY,
    175                                    TransformReferenceBox& aRefBox);
    176 
    177 /**
    178 * Given the x and y values, compute the 2d position with respect to the given
    179 * TransformReferenceBox that these values describe, in device pixels.
    180 */
    181 mozilla::gfx::Point Convert2DPosition(const mozilla::LengthPercentage& aX,
    182                                      const mozilla::LengthPercentage& aY,
    183                                      TransformReferenceBox& aRefBox,
    184                                      int32_t aAppUnitsPerDevPixel);
    185 
    186 }  // namespace nsStyleTransformMatrix
    187 
    188 #endif