LCOV - code coverage report
Current view: top level - layout/style - nsStyleTransformMatrix.h (source / functions) Hit Total Coverage
Test: output.info Lines: 20 38 52.6 %
Date: 2017-07-14 16:53:18 Functions: 6 10 60.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 2; 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             : 
       6             : /*
       7             :  * A class representing three matrices that can be used for style transforms.
       8             :  */
       9             : 
      10             : #ifndef nsStyleTransformMatrix_h_
      11             : #define nsStyleTransformMatrix_h_
      12             : 
      13             : #include "gfxPoint.h"
      14             : #include "mozilla/gfx/Matrix.h"
      15             : #include "mozilla/EnumeratedArray.h"
      16             : #include "nsCSSValue.h"
      17             : #include "nsSize.h"
      18             : 
      19             : #include <limits>
      20             : 
      21             : class nsIFrame;
      22             : class nsStyleContext;
      23             : class nsPresContext;
      24             : struct gfxQuaternion;
      25             : struct nsRect;
      26             : namespace mozilla {
      27             : class RuleNodeCacheConditions;
      28             : } // namespace mozilla
      29             : 
      30             : /**
      31             :  * A helper to generate gfxMatrixes from css transform functions.
      32             :  */
      33             : namespace nsStyleTransformMatrix {
      34             :   // The operator passed to Servo backend.
      35             :   enum class MatrixTransformOperator: uint8_t {
      36             :     Interpolate,
      37             :     Accumulate
      38             :   };
      39             : 
      40             :   // Function for applying perspective() transform function. We treat
      41             :   // any value smaller than epsilon as perspective(infinity), which
      42             :   // follows CSSWG's resolution on perspective(0). See bug 1316236.
      43           0 :   inline void ApplyPerspectiveToMatrix(mozilla::gfx::Matrix4x4& aMatrix,
      44             :                                        float aDepth)
      45             :   {
      46           0 :     if (aDepth >= std::numeric_limits<float>::epsilon()) {
      47           0 :       aMatrix.Perspective(aDepth);
      48             :     }
      49           0 :   }
      50             : 
      51             :   /**
      52             :    * This class provides on-demand access to the 'reference box' for CSS
      53             :    * transforms (needed to resolve percentage values in 'transform',
      54             :    * 'transform-origin', etc.):
      55             :    *
      56             :    *    http://dev.w3.org/csswg/css-transforms/#reference-box
      57             :    *
      58             :    * This class helps us to avoid calculating the reference box unless and
      59             :    * until it is actually needed. This is important for performance when
      60             :    * transforms are applied to SVG elements since the reference box for SVG is
      61             :    * much more expensive to calculate (than for elements with a CSS layout box
      62             :    * where we can use the nsIFrame's cached mRect), much more common (than on
      63             :    * HTML), and yet very rarely have percentage values that require the
      64             :    * reference box to be resolved. We also don't want to cause SVG frames to
      65             :    * cache lots of ObjectBoundingBoxProperty objects that aren't needed.
      66             :    *
      67             :    * If UNIFIED_CONTINUATIONS (experimental, and currently broke) is defined,
      68             :    * we consider the reference box for non-SVG frames to be the smallest
      69             :    * rectangle containing a frame and all of its continuations.  For example,
      70             :    * if there is a <span> element with several continuations split over
      71             :    * several lines, this function will return the rectangle containing all of
      72             :    * those continuations. (This behavior is not currently in a spec.)
      73             :    */
      74             :   class MOZ_STACK_CLASS TransformReferenceBox final {
      75             :   public:
      76             :     typedef nscoord (TransformReferenceBox::*DimensionGetter)();
      77             : 
      78         388 :     explicit TransformReferenceBox()
      79         388 :       : mFrame(nullptr)
      80         388 :       , mIsCached(false)
      81         388 :     {}
      82             : 
      83           0 :     explicit TransformReferenceBox(const nsIFrame* aFrame)
      84           0 :       : mFrame(aFrame)
      85           0 :       , mIsCached(false)
      86             :     {
      87           0 :       MOZ_ASSERT(mFrame);
      88           0 :     }
      89             : 
      90           0 :     explicit TransformReferenceBox(const nsIFrame* aFrame,
      91             :                                    const nsSize& aFallbackDimensions)
      92           0 :     {
      93           0 :       mFrame = aFrame;
      94           0 :       mIsCached = false;
      95           0 :       if (!mFrame) {
      96           0 :         Init(aFallbackDimensions);
      97             :       }
      98           0 :     }
      99             : 
     100         388 :     void Init(const nsIFrame* aFrame) {
     101         388 :       MOZ_ASSERT(!mFrame && !mIsCached);
     102         388 :       mFrame = aFrame;
     103         388 :     }
     104             : 
     105             :     void Init(const nsSize& aDimensions);
     106             : 
     107             :     /**
     108             :      * The offset of the reference box from the nsIFrame's TopLeft(). This
     109             :      * is non-zero only in the case of SVG content. If we can successfully
     110             :      * implement UNIFIED_CONTINUATIONS at some point in the future then it
     111             :      * may also be non-zero for non-SVG content.
     112             :      */
     113         144 :     nscoord X() {
     114         144 :       EnsureDimensionsAreCached();
     115         144 :       return mX;
     116             :     }
     117         144 :     nscoord Y() {
     118         144 :       EnsureDimensionsAreCached();
     119         144 :       return mY;
     120             :     }
     121             : 
     122             :     /**
     123             :      * The size of the reference box.
     124             :      */
     125         152 :     nscoord Width() {
     126         152 :       EnsureDimensionsAreCached();
     127         152 :       return mWidth;
     128             :     }
     129         152 :     nscoord Height() {
     130         152 :       EnsureDimensionsAreCached();
     131         152 :       return mHeight;
     132             :     }
     133             : 
     134           0 :     bool IsEmpty() {
     135           0 :       return !mFrame;
     136             :     }
     137             : 
     138             :   private:
     139             :     // We don't really need to prevent copying, but since none of our consumers
     140             :     // currently need to copy, preventing copying may allow us to catch some
     141             :     // cases where we use pass-by-value instead of pass-by-reference.
     142             :     TransformReferenceBox(const TransformReferenceBox&) = delete;
     143             : 
     144             :     void EnsureDimensionsAreCached();
     145             : 
     146             :     const nsIFrame* mFrame;
     147             :     nscoord mX, mY, mWidth, mHeight;
     148             :     bool mIsCached;
     149             :   };
     150             : 
     151             :   /**
     152             :    * Return the transform function, as an nsCSSKeyword, for the given
     153             :    * nsCSSValue::Array from a transform list.
     154             :    */
     155             :   nsCSSKeyword TransformFunctionOf(const nsCSSValue::Array* aData);
     156             : 
     157             :   void SetIdentityMatrix(nsCSSValue::Array* aMatrix);
     158             : 
     159             :   float ProcessTranslatePart(const nsCSSValue& aValue,
     160             :                              nsStyleContext* aContext,
     161             :                              nsPresContext* aPresContext,
     162             :                              mozilla::RuleNodeCacheConditions& aConditions,
     163             :                              TransformReferenceBox* aRefBox,
     164             :                              TransformReferenceBox::DimensionGetter aDimensionGetter = nullptr);
     165             : 
     166             :   void
     167             :   ProcessInterpolateMatrix(mozilla::gfx::Matrix4x4& aMatrix,
     168             :                            const nsCSSValue::Array* aData,
     169             :                            nsStyleContext* aContext,
     170             :                            nsPresContext* aPresContext,
     171             :                            mozilla::RuleNodeCacheConditions& aConditions,
     172             :                            TransformReferenceBox& aBounds,
     173             :                            bool* aContains3dTransform);
     174             : 
     175             :   void
     176             :   ProcessAccumulateMatrix(mozilla::gfx::Matrix4x4& aMatrix,
     177             :                           const nsCSSValue::Array* aData,
     178             :                           nsStyleContext* aContext,
     179             :                           nsPresContext* aPresContext,
     180             :                           mozilla::RuleNodeCacheConditions& aConditions,
     181             :                           TransformReferenceBox& aBounds,
     182             :                           bool* aContains3dTransform);
     183             : 
     184             :   /**
     185             :    * Given an nsCSSValueList containing -moz-transform functions,
     186             :    * returns a matrix containing the value of those functions.
     187             :    *
     188             :    * @param aData The nsCSSValueList containing the transform functions
     189             :    * @param aContext The style context, used for unit conversion.
     190             :    * @param aPresContext The presentation context, used for unit conversion.
     191             :    * @param aConditions Set to uncachable (by calling SetUncacheable()) if the
     192             :    *   result cannot be cached in the rule tree, otherwise untouched.
     193             :    * @param aBounds The frame's bounding rectangle.
     194             :    * @param aAppUnitsPerMatrixUnit The number of app units per device pixel.
     195             :    * @param aContains3dTransform [out] Set to true if aList contains at least
     196             :    *   one 3d transform function (as defined in the CSS transforms
     197             :    *   specification), false otherwise.
     198             :    *
     199             :    * aContext and aPresContext may be null if all of the (non-percent)
     200             :    * length values in aData are already known to have been converted to
     201             :    * eCSSUnit_Pixel (as they are in an StyleAnimationValue)
     202             :    */
     203             :   mozilla::gfx::Matrix4x4 ReadTransforms(const nsCSSValueList* aList,
     204             :                                          nsStyleContext* aContext,
     205             :                                          nsPresContext* aPresContext,
     206             :                                          mozilla::RuleNodeCacheConditions& aConditions,
     207             :                                          TransformReferenceBox& aBounds,
     208             :                                          float aAppUnitsPerMatrixUnit,
     209             :                                          bool* aContains3dTransform);
     210             : 
     211             :   /**
     212             :    * Given two nsStyleCoord values, compute the 2d position with respect to the
     213             :    * given TransformReferenceBox that these values describe, in device pixels.
     214             :    */
     215             :   mozilla::gfx::Point Convert2DPosition(nsStyleCoord const (&aValue)[2],
     216             :                                         TransformReferenceBox& aRefBox,
     217             :                                         int32_t aAppUnitsPerDevPixel);
     218             : 
     219             :   // Shear type for decomposition.
     220             :   enum class ShearType {
     221             :     XYSHEAR,
     222             :     XZSHEAR,
     223             :     YZSHEAR,
     224             :     Count
     225             :   };
     226             :   using ShearArray =
     227             :     mozilla::EnumeratedArray<ShearType, ShearType::Count, float>;
     228             : 
     229             :   /*
     230             :    * Implements the 2d transform matrix decomposition algorithm.
     231             :    */
     232             :   bool Decompose2DMatrix(const mozilla::gfx::Matrix& aMatrix,
     233             :                          mozilla::gfx::Point3D& aScale,
     234             :                          ShearArray& aShear,
     235             :                          gfxQuaternion& aRotate,
     236             :                          mozilla::gfx::Point3D& aTranslate);
     237             :   /*
     238             :    * Implements the 3d transform matrix decomposition algorithm.
     239             :    */
     240             :   bool Decompose3DMatrix(const mozilla::gfx::Matrix4x4& aMatrix,
     241             :                          mozilla::gfx::Point3D& aScale,
     242             :                          ShearArray& aShear,
     243             :                          gfxQuaternion& aRotate,
     244             :                          mozilla::gfx::Point3D& aTranslate,
     245             :                          mozilla::gfx::Point4D& aPerspective);
     246             : 
     247             :   mozilla::gfx::Matrix CSSValueArrayTo2DMatrix(nsCSSValue::Array* aArray);
     248             :   mozilla::gfx::Matrix4x4 CSSValueArrayTo3DMatrix(nsCSSValue::Array* aArray);
     249             : 
     250             :   gfxSize GetScaleValue(const nsCSSValueSharedList* aList,
     251             :                         const nsIFrame* aForFrame);
     252             : } // namespace nsStyleTransformMatrix
     253             : 
     254             : #endif

Generated by: LCOV version 1.13