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_isPaginated(pageLogicalHeight) | 37 : m_clipped(false) |
| 38 , m_isPaginated(pageLogicalHeight) |
38 , m_pageLogicalHeightChanged(pageLogicalHeightChanged) | 39 , m_pageLogicalHeightChanged(pageLogicalHeightChanged) |
| 40 , m_cachedOffsetsEnabled(true) |
39 , m_columnInfo(0) | 41 , m_columnInfo(0) |
40 , m_next(0) | 42 , m_next(0) |
41 , m_pageLogicalHeight(pageLogicalHeight) | 43 , m_pageLogicalHeight(pageLogicalHeight) |
42 , m_renderer(view) | 44 , m_renderer(view) |
43 { | 45 { |
44 ASSERT(!view.layoutState()); | 46 ASSERT(!view.layoutState()); |
45 view.pushLayoutState(*this); | 47 view.pushLayoutState(*this); |
46 } | 48 } |
47 | 49 |
48 LayoutState::LayoutState(RenderBox& renderer, const LayoutSize& offset, LayoutUn
it pageLogicalHeight, bool pageLogicalHeightChanged, ColumnInfo* columnInfo) | 50 LayoutState::LayoutState(RenderBox& renderer, const LayoutSize& offset, LayoutUn
it pageLogicalHeight, bool pageLogicalHeightChanged, ColumnInfo* columnInfo) |
49 : m_columnInfo(columnInfo) | 51 : m_columnInfo(columnInfo) |
50 , m_next(renderer.view()->layoutState()) | 52 , m_next(renderer.view()->layoutState()) |
51 , m_renderer(renderer) | 53 , m_renderer(renderer) |
52 { | 54 { |
53 renderer.view()->pushLayoutState(*this); | 55 renderer.view()->pushLayoutState(*this); |
| 56 m_cachedOffsetsEnabled = m_next->m_cachedOffsetsEnabled && renderer.supports
LayoutStateCachedOffsets(); |
54 bool fixed = renderer.isOutOfFlowPositioned() && renderer.style()->position(
) == FixedPosition; | 57 bool fixed = renderer.isOutOfFlowPositioned() && renderer.style()->position(
) == FixedPosition; |
55 if (fixed) { | 58 if (fixed) { |
56 // FIXME: This doesn't work correctly with transforms. | 59 // FIXME: This doesn't work correctly with transforms. |
57 FloatPoint fixedOffset = renderer.view()->localToAbsolute(FloatPoint(),
IsFixed); | 60 FloatPoint fixedOffset = renderer.view()->localToAbsolute(FloatPoint(),
IsFixed); |
58 m_layoutOffset = LayoutSize(fixedOffset.x(), fixedOffset.y()) + offset; | 61 m_paintOffset = LayoutSize(fixedOffset.x(), fixedOffset.y()) + offset; |
59 } else { | 62 } else { |
60 m_layoutOffset = m_next->m_layoutOffset + offset; | 63 m_paintOffset = m_next->m_paintOffset + offset; |
61 } | 64 } |
62 | 65 |
63 if (renderer.isOutOfFlowPositioned() && !fixed) { | 66 if (renderer.isOutOfFlowPositioned() && !fixed) { |
64 if (RenderObject* container = renderer.container()) { | 67 if (RenderObject* container = renderer.container()) { |
65 if (container->style()->hasInFlowPosition() && container->isRenderIn
line()) | 68 if (container->isRelPositioned() && container->isRenderInline()) |
66 m_layoutOffset += toRenderInline(container)->offsetForInFlowPosi
tionedInline(renderer); | 69 m_paintOffset += toRenderInline(container)->offsetForInFlowPosit
ionedInline(renderer); |
67 } | 70 } |
68 } | 71 } |
| 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 |
69 // If we establish a new page height, then cache the offset to the top of th
e first page. | 94 // If we establish a new page height, then cache the offset to the top of th
e first page. |
70 // We can compare this later on to figure out what part of the page we're ac
tually on, | 95 // We can compare this later on to figure out what part of the page we're ac
tually on, |
71 if (pageLogicalHeight || m_columnInfo || renderer.isRenderFlowThread()) { | 96 if (pageLogicalHeight || m_columnInfo || renderer.isRenderFlowThread()) { |
72 m_pageLogicalHeight = pageLogicalHeight; | 97 m_pageLogicalHeight = pageLogicalHeight; |
73 bool isFlipped = renderer.style()->isFlippedBlocksWritingMode(); | 98 bool isFlipped = renderer.style()->isFlippedBlocksWritingMode(); |
74 m_pageOffset = LayoutSize(m_layoutOffset.width() + (!isFlipped ? rendere
r.borderLeft() + renderer.paddingLeft() : renderer.borderRight() + renderer.padd
ingRight()), | 99 m_pageOffset = LayoutSize(m_layoutOffset.width() + (!isFlipped ? rendere
r.borderLeft() + renderer.paddingLeft() : renderer.borderRight() + renderer.padd
ingRight()), |
75 m_layoutOffset.height() + (!isFlipped ? renderer.borderTop() + rende
rer.paddingTop() : renderer.borderBottom() + renderer.paddingBottom())); | 100 m_layoutOffset.height() + (!isFlipped ? renderer.borderTop() + rende
rer.paddingTop() : renderer.borderBottom() + renderer.paddingBottom())); |
76 m_pageLogicalHeightChanged = pageLogicalHeightChanged; | 101 m_pageLogicalHeightChanged = pageLogicalHeightChanged; |
77 m_isPaginated = true; | 102 m_isPaginated = true; |
78 } else { | 103 } else { |
(...skipping 11 matching lines...) Expand all Loading... |
90 m_isPaginated = m_pageLogicalHeight || m_next->m_columnInfo || rende
rer.flowThreadContainingBlock(); | 115 m_isPaginated = m_pageLogicalHeight || m_next->m_columnInfo || rende
rer.flowThreadContainingBlock(); |
91 } | 116 } |
92 } | 117 } |
93 | 118 |
94 if (!m_columnInfo) | 119 if (!m_columnInfo) |
95 m_columnInfo = m_next->m_columnInfo; | 120 m_columnInfo = m_next->m_columnInfo; |
96 | 121 |
97 // FIXME: <http://bugs.webkit.org/show_bug.cgi?id=13443> Apply control clip
if present. | 122 // FIXME: <http://bugs.webkit.org/show_bug.cgi?id=13443> Apply control clip
if present. |
98 } | 123 } |
99 | 124 |
| 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 |
100 LayoutState::LayoutState(RenderObject& root) | 163 LayoutState::LayoutState(RenderObject& root) |
101 : m_isPaginated(false) | 164 : m_clipped(false) |
| 165 , m_isPaginated(false) |
102 , m_pageLogicalHeightChanged(false) | 166 , m_pageLogicalHeightChanged(false) |
| 167 , m_cachedOffsetsEnabled(shouldDisableLayoutStateForSubtree(root)) |
103 , m_columnInfo(0) | 168 , m_columnInfo(0) |
104 , m_next(root.view()->layoutState()) | 169 , m_next(root.view()->layoutState()) |
105 , m_pageLogicalHeight(0) | 170 , m_pageLogicalHeight(0) |
106 , m_renderer(root) | 171 , m_renderer(root) |
107 { | 172 { |
108 // FIXME: Why does RenderTableSection create this wonky LayoutState? | 173 // FIXME: Why does RenderTableSection create this wonky LayoutState? |
109 ASSERT(!m_next || root.isTableSection()); | 174 ASSERT(!m_next || root.isTableSection()); |
110 // We'll end up pushing in RenderView itself, so don't bother adding it. | 175 // We'll end up pushing in RenderView itself, so don't bother adding it. |
111 if (root.isRenderView()) | 176 if (root.isRenderView()) |
112 return; | 177 return; |
113 | 178 |
114 root.view()->pushLayoutState(*this); | 179 root.view()->pushLayoutState(*this); |
115 | 180 |
116 RenderObject* container = root.container(); | 181 RenderObject* container = root.container(); |
117 FloatPoint absContentPoint = container->localToAbsolute(FloatPoint(), UseTra
nsforms); | 182 FloatPoint absContentPoint = container->localToAbsolute(FloatPoint(), UseTra
nsforms); |
118 m_layoutOffset = LayoutSize(absContentPoint.x(), absContentPoint.y()); | 183 m_paintOffset = 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 } |
119 } | 191 } |
120 | 192 |
121 LayoutState::~LayoutState() | 193 LayoutState::~LayoutState() |
122 { | 194 { |
123 if (m_renderer.view()->layoutState()) { | 195 if (m_renderer.view()->layoutState()) { |
124 ASSERT(m_renderer.view()->layoutState() == this); | 196 ASSERT(m_renderer.view()->layoutState() == this); |
125 m_renderer.view()->popLayoutState(); | 197 m_renderer.view()->popLayoutState(); |
126 } | 198 } |
127 } | 199 } |
128 | 200 |
(...skipping 12 matching lines...) Expand all Loading... |
141 } | 213 } |
142 | 214 |
143 void LayoutState::addForcedColumnBreak(const RenderBox& child, const LayoutUnit&
childLogicalOffset) | 215 void LayoutState::addForcedColumnBreak(const RenderBox& child, const LayoutUnit&
childLogicalOffset) |
144 { | 216 { |
145 if (!m_columnInfo || m_columnInfo->columnHeight()) | 217 if (!m_columnInfo || m_columnInfo->columnHeight()) |
146 return; | 218 return; |
147 m_columnInfo->addForcedBreak(pageLogicalOffset(child, childLogicalOffset)); | 219 m_columnInfo->addForcedBreak(pageLogicalOffset(child, childLogicalOffset)); |
148 } | 220 } |
149 | 221 |
150 } // namespace WebCore | 222 } // namespace WebCore |
OLD | NEW |