File: OverflowModel.h

package info (click to toggle)
chromium-browser 57.0.2987.98-1~deb8u1
  • links: PTS, VCS
  • area: main
  • in suites: jessie
  • size: 2,637,852 kB
  • ctags: 2,544,394
  • sloc: cpp: 12,815,961; ansic: 3,676,222; python: 1,147,112; asm: 526,608; java: 523,212; xml: 286,794; perl: 92,654; sh: 86,408; objc: 73,271; makefile: 27,698; cs: 18,487; yacc: 13,031; tcl: 12,957; pascal: 4,875; ml: 4,716; lex: 3,904; sql: 3,862; ruby: 1,982; lisp: 1,508; php: 1,368; exp: 404; awk: 325; csh: 117; jsp: 39; sed: 37
file content (189 lines) | stat: -rw-r--r-- 7,870 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
/*
 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights
 * reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 *
 */

#ifndef OverflowModel_h
#define OverflowModel_h

#include "platform/geometry/LayoutRect.h"

namespace blink {

inline void uniteLayoutOverflowRect(LayoutRect& layoutOverflow,
                                    const LayoutRect& rect) {
  LayoutUnit maxX = std::max(rect.maxX(), layoutOverflow.maxX());
  LayoutUnit maxY = std::max(rect.maxY(), layoutOverflow.maxY());
  LayoutUnit minX = std::min(rect.x(), layoutOverflow.x());
  LayoutUnit minY = std::min(rect.y(), layoutOverflow.y());
  // In case the width/height is larger than LayoutUnit can represent, fix the
  // right/bottom edge and shift the top/left ones.
  layoutOverflow.setWidth(maxX - minX);
  layoutOverflow.setHeight(maxY - minY);
  layoutOverflow.setX(maxX - layoutOverflow.width());
  layoutOverflow.setY(maxY - layoutOverflow.height());
}

// OverflowModel classes track content that spills out of an object.
// SimpleOverflowModel is used by InlineFlowBox, and BoxOverflowModel is
// used by LayoutBox.
//
// SimpleOverflowModel tracks 2 types of overflows: layout and visual
// overflows. BoxOverflowModel separates visual overflow into self visual
// overflow and contents visual overflow.
//
// All overflows are in the coordinate space of the object (i.e. physical
// coordinates with flipped block-flow direction). See documentation of
// LayoutBoxModelObject and LayoutBox::noOverflowRect() for more details.
//
// The classes model the overflows as rectangles that unite all the sources of
// overflow. This is the natural choice for layout overflow (scrollbars are
// linear in nature, thus are modeled by rectangles in 2D). For visual overflow
// and content visual overflow, this is a first order simplification though as
// they can be thought of as a collection of (potentially overlapping)
// rectangles.
//
// Layout overflow is the overflow that is reachable via scrollbars. It is used
// to size the scrollbar thumb and determine its position, which is determined
// by the maximum layout overflow size.
// Layout overflow cannot occur without an overflow clip as this is the only way
// to get scrollbars. As its name implies, it is a direct consequence of layout.
// Example of layout overflow:
// * in the inline case, a tall image could spill out of a line box.
// * 'height' / 'width' set to a value smaller than the one needed by the
//   descendants.
// Due to how scrollbars work, no overflow in the logical top and logical left
// direction is allowed(see LayoutBox::addLayoutOverflow).
//
// Visual overflow covers all the effects that visually bleed out of the box.
// Its primary use is to determine the area to invalidate.
// Visual overflow includes ('text-shadow' / 'box-shadow'), text stroke,
// 'outline', 'border-image', etc.
//
// An overflow model object is allocated only when some of these fields have
// non-default values in the owning object. Care should be taken to use adder
// functions (addLayoutOverflow, addVisualOverflow, etc.) to keep this
// invariant.

class SimpleOverflowModel {
  WTF_MAKE_NONCOPYABLE(SimpleOverflowModel);
  USING_FAST_MALLOC(SimpleOverflowModel);

 public:
  SimpleOverflowModel(const LayoutRect& layoutRect,
                      const LayoutRect& visualRect)
      : m_layoutOverflow(layoutRect), m_visualOverflow(visualRect) {}

