OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2012 Apple Inc. All rights reserved. | 2 * Copyright (C) 2012 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 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
349 columnSet->detachRegion(); | 349 columnSet->detachRegion(); |
350 multiColumnBlockFlow()->resetMultiColumnFlowThread(); | 350 multiColumnBlockFlow()->resetMultiColumnFlowThread(); |
351 RenderFlowThread::willBeRemovedFromTree(); | 351 RenderFlowThread::willBeRemovedFromTree(); |
352 } | 352 } |
353 | 353 |
354 bool RenderMultiColumnFlowThread::hasColumnSpanner(const RenderObject* renderer)
const | 354 bool RenderMultiColumnFlowThread::hasColumnSpanner(const RenderObject* renderer)
const |
355 { | 355 { |
356 return m_spannerMap.get(renderer); | 356 return m_spannerMap.get(renderer); |
357 } | 357 } |
358 | 358 |
359 LayoutUnit RenderMultiColumnFlowThread::spannerLogicalTopAdjustment(RenderBox* r
enderer, LayoutUnit logicalTop) const | 359 LayoutUnit RenderMultiColumnFlowThread::enterColumnSpanner(RenderBox* renderer,
LayoutUnit logicalTop) |
360 { | 360 { |
361 ASSERT(m_spannerMap.get(renderer) == m_lastSetWorkedOn); | 361 ASSERT(renderer->isDescendantOf(this)); |
362 RenderMultiColumnSet* previousSet = m_lastSetWorkedOn->previousSiblingMultiC
olumnSet(); | 362 RenderMultiColumnSpannerSet* spannerSet = m_spannerMap.get(renderer); |
363 if (!previousSet || previousSet->isRenderMultiColumnSpannerSet() || !previou
sSet->pageLogicalHeight()) | 363 ASSERT(spannerSet); |
| 364 RenderMultiColumnSet* previousSet = spannerSet->previousSiblingMultiColumnSe
t(); |
| 365 if (!previousSet) { |
| 366 // The first set is entered at the beginning of flow thread layout. If t
he first set happens |
| 367 // to be a spanner, we have nothing more to do here. |
364 return LayoutUnit(); | 368 return LayoutUnit(); |
| 369 } |
365 | 370 |
366 RenderBlock* cb = renderer->containingBlock(); | 371 RenderBlock* cb = renderer->containingBlock(); |
367 LayoutUnit logicalTopInFlowThread = cb->offsetFromLogicalTopOfFirstPage() +
logicalTop; | 372 LayoutUnit logicalTopInFlowThread = cb->offsetFromLogicalTopOfFirstPage() +
logicalTop; |
368 LayoutUnit columnLogicalTopInFlowThread = previousSet->pageLogicalTopForOffs
et(logicalTopInFlowThread); | 373 LayoutUnit adjustment; |
369 if (columnLogicalTopInFlowThread == logicalTopInFlowThread) | 374 if (!previousSet->isRenderMultiColumnSpannerSet() && previousSet->pageLogica
lHeight()) { |
370 return LayoutUnit(); // Exactly at the top of a column. No need to adjus
t. | 375 // Pad flow thread offset to a column boundary, so that contents that's
supposed to come |
371 return columnLogicalTopInFlowThread + previousSet->pageLogicalHeight() - log
icalTopInFlowThread; | 376 // after the spanner (or the spanner itself) don't bleed into the column
preceding the |
372 } | 377 // spanner. |
373 | 378 LayoutUnit columnLogicalTopInFlowThread = previousSet->pageLogicalTopFor
Offset(logicalTopInFlowThread); |
374 void RenderMultiColumnFlowThread::enterColumnSpanner(RenderBox* renderer, Layout
Unit& logicalTop) | 379 if (columnLogicalTopInFlowThread != logicalTopInFlowThread) { |
375 { | 380 adjustment = columnLogicalTopInFlowThread + previousSet->pageLogical
Height() - logicalTopInFlowThread; |
376 ASSERT(m_spannerMap.get(renderer)); | 381 logicalTopInFlowThread += adjustment; |
377 ASSERT(renderer->isDescendantOf(this)); | 382 } |
378 | |
379 if (m_spannerMap.get(renderer) == m_lastSetWorkedOn) { | |
380 // The first set is entered at the beginning of flow thread layout. If t
he first set happens | |
381 // to be a spanner, we have nothing more to do here. | |
382 ASSERT(!m_lastSetWorkedOn->previousSiblingMultiColumnSet()); | |
383 return; | |
384 } | 383 } |
385 | 384 |
386 RenderMultiColumnSet* previousSet = m_lastSetWorkedOn; | |
387 m_lastSetWorkedOn = m_lastSetWorkedOn->nextSiblingMultiColumnSet(); | |
388 ASSERT(m_lastSetWorkedOn); | |
389 ASSERT(m_lastSetWorkedOn->isRenderMultiColumnSpannerSet()); | |
390 ASSERT(toRenderMultiColumnSpannerSet(m_lastSetWorkedOn)->renderer() == rende
rer); | |
391 | |
392 logicalTop += spannerLogicalTopAdjustment(renderer, logicalTop); | |
393 RenderBlock* cb = renderer->containingBlock(); | |
394 LayoutUnit logicalTopInFlowThread = cb->offsetFromLogicalTopOfFirstPage() +
logicalTop; | |
395 if (!previousSet->isRenderMultiColumnSpannerSet()) | 385 if (!previousSet->isRenderMultiColumnSpannerSet()) |
396 previousSet->endFlow(logicalTopInFlowThread); | 386 previousSet->endFlow(logicalTopInFlowThread); |
397 m_lastSetWorkedOn->beginFlow(logicalTopInFlowThread); | 387 spannerSet->beginFlow(logicalTopInFlowThread); |
| 388 |
| 389 m_lastSetWorkedOn = spannerSet; |
| 390 return adjustment; |
398 } | 391 } |
399 | 392 |
400 void RenderMultiColumnFlowThread::leaveColumnSpanner(RenderBox* renderer, Layout
Unit logicalBottom) | 393 void RenderMultiColumnFlowThread::leaveColumnSpanner(RenderBox* renderer, Layout
Unit logicalBottom) |
401 { | 394 { |
| 395 ASSERT(m_lastSetWorkedOn == m_spannerMap.get(renderer)); |
| 396 |
402 RenderBlock* cb = renderer->containingBlock(); | 397 RenderBlock* cb = renderer->containingBlock(); |
403 LayoutUnit logicalBottomInFlowThread = cb->offsetFromLogicalTopOfFirstPage()
+ logicalBottom; | 398 LayoutUnit logicalBottomInFlowThread = cb->offsetFromLogicalTopOfFirstPage()
+ logicalBottom; |
404 m_lastSetWorkedOn->endFlow(logicalBottomInFlowThread); | 399 m_lastSetWorkedOn->endFlow(logicalBottomInFlowThread); |
405 RenderMultiColumnSet* nextSet = m_lastSetWorkedOn->nextSiblingMultiColumnSet
(); | 400 RenderMultiColumnSet* nextSet = m_lastSetWorkedOn->nextSiblingMultiColumnSet
(); |
406 if (nextSet && !nextSet->isRenderMultiColumnSpannerSet()) { | 401 if (nextSet) { |
407 m_lastSetWorkedOn = nextSet; | 402 m_lastSetWorkedOn = nextSet; |
408 if (m_lastSetWorkedOn) | 403 if (!m_lastSetWorkedOn->isRenderMultiColumnSpannerSet()) |
409 m_lastSetWorkedOn->beginFlow(logicalBottomInFlowThread); | 404 m_lastSetWorkedOn->beginFlow(logicalBottomInFlowThread); |
410 } | 405 } |
411 } | 406 } |
412 | 407 |
413 void RenderMultiColumnFlowThread::flowThreadDescendantInserted(RenderObject* des
cendant) | 408 void RenderMultiColumnFlowThread::flowThreadDescendantInserted(RenderObject* des
cendant) |
414 { | 409 { |
415 ASSERT(!m_beingEvacuated); | 410 ASSERT(!m_beingEvacuated); |
416 RenderObject* subtreeRoot = descendant; | 411 RenderObject* subtreeRoot = descendant; |
417 RenderBlockFlow* multicolContainer = multiColumnBlockFlow(); | 412 RenderBlockFlow* multicolContainer = multiColumnBlockFlow(); |
418 for (; descendant; descendant = descendant->nextInPreOrder(subtreeRoot)) { | 413 for (; descendant; descendant = descendant->nextInPreOrder(subtreeRoot)) { |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
494 invalidateRegions(); | 489 invalidateRegions(); |
495 } | 490 } |
496 } | 491 } |
497 m_spannerMap.remove(descendant); | 492 m_spannerMap.remove(descendant); |
498 spanner->destroy(); | 493 spanner->destroy(); |
499 } | 494 } |
500 // FIXME: do we care that we might end up with (harmless) empty sets her
e? | 495 // FIXME: do we care that we might end up with (harmless) empty sets her
e? |
501 } | 496 } |
502 } | 497 } |
503 | 498 |
| 499 void RenderMultiColumnFlowThread::flowThreadDescendantStyleDidChange(RenderObjec
t* descendant) |
| 500 { |
| 501 ASSERT(descendant->isDescendantOf(this)); |
| 502 if (RenderMultiColumnSpannerSet* spanner = m_spannerMap.get(descendant)) { |
| 503 RefPtr<RenderStyle> newStyle = RenderStyle::clone(style()); |
| 504 spanner->updateMarginProperties(newStyle.get(), descendant); |
| 505 setStyle(newStyle); |
| 506 } |
| 507 } |
| 508 |
504 void RenderMultiColumnFlowThread::computeLogicalHeight(LayoutUnit logicalHeight,
LayoutUnit logicalTop, LogicalExtentComputedValues& computedValues) const | 509 void RenderMultiColumnFlowThread::computeLogicalHeight(LayoutUnit logicalHeight,
LayoutUnit logicalTop, LogicalExtentComputedValues& computedValues) const |
505 { | 510 { |
506 // We simply remain at our intrinsic height. | 511 // We simply remain at our intrinsic height. |
507 computedValues.m_extent = logicalHeight; | 512 computedValues.m_extent = logicalHeight; |
508 computedValues.m_position = logicalTop; | 513 computedValues.m_position = logicalTop; |
509 } | 514 } |
510 | 515 |
511 void RenderMultiColumnFlowThread::updateLogicalWidth() | 516 void RenderMultiColumnFlowThread::updateLogicalWidth() |
512 { | 517 { |
513 LayoutUnit columnWidth; | 518 LayoutUnit columnWidth; |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
596 } | 601 } |
597 | 602 |
598 bool RenderMultiColumnFlowThread::isPageLogicalHeightKnown() const | 603 bool RenderMultiColumnFlowThread::isPageLogicalHeightKnown() const |
599 { | 604 { |
600 if (RenderMultiColumnSet* columnSet = lastMultiColumnSet()) | 605 if (RenderMultiColumnSet* columnSet = lastMultiColumnSet()) |
601 return columnSet->pageLogicalHeight(); | 606 return columnSet->pageLogicalHeight(); |
602 return false; | 607 return false; |
603 } | 608 } |
604 | 609 |
605 } | 610 } |
OLD | NEW |