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