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 |