From 2aa4a82499d4becd2284cdb482213d541b8804dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 28 Apr 2024 16:29:10 +0200 Subject: Adding upstream version 86.0.1. Signed-off-by: Daniel Baumann --- layout/painting/TransformClipNode.h | 138 ++++++++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 layout/painting/TransformClipNode.h (limited to 'layout/painting/TransformClipNode.h') diff --git a/layout/painting/TransformClipNode.h b/layout/painting/TransformClipNode.h new file mode 100644 index 0000000000..a28dc3dbc0 --- /dev/null +++ b/layout/painting/TransformClipNode.h @@ -0,0 +1,138 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef MOZILLA_PAINTING_TRANSFORMCLIPNODE_H +#define MOZILLA_PAINTING_TRANSFORMCLIPNODE_H + +#include "mozilla/gfx/MatrixFwd.h" +#include "mozilla/gfx/Rect.h" +#include "mozilla/Maybe.h" +#include "nsISupports.h" +#include "nsRegionFwd.h" + +namespace mozilla { + +/** + * TransformClipNode stores a transformation matrix and a post-transform + * clip rect. + * They can be used to transform and clip a display item inside a flattened + * nsDisplayTransform to the coordinate space of that nsDisplayTransform. + */ +class TransformClipNode { + NS_INLINE_DECL_REFCOUNTING(TransformClipNode); + + public: + TransformClipNode(const RefPtr& aParent, + const gfx::Matrix4x4Flagged& aTransform, + const Maybe& aClip) + : mParent(aParent), mTransform(aTransform), mClip(aClip) { + MOZ_COUNT_CTOR(TransformClipNode); + } + + /** + * Returns the parent node, or nullptr if this is the root node. + */ + const RefPtr& Parent() const { return mParent; } + + /** + * Transforms and clips |aRect| up to the root transform node. + * |aRect| is expected to be in app units. + */ + nsRect TransformRect(const nsRect& aRect, const int32_t aA2D) const { + if (aRect.IsEmpty()) { + return aRect; + } + + gfx::Rect result(NSAppUnitsToFloatPixels(aRect.x, aA2D), + NSAppUnitsToFloatPixels(aRect.y, aA2D), + NSAppUnitsToFloatPixels(aRect.width, aA2D), + NSAppUnitsToFloatPixels(aRect.height, aA2D)); + TransformRect(result); + return nsRect(NSFloatPixelsToAppUnits(result.x, aA2D), + NSFloatPixelsToAppUnits(result.y, aA2D), + NSFloatPixelsToAppUnits(result.width, aA2D), + NSFloatPixelsToAppUnits(result.height, aA2D)); + } + + /** + * Transforms and clips |aRect| up to the root transform node. + * |aRect| is expected to be in integer pixels. + */ + gfx::IntRect TransformRect(const gfx::IntRect& aRect) const { + if (aRect.IsEmpty()) { + return aRect; + } + + gfx::Rect result(IntRectToRect(aRect)); + TransformRect(result); + return RoundedToInt(result); + } + + /** + * Transforms and clips |aRegion| up to the root transform node. + * |aRegion| is expected be in integer pixels. + */ + nsIntRegion TransformRegion(const nsIntRegion& aRegion) { + if (aRegion.IsEmpty()) { + return aRegion; + } + + nsIntRegion result = aRegion; + + const TransformClipNode* node = this; + while (node) { + const gfx::Matrix4x4Flagged& transform = node->Transform(); + result = result.Transform(transform.GetMatrix()); + + if (node->Clip()) { + const gfx::IntRect clipRect = *node->Clip(); + result.AndWith(clipRect); + } + + node = node->Parent(); + } + + return result; + } + + protected: + /** + * Returns the post-transform clip, if there is one. + */ + const Maybe& Clip() const { return mClip; } + + /** + * Returns the matrix that transforms the item bounds to the coordinate space + * of the flattened nsDisplayTransform. + */ + const gfx::Matrix4x4Flagged& Transform() const { return mTransform; } + + void TransformRect(gfx::Rect& aRect) const { + const TransformClipNode* node = this; + while (node) { + const gfx::Matrix4x4Flagged& transform = node->Transform(); + gfx::Rect maxBounds = gfx::Rect::MaxIntRect(); + + if (node->Clip()) { + maxBounds = IntRectToRect(*node->Clip()); + } + + aRect = transform.TransformAndClipBounds(aRect, maxBounds); + node = node->Parent(); + } + } + + private: + MOZ_COUNTED_DTOR(TransformClipNode) + + const RefPtr mParent; + const gfx::Matrix4x4Flagged mTransform; + const Maybe mClip; +}; + +} // namespace mozilla + +#endif /* MOZILLA_PAINTING_TRANSFORMCLIPNODE_H */ -- cgit v1.2.3