2 * Copyright (C) 2017 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 #include "LayoutUnit.h"
31 #include <wtf/WeakPtr.h>
41 class RenderBlockFlow;
49 LayoutContext(FrameView&);
53 void setNeedsLayout();
54 bool needsLayout() const;
56 void scheduleLayout();
57 void scheduleSubtreeLayout(RenderElement& layoutRoot);
58 void unscheduleLayout();
60 void startDisallowingLayout() { ++m_layoutDisallowedCount; }
61 void endDisallowingLayout() { ASSERT(m_layoutDisallowedCount > 0); --m_layoutDisallowedCount; }
63 void disableSetNeedsLayout();
64 void enableSetNeedsLayout();
66 enum class LayoutPhase {
73 LayoutPhase layoutPhase() const { return m_layoutPhase; }
74 bool isLayoutNested() const { return m_layoutNestedState == LayoutNestedState::Nested; }
75 bool isLayoutPending() const { return m_layoutTimer.isActive(); }
76 bool isInLayout() const { return layoutPhase() != LayoutPhase::OutsideLayout; }
77 bool isInRenderTreeLayout() const { return layoutPhase() == LayoutPhase::InRenderTreeLayout; }
78 bool inPaintableState() const { return layoutPhase() != LayoutPhase::InRenderTreeLayout && layoutPhase() != LayoutPhase::InViewSizeAdjust && (layoutPhase() != LayoutPhase::InPostLayout || inAsynchronousTasks()); }
80 unsigned layoutCount() const { return m_layoutCount; }
82 RenderElement* subtreeLayoutRoot() const { return m_subtreeLayoutRoot.get(); }
83 void clearSubtreeLayoutRoot() { m_subtreeLayoutRoot.clear(); }
84 void convertSubtreeLayoutToFullLayout();
87 void resetFirstLayoutFlag() { m_firstLayout = true; }
88 bool didFirstLayout() const { return !m_firstLayout; }
90 void setNeedsFullRepaint() { m_needsFullRepaint = true; }
91 bool needsFullRepaint() const { return m_needsFullRepaint; }
93 void flushAsynchronousTasks();
96 void pushLayoutState(RenderElement&);
97 bool pushLayoutStateForPaginationIfNeeded(RenderBlockFlow&);
98 void popLayoutState(RenderObject&);
99 LayoutState* layoutState() const;
100 // Returns true if layoutState should be used for its cached offset and clip.
101 bool isPaintOffsetCacheEnabled() const { return !m_paintOffsetCacheDisableCount && layoutState(); }
103 void checkLayoutState();
105 // layoutDelta is used transiently during layout to store how far an object has moved from its
106 // last layout location, in order to repaint correctly.
107 // If we're doing a full repaint m_layoutState will be 0, but in that case layoutDelta doesn't matter.
108 LayoutSize layoutDelta() const;
109 void addLayoutDelta(const LayoutSize& delta);
111 bool layoutDeltaMatches(const LayoutSize& delta);
113 using LayoutStateStack = Vector<std::unique_ptr<LayoutState>>;
116 friend class LayoutScope;
117 friend class LayoutStateMaintainer;
118 friend class LayoutStateDisabler;
119 friend class SubtreeLayoutStateMaintainer;
121 bool canPerformLayout() const;
122 bool layoutDisallowed() const { return m_layoutDisallowedCount; }
123 bool isLayoutSchedulingEnabled() const { return m_layoutSchedulingIsEnabled; }
125 void layoutTimerFired();
126 void runAsynchronousTasks();
127 void runOrScheduleAsynchronousTasks();
128 bool inAsynchronousTasks() const { return m_inAsynchronousTasks; }
130 void setSubtreeLayoutRoot(RenderElement&);
132 #if ENABLE(TEXT_AUTOSIZING)
133 void applyTextSizingIfNeeded(RenderElement& layoutRoot);
135 void updateStyleForLayout();
137 bool handleLayoutWithFrameFlatteningIfNeeded();
138 void startLayoutAtMainFrameViewIfNeeded();
140 // These functions may only be accessed by LayoutStateMaintainer.
141 bool pushLayoutState(RenderBox& renderer, const LayoutSize& offset, LayoutUnit pageHeight = 0, bool pageHeightChanged = false);
142 void popLayoutState();
144 // Suspends the LayoutState optimization. Used under transforms that cannot be represented by
145 // LayoutState (common in SVG) and when manipulating the render tree during layout in ways
146 // that can trigger repaint of a non-child (e.g. when a list item moves its list marker around).
147 // Note that even when disabled, LayoutState is still used to store layoutDelta.
148 // These functions may only be accessed by LayoutStateMaintainer or LayoutStateDisabler.
149 void disablePaintOffsetCache() { m_paintOffsetCacheDisableCount++; }
150 void enablePaintOffsetCache() { ASSERT(m_paintOffsetCacheDisableCount > 0); m_paintOffsetCacheDisableCount--; }
152 Frame& frame() const;
153 FrameView& view() const;
154 RenderView* renderView() const;
155 Document* document() const;
157 FrameView& m_frameView;
159 Timer m_asynchronousTasksTimer;
161 bool m_layoutSchedulingIsEnabled { true };
162 bool m_delayedLayout { false };
163 bool m_firstLayout { true };
164 bool m_needsFullRepaint { true };
165 bool m_inAsynchronousTasks { false };
166 bool m_setNeedsLayoutWasDeferred { false };
167 LayoutPhase m_layoutPhase { LayoutPhase::OutsideLayout };
168 enum class LayoutNestedState { NotInLayout, NotNested, Nested };
169 LayoutNestedState m_layoutNestedState { LayoutNestedState::NotInLayout };
170 unsigned m_layoutCount { 0 };
171 unsigned m_disableSetNeedsLayoutCount { 0 };
172 int m_layoutDisallowedCount { 0 };
173 WeakPtr<RenderElement> m_subtreeLayoutRoot;
174 LayoutStateStack m_layoutStateStack;
175 unsigned m_paintOffsetCacheDisableCount { 0 };
178 } // namespace WebCore