OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2011 Adobe Systems Incorporated. All rights reserved. | 2 * Copyright (C) 2011 Adobe Systems Incorporated. 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 * | 7 * |
8 * 1. Redistributions of source code must retain the above | 8 * 1. Redistributions of source code must retain the above |
9 * copyright notice, this list of conditions and the following | 9 * copyright notice, this list of conditions and the following |
10 * disclaimer. | 10 * disclaimer. |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
213 LayoutRect fragmentRect(layerBoundingBox); | 213 LayoutRect fragmentRect(layerBoundingBox); |
214 fragmentRect.intersect(fragment.paginationClip); | 214 fragmentRect.intersect(fragment.paginationClip); |
215 fragmentRect.moveBy(fragment.paginationOffset); | 215 fragmentRect.moveBy(fragment.paginationOffset); |
216 result.unite(fragmentRect); | 216 result.unite(fragmentRect); |
217 } | 217 } |
218 } | 218 } |
219 | 219 |
220 return result; | 220 return result; |
221 } | 221 } |
222 | 222 |
223 bool RenderFlowThread::cachedOffsetFromLogicalTopOfFirstRegion(const RenderBox*
box, LayoutUnit& result) const | |
224 { | |
225 RenderBoxToOffsetMap::const_iterator offsetIterator = m_boxesToOffsetMap.fin
d(box); | |
226 if (offsetIterator == m_boxesToOffsetMap.end()) | |
227 return false; | |
228 | |
229 result = offsetIterator->value; | |
230 return true; | |
231 } | |
232 | |
233 void RenderFlowThread::setOffsetFromLogicalTopOfFirstRegion(const RenderBox* box
, LayoutUnit offset) | |
234 { | |
235 m_boxesToOffsetMap.set(box, offset); | |
236 } | |
237 | |
238 void RenderFlowThread::clearOffsetFromLogicalTopOfFirstRegion(const RenderBox* b
ox) | |
239 { | |
240 ASSERT(m_boxesToOffsetMap.contains(box)); | |
241 m_boxesToOffsetMap.remove(box); | |
242 } | |
243 | |
244 const RenderBox* RenderFlowThread::currentStatePusherRenderBox() const | |
245 { | |
246 const RenderObject* currentObject = m_statePusherObjectsStack.isEmpty() ? 0
: m_statePusherObjectsStack.last(); | |
247 if (currentObject && currentObject->isBox()) | |
248 return toRenderBox(currentObject); | |
249 | |
250 return 0; | |
251 } | |
252 | |
253 void RenderFlowThread::pushFlowThreadLayoutState(const RenderObject& object) | |
254 { | |
255 if (const RenderBox* currentBoxDescendant = currentStatePusherRenderBox()) { | |
256 LayoutState* layoutState = currentBoxDescendant->view()->layoutState(); | |
257 if (layoutState && layoutState->isPaginated()) { | |
258 ASSERT(layoutState->renderer() == currentBoxDescendant); | |
259 LayoutSize offsetDelta = layoutState->layoutOffset() - layoutState->
pageOffset(); | |
260 setOffsetFromLogicalTopOfFirstRegion(currentBoxDescendant, currentBo
xDescendant->isHorizontalWritingMode() ? offsetDelta.height() : offsetDelta.widt
h()); | |
261 } | |
262 } | |
263 | |
264 ASSERT(!m_statePusherObjectsStack.contains(&object)); | |
265 m_statePusherObjectsStack.add(&object); | |
266 } | |
267 | |
268 void RenderFlowThread::popFlowThreadLayoutState() | |
269 { | |
270 m_statePusherObjectsStack.removeLast(); | |
271 | |
272 if (const RenderBox* currentBoxDescendant = currentStatePusherRenderBox()) { | |
273 LayoutState* layoutState = currentBoxDescendant->view()->layoutState(); | |
274 if (layoutState && layoutState->isPaginated()) | |
275 clearOffsetFromLogicalTopOfFirstRegion(currentBoxDescendant); | |
276 } | |
277 } | |
278 | |
279 LayoutUnit RenderFlowThread::offsetFromLogicalTopOfFirstRegion(const RenderBlock
* currentBlock) const | |
280 { | |
281 // First check if we cached the offset for the block if it's an ancestor con
taining block of the box | |
282 // being currently laid out. | |
283 LayoutUnit offset; | |
284 if (cachedOffsetFromLogicalTopOfFirstRegion(currentBlock, offset)) | |
285 return offset; | |
286 | |
287 // If it's the current box being laid out, use the layout state. | |
288 const RenderBox* currentBoxDescendant = currentStatePusherRenderBox(); | |
289 if (currentBlock == currentBoxDescendant) { | |
290 LayoutState* layoutState = view()->layoutState(); | |
291 ASSERT(layoutState->renderer() == currentBlock); | |
292 ASSERT(layoutState && layoutState->isPaginated()); | |
293 LayoutSize offsetDelta = layoutState->layoutOffset() - layoutState->page
Offset(); | |
294 return currentBoxDescendant->isHorizontalWritingMode() ? offsetDelta.hei
ght() : offsetDelta.width(); | |
295 } | |
296 | |
297 // As a last resort, take the slow path. | |
298 LayoutRect blockRect(0, 0, currentBlock->width(), currentBlock->height()); | |
299 while (currentBlock && !currentBlock->isRenderFlowThread()) { | |
300 RenderBlock* containerBlock = currentBlock->containingBlock(); | |
301 ASSERT(containerBlock); | |
302 if (!containerBlock) | |
303 return 0; | |
304 LayoutPoint currentBlockLocation = currentBlock->location(); | |
305 | |
306 if (containerBlock->style()->writingMode() != currentBlock->style()->wri
tingMode()) { | |
307 // We have to put the block rect in container coordinates | |
308 // and we have to take into account both the container and current b
lock flipping modes | |
309 if (containerBlock->style()->isFlippedBlocksWritingMode()) { | |
310 if (containerBlock->isHorizontalWritingMode()) | |
311 blockRect.setY(currentBlock->height() - blockRect.maxY()); | |
312 else | |
313 blockRect.setX(currentBlock->width() - blockRect.maxX()); | |
314 } | |
315 currentBlock->flipForWritingMode(blockRect); | |
316 } | |
317 blockRect.moveBy(currentBlockLocation); | |
318 currentBlock = containerBlock; | |
319 } | |
320 | |
321 return currentBlock->isHorizontalWritingMode() ? blockRect.y() : blockRect.x
(); | |
322 } | |
323 | |
324 void RenderFlowThread::RegionSearchAdapter::collectIfNeeded(const MultiColumnSet
Interval& interval) | 223 void RenderFlowThread::RegionSearchAdapter::collectIfNeeded(const MultiColumnSet
Interval& interval) |
325 { | 224 { |
326 if (m_result) | 225 if (m_result) |
327 return; | 226 return; |
328 if (interval.low() <= m_offset && interval.high() > m_offset) | 227 if (interval.low() <= m_offset && interval.high() > m_offset) |
329 m_result = interval.data(); | 228 m_result = interval.data(); |
330 } | 229 } |
331 | 230 |
332 } // namespace blink | 231 } // namespace blink |
OLD | NEW |