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 15 matching lines...) Expand all Loading... |
26 #include "config.h" | 26 #include "config.h" |
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(LayoutState* prev, RenderBox* renderer, const LayoutSiz
e& offset, LayoutUnit pageLogicalHeight, bool pageLogicalHeightChanged, ColumnIn
fo* columnInfo) | 36 LayoutState::LayoutState(LayoutState* prev, RenderBox* renderer, const LayoutSiz
e& offset, LayoutUnit pageLogicalHeight, bool pageLogicalHeightChanged) |
37 : m_columnInfo(columnInfo) | 37 : m_lineGrid(0) |
38 , m_lineGrid(0) | |
39 , m_next(prev) | 38 , m_next(prev) |
40 , m_shapeInsideInfo(0) | 39 , m_shapeInsideInfo(0) |
41 #ifndef NDEBUG | 40 #ifndef NDEBUG |
42 , m_renderer(renderer) | 41 , m_renderer(renderer) |
43 #endif | 42 #endif |
44 { | 43 { |
45 ASSERT(m_next); | 44 ASSERT(m_next); |
46 | 45 |
47 bool fixed = renderer->isOutOfFlowPositioned() && renderer->style()->positio
n() == FixedPosition; | 46 bool fixed = renderer->isOutOfFlowPositioned() && renderer->style()->positio
n() == FixedPosition; |
48 if (fixed) { | 47 if (fixed) { |
(...skipping 28 matching lines...) Expand all Loading... |
77 else { | 76 else { |
78 m_clipRect = clipRect; | 77 m_clipRect = clipRect; |
79 m_clipped = true; | 78 m_clipped = true; |
80 } | 79 } |
81 | 80 |
82 m_paintOffset -= renderer->scrolledContentOffset(); | 81 m_paintOffset -= renderer->scrolledContentOffset(); |
83 } | 82 } |
84 | 83 |
85 // If we establish a new page height, then cache the offset to the top of th
e first page. | 84 // If we establish a new page height, then cache the offset to the top of th
e first page. |
86 // We can compare this later on to figure out what part of the page we're ac
tually on, | 85 // We can compare this later on to figure out what part of the page we're ac
tually on, |
87 if (pageLogicalHeight || m_columnInfo || renderer->isRenderFlowThread()) { | 86 if (pageLogicalHeight || renderer->isRenderFlowThread()) { |
88 m_pageLogicalHeight = pageLogicalHeight; | 87 m_pageLogicalHeight = pageLogicalHeight; |
89 bool isFlipped = renderer->style()->isFlippedBlocksWritingMode(); | 88 bool isFlipped = renderer->style()->isFlippedBlocksWritingMode(); |
90 m_pageOffset = LayoutSize(m_layoutOffset.width() + (!isFlipped ? rendere
r->borderLeft() + renderer->paddingLeft() : renderer->borderRight() + renderer->
paddingRight()), | 89 m_pageOffset = LayoutSize(m_layoutOffset.width() + (!isFlipped ? rendere
r->borderLeft() + renderer->paddingLeft() : renderer->borderRight() + renderer->
paddingRight()), |
91 m_layoutOffset.height() + (!isFlipped ? renderer-
>borderTop() + renderer->paddingTop() : renderer->borderBottom() + renderer->pad
dingBottom())); | 90 m_layoutOffset.height() + (!isFlipped ? renderer-
>borderTop() + renderer->paddingTop() : renderer->borderBottom() + renderer->pad
dingBottom())); |
92 m_pageLogicalHeightChanged = pageLogicalHeightChanged; | 91 m_pageLogicalHeightChanged = pageLogicalHeightChanged; |
93 } else { | 92 } else { |
94 // If we don't establish a new page height, then propagate the old page
height and offset down. | 93 // If we don't establish a new page height, then propagate the old page
height and offset down. |
95 m_pageLogicalHeight = m_next->m_pageLogicalHeight; | 94 m_pageLogicalHeight = m_next->m_pageLogicalHeight; |
96 m_pageLogicalHeightChanged = m_next->m_pageLogicalHeightChanged; | 95 m_pageLogicalHeightChanged = m_next->m_pageLogicalHeightChanged; |
97 m_pageOffset = m_next->m_pageOffset; | 96 m_pageOffset = m_next->m_pageOffset; |
98 | 97 |
99 // Disable pagination for objects we don't support. For now this include
s overflow:scroll/auto, inline blocks and | 98 // Disable pagination for objects we don't support. For now this include
s overflow:scroll/auto, inline blocks and |
100 // writing mode roots. | 99 // writing mode roots. |
101 if (renderer->isUnsplittableForPagination()) | 100 if (renderer->isUnsplittableForPagination()) |
102 m_pageLogicalHeight = 0; | 101 m_pageLogicalHeight = 0; |
103 } | 102 } |
104 | 103 |
105 // Propagate line grid information. | 104 // Propagate line grid information. |
106 propagateLineGridInfo(renderer); | 105 propagateLineGridInfo(renderer); |
107 | 106 |
108 if (!m_columnInfo) | |
109 m_columnInfo = m_next->m_columnInfo; | |
110 | |
111 if (renderer->isRenderBlock()) { | 107 if (renderer->isRenderBlock()) { |
112 const RenderBlock* renderBlock = toRenderBlock(renderer); | 108 const RenderBlock* renderBlock = toRenderBlock(renderer); |
113 m_shapeInsideInfo = renderBlock->shapeInsideInfo(); | 109 m_shapeInsideInfo = renderBlock->shapeInsideInfo(); |
114 if (!m_shapeInsideInfo && m_next->m_shapeInsideInfo && renderBlock->allo
wsShapeInsideInfoSharing(m_next->m_shapeInsideInfo->owner())) | 110 if (!m_shapeInsideInfo && m_next->m_shapeInsideInfo && renderBlock->allo
wsShapeInsideInfoSharing(m_next->m_shapeInsideInfo->owner())) |
115 m_shapeInsideInfo = m_next->m_shapeInsideInfo; | 111 m_shapeInsideInfo = m_next->m_shapeInsideInfo; |
116 } | 112 } |
117 | 113 |
118 if (!RuntimeEnabledFeatures::repaintAfterLayoutEnabled()) { | 114 if (!RuntimeEnabledFeatures::repaintAfterLayoutEnabled()) { |
119 m_layoutDelta = m_next->m_layoutDelta; | 115 m_layoutDelta = m_next->m_layoutDelta; |
120 #if !ASSERT_DISABLED | 116 #if !ASSERT_DISABLED |
121 m_layoutDeltaXSaturated = m_next->m_layoutDeltaXSaturated; | 117 m_layoutDeltaXSaturated = m_next->m_layoutDeltaXSaturated; |
122 m_layoutDeltaYSaturated = m_next->m_layoutDeltaYSaturated; | 118 m_layoutDeltaYSaturated = m_next->m_layoutDeltaYSaturated; |
123 #endif | 119 #endif |
124 } | 120 } |
125 | 121 |
126 m_isPaginated = m_pageLogicalHeight || m_columnInfo || renderer->isRenderFlo
wThread(); | 122 m_isPaginated = m_pageLogicalHeight || renderer->isRenderFlowThread(); |
127 | |
128 if (lineGrid() && renderer->hasColumns() && renderer->style()->hasInlineColu
mnAxis()) | |
129 computeLineGridPaginationOrigin(renderer); | |
130 | 123 |
131 // If we have a new grid to track, then add it to our set. | 124 // If we have a new grid to track, then add it to our set. |
132 if (renderer->style()->lineGrid() != RenderStyle::initialLineGrid() && rende
rer->isRenderBlockFlow()) | 125 if (renderer->style()->lineGrid() != RenderStyle::initialLineGrid() && rende
rer->isRenderBlockFlow()) |
133 establishLineGrid(toRenderBlockFlow(renderer)); | 126 establishLineGrid(toRenderBlockFlow(renderer)); |
134 | 127 |
135 // FIXME: <http://bugs.webkit.org/show_bug.cgi?id=13443> Apply control clip
if present. | 128 // FIXME: <http://bugs.webkit.org/show_bug.cgi?id=13443> Apply control clip
if present. |
136 } | 129 } |
137 | 130 |
138 LayoutState::LayoutState(RenderObject* root) | 131 LayoutState::LayoutState(RenderObject* root) |
139 : m_clipped(false) | 132 : m_clipped(false) |
140 , m_isPaginated(false) | 133 , m_isPaginated(false) |
141 , m_pageLogicalHeightChanged(false) | 134 , m_pageLogicalHeightChanged(false) |
142 #if !ASSERT_DISABLED | 135 #if !ASSERT_DISABLED |
143 , m_layoutDeltaXSaturated(false) | 136 , m_layoutDeltaXSaturated(false) |
144 , m_layoutDeltaYSaturated(false) | 137 , m_layoutDeltaYSaturated(false) |
145 #endif | 138 #endif |
146 , m_columnInfo(0) | |
147 , m_lineGrid(0) | 139 , m_lineGrid(0) |
148 , m_next(0) | 140 , m_next(0) |
149 , m_shapeInsideInfo(0) | 141 , m_shapeInsideInfo(0) |
150 , m_pageLogicalHeight(0) | 142 , m_pageLogicalHeight(0) |
151 #ifndef NDEBUG | 143 #ifndef NDEBUG |
152 , m_renderer(root) | 144 , m_renderer(root) |
153 #endif | 145 #endif |
154 { | 146 { |
155 RenderObject* container = root->container(); | 147 RenderObject* container = root->container(); |
156 FloatPoint absContentPoint = container->localToAbsolute(FloatPoint(), UseTra
nsforms); | 148 FloatPoint absContentPoint = container->localToAbsolute(FloatPoint(), UseTra
nsforms); |
(...skipping 10 matching lines...) Expand all Loading... |
167 void* LayoutState::operator new(size_t sz) | 159 void* LayoutState::operator new(size_t sz) |
168 { | 160 { |
169 return partitionAlloc(Partitions::getRenderingPartition(), sz); | 161 return partitionAlloc(Partitions::getRenderingPartition(), sz); |
170 } | 162 } |
171 | 163 |
172 void LayoutState::operator delete(void* ptr) | 164 void LayoutState::operator delete(void* ptr) |
173 { | 165 { |
174 partitionFree(ptr); | 166 partitionFree(ptr); |
175 } | 167 } |
176 | 168 |
177 void LayoutState::clearPaginationInformation() | |
178 { | |
179 m_pageLogicalHeight = m_next->m_pageLogicalHeight; | |
180 m_pageOffset = m_next->m_pageOffset; | |
181 m_columnInfo = m_next->m_columnInfo; | |
182 } | |
183 | |
184 LayoutUnit LayoutState::pageLogicalOffset(RenderBox* child, LayoutUnit childLogi
calOffset) const | 169 LayoutUnit LayoutState::pageLogicalOffset(RenderBox* child, LayoutUnit childLogi
calOffset) const |
185 { | 170 { |
186 if (child->isHorizontalWritingMode()) | 171 if (child->isHorizontalWritingMode()) |
187 return m_layoutOffset.height() + childLogicalOffset - m_pageOffset.heigh
t(); | 172 return m_layoutOffset.height() + childLogicalOffset - m_pageOffset.heigh
t(); |
188 return m_layoutOffset.width() + childLogicalOffset - m_pageOffset.width(); | 173 return m_layoutOffset.width() + childLogicalOffset - m_pageOffset.width(); |
189 } | 174 } |
190 | 175 |
191 void LayoutState::addForcedColumnBreak(RenderBox* child, LayoutUnit childLogical
Offset) | |
192 { | |
193 if (!m_columnInfo || m_columnInfo->columnHeight()) | |
194 return; | |
195 m_columnInfo->addForcedBreak(pageLogicalOffset(child, childLogicalOffset)); | |
196 } | |
197 | |
198 void LayoutState::propagateLineGridInfo(RenderBox* renderer) | 176 void LayoutState::propagateLineGridInfo(RenderBox* renderer) |
199 { | 177 { |
200 // Disable line grids for objects we don't support. For now this includes ov
erflow:scroll/auto, inline blocks and | 178 // Disable line grids for objects we don't support. For now this includes ov
erflow:scroll/auto, inline blocks and |
201 // writing mode roots. | 179 // writing mode roots. |
202 if (!m_next || renderer->isUnsplittableForPagination()) | 180 if (!m_next || renderer->isUnsplittableForPagination()) |
203 return; | 181 return; |
204 | 182 |
205 m_lineGrid = m_next->m_lineGrid; | 183 m_lineGrid = m_next->m_lineGrid; |
206 m_lineGridOffset = m_next->m_lineGridOffset; | 184 m_lineGridOffset = m_next->m_lineGridOffset; |
207 m_lineGridPaginationOrigin = m_next->m_lineGridPaginationOrigin; | 185 m_lineGridPaginationOrigin = m_next->m_lineGridPaginationOrigin; |
(...skipping 18 matching lines...) Expand all Loading... |
226 return; | 204 return; |
227 } | 205 } |
228 } | 206 } |
229 } | 207 } |
230 | 208 |
231 // We didn't find an already-established grid with this identifier. Our rend
er object establishes the grid. | 209 // We didn't find an already-established grid with this identifier. Our rend
er object establishes the grid. |
232 m_lineGrid = block; | 210 m_lineGrid = block; |
233 m_lineGridOffset = m_layoutOffset; | 211 m_lineGridOffset = m_layoutOffset; |
234 } | 212 } |
235 | 213 |
236 void LayoutState::computeLineGridPaginationOrigin(RenderBox* renderer) | |
237 { | |
238 // We need to cache a line grid pagination origin so that we understand how
to reset the line grid | |
239 // at the top of each column. | |
240 // Get the current line grid and offset. | |
241 if (!lineGrid() || lineGrid()->style()->writingMode() != renderer->style()->
writingMode()) | |
242 return; | |
243 | |
244 // Get the hypothetical line box used to establish the grid. | |
245 RootInlineBox* lineGridBox = lineGrid()->lineGridBox(); | |
246 if (!lineGridBox) | |
247 return; | |
248 | |
249 bool isHorizontalWritingMode = lineGrid()->isHorizontalWritingMode(); | |
250 | |
251 LayoutUnit lineGridBlockOffset = isHorizontalWritingMode ? lineGridOffset().
height() : lineGridOffset().width(); | |
252 | |
253 // Now determine our position on the grid. Our baseline needs to be adjusted
to the nearest baseline multiple | |
254 // as established by the line box. | |
255 // FIXME: Need to handle crazy line-box-contain values that cause the root l
ine box to not be considered. I assume | |
256 // the grid should honor line-box-contain. | |
257 LayoutUnit gridLineHeight = lineGridBox->lineBottomWithLeading() - lineGridB
ox->lineTopWithLeading(); | |
258 if (!gridLineHeight) | |
259 return; | |
260 | |
261 LayoutUnit firstLineTopWithLeading = lineGridBlockOffset + lineGridBox->line
TopWithLeading(); | |
262 | |
263 if (isPaginated() && pageLogicalHeight()) { | |
264 LayoutUnit pageLogicalTop = renderer->isHorizontalWritingMode() ? m_page
Offset.height() : m_pageOffset.width(); | |
265 if (pageLogicalTop > firstLineTopWithLeading) { | |
266 // Shift to the next highest line grid multiple past the page logica
l top. Cache the delta | |
267 // between this new value and the page logical top as the pagination
origin. | |
268 LayoutUnit remainder = roundToInt(pageLogicalTop - firstLineTopWithL
eading) % roundToInt(gridLineHeight); | |
269 LayoutUnit paginationDelta = gridLineHeight - remainder; | |
270 if (isHorizontalWritingMode) | |
271 m_lineGridPaginationOrigin.setHeight(paginationDelta); | |
272 else | |
273 m_lineGridPaginationOrigin.setWidth(paginationDelta); | |
274 } | |
275 } | |
276 } | |
277 | |
278 } // namespace WebCore | 214 } // namespace WebCore |
OLD | NEW |