TransformClipNode.h (4143B)
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_PAINTING_TRANSFORMCLIPNODE_H 8 #define MOZILLA_PAINTING_TRANSFORMCLIPNODE_H 9 10 #include "mozilla/Maybe.h" 11 #include "mozilla/gfx/MatrixFwd.h" 12 #include "mozilla/gfx/Rect.h" 13 #include "nsISupports.h" 14 #include "nsRegionFwd.h" 15 16 namespace mozilla { 17 18 /** 19 * TransformClipNode stores a transformation matrix and a post-transform 20 * clip rect. 21 * They can be used to transform and clip a display item inside a flattened 22 * nsDisplayTransform to the coordinate space of that nsDisplayTransform. 23 */ 24 class TransformClipNode { 25 NS_INLINE_DECL_REFCOUNTING(TransformClipNode); 26 27 public: 28 TransformClipNode(const RefPtr<TransformClipNode>& aParent, 29 const gfx::Matrix4x4Flagged& aTransform, 30 const Maybe<gfx::IntRect>& aClip) 31 : mParent(aParent), mTransform(aTransform), mClip(aClip) { 32 MOZ_COUNT_CTOR(TransformClipNode); 33 } 34 35 /** 36 * Returns the parent node, or nullptr if this is the root node. 37 */ 38 const RefPtr<TransformClipNode>& Parent() const { return mParent; } 39 40 /** 41 * Transforms and clips |aRect| up to the root transform node. 42 * |aRect| is expected to be in app units. 43 */ 44 nsRect TransformRect(const nsRect& aRect, const int32_t aA2D) const { 45 if (aRect.IsEmpty()) { 46 return aRect; 47 } 48 49 gfx::Rect result(NSAppUnitsToFloatPixels(aRect.x, aA2D), 50 NSAppUnitsToFloatPixels(aRect.y, aA2D), 51 NSAppUnitsToFloatPixels(aRect.width, aA2D), 52 NSAppUnitsToFloatPixels(aRect.height, aA2D)); 53 TransformRect(result); 54 return nsRect(NSFloatPixelsToAppUnits(result.x, aA2D), 55 NSFloatPixelsToAppUnits(result.y, aA2D), 56 NSFloatPixelsToAppUnits(result.width, aA2D), 57 NSFloatPixelsToAppUnits(result.height, aA2D)); 58 } 59 60 /** 61 * Transforms and clips |aRect| up to the root transform node. 62 * |aRect| is expected to be in integer pixels. 63 */ 64 gfx::IntRect TransformRect(const gfx::IntRect& aRect) const { 65 if (aRect.IsEmpty()) { 66 return aRect; 67 } 68 69 gfx::Rect result(IntRectToRect(aRect)); 70 TransformRect(result); 71 return RoundedToInt(result); 72 } 73 74 /** 75 * Transforms and clips |aRegion| up to the root transform node. 76 * |aRegion| is expected be in integer pixels. 77 */ 78 nsIntRegion TransformRegion(const nsIntRegion& aRegion) { 79 if (aRegion.IsEmpty()) { 80 return aRegion; 81 } 82 83 nsIntRegion result = aRegion; 84 85 const TransformClipNode* node = this; 86 while (node) { 87 const gfx::Matrix4x4Flagged& transform = node->Transform(); 88 result = result.Transform(transform.GetMatrix()); 89 90 if (node->Clip()) { 91 const gfx::IntRect clipRect = *node->Clip(); 92 result.AndWith(clipRect); 93 } 94 95 node = node->Parent(); 96 } 97 98 return result; 99 } 100 101 protected: 102 /** 103 * Returns the post-transform clip, if there is one. 104 */ 105 const Maybe<gfx::IntRect>& Clip() const { return mClip; } 106 107 /** 108 * Returns the matrix that transforms the item bounds to the coordinate space 109 * of the flattened nsDisplayTransform. 110 */ 111 const gfx::Matrix4x4Flagged& Transform() const { return mTransform; } 112 113 void TransformRect(gfx::Rect& aRect) const { 114 const TransformClipNode* node = this; 115 while (node) { 116 const gfx::Matrix4x4Flagged& transform = node->Transform(); 117 gfx::Rect maxBounds = gfx::Rect::MaxIntRect(); 118 119 if (node->Clip()) { 120 maxBounds = IntRectToRect(*node->Clip()); 121 } 122 123 aRect = transform.TransformAndClipBounds(aRect, maxBounds); 124 node = node->Parent(); 125 } 126 } 127 128 private: 129 MOZ_COUNTED_DTOR(TransformClipNode) 130 131 const RefPtr<TransformClipNode> mParent; 132 const gfx::Matrix4x4Flagged mTransform; 133 const Maybe<gfx::IntRect> mClip; 134 }; 135 136 } // namespace mozilla 137 138 #endif /* MOZILLA_PAINTING_TRANSFORMCLIPNODE_H */