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 |