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 |