Coverage Report

Created: 2018-09-25 14:53

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