| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2000 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 2000 Lars Knoll (knoll@kde.org) |
| 3 * Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All r
ight reserved. | 3 * Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All r
ight reserved. |
| 4 * Copyright (C) 2010 Google Inc. All rights reserved. | 4 * Copyright (C) 2010 Google Inc. All rights reserved. |
| 5 * | 5 * |
| 6 * This library is free software; you can redistribute it and/or | 6 * This library is free software; you can redistribute it and/or |
| 7 * modify it under the terms of the GNU Library General Public | 7 * modify it under the terms of the GNU Library General Public |
| 8 * License as published by the Free Software Foundation; either | 8 * License as published by the Free Software Foundation; either |
| 9 * version 2 of the License, or (at your option) any later version. | 9 * version 2 of the License, or (at your option) any later version. |
| 10 * | 10 * |
| (...skipping 721 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 732 // Compute our overflow now. | 732 // Compute our overflow now. |
| 733 lineBox->computeOverflow(lineBox->lineTop(), lineBox->lineBottom(), textBoxD
ataMap); | 733 lineBox->computeOverflow(lineBox->lineTop(), lineBox->lineBottom(), textBoxD
ataMap); |
| 734 | 734 |
| 735 return lineBox; | 735 return lineBox; |
| 736 } | 736 } |
| 737 | 737 |
| 738 static void deleteLineRange(LineLayoutState& layoutState, RootInlineBox* startLi
ne, RootInlineBox* stopLine = 0) | 738 static void deleteLineRange(LineLayoutState& layoutState, RootInlineBox* startLi
ne, RootInlineBox* stopLine = 0) |
| 739 { | 739 { |
| 740 RootInlineBox* boxToDelete = startLine; | 740 RootInlineBox* boxToDelete = startLine; |
| 741 while (boxToDelete && boxToDelete != stopLine) { | 741 while (boxToDelete && boxToDelete != stopLine) { |
| 742 layoutState.updatePaintInvalidationRangeFromBox(boxToDelete); | |
| 743 // Note: deleteLineRange(firstRootBox()) is not identical to deleteLineB
oxTree(). | 742 // Note: deleteLineRange(firstRootBox()) is not identical to deleteLineB
oxTree(). |
| 744 // deleteLineBoxTree uses nextLineBox() instead of nextRootBox() when tr
aversing. | 743 // deleteLineBoxTree uses nextLineBox() instead of nextRootBox() when tr
aversing. |
| 745 RootInlineBox* next = boxToDelete->nextRootBox(); | 744 RootInlineBox* next = boxToDelete->nextRootBox(); |
| 746 boxToDelete->deleteLine(); | 745 boxToDelete->deleteLine(); |
| 747 boxToDelete = next; | 746 boxToDelete = next; |
| 748 } | 747 } |
| 749 } | 748 } |
| 750 | 749 |
| 751 void LayoutBlockFlow::layoutRunsAndFloats(LineLayoutState& layoutState) | 750 void LayoutBlockFlow::layoutRunsAndFloats(LineLayoutState& layoutState) |
| 752 { | 751 { |
| 753 // We want to skip ahead to the first dirty line | 752 // We want to skip ahead to the first dirty line |
| 754 InlineBidiResolver resolver; | 753 InlineBidiResolver resolver; |
| 755 RootInlineBox* startLine = determineStartPosition(layoutState, resolver); | 754 RootInlineBox* startLine = determineStartPosition(layoutState, resolver); |
| 756 | 755 |
| 757 if (containsFloats()) | 756 if (containsFloats()) |
| 758 layoutState.setLastFloat(m_floatingObjects->set().last().get()); | 757 layoutState.setLastFloat(m_floatingObjects->set().last().get()); |
| 759 | 758 |
| 760 // We also find the first clean line and extract these lines. We will add t
hem back | 759 // We also find the first clean line and extract these lines. We will add t
hem back |
| 761 // if we determine that we're able to synchronize after handling all our dir
ty lines. | 760 // if we determine that we're able to synchronize after handling all our dir
ty lines. |
| 762 InlineIterator cleanLineStart; | 761 InlineIterator cleanLineStart; |
| 763 BidiStatus cleanLineBidiStatus; | 762 BidiStatus cleanLineBidiStatus; |
| 764 if (!layoutState.isFullLayout() && startLine) | 763 if (!layoutState.isFullLayout() && startLine) |
| 765 determineEndPosition(layoutState, startLine, cleanLineStart, cleanLineBi
diStatus); | 764 determineEndPosition(layoutState, startLine, cleanLineStart, cleanLineBi
diStatus); |
| 766 | 765 |
| 767 if (startLine) { | 766 if (startLine) |
| 768 if (!layoutState.usesPaintInvalidationBounds()) | |
| 769 layoutState.setPaintInvalidationRange(logicalHeight()); | |
| 770 deleteLineRange(layoutState, startLine); | 767 deleteLineRange(layoutState, startLine); |
| 771 } | |
| 772 | 768 |
| 773 layoutRunsAndFloatsInRange(layoutState, resolver, cleanLineStart, cleanLineB
idiStatus); | 769 layoutRunsAndFloatsInRange(layoutState, resolver, cleanLineStart, cleanLineB
idiStatus); |
| 774 linkToEndLineIfNeeded(layoutState); | 770 linkToEndLineIfNeeded(layoutState); |
| 775 markDirtyFloatsForPaintInvalidation(layoutState.floats()); | 771 markDirtyFloatsForPaintInvalidation(layoutState.floats()); |
| 776 } | 772 } |
| 777 | 773 |
| 778 // Before restarting the layout loop with a new logicalHeight, remove all floats
that were added and reset the resolver. | 774 // Before restarting the layout loop with a new logicalHeight, remove all floats
that were added and reset the resolver. |
| 779 inline const InlineIterator& LayoutBlockFlow::restartLayoutRunsAndFloatsInRange(
LayoutUnit oldLogicalHeight, LayoutUnit newLogicalHeight, FloatingObject* lastF
loatFromPreviousLine, InlineBidiResolver& resolver, const InlineIterator& oldEn
d) | 775 inline const InlineIterator& LayoutBlockFlow::restartLayoutRunsAndFloatsInRange(
LayoutUnit oldLogicalHeight, LayoutUnit newLogicalHeight, FloatingObject* lastF
loatFromPreviousLine, InlineBidiResolver& resolver, const InlineIterator& oldEn
d) |
| 780 { | 776 { |
| 781 removeFloatingObjectsBelow(lastFloatFromPreviousLine, oldLogicalHeight); | 777 removeFloatingObjectsBelow(lastFloatFromPreviousLine, oldLogicalHeight); |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 901 RootInlineBox* lineBox = createLineBoxesFromBidiRuns(resolver.status
().context->level(), bidiRuns, endOfLine, layoutState.lineInfo(), verticalPositi
onCache, trailingSpaceRun, wordMeasurements); | 897 RootInlineBox* lineBox = createLineBoxesFromBidiRuns(resolver.status
().context->level(), bidiRuns, endOfLine, layoutState.lineInfo(), verticalPositi
onCache, trailingSpaceRun, wordMeasurements); |
| 902 | 898 |
| 903 bidiRuns.deleteRuns(); | 899 bidiRuns.deleteRuns(); |
| 904 resolver.markCurrentRunEmpty(); // FIXME: This can probably be repla
ced by an ASSERT (or just removed). | 900 resolver.markCurrentRunEmpty(); // FIXME: This can probably be repla
ced by an ASSERT (or just removed). |
| 905 | 901 |
| 906 // If we decided to re-create the line due to pagination, we better
have a new line now. | 902 // If we decided to re-create the line due to pagination, we better
have a new line now. |
| 907 ASSERT(lineBox || !paginationStrutFromDeletedLine); | 903 ASSERT(lineBox || !paginationStrutFromDeletedLine); |
| 908 | 904 |
| 909 if (lineBox) { | 905 if (lineBox) { |
| 910 lineBox->setLineBreakInfo(endOfLine.getLineLayoutItem(), endOfLi
ne.offset(), resolver.status()); | 906 lineBox->setLineBreakInfo(endOfLine.getLineLayoutItem(), endOfLi
ne.offset(), resolver.status()); |
| 911 if (layoutState.usesPaintInvalidationBounds()) | |
| 912 layoutState.updatePaintInvalidationRangeFromBox(lineBox); | |
| 913 | |
| 914 if (paginated) { | 907 if (paginated) { |
| 915 if (paginationStrutFromDeletedLine) { | 908 if (paginationStrutFromDeletedLine) { |
| 916 // This is a line that got re-created because it got pus
hed to the next fragmentainer, and there | 909 // This is a line that got re-created because it got pus
hed to the next fragmentainer, and there |
| 917 // were floats in the vicinity that affected the availab
le width. Restore the pagination info | 910 // were floats in the vicinity that affected the availab
le width. Restore the pagination info |
| 918 // for this line. | 911 // for this line. |
| 919 lineBox->setIsFirstAfterPageBreak(true); | 912 lineBox->setIsFirstAfterPageBreak(true); |
| 920 lineBox->setPaginationStrut(paginationStrutFromDeletedLi
ne); | 913 lineBox->setPaginationStrut(paginationStrutFromDeletedLi
ne); |
| 921 paginationStrutFromDeletedLine = LayoutUnit(); | 914 paginationStrutFromDeletedLine = LayoutUnit(); |
| 922 } else { | 915 } else { |
| 923 LayoutUnit adjustment; | 916 LayoutUnit adjustment; |
| 924 adjustLinePositionForPagination(*lineBox, adjustment); | 917 adjustLinePositionForPagination(*lineBox, adjustment); |
| 925 if (adjustment) { | 918 if (adjustment) { |
| 926 LayoutUnit oldLineWidth = availableLogicalWidthForLi
ne(oldLogicalHeight, layoutState.lineInfo().isFirstLine() ? IndentText : DoNotIn
dentText); | 919 LayoutUnit oldLineWidth = availableLogicalWidthForLi
ne(oldLogicalHeight, layoutState.lineInfo().isFirstLine() ? IndentText : DoNotIn
dentText); |
| 927 lineBox->moveInBlockDirection(adjustment); | 920 lineBox->moveInBlockDirection(adjustment); |
| 928 if (layoutState.usesPaintInvalidationBounds()) | |
| 929 layoutState.updatePaintInvalidationRangeFromBox(
lineBox); | |
| 930 | |
| 931 if (availableLogicalWidthForLine(oldLogicalHeight +
adjustment, layoutState.lineInfo().isFirstLine() ? IndentText: DoNotIndentText)
!= oldLineWidth) { | 921 if (availableLogicalWidthForLine(oldLogicalHeight +
adjustment, layoutState.lineInfo().isFirstLine() ? IndentText: DoNotIndentText)
!= oldLineWidth) { |
| 932 // We have to delete this line, remove all float
s that got added, and let line layout | 922 // We have to delete this line, remove all float
s that got added, and let line layout |
| 933 // re-run. We had just calculated the pagination
strut for this line, and we need to | 923 // re-run. We had just calculated the pagination
strut for this line, and we need to |
| 934 // stow it away, so that we can re-apply it when
the new line has been created. | 924 // stow it away, so that we can re-apply it when
the new line has been created. |
| 935 paginationStrutFromDeletedLine = lineBox->pagina
tionStrut(); | 925 paginationStrutFromDeletedLine = lineBox->pagina
tionStrut(); |
| 936 ASSERT(paginationStrutFromDeletedLine); | 926 ASSERT(paginationStrutFromDeletedLine); |
| 937 // We're also going to assume that we're right a
fter a page break when re-creating this | 927 // We're also going to assume that we're right a
fter a page break when re-creating this |
| 938 // line, so it better be so. | 928 // line, so it better be so. |
| 939 ASSERT(lineBox->isFirstAfterPageBreak()); | 929 ASSERT(lineBox->isFirstAfterPageBreak()); |
| 940 lineBox->deleteLine(); | 930 lineBox->deleteLine(); |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1040 if (layoutState.endLineMatched()) { | 1030 if (layoutState.endLineMatched()) { |
| 1041 bool paginated = view()->layoutState() && view()->layoutState()->isP
aginated(); | 1031 bool paginated = view()->layoutState() && view()->layoutState()->isP
aginated(); |
| 1042 // Attach all the remaining lines, and then adjust their y-positions
as needed. | 1032 // Attach all the remaining lines, and then adjust their y-positions
as needed. |
| 1043 LayoutUnit delta = logicalHeight() - layoutState.endLineLogicalTop()
; | 1033 LayoutUnit delta = logicalHeight() - layoutState.endLineLogicalTop()
; |
| 1044 for (RootInlineBox* line = layoutState.endLine(); line; line = line-
>nextRootBox()) { | 1034 for (RootInlineBox* line = layoutState.endLine(); line; line = line-
>nextRootBox()) { |
| 1045 line->attachLine(); | 1035 line->attachLine(); |
| 1046 if (paginated) { | 1036 if (paginated) { |
| 1047 delta -= line->paginationStrut(); | 1037 delta -= line->paginationStrut(); |
| 1048 adjustLinePositionForPagination(*line, delta); | 1038 adjustLinePositionForPagination(*line, delta); |
| 1049 } | 1039 } |
| 1050 if (delta) { | 1040 if (delta) |
| 1051 layoutState.updatePaintInvalidationRangeFromBox(line, delta)
; | |
| 1052 line->moveInBlockDirection(delta); | 1041 line->moveInBlockDirection(delta); |
| 1053 } | |
| 1054 if (Vector<LayoutBox*>* cleanLineFloats = line->floatsPtr()) { | 1042 if (Vector<LayoutBox*>* cleanLineFloats = line->floatsPtr()) { |
| 1055 for (auto* box : *cleanLineFloats) { | 1043 for (auto* box : *cleanLineFloats) { |
| 1056 FloatingObject* floatingObject = insertFloatingObject(*b
ox); | 1044 FloatingObject* floatingObject = insertFloatingObject(*b
ox); |
| 1057 ASSERT(!floatingObject->originatingLine()); | 1045 ASSERT(!floatingObject->originatingLine()); |
| 1058 floatingObject->setOriginatingLine(line); | 1046 floatingObject->setOriginatingLine(line); |
| 1059 setLogicalHeight(logicalTopForChild(*box) - marginBefore
ForChild(*box) + delta); | 1047 setLogicalHeight(logicalTopForChild(*box) - marginBefore
ForChild(*box) + delta); |
| 1060 positionNewFloats(); | 1048 positionNewFloats(); |
| 1061 } | 1049 } |
| 1062 } | 1050 } |
| 1063 } | 1051 } |
| (...skipping 475 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1539 const LayoutObject* objectToCheck = block; | 1527 const LayoutObject* objectToCheck = block; |
| 1540 if (block->isAnonymousBlock()) { | 1528 if (block->isAnonymousBlock()) { |
| 1541 const LayoutObject* parent = block->parent(); | 1529 const LayoutObject* parent = block->parent(); |
| 1542 if (!parent || !parent->behavesLikeBlockContainer()) | 1530 if (!parent || !parent->behavesLikeBlockContainer()) |
| 1543 return false; | 1531 return false; |
| 1544 objectToCheck = parent; | 1532 objectToCheck = parent; |
| 1545 } | 1533 } |
| 1546 return objectToCheck->hasOverflowClip() && objectToCheck->style()->getTextOv
erflow(); | 1534 return objectToCheck->hasOverflowClip() && objectToCheck->style()->getTextOv
erflow(); |
| 1547 } | 1535 } |
| 1548 | 1536 |
| 1549 void LayoutBlockFlow::layoutInlineChildren(bool relayoutChildren, LayoutUnit& pa
intInvalidationLogicalTop, LayoutUnit& paintInvalidationLogicalBottom, LayoutUni
t afterEdge) | 1537 void LayoutBlockFlow::layoutInlineChildren(bool relayoutChildren, LayoutUnit aft
erEdge) |
| 1550 { | 1538 { |
| 1551 // Figure out if we should clear out our line boxes. | 1539 // Figure out if we should clear out our line boxes. |
| 1552 // FIXME: Handle resize eventually! | 1540 // FIXME: Handle resize eventually! |
| 1553 bool isFullLayout = !firstLineBox() || selfNeedsLayout() || relayoutChildren
; | 1541 bool isFullLayout = !firstLineBox() || selfNeedsLayout() || relayoutChildren
; |
| 1554 LineLayoutState layoutState(isFullLayout, paintInvalidationLogicalTop, paint
InvalidationLogicalBottom); | 1542 LineLayoutState layoutState(isFullLayout); |
| 1555 | 1543 |
| 1556 if (isFullLayout) { | 1544 if (isFullLayout) { |
| 1557 // Ensure the old line boxes will be erased. | 1545 // Ensure the old line boxes will be erased. |
| 1558 if (firstLineBox()) | 1546 if (firstLineBox()) |
| 1559 setShouldDoFullPaintInvalidation(); | 1547 setShouldDoFullPaintInvalidation(); |
| 1560 lineBoxes()->deleteLineBoxes(); | 1548 lineBoxes()->deleteLineBoxes(); |
| 1561 } | 1549 } |
| 1562 | 1550 |
| 1563 // Text truncation kicks in if overflow isn't visible and text-overflow isn'
t 'clip'. If this is | 1551 // Text truncation kicks in if overflow isn't visible and text-overflow isn'
t 'clip'. If this is |
| 1564 // an anonymous block, we have to examine the parent. | 1552 // an anonymous block, we have to examine the parent. |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1654 for (curr = firstRootBox(); curr && !curr->isDirty(); curr = curr->nextR
ootBox()) { | 1642 for (curr = firstRootBox(); curr && !curr->isDirty(); curr = curr->nextR
ootBox()) { |
| 1655 if (paginated) { | 1643 if (paginated) { |
| 1656 paginationDelta -= curr->paginationStrut(); | 1644 paginationDelta -= curr->paginationStrut(); |
| 1657 adjustLinePositionForPagination(*curr, paginationDelta); | 1645 adjustLinePositionForPagination(*curr, paginationDelta); |
| 1658 if (paginationDelta) { | 1646 if (paginationDelta) { |
| 1659 if (containsFloats() || !layoutState.floats().isEmpty()) { | 1647 if (containsFloats() || !layoutState.floats().isEmpty()) { |
| 1660 // FIXME: Do better eventually. For now if we ever shif
t because of pagination and floats are present just go to a full layout. | 1648 // FIXME: Do better eventually. For now if we ever shif
t because of pagination and floats are present just go to a full layout. |
| 1661 layoutState.markForFullLayout(); | 1649 layoutState.markForFullLayout(); |
| 1662 break; | 1650 break; |
| 1663 } | 1651 } |
| 1664 | |
| 1665 layoutState.updatePaintInvalidationRangeFromBox(curr, pagina
tionDelta); | |
| 1666 curr->moveInBlockDirection(paginationDelta); | 1652 curr->moveInBlockDirection(paginationDelta); |
| 1667 } | 1653 } |
| 1668 } | 1654 } |
| 1669 | 1655 |
| 1670 // If the linebox breaks cleanly and with clearance then dirty from
at least this point onwards so that we can clear the correct floats without diff
iculty. | 1656 // If the linebox breaks cleanly and with clearance then dirty from
at least this point onwards so that we can clear the correct floats without diff
iculty. |
| 1671 if (!firstLineBoxWithBreakAndClearance && lineBoxHasBRWithClearance(
curr)) | 1657 if (!firstLineBoxWithBreakAndClearance && lineBoxHasBRWithClearance(
curr)) |
| 1672 firstLineBoxWithBreakAndClearance = curr; | 1658 firstLineBoxWithBreakAndClearance = curr; |
| 1673 | 1659 |
| 1674 if (layoutState.isFullLayout()) | 1660 if (layoutState.isFullLayout()) |
| 1675 break; | 1661 break; |
| (...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2061 LayoutUnit totalLogicalWidth; | 2047 LayoutUnit totalLogicalWidth; |
| 2062 LayoutUnit logicalLeft = logicalLeftOffsetForLine(logicalHeight(), DoNotInde
ntText); | 2048 LayoutUnit logicalLeft = logicalLeftOffsetForLine(logicalHeight(), DoNotInde
ntText); |
| 2063 LayoutUnit availableLogicalWidth = logicalRightOffsetForLine(logicalHeight()
, DoNotIndentText) - logicalLeft; | 2049 LayoutUnit availableLogicalWidth = logicalRightOffsetForLine(logicalHeight()
, DoNotIndentText) - logicalLeft; |
| 2064 updateLogicalWidthForAlignment(textAlign, 0, 0, logicalLeft, totalLogicalWid
th, availableLogicalWidth, 0); | 2050 updateLogicalWidthForAlignment(textAlign, 0, 0, logicalLeft, totalLogicalWid
th, availableLogicalWidth, 0); |
| 2065 | 2051 |
| 2066 if (!style()->isLeftToRightDirection()) | 2052 if (!style()->isLeftToRightDirection()) |
| 2067 return logicalWidth() - logicalLeft; | 2053 return logicalWidth() - logicalLeft; |
| 2068 return logicalLeft; | 2054 return logicalLeft; |
| 2069 } | 2055 } |
| 2070 | 2056 |
| 2071 void LayoutBlockFlow::invalidateDisplayItemClientsOfFirstLine() | 2057 void LayoutBlockFlow::setShouldDoFullPaintInvalidationForFirstLine() |
| 2072 { | 2058 { |
| 2073 ASSERT(childrenInline()); | 2059 ASSERT(childrenInline()); |
| 2074 if (RootInlineBox* firstRootBox = this->firstRootBox()) | 2060 if (RootInlineBox* firstRootBox = this->firstRootBox()) |
| 2075 firstRootBox->invalidateDisplayItemClientsRecursively(); | 2061 firstRootBox->setShouldDoFullPaintInvalidationRecursively(); |
| 2076 } | 2062 } |
| 2077 | 2063 |
| 2078 PaintInvalidationReason LayoutBlockFlow::invalidatePaintIfNeeded(const PaintInva
lidationState& paintInvalidationState) | 2064 PaintInvalidationReason LayoutBlockFlow::invalidatePaintIfNeeded(const PaintInva
lidationState& paintInvalidationState) |
| 2079 { | 2065 { |
| 2080 if (containsFloats()) | 2066 if (containsFloats()) |
| 2081 paintInvalidationState.paintingLayer().setNeedsPaintPhaseFloat(); | 2067 paintInvalidationState.paintingLayer().setNeedsPaintPhaseFloat(); |
| 2082 | 2068 |
| 2083 PaintInvalidationReason reason = LayoutBlock::invalidatePaintIfNeeded(paintI
nvalidationState); | 2069 PaintInvalidationReason reason = LayoutBlock::invalidatePaintIfNeeded(paintI
nvalidationState); |
| 2084 if (reason == PaintInvalidationNone) | 2070 if (reason == PaintInvalidationNone) |
| 2085 return reason; | 2071 return reason; |
| 2086 RootInlineBox* line = firstRootBox(); | 2072 RootInlineBox* line = firstRootBox(); |
| 2087 if (!line || !line->isFirstLineStyle()) | 2073 if (!line || !line->isFirstLineStyle()) |
| 2088 return reason; | 2074 return reason; |
| 2089 // It's the RootInlineBox that paints the ::first-line background. Note that
since it may be | 2075 // It's the RootInlineBox that paints the ::first-line background. Note that
since it may be |
| 2090 // expensive to figure out if the first line is affected by any ::first-line
selectors at all, | 2076 // expensive to figure out if the first line is affected by any ::first-line
selectors at all, |
| 2091 // we just invalidate it unconditionally, since that's typically cheaper. | 2077 // we just invalidate it unconditionally, since that's typically cheaper. |
| 2092 invalidateDisplayItemClient(*line, reason); | 2078 invalidateDisplayItemClient(*line, reason); |
| 2093 return reason; | 2079 return reason; |
| 2094 } | 2080 } |
| 2095 | 2081 |
| 2096 } // namespace blink | 2082 } // namespace blink |
| OLD | NEW |