| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 1997 Martin Jones (mjones@kde.org) | 2 * Copyright (C) 1997 Martin Jones (mjones@kde.org) |
| 3 * (C) 1997 Torben Weis (weis@kde.org) | 3 * (C) 1997 Torben Weis (weis@kde.org) |
| 4 * (C) 1998 Waldo Bastian (bastian@kde.org) | 4 * (C) 1998 Waldo Bastian (bastian@kde.org) |
| 5 * (C) 1999 Lars Knoll (knoll@kde.org) | 5 * (C) 1999 Lars Knoll (knoll@kde.org) |
| 6 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 6 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
| 7 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All r
ights reserved. | 7 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All r
ights reserved. |
| 8 * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com) | 8 * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com) |
| 9 * | 9 * |
| 10 * This library is free software; you can redistribute it and/or | 10 * This library is free software; you can redistribute it and/or |
| (...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 421 | 421 |
| 422 if (simplifiedLayout()) | 422 if (simplifiedLayout()) |
| 423 return; | 423 return; |
| 424 | 424 |
| 425 recalcSectionsIfNeeded(); | 425 recalcSectionsIfNeeded(); |
| 426 // FIXME: We should do this recalc lazily in borderStart/borderEnd so that w
e don't have to make sure | 426 // FIXME: We should do this recalc lazily in borderStart/borderEnd so that w
e don't have to make sure |
| 427 // to call this before we call borderStart/borderEnd to avoid getting a stal
e value. | 427 // to call this before we call borderStart/borderEnd to avoid getting a stal
e value. |
| 428 recalcBordersInRowDirection(); | 428 recalcBordersInRowDirection(); |
| 429 | 429 |
| 430 LayoutRepainter repainter(*this, checkForRepaintDuringLayout()); | 430 LayoutRepainter repainter(*this, checkForRepaintDuringLayout()); |
| 431 LayoutStateMaintainer statePusher(*this, locationOffset()); | |
| 432 | |
| 433 setLogicalHeight(0); | |
| 434 | |
| 435 LayoutUnit oldLogicalWidth = logicalWidth(); | |
| 436 updateLogicalWidth(); | |
| 437 | |
| 438 SubtreeLayoutScope layouter(this); | 431 SubtreeLayoutScope layouter(this); |
| 439 | 432 |
| 440 if (logicalWidth() != oldLogicalWidth) { | |
| 441 for (unsigned i = 0; i < m_captions.size(); i++) | |
| 442 layouter.setNeedsLayout(m_captions[i]); | |
| 443 } | |
| 444 // FIXME: The optimisation below doesn't work since the internal table | |
| 445 // layout could have changed. we need to add a flag to the table | |
| 446 // layout that tells us if something has changed in the min max | |
| 447 // calculations to do it correctly. | |
| 448 // if ( oldWidth != width() || columns.size() + 1 != columnPos.size() ) | |
| 449 m_tableLayout->layout(); | |
| 450 | |
| 451 LayoutUnit totalSectionLogicalHeight = 0; | |
| 452 LayoutUnit oldTableLogicalTop = 0; | |
| 453 for (unsigned i = 0; i < m_captions.size(); i++) | |
| 454 oldTableLogicalTop += m_captions[i]->logicalHeight() + m_captions[i]->ma
rginBefore() + m_captions[i]->marginAfter(); | |
| 455 | |
| 456 bool collapsing = collapseBorders(); | |
| 457 | |
| 458 for (RenderObject* child = firstChild(); child; child = child->nextSibling()
) { | |
| 459 if (!child->needsLayout() && child->isBox()) | |
| 460 toRenderBox(child)->markForPaginationRelayoutIfNeeded(layouter); | |
| 461 if (child->isTableSection()) { | |
| 462 RenderTableSection* section = toRenderTableSection(child); | |
| 463 if (m_columnLogicalWidthChanged) | |
| 464 layouter.setChildNeedsLayout(section); | |
| 465 section->layoutIfNeeded(); | |
| 466 totalSectionLogicalHeight += section->calcRowLogicalHeight(); | |
| 467 if (collapsing) | |
| 468 section->recalcOuterBorder(); | |
| 469 ASSERT(!section->needsLayout()); | |
| 470 } else if (child->isRenderTableCol()) { | |
| 471 child->layoutIfNeeded(); | |
| 472 ASSERT(!child->needsLayout()); | |
| 473 } else { | |
| 474 // FIXME: We should never have other type of children (they should b
e wrapped in an | |
| 475 // anonymous table section) but our code is too crazy and this can h
appen in practice. | |
| 476 // Until this is fixed, let's make sure we don't leave non laid out
children in the tree. | |
| 477 child->layoutIfNeeded(); | |
| 478 } | |
| 479 } | |
| 480 | 433 |
| 481 // If any table section moved vertically, we will just repaint everything fr
om that | 434 // If any table section moved vertically, we will just repaint everything fr
om that |
| 482 // section down (it is quite unlikely that any of the following sections | 435 // section down (it is quite unlikely that any of the following sections |
| 483 // did not shift). | 436 // did not shift). |
| 484 bool sectionMoved = false; | 437 bool sectionMoved = false; |
| 485 LayoutUnit movedSectionLogicalTop = 0; | 438 LayoutUnit movedSectionLogicalTop = 0; |
| 439 { |
| 440 LayoutStateMaintainer statePusher(*this, locationOffset()); |
| 486 | 441 |
| 487 // FIXME: Collapse caption margin. | 442 setLogicalHeight(0); |
| 488 if (!m_captions.isEmpty()) { | 443 |
| 444 LayoutUnit oldLogicalWidth = logicalWidth(); |
| 445 updateLogicalWidth(); |
| 446 |
| 447 if (logicalWidth() != oldLogicalWidth) { |
| 448 for (unsigned i = 0; i < m_captions.size(); i++) |
| 449 layouter.setNeedsLayout(m_captions[i]); |
| 450 } |
| 451 // FIXME: The optimisation below doesn't work since the internal table |
| 452 // layout could have changed. We need to add a flag to the table |
| 453 // layout that tells us if something has changed in the min max |
| 454 // calculations to do it correctly. |
| 455 // if ( oldWidth != width() || columns.size() + 1 != columnPos.size() ) |
| 456 m_tableLayout->layout(); |
| 457 |
| 458 LayoutUnit totalSectionLogicalHeight = 0; |
| 459 LayoutUnit oldTableLogicalTop = 0; |
| 460 for (unsigned i = 0; i < m_captions.size(); i++) |
| 461 oldTableLogicalTop += m_captions[i]->logicalHeight() + m_captions[i]
->marginBefore() + m_captions[i]->marginAfter(); |
| 462 |
| 463 bool collapsing = collapseBorders(); |
| 464 |
| 465 for (RenderObject* child = firstChild(); child; child = child->nextSibli
ng()) { |
| 466 if (child->isTableSection()) { |
| 467 RenderTableSection* section = toRenderTableSection(child); |
| 468 if (m_columnLogicalWidthChanged) |
| 469 layouter.setChildNeedsLayout(section); |
| 470 section->layoutIfNeeded(); |
| 471 totalSectionLogicalHeight += section->calcRowLogicalHeight(); |
| 472 if (collapsing) |
| 473 section->recalcOuterBorder(); |
| 474 ASSERT(!section->needsLayout()); |
| 475 } else if (child->isRenderTableCol()) { |
| 476 child->layoutIfNeeded(); |
| 477 ASSERT(!child->needsLayout()); |
| 478 } else { |
| 479 // FIXME: We should never have other type of children (they shou
ld be wrapped in an |
| 480 // anonymous table section) but our code is too crazy and this c
an happen in practice. |
| 481 // Until this is fixed, let's make sure we don't leave non laid
out children in the tree. |
| 482 child->layoutIfNeeded(); |
| 483 } |
| 484 } |
| 485 |
| 486 // FIXME: Collapse caption margin. |
| 487 if (!m_captions.isEmpty()) { |
| 488 for (unsigned i = 0; i < m_captions.size(); i++) { |
| 489 if (m_captions[i]->style()->captionSide() == CAPBOTTOM) |
| 490 continue; |
| 491 layoutCaption(m_captions[i]); |
| 492 } |
| 493 if (logicalHeight() != oldTableLogicalTop) { |
| 494 sectionMoved = true; |
| 495 movedSectionLogicalTop = min(logicalHeight(), oldTableLogicalTop
); |
| 496 } |
| 497 } |
| 498 |
| 499 LayoutUnit borderAndPaddingBefore = borderBefore() + (collapsing ? Layou
tUnit() : paddingBefore()); |
| 500 LayoutUnit borderAndPaddingAfter = borderAfter() + (collapsing ? LayoutU
nit() : paddingAfter()); |
| 501 |
| 502 setLogicalHeight(logicalHeight() + borderAndPaddingBefore); |
| 503 |
| 504 if (!isOutOfFlowPositioned()) |
| 505 updateLogicalHeight(); |
| 506 |
| 507 LayoutUnit computedLogicalHeight = 0; |
| 508 |
| 509 Length logicalHeightLength = style()->logicalHeight(); |
| 510 if (logicalHeightLength.isIntrinsic() || (logicalHeightLength.isSpecifie
d() && logicalHeightLength.isPositive())) |
| 511 computedLogicalHeight = convertStyleLogicalHeightToComputedHeight(lo
gicalHeightLength); |
| 512 |
| 513 Length logicalMaxHeightLength = style()->logicalMaxHeight(); |
| 514 if (logicalMaxHeightLength.isIntrinsic() || (logicalMaxHeightLength.isSp
ecified() && !logicalMaxHeightLength.isNegative())) { |
| 515 LayoutUnit computedMaxLogicalHeight = convertStyleLogicalHeightToCom
putedHeight(logicalMaxHeightLength); |
| 516 computedLogicalHeight = min(computedLogicalHeight, computedMaxLogica
lHeight); |
| 517 } |
| 518 |
| 519 Length logicalMinHeightLength = style()->logicalMinHeight(); |
| 520 if (logicalMinHeightLength.isIntrinsic() || (logicalMinHeightLength.isSp
ecified() && !logicalMinHeightLength.isNegative())) { |
| 521 LayoutUnit computedMinLogicalHeight = convertStyleLogicalHeightToCom
putedHeight(logicalMinHeightLength); |
| 522 computedLogicalHeight = max(computedLogicalHeight, computedMinLogica
lHeight); |
| 523 } |
| 524 |
| 525 distributeExtraLogicalHeight(floorToInt(computedLogicalHeight - totalSec
tionLogicalHeight)); |
| 526 |
| 527 for (RenderTableSection* section = topSection(); section; section = sect
ionBelow(section)) |
| 528 section->layoutRows(); |
| 529 |
| 530 if (!topSection() && computedLogicalHeight > totalSectionLogicalHeight &
& !document().inQuirksMode()) { |
| 531 // Completely empty tables (with no sections or anything) should at
least honor specified height |
| 532 // in strict mode. |
| 533 setLogicalHeight(logicalHeight() + computedLogicalHeight); |
| 534 } |
| 535 |
| 536 LayoutUnit sectionLogicalLeft = style()->isLeftToRightDirection() ? bord
erStart() : borderEnd(); |
| 537 if (!collapsing) |
| 538 sectionLogicalLeft += style()->isLeftToRightDirection() ? paddingSta
rt() : paddingEnd(); |
| 539 |
| 540 // position the table sections |
| 541 RenderTableSection* section = topSection(); |
| 542 while (section) { |
| 543 if (!sectionMoved && section->logicalTop() != logicalHeight()) { |
| 544 sectionMoved = true; |
| 545 movedSectionLogicalTop = min(logicalHeight(), section->logicalTo
p()) + (style()->isHorizontalWritingMode() ? section->visualOverflowRect().y() :
section->visualOverflowRect().x()); |
| 546 } |
| 547 section->setLogicalLocation(LayoutPoint(sectionLogicalLeft, logicalH
eight())); |
| 548 |
| 549 setLogicalHeight(logicalHeight() + section->logicalHeight()); |
| 550 section = sectionBelow(section); |
| 551 } |
| 552 |
| 553 setLogicalHeight(logicalHeight() + borderAndPaddingAfter); |
| 554 |
| 489 for (unsigned i = 0; i < m_captions.size(); i++) { | 555 for (unsigned i = 0; i < m_captions.size(); i++) { |
| 490 if (m_captions[i]->style()->captionSide() == CAPBOTTOM) | 556 if (m_captions[i]->style()->captionSide() != CAPBOTTOM) |
| 491 continue; | 557 continue; |
| 492 layoutCaption(m_captions[i]); | 558 layoutCaption(m_captions[i]); |
| 493 } | 559 } |
| 494 if (logicalHeight() != oldTableLogicalTop) { | 560 |
| 495 sectionMoved = true; | 561 if (isOutOfFlowPositioned()) |
| 496 movedSectionLogicalTop = min(logicalHeight(), oldTableLogicalTop); | 562 updateLogicalHeight(); |
| 497 } | 563 |
| 564 // table can be containing block of positioned elements. |
| 565 // FIXME: Only pass true if width or height changed. |
| 566 layoutPositionedObjects(true); |
| 567 |
| 568 updateLayerTransform(); |
| 569 |
| 570 // Layout was changed, so probably borders too. |
| 571 invalidateCollapsedBorders(); |
| 572 |
| 573 computeOverflow(clientLogicalBottom()); |
| 498 } | 574 } |
| 499 | 575 |
| 500 LayoutUnit borderAndPaddingBefore = borderBefore() + (collapsing ? LayoutUni
t() : paddingBefore()); | |
| 501 LayoutUnit borderAndPaddingAfter = borderAfter() + (collapsing ? LayoutUnit(
) : paddingAfter()); | |
| 502 | |
| 503 setLogicalHeight(logicalHeight() + borderAndPaddingBefore); | |
| 504 | |
| 505 if (!isOutOfFlowPositioned()) | |
| 506 updateLogicalHeight(); | |
| 507 | |
| 508 LayoutUnit computedLogicalHeight = 0; | |
| 509 | |
| 510 Length logicalHeightLength = style()->logicalHeight(); | |
| 511 if (logicalHeightLength.isIntrinsic() || (logicalHeightLength.isSpecified()
&& logicalHeightLength.isPositive())) | |
| 512 computedLogicalHeight = convertStyleLogicalHeightToComputedHeight(logica
lHeightLength); | |
| 513 | |
| 514 Length logicalMaxHeightLength = style()->logicalMaxHeight(); | |
| 515 if (logicalMaxHeightLength.isIntrinsic() || (logicalMaxHeightLength.isSpecif
ied() && !logicalMaxHeightLength.isNegative())) { | |
| 516 LayoutUnit computedMaxLogicalHeight = convertStyleLogicalHeightToCompute
dHeight(logicalMaxHeightLength); | |
| 517 computedLogicalHeight = min(computedLogicalHeight, computedMaxLogicalHei
ght); | |
| 518 } | |
| 519 | |
| 520 Length logicalMinHeightLength = style()->logicalMinHeight(); | |
| 521 if (logicalMinHeightLength.isIntrinsic() || (logicalMinHeightLength.isSpecif
ied() && !logicalMinHeightLength.isNegative())) { | |
| 522 LayoutUnit computedMinLogicalHeight = convertStyleLogicalHeightToCompute
dHeight(logicalMinHeightLength); | |
| 523 computedLogicalHeight = max(computedLogicalHeight, computedMinLogicalHei
ght); | |
| 524 } | |
| 525 | |
| 526 distributeExtraLogicalHeight(floorToInt(computedLogicalHeight - totalSection
LogicalHeight)); | |
| 527 | |
| 528 for (RenderTableSection* section = topSection(); section; section = sectionB
elow(section)) | |
| 529 section->layoutRows(); | |
| 530 | |
| 531 if (!topSection() && computedLogicalHeight > totalSectionLogicalHeight && !d
ocument().inQuirksMode()) { | |
| 532 // Completely empty tables (with no sections or anything) should at leas
t honor specified height | |
| 533 // in strict mode. | |
| 534 setLogicalHeight(logicalHeight() + computedLogicalHeight); | |
| 535 } | |
| 536 | |
| 537 LayoutUnit sectionLogicalLeft = style()->isLeftToRightDirection() ? borderSt
art() : borderEnd(); | |
| 538 if (!collapsing) | |
| 539 sectionLogicalLeft += style()->isLeftToRightDirection() ? paddingStart()
: paddingEnd(); | |
| 540 | |
| 541 // position the table sections | |
| 542 RenderTableSection* section = topSection(); | |
| 543 while (section) { | |
| 544 if (!sectionMoved && section->logicalTop() != logicalHeight()) { | |
| 545 sectionMoved = true; | |
| 546 movedSectionLogicalTop = min(logicalHeight(), section->logicalTop())
+ (style()->isHorizontalWritingMode() ? section->visualOverflowRect().y() : sec
tion->visualOverflowRect().x()); | |
| 547 } | |
| 548 section->setLogicalLocation(LayoutPoint(sectionLogicalLeft, logicalHeigh
t())); | |
| 549 | |
| 550 setLogicalHeight(logicalHeight() + section->logicalHeight()); | |
| 551 section = sectionBelow(section); | |
| 552 } | |
| 553 | |
| 554 setLogicalHeight(logicalHeight() + borderAndPaddingAfter); | |
| 555 | |
| 556 for (unsigned i = 0; i < m_captions.size(); i++) { | |
| 557 if (m_captions[i]->style()->captionSide() != CAPBOTTOM) | |
| 558 continue; | |
| 559 layoutCaption(m_captions[i]); | |
| 560 } | |
| 561 | |
| 562 if (isOutOfFlowPositioned()) | |
| 563 updateLogicalHeight(); | |
| 564 | |
| 565 // table can be containing block of positioned elements. | |
| 566 // FIXME: Only pass true if width or height changed. | |
| 567 layoutPositionedObjects(true); | |
| 568 | |
| 569 updateLayerTransform(); | |
| 570 | |
| 571 // Layout was changed, so probably borders too. | |
| 572 invalidateCollapsedBorders(); | |
| 573 | |
| 574 computeOverflow(clientLogicalBottom()); | |
| 575 | |
| 576 statePusher.pop(); | |
| 577 | |
| 578 if (view()->layoutState()->pageLogicalHeight()) | 576 if (view()->layoutState()->pageLogicalHeight()) |
| 579 setPageLogicalOffset(view()->layoutState()->pageLogicalOffset(*this, log
icalTop())); | 577 setPageLogicalOffset(view()->layoutState()->pageLogicalOffset(*this, log
icalTop())); |
| 580 | 578 |
| 581 bool didFullRepaint = repainter.repaintAfterLayout(); | 579 bool didFullRepaint = repainter.repaintAfterLayout(); |
| 582 // Repaint with our new bounds if they are different from our old bounds. | 580 // Repaint with our new bounds if they are different from our old bounds. |
| 583 if (!RuntimeEnabledFeatures::repaintAfterLayoutEnabled() | 581 if (!RuntimeEnabledFeatures::repaintAfterLayoutEnabled() |
| 584 && !didFullRepaint && sectionMoved) { | 582 && !didFullRepaint && sectionMoved) { |
| 585 if (style()->isHorizontalWritingMode()) | 583 if (style()->isHorizontalWritingMode()) |
| 586 repaintRectangle(LayoutRect(visualOverflowRect().x(), movedSectionLo
gicalTop, visualOverflowRect().width(), visualOverflowRect().maxY() - movedSecti
onLogicalTop)); | 584 repaintRectangle(LayoutRect(visualOverflowRect().x(), movedSectionLo
gicalTop, visualOverflowRect().width(), visualOverflowRect().maxY() - movedSecti
onLogicalTop)); |
| 587 else | 585 else |
| (...skipping 869 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1457 const BorderValue& RenderTable::tableEndBorderAdjoiningCell(const RenderTableCel
l* cell) const | 1455 const BorderValue& RenderTable::tableEndBorderAdjoiningCell(const RenderTableCel
l* cell) const |
| 1458 { | 1456 { |
| 1459 ASSERT(cell->isFirstOrLastCellInRow()); | 1457 ASSERT(cell->isFirstOrLastCellInRow()); |
| 1460 if (hasSameDirectionAs(cell->row())) | 1458 if (hasSameDirectionAs(cell->row())) |
| 1461 return style()->borderEnd(); | 1459 return style()->borderEnd(); |
| 1462 | 1460 |
| 1463 return style()->borderStart(); | 1461 return style()->borderStart(); |
| 1464 } | 1462 } |
| 1465 | 1463 |
| 1466 } | 1464 } |
| OLD | NEW |