Backed out changeset 496886cb30a5 (bug 1867152) for bc failures on browser_user_input...
[gecko.git] / layout / painting / TransformClipNode.h
bloba28dc3dbc04a864faf4322bb5fdff61f4b827f66
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/. */
7 #ifndef MOZILLA_PAINTING_TRANSFORMCLIPNODE_H
8 #define MOZILLA_PAINTING_TRANSFORMCLIPNODE_H
10 #include "mozilla/gfx/MatrixFwd.h"
11 #include "mozilla/gfx/Rect.h"
12 #include "mozilla/Maybe.h"
13 #include "nsISupports.h"
14 #include "nsRegionFwd.h"
16 namespace mozilla {
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.
24 class TransformClipNode {
25 NS_INLINE_DECL_REFCOUNTING(TransformClipNode);
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);
35 /**
36 * Returns the parent node, or nullptr if this is the root node.
38 const RefPtr<TransformClipNode>& Parent() const { return mParent; }
40 /**
41 * Transforms and clips |aRect| up to the root transform node.
42 * |aRect| is expected to be in app units.
44 nsRect TransformRect(const nsRect& aRect, const int32_t aA2D) const {
45 if (aRect.IsEmpty()) {
46 return aRect;
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));
60 /**
61 * Transforms and clips |aRect| up to the root transform node.
62 * |aRect| is expected to be in integer pixels.
64 gfx::IntRect TransformRect(const gfx::IntRect& aRect) const {
65 if (aRect.IsEmpty()) {
66 return aRect;
69 gfx::Rect result(IntRectToRect(aRect));
70 TransformRect(result);
71 return RoundedToInt(result);
74 /**
75 * Transforms and clips |aRegion| up to the root transform node.
76 * |aRegion| is expected be in integer pixels.
78 nsIntRegion TransformRegion(const nsIntRegion& aRegion) {
79 if (aRegion.IsEmpty()) {
80 return aRegion;
83 nsIntRegion result = aRegion;
85 const TransformClipNode* node = this;
86 while (node) {
87 const gfx::Matrix4x4Flagged& transform = node->Transform();
88 result = result.Transform(transform.GetMatrix());
90 if (node->Clip()) {
91 const gfx::IntRect clipRect = *node->Clip();
92 result.AndWith(clipRect);
95 node = node->Parent();
98 return result;
101 protected:
103 * Returns the post-transform clip, if there is one.
105 const Maybe<gfx::IntRect>& Clip() const { return mClip; }
108 * Returns the matrix that transforms the item bounds to the coordinate space
109 * of the flattened nsDisplayTransform.
111 const gfx::Matrix4x4Flagged& Transform() const { return mTransform; }
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();
119 if (node->Clip()) {
120 maxBounds = IntRectToRect(*node->Clip());
123 aRect = transform.TransformAndClipBounds(aRect, maxBounds);
124 node = node->Parent();
128 private:
129 MOZ_COUNTED_DTOR(TransformClipNode)
131 const RefPtr<TransformClipNode> mParent;
132 const gfx::Matrix4x4Flagged mTransform;
133 const Maybe<gfx::IntRect> mClip;
136 } // namespace mozilla
138 #endif /* MOZILLA_PAINTING_TRANSFORMCLIPNODE_H */