  const LayoutRect& layoutOverflowRect() const { return m_layoutOverflow; }
  void setLayoutOverflow(const LayoutRect& rect) { m_layoutOverflow = rect; }
  void addLayoutOverflow(const LayoutRect& rect) {
    uniteLayoutOverflowRect(m_layoutOverflow, rect);
  }

  const LayoutRect& visualOverflowRect() const { return m_visualOverflow; }
  void setVisualOverflow(const LayoutRect& rect) { m_visualOverflow = rect; }
  void addVisualOverflow(const LayoutRect& rect) {
    m_visualOverflow.unite(rect);
  }

  void move(LayoutUnit dx, LayoutUnit dy) {
    m_layoutOverflow.move(dx, dy);
    m_visualOverflow.move(dx, dy);
  }

 private:
  LayoutRect m_layoutOverflow;
  LayoutRect m_visualOverflow;
};

// BoxModelOverflow tracks overflows of a LayoutBox. It separates visual
// overflow into self visual overflow and contents visual overflow.
//
// Self visual overflow covers all the effects of the object itself that
// visually bleed out of the box.
//
// Content visual overflow includes anything that would bleed out of the box and
// would be clipped by the overflow clip ('overflow' != visible). This
// corresponds to children that overflows their parent.
// It's important to note that this overflow ignores descendants with
// self-painting layers (see the SELF-PAINTING LAYER section in PaintLayer).
// This is required by the simplification made by this model (single united
// rectangle) to avoid gigantic invalidation. A good example for this is
// positioned objects that can be anywhere on the page and could artificially
// inflate the visual overflow.
// The main use of content visual overflow is to prevent unneeded clipping in
// BoxPainter (see https://crbug.com/238732). Note that the code path for
// self-painting layer is handled by PaintLayerPainter, which relies on
// PaintLayerClipper and thus ignores this optimization.
//
// Visual overflow covers self visual overflow, and if the box doesn't clip
// overflow, also content visual overflow. OverflowModel doesn't keep visual
// overflow, but keeps self visual overflow and contents visual overflow
// separately. The box should use self visual overflow as visual overflow if
// it clips overflow, otherwise union of self visual overflow and contents
// visual overflow.

class BoxOverflowModel {
 public:
  BoxOverflowModel(const LayoutRect& layoutRect,
                   const LayoutRect& selfVisualOverflowRect)
      : m_layoutOverflow(layoutRect),
        m_selfVisualOverflow(selfVisualOverflowRect) {}

  const LayoutRect& layoutOverflowRect() const { return m_layoutOverflow; }
  void setLayoutOverflow(const LayoutRect& rect) { m_layoutOverflow = rect; }
  void addLayoutOverflow(const LayoutRect& rect) {
    uniteLayoutOverflowRect(m_layoutOverflow, rect);
  }

  const LayoutRect& selfVisualOverflowRect() const {
    return m_selfVisualOverflow;
  }
  void addSelfVisualOverflow(const LayoutRect& rect) {
    m_selfVisualOverflow.unite(rect);
  }

  const LayoutRect& contentsVisualOverflowRect() const {
    return m_contentsVisualOverflow;
  }
  void addContentsVisualOverflow(const LayoutRect& rect) {
    m_contentsVisualOverflow.unite(rect);
  }

  void move(LayoutUnit dx, LayoutUnit dy) {
    m_layoutOverflow.move(dx, dy);
    m_selfVisualOverflow.move(dx, dy);
    m_contentsVisualOverflow.move(dx, dy);
  }

  LayoutUnit layoutClientAfterEdge() const { return m_layoutClientAfterEdge; }
  void setLayoutClientAfterEdge(LayoutUnit clientAfterEdge) {
    m_layoutClientAfterEdge = clientAfterEdge;
  }

 private:
  LayoutRect m_layoutOverflow;
  LayoutRect m_selfVisualOverflow;
  LayoutRect m_contentsVisualOverflow;
  LayoutUnit m_layoutClientAfterEdge;
};

}  // namespace blink

#endif  // OverflowModel_h