tor-browser

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

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 */