OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2007 Apple Inc. All rights reserved. | 2 * Copyright (C) 2007 Apple Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
(...skipping 16 matching lines...) Expand all Loading... |
27 #include "core/rendering/LayoutState.h" | 27 #include "core/rendering/LayoutState.h" |
28 | 28 |
29 #include "core/rendering/RenderInline.h" | 29 #include "core/rendering/RenderInline.h" |
30 #include "core/rendering/RenderLayer.h" | 30 #include "core/rendering/RenderLayer.h" |
31 #include "core/rendering/RenderView.h" | 31 #include "core/rendering/RenderView.h" |
32 #include "platform/Partitions.h" | 32 #include "platform/Partitions.h" |
33 | 33 |
34 namespace WebCore { | 34 namespace WebCore { |
35 | 35 |
36 LayoutState::LayoutState(LayoutUnit pageLogicalHeight, bool pageLogicalHeightCha
nged, RenderView& view) | 36 LayoutState::LayoutState(LayoutUnit pageLogicalHeight, bool pageLogicalHeightCha
nged, RenderView& view) |
37 : m_clipped(false) | 37 : m_isPaginated(pageLogicalHeight) |
38 , m_isPaginated(pageLogicalHeight) | |
39 , m_pageLogicalHeightChanged(pageLogicalHeightChanged) | 38 , m_pageLogicalHeightChanged(pageLogicalHeightChanged) |
40 , m_cachedOffsetsEnabled(true) | |
41 , m_columnInfo(0) | 39 , m_columnInfo(0) |
42 , m_next(0) | 40 , m_next(0) |
43 , m_pageLogicalHeight(pageLogicalHeight) | 41 , m_pageLogicalHeight(pageLogicalHeight) |
44 , m_renderer(view) | 42 , m_renderer(view) |
45 { | 43 { |
46 ASSERT(!view.layoutState()); | 44 ASSERT(!view.layoutState()); |
47 view.pushLayoutState(*this); | 45 view.pushLayoutState(*this); |
48 } | 46 } |
49 | 47 |
50 LayoutState::LayoutState(RenderBox& renderer, const LayoutSize& offset, LayoutUn
it pageLogicalHeight, bool pageLogicalHeightChanged, ColumnInfo* columnInfo) | 48 LayoutState::LayoutState(RenderBox& renderer, const LayoutSize& offset, LayoutUn
it pageLogicalHeight, bool pageLogicalHeightChanged, ColumnInfo* columnInfo) |
51 : m_columnInfo(columnInfo) | 49 : m_columnInfo(columnInfo) |
52 , m_next(renderer.view()->layoutState()) | 50 , m_next(renderer.view()->layoutState()) |
53 , m_renderer(renderer) | 51 , m_renderer(renderer) |
54 { | 52 { |
55 renderer.view()->pushLayoutState(*this); | 53 renderer.view()->pushLayoutState(*this); |
56 m_cachedOffsetsEnabled = m_next->m_cachedOffsetsEnabled && renderer.supports
LayoutStateCachedOffsets(); | |
57 bool fixed = renderer.isOutOfFlowPositioned() && renderer.style()->position(
) == FixedPosition; | 54 bool fixed = renderer.isOutOfFlowPositioned() && renderer.style()->position(
) == FixedPosition; |
58 if (fixed) { | 55 if (fixed) { |
59 // FIXME: This doesn't work correctly with transforms. | 56 // FIXME: This doesn't work correctly with transforms. |
60 FloatPoint fixedOffset = renderer.view()->localToAbsolute(FloatPoint(),
IsFixed); | 57 FloatPoint fixedOffset = renderer.view()->localToAbsolute(FloatPoint(),
IsFixed); |
61 m_paintOffset = LayoutSize(fixedOffset.x(), fixedOffset.y()) + offset; | 58 m_layoutOffset = LayoutSize(fixedOffset.x(), fixedOffset.y()) + offset; |
62 } else { | 59 } else { |
63 m_paintOffset = m_next->m_paintOffset + offset; | 60 m_layoutOffset = m_next->m_layoutOffset + offset; |
64 } | 61 } |
65 | 62 |
66 if (renderer.isOutOfFlowPositioned() && !fixed) { | 63 if (renderer.isOutOfFlowPositioned() && !fixed) { |
67 if (RenderObject* container = renderer.container()) { | 64 if (RenderObject* container = renderer.container()) { |
68 if (container->isRelPositioned() && container->isRenderInline()) | 65 if (container->style()->hasInFlowPosition() && container->isRenderIn
line()) |
69 m_paintOffset += toRenderInline(container)->offsetForInFlowPosit
ionedInline(renderer); | 66 m_layoutOffset += toRenderInline(container)->offsetForInFlowPosi
tionedInline(renderer); |
70 } | 67 } |
71 } | 68 } |
72 | |
73 m_layoutOffset = m_paintOffset; | |
74 | |
75 if (renderer.isRelPositioned() && renderer.hasLayer()) | |
76 m_paintOffset += renderer.layer()->offsetForInFlowPosition(); | |
77 | |
78 m_clipped = !fixed && m_next->m_clipped; | |
79 if (m_clipped) | |
80 m_clipRect = m_next->m_clipRect; | |
81 | |
82 if (renderer.hasOverflowClip()) { | |
83 LayoutRect clipRect(toPoint(m_paintOffset), renderer.cachedSizeForOverfl
owClip()); | |
84 if (m_clipped) | |
85 m_clipRect.intersect(clipRect); | |
86 else { | |
87 m_clipRect = clipRect; | |
88 m_clipped = true; | |
89 } | |
90 | |
91 m_paintOffset -= renderer.scrolledContentOffset(); | |
92 } | |
93 | |
94 // If we establish a new page height, then cache the offset to the top of th
e first page. | 69 // If we establish a new page height, then cache the offset to the top of th
e first page. |
95 // We can compare this later on to figure out what part of the page we're ac
tually on, | 70 // We can compare this later on to figure out what part of the page we're ac
tually on, |
96 if (pageLogicalHeight || m_columnInfo || renderer.isRenderFlowThread()) { | 71 if (pageLogicalHeight || m_columnInfo || renderer.isRenderFlowThread()) { |
97 m_pageLogicalHeight = pageLogicalHeight; | 72 m_pageLogicalHeight = pageLogicalHeight; |
98 bool isFlipped = renderer.style()->isFlippedBlocksWritingMode(); | 73 bool isFlipped = renderer.style()->isFlippedBlocksWritingMode(); |
99 m_pageOffset = LayoutSize(m_layoutOffset.width() + (!isFlipped ? rendere
r.borderLeft() + renderer.paddingLeft() : renderer.borderRight() + renderer.padd
ingRight()), | 74 m_pageOffset = LayoutSize(m_layoutOffset.width() + (!isFlipped ? rendere
r.borderLeft() + renderer.paddingLeft() : renderer.borderRight() + renderer.padd
ingRight()), |
100 m_layoutOffset.height() + (!isFlipped ? renderer.borderTop() + rende
rer.paddingTop() : renderer.borderBottom() + renderer.paddingBottom())); | 75 m_layoutOffset.height() + (!isFlipped ? renderer.borderTop() + rende
rer.paddingTop() : renderer.borderBottom() + renderer.paddingBottom())); |
101 m_pageLogicalHeightChanged = pageLogicalHeightChanged; | 76 m_pageLogicalHeightChanged = pageLogicalHeightChanged; |
102 m_isPaginated = true; | 77 m_isPaginated = true; |
103 } else { | 78 } else { |
(...skipping 11 matching lines...) Expand all Loading... |
115 m_isPaginated = m_pageLogicalHeight || m_next->m_columnInfo || rende
rer.flowThreadContainingBlock(); | 90 m_isPaginated = m_pageLogicalHeight || m_next->m_columnInfo || rende
rer.flowThreadContainingBlock(); |
116 } | 91 } |
117 } | 92 } |
118 | 93 |
119 if (!m_columnInfo) | 94 if (!m_columnInfo) |
120 m_columnInfo = m_next->m_columnInfo; | 95 m_columnInfo = m_next->m_columnInfo; |
121 | 96 |
122 // FIXME: <http://bugs.webkit.org/show_bug.cgi?id=13443> Apply control clip
if present. | 97 // FIXME: <http://bugs.webkit.org/show_bug.cgi?id=13443> Apply control clip
if present. |
123 } | 98 } |
124 | 99 |
125 LayoutState::LayoutState(RenderInline& renderer) | |
126 : m_next(renderer.view()->layoutState()) | |
127 , m_renderer(renderer) | |
128 { | |
129 ASSERT(m_next); | |
130 | |
131 renderer.view()->pushLayoutState(*this); | |
132 m_cachedOffsetsEnabled = m_next->m_cachedOffsetsEnabled && renderer.supports
LayoutStateCachedOffsets(); | |
133 | |
134 m_paintOffset = m_next->m_paintOffset; | |
135 // Handle relative positioned inline. | |
136 if (renderer.style()->hasInFlowPosition() && renderer.layer()) | |
137 m_paintOffset += renderer.layer()->offsetForInFlowPosition(); | |
138 | |
139 // RenderInline can't be out-of-flow positioned. | |
140 | |
141 // The following can't apply to RenderInline so we just propagate them. | |
142 m_clipped = m_next->m_clipped; | |
143 m_clipRect = m_next->m_clipRect; | |
144 | |
145 m_pageLogicalHeight = m_next->m_pageLogicalHeight; | |
146 m_pageLogicalHeightChanged = m_next->m_pageLogicalHeightChanged; | |
147 m_pageOffset = m_next->m_pageOffset; | |
148 | |
149 m_columnInfo = m_next->m_columnInfo; | |
150 } | |
151 | |
152 inline static bool shouldDisableLayoutStateForSubtree(RenderObject& renderer) | |
153 { | |
154 RenderObject* object = &renderer; | |
155 while (object) { | |
156 if (object->supportsLayoutStateCachedOffsets()) | |
157 return true; | |
158 object = object->container(); | |
159 } | |
160 return false; | |
161 } | |
162 | |
163 LayoutState::LayoutState(RenderObject& root) | 100 LayoutState::LayoutState(RenderObject& root) |
164 : m_clipped(false) | 101 : m_isPaginated(false) |
165 , m_isPaginated(false) | |
166 , m_pageLogicalHeightChanged(false) | 102 , m_pageLogicalHeightChanged(false) |
167 , m_cachedOffsetsEnabled(shouldDisableLayoutStateForSubtree(root)) | |
168 , m_columnInfo(0) | 103 , m_columnInfo(0) |
169 , m_next(root.view()->layoutState()) | 104 , m_next(root.view()->layoutState()) |
170 , m_pageLogicalHeight(0) | 105 , m_pageLogicalHeight(0) |
171 , m_renderer(root) | 106 , m_renderer(root) |
172 { | 107 { |
173 // FIXME: Why does RenderTableSection create this wonky LayoutState? | 108 // FIXME: Why does RenderTableSection create this wonky LayoutState? |
174 ASSERT(!m_next || root.isTableSection()); | 109 ASSERT(!m_next || root.isTableSection()); |
175 // We'll end up pushing in RenderView itself, so don't bother adding it. | 110 // We'll end up pushing in RenderView itself, so don't bother adding it. |
176 if (root.isRenderView()) | 111 if (root.isRenderView()) |
177 return; | 112 return; |
178 | 113 |
179 root.view()->pushLayoutState(*this); | 114 root.view()->pushLayoutState(*this); |
180 | 115 |
181 RenderObject* container = root.container(); | 116 RenderObject* container = root.container(); |
182 FloatPoint absContentPoint = container->localToAbsolute(FloatPoint(), UseTra
nsforms); | 117 FloatPoint absContentPoint = container->localToAbsolute(FloatPoint(), UseTra
nsforms); |
183 m_paintOffset = LayoutSize(absContentPoint.x(), absContentPoint.y()); | 118 m_layoutOffset = LayoutSize(absContentPoint.x(), absContentPoint.y()); |
184 | |
185 if (container->hasOverflowClip()) { | |
186 m_clipped = true; | |
187 RenderBox* containerBox = toRenderBox(container); | |
188 m_clipRect = LayoutRect(toPoint(m_paintOffset), containerBox->cachedSize
ForOverflowClip()); | |
189 m_paintOffset -= containerBox->scrolledContentOffset(); | |
190 } | |
191 } | 119 } |
192 | 120 |
193 LayoutState::~LayoutState() | 121 LayoutState::~LayoutState() |
194 { | 122 { |
195 if (m_renderer.view()->layoutState()) { | 123 if (m_renderer.view()->layoutState()) { |
196 ASSERT(m_renderer.view()->layoutState() == this); | 124 ASSERT(m_renderer.view()->layoutState() == this); |
197 m_renderer.view()->popLayoutState(); | 125 m_renderer.view()->popLayoutState(); |
198 } | 126 } |
199 } | 127 } |
200 | 128 |
(...skipping 12 matching lines...) Expand all Loading... |
213 } | 141 } |
214 | 142 |
215 void LayoutState::addForcedColumnBreak(const RenderBox& child, const LayoutUnit&
childLogicalOffset) | 143 void LayoutState::addForcedColumnBreak(const RenderBox& child, const LayoutUnit&
childLogicalOffset) |
216 { | 144 { |
217 if (!m_columnInfo || m_columnInfo->columnHeight()) | 145 if (!m_columnInfo || m_columnInfo->columnHeight()) |
218 return; | 146 return; |
219 m_columnInfo->addForcedBreak(pageLogicalOffset(child, childLogicalOffset)); | 147 m_columnInfo->addForcedBreak(pageLogicalOffset(child, childLogicalOffset)); |
220 } | 148 } |
221 | 149 |
222 } // namespace WebCore | 150 } // namespace WebCore |
OLD | NEW |