| 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. | 3 * Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. |
| 4 * All right reserved. | 4 * All right reserved. |
| 5 * Copyright (C) 2010 Google Inc. All rights reserved. | 5 * Copyright (C) 2010 Google Inc. All rights reserved. |
| 6 * | 6 * |
| 7 * This library is free software; you can redistribute it and/or | 7 * This library is free software; you can redistribute it and/or |
| 8 * modify it under the terms of the GNU Library General Public | 8 * modify it under the terms of the GNU Library General Public |
| 9 * License as published by the Free Software Foundation; either | 9 * License as published by the Free Software Foundation; either |
| 10 * version 2 of the License, or (at your option) any later version. | 10 * version 2 of the License, or (at your option) any later version. |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 118 private: | 118 private: |
| 119 Vector<unsigned, 16> m_runsWithExpansions; | 119 Vector<unsigned, 16> m_runsWithExpansions; |
| 120 unsigned m_totalOpportunities; | 120 unsigned m_totalOpportunities; |
| 121 }; | 121 }; |
| 122 | 122 |
| 123 static inline InlineBox* createInlineBoxForLayoutObject( | 123 static inline InlineBox* createInlineBoxForLayoutObject( |
| 124 LineLayoutItem lineLayoutItem, | 124 LineLayoutItem lineLayoutItem, |
| 125 bool isRootLineBox, | 125 bool isRootLineBox, |
| 126 bool isOnlyRun = false) { | 126 bool isOnlyRun = false) { |
| 127 // Callers should handle text themselves. | 127 // Callers should handle text themselves. |
| 128 ASSERT(!lineLayoutItem.isText()); | 128 DCHECK(!lineLayoutItem.isText()); |
| 129 | 129 |
| 130 if (isRootLineBox) | 130 if (isRootLineBox) |
| 131 return LineLayoutBlockFlow(lineLayoutItem).createAndAppendRootInlineBox(); | 131 return LineLayoutBlockFlow(lineLayoutItem).createAndAppendRootInlineBox(); |
| 132 | 132 |
| 133 if (lineLayoutItem.isBox()) | 133 if (lineLayoutItem.isBox()) |
| 134 return LineLayoutBox(lineLayoutItem).createInlineBox(); | 134 return LineLayoutBox(lineLayoutItem).createInlineBox(); |
| 135 | 135 |
| 136 return LineLayoutInline(lineLayoutItem).createAndAppendInlineFlowBox(); | 136 return LineLayoutInline(lineLayoutItem).createAndAppendInlineFlowBox(); |
| 137 } | 137 } |
| 138 | 138 |
| 139 static inline InlineTextBox* createInlineBoxForText(BidiRun& run, | 139 static inline InlineTextBox* createInlineBoxForText(BidiRun& run, |
| 140 bool isOnlyRun) { | 140 bool isOnlyRun) { |
| 141 ASSERT(run.m_lineLayoutItem.isText()); | 141 DCHECK(run.m_lineLayoutItem.isText()); |
| 142 LineLayoutText text = LineLayoutText(run.m_lineLayoutItem); | 142 LineLayoutText text = LineLayoutText(run.m_lineLayoutItem); |
| 143 InlineTextBox* textBox = | 143 InlineTextBox* textBox = |
| 144 text.createInlineTextBox(run.m_start, run.m_stop - run.m_start); | 144 text.createInlineTextBox(run.m_start, run.m_stop - run.m_start); |
| 145 // We only treat a box as text for a <br> if we are on a line by ourself or in | 145 // We only treat a box as text for a <br> if we are on a line by ourself or in |
| 146 // strict mode (Note the use of strict mode. In "almost strict" mode, we | 146 // strict mode (Note the use of strict mode. In "almost strict" mode, we |
| 147 // don't treat the box for <br> as text.) | 147 // don't treat the box for <br> as text.) |
| 148 if (text.isBR()) | 148 if (text.isBR()) |
| 149 textBox->setIsText(isOnlyRun || text.document().inNoQuirksMode()); | 149 textBox->setIsText(isOnlyRun || text.document().inNoQuirksMode()); |
| 150 textBox->setDirOverride( | 150 textBox->setDirOverride( |
| 151 run.dirOverride(text.style()->rtlOrdering() == EOrder::kVisual)); | 151 run.dirOverride(text.style()->rtlOrdering() == EOrder::kVisual)); |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 265 if (pos >= length) | 265 if (pos >= length) |
| 266 return true; | 266 return true; |
| 267 | 267 |
| 268 if (layoutText.is8Bit()) | 268 if (layoutText.is8Bit()) |
| 269 return endsWithASCIISpaces(layoutText.characters8(), pos, length); | 269 return endsWithASCIISpaces(layoutText.characters8(), pos, length); |
| 270 return endsWithASCIISpaces(layoutText.characters16(), pos, length); | 270 return endsWithASCIISpaces(layoutText.characters16(), pos, length); |
| 271 } | 271 } |
| 272 | 272 |
| 273 RootInlineBox* LayoutBlockFlow::constructLine(BidiRunList<BidiRun>& bidiRuns, | 273 RootInlineBox* LayoutBlockFlow::constructLine(BidiRunList<BidiRun>& bidiRuns, |
| 274 const LineInfo& lineInfo) { | 274 const LineInfo& lineInfo) { |
| 275 ASSERT(bidiRuns.firstRun()); | 275 DCHECK(bidiRuns.firstRun()); |
| 276 | 276 |
| 277 bool rootHasSelectedChildren = false; | 277 bool rootHasSelectedChildren = false; |
| 278 InlineFlowBox* parentBox = nullptr; | 278 InlineFlowBox* parentBox = nullptr; |
| 279 int runCount = bidiRuns.runCount() - lineInfo.runsFromLeadingWhitespace(); | 279 int runCount = bidiRuns.runCount() - lineInfo.runsFromLeadingWhitespace(); |
| 280 for (BidiRun* r = bidiRuns.firstRun(); r; r = r->next()) { | 280 for (BidiRun* r = bidiRuns.firstRun(); r; r = r->next()) { |
| 281 // Create a box for our object. | 281 // Create a box for our object. |
| 282 bool isOnlyRun = (runCount == 1); | 282 bool isOnlyRun = (runCount == 1); |
| 283 if (runCount == 2 && !r->m_lineLayoutItem.isListMarker()) | 283 if (runCount == 2 && !r->m_lineLayoutItem.isListMarker()) |
| 284 isOnlyRun = (!style()->isLeftToRightDirection() ? bidiRuns.lastRun() | 284 isOnlyRun = (!style()->isLeftToRightDirection() ? bidiRuns.lastRun() |
| 285 : bidiRuns.firstRun()) | 285 : bidiRuns.firstRun()) |
| 286 ->m_lineLayoutItem.isListMarker(); | 286 ->m_lineLayoutItem.isListMarker(); |
| 287 | 287 |
| 288 if (lineInfo.isEmpty()) | 288 if (lineInfo.isEmpty()) |
| 289 continue; | 289 continue; |
| 290 | 290 |
| 291 InlineBox* box; | 291 InlineBox* box; |
| 292 if (r->m_lineLayoutItem.isText()) | 292 if (r->m_lineLayoutItem.isText()) |
| 293 box = createInlineBoxForText(*r, isOnlyRun); | 293 box = createInlineBoxForText(*r, isOnlyRun); |
| 294 else | 294 else |
| 295 box = | 295 box = |
| 296 createInlineBoxForLayoutObject(r->m_lineLayoutItem, false, isOnlyRun); | 296 createInlineBoxForLayoutObject(r->m_lineLayoutItem, false, isOnlyRun); |
| 297 r->m_box = box; | 297 r->m_box = box; |
| 298 | 298 |
| 299 ASSERT(box); | 299 DCHECK(box); |
| 300 if (!box) | 300 if (!box) |
| 301 continue; | 301 continue; |
| 302 | 302 |
| 303 if (!rootHasSelectedChildren && | 303 if (!rootHasSelectedChildren && |
| 304 box->getLineLayoutItem().getSelectionState() != SelectionNone) | 304 box->getLineLayoutItem().getSelectionState() != SelectionNone) |
| 305 rootHasSelectedChildren = true; | 305 rootHasSelectedChildren = true; |
| 306 | 306 |
| 307 // If we have no parent box yet, or if the run is not simply a sibling, | 307 // If we have no parent box yet, or if the run is not simply a sibling, |
| 308 // then we need to construct inline boxes as necessary to properly enclose | 308 // then we need to construct inline boxes as necessary to properly enclose |
| 309 // the run's inline box. Segments can only be siblings at the root level, as | 309 // the run's inline box. Segments can only be siblings at the root level, as |
| (...skipping 11 matching lines...) Expand all Loading... |
| 321 box->setBidiLevel(r->level()); | 321 box->setBidiLevel(r->level()); |
| 322 | 322 |
| 323 if (box->isInlineTextBox()) { | 323 if (box->isInlineTextBox()) { |
| 324 if (AXObjectCache* cache = document().existingAXObjectCache()) | 324 if (AXObjectCache* cache = document().existingAXObjectCache()) |
| 325 cache->inlineTextBoxesUpdated(r->m_lineLayoutItem); | 325 cache->inlineTextBoxesUpdated(r->m_lineLayoutItem); |
| 326 } | 326 } |
| 327 } | 327 } |
| 328 | 328 |
| 329 // We should have a root inline box. It should be unconstructed and | 329 // We should have a root inline box. It should be unconstructed and |
| 330 // be the last continuation of our line list. | 330 // be the last continuation of our line list. |
| 331 ASSERT(lastLineBox() && !lastLineBox()->isConstructed()); | 331 DCHECK(lastLineBox()); |
| 332 DCHECK(!lastLineBox()->isConstructed()); |
| 332 | 333 |
| 333 // Set the m_selectedChildren flag on the root inline box if one of the leaf | 334 // Set the m_selectedChildren flag on the root inline box if one of the leaf |
| 334 // inline box from the bidi runs walk above has a selection state. | 335 // inline box from the bidi runs walk above has a selection state. |
| 335 if (rootHasSelectedChildren) | 336 if (rootHasSelectedChildren) |
| 336 lastLineBox()->root().setHasSelectedChildren(true); | 337 lastLineBox()->root().setHasSelectedChildren(true); |
| 337 | 338 |
| 338 // Set bits on our inline flow boxes that indicate which sides should | 339 // Set bits on our inline flow boxes that indicate which sides should |
| 339 // paint borders/margins/padding. This knowledge will ultimately be used when | 340 // paint borders/margins/padding. This knowledge will ultimately be used when |
| 340 // we determine the horizontal positions and widths of all the inline boxes on | 341 // we determine the horizontal positions and widths of all the inline boxes on |
| 341 // the line. | 342 // the line. |
| (...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 645 } | 646 } |
| 646 | 647 |
| 647 const SimpleFontData* fontData = font.primaryFont(); | 648 const SimpleFontData* fontData = font.primaryFont(); |
| 648 DCHECK(fontData); | 649 DCHECK(fontData); |
| 649 glyphOverflow.setFromBounds( | 650 glyphOverflow.setFromBounds( |
| 650 glyphBounds, fontData ? fontData->getFontMetrics().floatAscent() : 0, | 651 glyphBounds, fontData ? fontData->getFontMetrics().floatAscent() : 0, |
| 651 fontData ? fontData->getFontMetrics().floatDescent() : 0, measuredWidth); | 652 fontData ? fontData->getFontMetrics().floatDescent() : 0, measuredWidth); |
| 652 | 653 |
| 653 run->m_box->setLogicalWidth(LayoutUnit(measuredWidth) + hyphenWidth); | 654 run->m_box->setLogicalWidth(LayoutUnit(measuredWidth) + hyphenWidth); |
| 654 if (!fallbackFonts.isEmpty()) { | 655 if (!fallbackFonts.isEmpty()) { |
| 655 ASSERT(run->m_box->isText()); | 656 DCHECK(run->m_box->isText()); |
| 656 GlyphOverflowAndFallbackFontsMap::ValueType* it = | 657 GlyphOverflowAndFallbackFontsMap::ValueType* it = |
| 657 textBoxDataMap | 658 textBoxDataMap |
| 658 .insert(toInlineTextBox(run->m_box), | 659 .insert(toInlineTextBox(run->m_box), |
| 659 std::make_pair(Vector<const SimpleFontData*>(), | 660 std::make_pair(Vector<const SimpleFontData*>(), |
| 660 GlyphOverflow())) | 661 GlyphOverflow())) |
| 661 .storedValue; | 662 .storedValue; |
| 662 ASSERT(it->value.first.isEmpty()); | 663 DCHECK(it->value.first.isEmpty()); |
| 663 copyToVector(fallbackFonts, it->value.first); | 664 copyToVector(fallbackFonts, it->value.first); |
| 664 run->m_box->parent()->clearDescendantsHaveSameLineHeightAndBaseline(); | 665 run->m_box->parent()->clearDescendantsHaveSameLineHeightAndBaseline(); |
| 665 } | 666 } |
| 666 if (!glyphOverflow.isApproximatelyZero()) { | 667 if (!glyphOverflow.isApproximatelyZero()) { |
| 667 ASSERT(run->m_box->isText()); | 668 DCHECK(run->m_box->isText()); |
| 668 GlyphOverflowAndFallbackFontsMap::ValueType* it = | 669 GlyphOverflowAndFallbackFontsMap::ValueType* it = |
| 669 textBoxDataMap | 670 textBoxDataMap |
| 670 .insert(toInlineTextBox(run->m_box), | 671 .insert(toInlineTextBox(run->m_box), |
| 671 std::make_pair(Vector<const SimpleFontData*>(), | 672 std::make_pair(Vector<const SimpleFontData*>(), |
| 672 GlyphOverflow())) | 673 GlyphOverflow())) |
| 673 .storedValue; | 674 .storedValue; |
| 674 it->value.second = glyphOverflow; | 675 it->value.second = glyphOverflow; |
| 675 run->m_box->clearKnownToHaveNoOverflow(); | 676 run->m_box->clearKnownToHaveNoOverflow(); |
| 676 } | 677 } |
| 677 } | 678 } |
| (...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 899 void LayoutBlockFlow::computeBlockDirectionPositionsForLine( | 900 void LayoutBlockFlow::computeBlockDirectionPositionsForLine( |
| 900 RootInlineBox* lineBox, | 901 RootInlineBox* lineBox, |
| 901 BidiRun* firstRun, | 902 BidiRun* firstRun, |
| 902 GlyphOverflowAndFallbackFontsMap& textBoxDataMap, | 903 GlyphOverflowAndFallbackFontsMap& textBoxDataMap, |
| 903 VerticalPositionCache& verticalPositionCache) { | 904 VerticalPositionCache& verticalPositionCache) { |
| 904 setLogicalHeight(lineBox->alignBoxesInBlockDirection( | 905 setLogicalHeight(lineBox->alignBoxesInBlockDirection( |
| 905 logicalHeight(), textBoxDataMap, verticalPositionCache)); | 906 logicalHeight(), textBoxDataMap, verticalPositionCache)); |
| 906 | 907 |
| 907 // Now make sure we place replaced layout objects correctly. | 908 // Now make sure we place replaced layout objects correctly. |
| 908 for (BidiRun* r = firstRun; r; r = r->next()) { | 909 for (BidiRun* r = firstRun; r; r = r->next()) { |
| 909 ASSERT(r->m_box); | 910 DCHECK(r->m_box); |
| 910 if (!r->m_box) | 911 if (!r->m_box) |
| 911 continue; // Skip runs with no line boxes. | 912 continue; // Skip runs with no line boxes. |
| 912 | 913 |
| 913 // Align positioned boxes with the top of the line box. This is | 914 // Align positioned boxes with the top of the line box. This is |
| 914 // a reasonable approximation of an appropriate y position. | 915 // a reasonable approximation of an appropriate y position. |
| 915 if (r->m_lineLayoutItem.isOutOfFlowPositioned()) | 916 if (r->m_lineLayoutItem.isOutOfFlowPositioned()) |
| 916 r->m_box->setLogicalTop(logicalHeight()); | 917 r->m_box->setLogicalTop(logicalHeight()); |
| 917 | 918 |
| 918 // Position is used to properly position both replaced elements and | 919 // Position is used to properly position both replaced elements and |
| 919 // to update the static normal flow x/y of positioned elements. | 920 // to update the static normal flow x/y of positioned elements. |
| 920 if (r->m_lineLayoutItem.isText()) | 921 if (r->m_lineLayoutItem.isText()) |
| 921 toLayoutText(r->m_lineLayoutItem.layoutObject()) | 922 toLayoutText(r->m_lineLayoutItem.layoutObject()) |
| 922 ->positionLineBox(r->m_box); | 923 ->positionLineBox(r->m_box); |
| 923 else if (r->m_lineLayoutItem.isBox()) | 924 else if (r->m_lineLayoutItem.isBox()) |
| 924 toLayoutBox(r->m_lineLayoutItem.layoutObject()) | 925 toLayoutBox(r->m_lineLayoutItem.layoutObject()) |
| 925 ->positionLineBox(r->m_box); | 926 ->positionLineBox(r->m_box); |
| 926 } | 927 } |
| 927 } | 928 } |
| 928 | 929 |
| 929 void LayoutBlockFlow::appendFloatingObjectToLastLine( | 930 void LayoutBlockFlow::appendFloatingObjectToLastLine( |
| 930 FloatingObject& floatingObject) { | 931 FloatingObject& floatingObject) { |
| 931 ASSERT(!floatingObject.originatingLine()); | 932 DCHECK(!floatingObject.originatingLine()); |
| 932 floatingObject.setOriginatingLine(lastRootBox()); | 933 floatingObject.setOriginatingLine(lastRootBox()); |
| 933 lastRootBox()->appendFloat(floatingObject.layoutObject()); | 934 lastRootBox()->appendFloat(floatingObject.layoutObject()); |
| 934 } | 935 } |
| 935 | 936 |
| 936 // This function constructs line boxes for all of the text runs in the resolver | 937 // This function constructs line boxes for all of the text runs in the resolver |
| 937 // and computes their position. | 938 // and computes their position. |
| 938 RootInlineBox* LayoutBlockFlow::createLineBoxesFromBidiRuns( | 939 RootInlineBox* LayoutBlockFlow::createLineBoxesFromBidiRuns( |
| 939 unsigned bidiLevel, | 940 unsigned bidiLevel, |
| 940 BidiRunList<BidiRun>& bidiRuns, | 941 BidiRunList<BidiRun>& bidiRuns, |
| 941 const InlineIterator& end, | 942 const InlineIterator& end, |
| (...skipping 27 matching lines...) Expand all Loading... |
| 969 // Now position our text runs vertically. | 970 // Now position our text runs vertically. |
| 970 computeBlockDirectionPositionsForLine(lineBox, bidiRuns.firstRun(), | 971 computeBlockDirectionPositionsForLine(lineBox, bidiRuns.firstRun(), |
| 971 textBoxDataMap, verticalPositionCache); | 972 textBoxDataMap, verticalPositionCache); |
| 972 | 973 |
| 973 // SVG text layout code computes vertical & horizontal positions on its own. | 974 // SVG text layout code computes vertical & horizontal positions on its own. |
| 974 // Note that we still need to execute computeVerticalPositionsForLine() as | 975 // Note that we still need to execute computeVerticalPositionsForLine() as |
| 975 // it calls InlineTextBox::positionLineBox(), which tracks whether the box | 976 // it calls InlineTextBox::positionLineBox(), which tracks whether the box |
| 976 // contains reversed text or not. If we wouldn't do that editing and thus | 977 // contains reversed text or not. If we wouldn't do that editing and thus |
| 977 // text selection in RTL boxes would not work as expected. | 978 // text selection in RTL boxes would not work as expected. |
| 978 if (isSVGRootInlineBox) { | 979 if (isSVGRootInlineBox) { |
| 979 ASSERT(isSVGText()); | 980 DCHECK(isSVGText()); |
| 980 toSVGRootInlineBox(lineBox)->computePerCharacterLayoutInformation(); | 981 toSVGRootInlineBox(lineBox)->computePerCharacterLayoutInformation(); |
| 981 } | 982 } |
| 982 | 983 |
| 983 // Compute our overflow now. | 984 // Compute our overflow now. |
| 984 lineBox->computeOverflow(lineBox->lineTop(), lineBox->lineBottom(), | 985 lineBox->computeOverflow(lineBox->lineTop(), lineBox->lineBottom(), |
| 985 textBoxDataMap); | 986 textBoxDataMap); |
| 986 | 987 |
| 987 return lineBox; | 988 return lineBox; |
| 988 } | 989 } |
| 989 | 990 |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1045 LineLayoutState& layoutState, | 1046 LineLayoutState& layoutState, |
| 1046 const InlineIterator& cleanLineStart, | 1047 const InlineIterator& cleanLineStart, |
| 1047 const InlineBidiResolver& resolver, | 1048 const InlineBidiResolver& resolver, |
| 1048 const BidiStatus& cleanLineBidiStatus) { | 1049 const BidiStatus& cleanLineBidiStatus) { |
| 1049 const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); | 1050 const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); |
| 1050 FloatingObjectSetIterator it = floatingObjectSet.begin(); | 1051 FloatingObjectSetIterator it = floatingObjectSet.begin(); |
| 1051 FloatingObjectSetIterator end = floatingObjectSet.end(); | 1052 FloatingObjectSetIterator end = floatingObjectSet.end(); |
| 1052 if (layoutState.lastFloat()) { | 1053 if (layoutState.lastFloat()) { |
| 1053 FloatingObjectSetIterator lastFloatIterator = | 1054 FloatingObjectSetIterator lastFloatIterator = |
| 1054 floatingObjectSet.find(layoutState.lastFloat()); | 1055 floatingObjectSet.find(layoutState.lastFloat()); |
| 1055 ASSERT(lastFloatIterator != end); | 1056 DCHECK(lastFloatIterator != end); |
| 1056 ++lastFloatIterator; | 1057 ++lastFloatIterator; |
| 1057 it = lastFloatIterator; | 1058 it = lastFloatIterator; |
| 1058 } | 1059 } |
| 1059 for (; it != end; ++it) { | 1060 for (; it != end; ++it) { |
| 1060 FloatingObject& floatingObject = *it->get(); | 1061 FloatingObject& floatingObject = *it->get(); |
| 1061 // If we've reached the start of clean lines any remaining floating children | 1062 // If we've reached the start of clean lines any remaining floating children |
| 1062 // belong to them. | 1063 // belong to them. |
| 1063 if (cleanLineStart.getLineLayoutItem().isEqual( | 1064 if (cleanLineStart.getLineLayoutItem().isEqual( |
| 1064 floatingObject.layoutObject()) && | 1065 floatingObject.layoutObject()) && |
| 1065 layoutState.endLine()) { | 1066 layoutState.endLine()) { |
| 1066 layoutState.setEndLineMatched(layoutState.endLineMatched() || | 1067 layoutState.setEndLineMatched(layoutState.endLineMatched() || |
| 1067 matchedEndLine(layoutState, resolver, | 1068 matchedEndLine(layoutState, resolver, |
| 1068 cleanLineStart, | 1069 cleanLineStart, |
| 1069 cleanLineBidiStatus)); | 1070 cleanLineBidiStatus)); |
| 1070 if (layoutState.endLineMatched()) { | 1071 if (layoutState.endLineMatched()) { |
| 1071 layoutState.setLastFloat(&floatingObject); | 1072 layoutState.setLastFloat(&floatingObject); |
| 1072 return; | 1073 return; |
| 1073 } | 1074 } |
| 1074 } | 1075 } |
| 1075 appendFloatingObjectToLastLine(floatingObject); | 1076 appendFloatingObjectToLastLine(floatingObject); |
| 1076 ASSERT(floatingObject.layoutObject() == | 1077 DCHECK_EQ(floatingObject.layoutObject(), |
| 1077 layoutState.floats()[layoutState.floatIndex()].object); | 1078 layoutState.floats()[layoutState.floatIndex()].object); |
| 1078 // If a float's geometry has changed, give up on syncing with clean lines. | 1079 // If a float's geometry has changed, give up on syncing with clean lines. |
| 1079 if (layoutState.floats()[layoutState.floatIndex()].rect != | 1080 if (layoutState.floats()[layoutState.floatIndex()].rect != |
| 1080 floatingObject.frameRect()) { | 1081 floatingObject.frameRect()) { |
| 1081 // Delete all the remaining lines. | 1082 // Delete all the remaining lines. |
| 1082 deleteLineRange(layoutState, layoutState.endLine()); | 1083 deleteLineRange(layoutState, layoutState.endLine()); |
| 1083 layoutState.setEndLine(nullptr); | 1084 layoutState.setEndLine(nullptr); |
| 1084 } | 1085 } |
| 1085 layoutState.setFloatIndex(layoutState.floatIndex() + 1); | 1086 layoutState.setFloatIndex(layoutState.floatIndex() + 1); |
| 1086 } | 1087 } |
| 1087 layoutState.setLastFloat( | 1088 layoutState.setLastFloat( |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1108 LayoutUnit paginationStrutFromDeletedLine; | 1109 LayoutUnit paginationStrutFromDeletedLine; |
| 1109 | 1110 |
| 1110 LineBreaker lineBreaker(LineLayoutBlockFlow(this)); | 1111 LineBreaker lineBreaker(LineLayoutBlockFlow(this)); |
| 1111 | 1112 |
| 1112 // We avoid inline capacity to save the stack space. | 1113 // We avoid inline capacity to save the stack space. |
| 1113 WordMeasurements wordMeasurements; | 1114 WordMeasurements wordMeasurements; |
| 1114 wordMeasurements.reserveInitialCapacity(64); | 1115 wordMeasurements.reserveInitialCapacity(64); |
| 1115 | 1116 |
| 1116 while (!endOfLine.atEnd()) { | 1117 while (!endOfLine.atEnd()) { |
| 1117 // The runs from the previous line should have been cleaned up. | 1118 // The runs from the previous line should have been cleaned up. |
| 1118 ASSERT(!resolver.runs().runCount()); | 1119 DCHECK(!resolver.runs().runCount()); |
| 1119 | 1120 |
| 1120 // FIXME: Is this check necessary before the first iteration or can it be | 1121 // FIXME: Is this check necessary before the first iteration or can it be |
| 1121 // moved to the end? | 1122 // moved to the end? |
| 1122 if (layoutState.endLine()) { | 1123 if (layoutState.endLine()) { |
| 1123 layoutState.setEndLineMatched(layoutState.endLineMatched() || | 1124 layoutState.setEndLineMatched(layoutState.endLineMatched() || |
| 1124 matchedEndLine(layoutState, resolver, | 1125 matchedEndLine(layoutState, resolver, |
| 1125 cleanLineStart, | 1126 cleanLineStart, |
| 1126 cleanLineBidiStatus)); | 1127 cleanLineBidiStatus)); |
| 1127 if (layoutState.endLineMatched()) { | 1128 if (layoutState.endLineMatched()) { |
| 1128 resolver.setPosition(InlineIterator(resolver.position().root(), 0, 0), | 1129 resolver.setPosition(InlineIterator(resolver.position().root(), 0, 0), |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1149 // FIXME: We shouldn't be creating any runs in nextLineBreak to begin | 1150 // FIXME: We shouldn't be creating any runs in nextLineBreak to begin |
| 1150 // with! Once BidiRunList is separated from BidiResolver this will not be | 1151 // with! Once BidiRunList is separated from BidiResolver this will not be |
| 1151 // needed. | 1152 // needed. |
| 1152 resolver.runs().deleteRuns(); | 1153 resolver.runs().deleteRuns(); |
| 1153 resolver.markCurrentRunEmpty(); // FIXME: This can probably be replaced | 1154 resolver.markCurrentRunEmpty(); // FIXME: This can probably be replaced |
| 1154 // by an ASSERT (or just removed). | 1155 // by an ASSERT (or just removed). |
| 1155 resolver.setPosition(InlineIterator(resolver.position().root(), 0, 0), 0); | 1156 resolver.setPosition(InlineIterator(resolver.position().root(), 0, 0), 0); |
| 1156 break; | 1157 break; |
| 1157 } | 1158 } |
| 1158 | 1159 |
| 1159 ASSERT(endOfLine != resolver.position()); | 1160 DCHECK(endOfLine != resolver.position()); |
| 1160 RootInlineBox* lineBox = nullptr; | 1161 RootInlineBox* lineBox = nullptr; |
| 1161 | 1162 |
| 1162 // This is a short-cut for empty lines. | 1163 // This is a short-cut for empty lines. |
| 1163 if (layoutState.lineInfo().isEmpty()) { | 1164 if (layoutState.lineInfo().isEmpty()) { |
| 1164 ASSERT(!paginationStrutFromDeletedLine); | 1165 DCHECK(!paginationStrutFromDeletedLine); |
| 1165 if (lastRootBox()) | 1166 if (lastRootBox()) |
| 1166 lastRootBox()->setLineBreakInfo(endOfLine.getLineLayoutItem(), | 1167 lastRootBox()->setLineBreakInfo(endOfLine.getLineLayoutItem(), |
| 1167 endOfLine.offset(), resolver.status()); | 1168 endOfLine.offset(), resolver.status()); |
| 1168 resolver.runs().deleteRuns(); | 1169 resolver.runs().deleteRuns(); |
| 1169 } else { | 1170 } else { |
| 1170 VisualDirectionOverride override = | 1171 VisualDirectionOverride override = |
| 1171 (styleToUse.rtlOrdering() == EOrder::kVisual | 1172 (styleToUse.rtlOrdering() == EOrder::kVisual |
| 1172 ? (styleToUse.direction() == TextDirection::kLtr | 1173 ? (styleToUse.direction() == TextDirection::kLtr |
| 1173 ? VisualLeftToRightOverride | 1174 ? VisualLeftToRightOverride |
| 1174 : VisualRightToLeftOverride) | 1175 : VisualRightToLeftOverride) |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1189 layoutState.lineInfo().setTextAlign(textAlign); | 1190 layoutState.lineInfo().setTextAlign(textAlign); |
| 1190 resolver.setNeedsTrailingSpace( | 1191 resolver.setNeedsTrailingSpace( |
| 1191 textAlignmentNeedsTrailingSpace(textAlign, styleToUse)); | 1192 textAlignmentNeedsTrailingSpace(textAlign, styleToUse)); |
| 1192 | 1193 |
| 1193 // FIXME: This ownership is reversed. We should own the BidiRunList and | 1194 // FIXME: This ownership is reversed. We should own the BidiRunList and |
| 1194 // pass it to createBidiRunsForLine. | 1195 // pass it to createBidiRunsForLine. |
| 1195 BidiRunList<BidiRun>& bidiRuns = resolver.runs(); | 1196 BidiRunList<BidiRun>& bidiRuns = resolver.runs(); |
| 1196 constructBidiRunsForLine( | 1197 constructBidiRunsForLine( |
| 1197 resolver, bidiRuns, endOfLine, override, | 1198 resolver, bidiRuns, endOfLine, override, |
| 1198 layoutState.lineInfo().previousLineBrokeCleanly(), isNewUBAParagraph); | 1199 layoutState.lineInfo().previousLineBrokeCleanly(), isNewUBAParagraph); |
| 1199 ASSERT(resolver.position() == endOfLine); | 1200 DCHECK(resolver.position() == endOfLine); |
| 1200 | 1201 |
| 1201 BidiRun* trailingSpaceRun = resolver.trailingSpaceRun(); | 1202 BidiRun* trailingSpaceRun = resolver.trailingSpaceRun(); |
| 1202 | 1203 |
| 1203 if (bidiRuns.runCount() && lineBreaker.lineWasHyphenated()) | 1204 if (bidiRuns.runCount() && lineBreaker.lineWasHyphenated()) |
| 1204 bidiRuns.logicallyLastRun()->m_hasHyphen = true; | 1205 bidiRuns.logicallyLastRun()->m_hasHyphen = true; |
| 1205 | 1206 |
| 1206 // Now that the runs have been ordered, we create the line boxes. | 1207 // Now that the runs have been ordered, we create the line boxes. |
| 1207 // At the same time we figure out where border/padding/margin should be | 1208 // At the same time we figure out where border/padding/margin should be |
| 1208 // applied for | 1209 // applied for |
| 1209 // inline flow boxes. | 1210 // inline flow boxes. |
| 1210 | 1211 |
| 1211 LayoutUnit oldLogicalHeight = logicalHeight(); | 1212 LayoutUnit oldLogicalHeight = logicalHeight(); |
| 1212 lineBox = createLineBoxesFromBidiRuns( | 1213 lineBox = createLineBoxesFromBidiRuns( |
| 1213 resolver.status().context->level(), bidiRuns, endOfLine, | 1214 resolver.status().context->level(), bidiRuns, endOfLine, |
| 1214 layoutState.lineInfo(), verticalPositionCache, trailingSpaceRun, | 1215 layoutState.lineInfo(), verticalPositionCache, trailingSpaceRun, |
| 1215 wordMeasurements); | 1216 wordMeasurements); |
| 1216 | 1217 |
| 1217 bidiRuns.deleteRuns(); | 1218 bidiRuns.deleteRuns(); |
| 1218 resolver.markCurrentRunEmpty(); // FIXME: This can probably be replaced | 1219 resolver.markCurrentRunEmpty(); // FIXME: This can probably be replaced |
| 1219 // by an ASSERT (or just removed). | 1220 // by an ASSERT (or just removed). |
| 1220 | 1221 |
| 1221 // If we decided to re-create the line due to pagination, we better have a | 1222 // If we decided to re-create the line due to pagination, we better have a |
| 1222 // new line now. | 1223 // new line now. |
| 1223 ASSERT(lineBox || !paginationStrutFromDeletedLine); | 1224 DCHECK(lineBox || !paginationStrutFromDeletedLine); |
| 1224 | 1225 |
| 1225 if (lineBox) { | 1226 if (lineBox) { |
| 1226 lineBox->setLineBreakInfo(endOfLine.getLineLayoutItem(), | 1227 lineBox->setLineBreakInfo(endOfLine.getLineLayoutItem(), |
| 1227 endOfLine.offset(), resolver.status()); | 1228 endOfLine.offset(), resolver.status()); |
| 1228 if (recalculateStruts) { | 1229 if (recalculateStruts) { |
| 1229 if (paginationStrutFromDeletedLine) { | 1230 if (paginationStrutFromDeletedLine) { |
| 1230 // This is a line that got re-created because it got pushed to the | 1231 // This is a line that got re-created because it got pushed to the |
| 1231 // next fragmentainer, and there were floats in the vicinity that | 1232 // next fragmentainer, and there were floats in the vicinity that |
| 1232 // affected the available width. | 1233 // affected the available width. |
| 1233 // Restore the pagination info for this line. | 1234 // Restore the pagination info for this line. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1247 oldLogicalHeight + adjustment, | 1248 oldLogicalHeight + adjustment, |
| 1248 layoutState.lineInfo().isFirstLine() | 1249 layoutState.lineInfo().isFirstLine() |
| 1249 ? IndentText | 1250 ? IndentText |
| 1250 : DoNotIndentText) != oldLineWidth) { | 1251 : DoNotIndentText) != oldLineWidth) { |
| 1251 // We have to delete this line, remove all floats that got | 1252 // We have to delete this line, remove all floats that got |
| 1252 // added, and let line layout re-run. We had just calculated the | 1253 // added, and let line layout re-run. We had just calculated the |
| 1253 // pagination strut for this line, and we need to stow it away, | 1254 // pagination strut for this line, and we need to stow it away, |
| 1254 // so that we can re-apply it when the new line has been | 1255 // so that we can re-apply it when the new line has been |
| 1255 // created. | 1256 // created. |
| 1256 paginationStrutFromDeletedLine = lineBox->paginationStrut(); | 1257 paginationStrutFromDeletedLine = lineBox->paginationStrut(); |
| 1257 ASSERT(paginationStrutFromDeletedLine); | 1258 DCHECK(paginationStrutFromDeletedLine); |
| 1258 // We're also going to assume that we're right after a page | 1259 // We're also going to assume that we're right after a page |
| 1259 // break when re-creating this line, so it better be so. | 1260 // break when re-creating this line, so it better be so. |
| 1260 ASSERT(lineBox->isFirstAfterPageBreak()); | 1261 DCHECK(lineBox->isFirstAfterPageBreak()); |
| 1261 lineBox->deleteLine(); | 1262 lineBox->deleteLine(); |
| 1262 endOfLine = restartLayoutRunsAndFloatsInRange( | 1263 endOfLine = restartLayoutRunsAndFloatsInRange( |
| 1263 oldLogicalHeight, oldLogicalHeight + adjustment, | 1264 oldLogicalHeight, oldLogicalHeight + adjustment, |
| 1264 lastFloatFromPreviousLine, resolver, previousEndofLine); | 1265 lastFloatFromPreviousLine, resolver, previousEndofLine); |
| 1265 } else { | 1266 } else { |
| 1266 setLogicalHeight(lineBox->lineBottomWithLeading()); | 1267 setLogicalHeight(lineBox->lineBottomWithLeading()); |
| 1267 } | 1268 } |
| 1268 } | 1269 } |
| 1269 } | 1270 } |
| 1270 } | 1271 } |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1300 appendFloatsToLastLine(layoutState, cleanLineStart, endOfLineResolver, | 1301 appendFloatsToLastLine(layoutState, cleanLineStart, endOfLineResolver, |
| 1301 cleanLineBidiStatus); | 1302 cleanLineBidiStatus); |
| 1302 } | 1303 } |
| 1303 } | 1304 } |
| 1304 | 1305 |
| 1305 lineMidpointState.reset(); | 1306 lineMidpointState.reset(); |
| 1306 resolver.setPosition(endOfLine, numberOfIsolateAncestors(endOfLine)); | 1307 resolver.setPosition(endOfLine, numberOfIsolateAncestors(endOfLine)); |
| 1307 } | 1308 } |
| 1308 | 1309 |
| 1309 // The resolver runs should have been cleared, otherwise they're leaking. | 1310 // The resolver runs should have been cleared, otherwise they're leaking. |
| 1310 ASSERT(!resolver.runs().runCount()); | 1311 DCHECK(!resolver.runs().runCount()); |
| 1311 | 1312 |
| 1312 // In case we already adjusted the line positions during this layout to avoid | 1313 // In case we already adjusted the line positions during this layout to avoid |
| 1313 // widows then we need to ignore the possibility of having a new widows | 1314 // widows then we need to ignore the possibility of having a new widows |
| 1314 // situation. Otherwise, we risk leaving empty containers which is against the | 1315 // situation. Otherwise, we risk leaving empty containers which is against the |
| 1315 // block fragmentation principles. | 1316 // block fragmentation principles. |
| 1316 if (paginated && style()->widows() > 1 && !didBreakAtLineToAvoidWidow()) { | 1317 if (paginated && style()->widows() > 1 && !didBreakAtLineToAvoidWidow()) { |
| 1317 // Check the line boxes to make sure we didn't create unacceptable widows. | 1318 // Check the line boxes to make sure we didn't create unacceptable widows. |
| 1318 // However, we'll prioritize orphans - so nothing we do here should create | 1319 // However, we'll prioritize orphans - so nothing we do here should create |
| 1319 // a new orphan. | 1320 // a new orphan. |
| 1320 | 1321 |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1391 line->attachLine(); | 1392 line->attachLine(); |
| 1392 if (recalculateStruts) { | 1393 if (recalculateStruts) { |
| 1393 delta -= line->paginationStrut(); | 1394 delta -= line->paginationStrut(); |
| 1394 adjustLinePositionForPagination(*line, delta); | 1395 adjustLinePositionForPagination(*line, delta); |
| 1395 } | 1396 } |
| 1396 if (delta) | 1397 if (delta) |
| 1397 line->moveInBlockDirection(delta); | 1398 line->moveInBlockDirection(delta); |
| 1398 if (Vector<LayoutBox*>* cleanLineFloats = line->floatsPtr()) { | 1399 if (Vector<LayoutBox*>* cleanLineFloats = line->floatsPtr()) { |
| 1399 for (auto* box : *cleanLineFloats) { | 1400 for (auto* box : *cleanLineFloats) { |
| 1400 FloatingObject* floatingObject = insertFloatingObject(*box); | 1401 FloatingObject* floatingObject = insertFloatingObject(*box); |
| 1401 ASSERT(!floatingObject->originatingLine()); | 1402 DCHECK(!floatingObject->originatingLine()); |
| 1402 floatingObject->setOriginatingLine(line); | 1403 floatingObject->setOriginatingLine(line); |
| 1403 LayoutUnit logicalTop = | 1404 LayoutUnit logicalTop = |
| 1404 logicalTopForChild(*box) - marginBeforeForChild(*box) + delta; | 1405 logicalTopForChild(*box) - marginBeforeForChild(*box) + delta; |
| 1405 placeNewFloats(logicalTop); | 1406 placeNewFloats(logicalTop); |
| 1406 } | 1407 } |
| 1407 } | 1408 } |
| 1408 } | 1409 } |
| 1409 setLogicalHeight(lastRootBox()->lineBottomWithLeading()); | 1410 setLogicalHeight(lastRootBox()->lineBottomWithLeading()); |
| 1410 } else { | 1411 } else { |
| 1411 // Delete all the remaining lines. | 1412 // Delete all the remaining lines. |
| (...skipping 668 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2080 // If we encountered a new float and have inline children, mark ourself to | 2081 // If we encountered a new float and have inline children, mark ourself to |
| 2081 // force us to issue paint invalidations. | 2082 // force us to issue paint invalidations. |
| 2082 if (layoutState.hasInlineChild() && !selfNeedsLayout()) { | 2083 if (layoutState.hasInlineChild() && !selfNeedsLayout()) { |
| 2083 setNeedsLayoutAndFullPaintInvalidation( | 2084 setNeedsLayoutAndFullPaintInvalidation( |
| 2084 LayoutInvalidationReason::FloatDescendantChanged, MarkOnlyThis); | 2085 LayoutInvalidationReason::FloatDescendantChanged, MarkOnlyThis); |
| 2085 setShouldDoFullPaintInvalidation(); | 2086 setShouldDoFullPaintInvalidation(); |
| 2086 } | 2087 } |
| 2087 | 2088 |
| 2088 deleteLineBoxTree(); | 2089 deleteLineBoxTree(); |
| 2089 curr = nullptr; | 2090 curr = nullptr; |
| 2090 ASSERT(!firstLineBox() && !lastLineBox()); | 2091 DCHECK(!firstLineBox()); |
| 2092 DCHECK(!lastLineBox()); |
| 2091 } else { | 2093 } else { |
| 2092 if (firstLineBoxWithBreakAndClearance) | 2094 if (firstLineBoxWithBreakAndClearance) |
| 2093 curr = firstLineBoxWithBreakAndClearance; | 2095 curr = firstLineBoxWithBreakAndClearance; |
| 2094 if (curr) { | 2096 if (curr) { |
| 2095 // We have a dirty line. | 2097 // We have a dirty line. |
| 2096 if (RootInlineBox* prevRootBox = curr->prevRootBox()) { | 2098 if (RootInlineBox* prevRootBox = curr->prevRootBox()) { |
| 2097 // We have a previous line. | 2099 // We have a previous line. |
| 2098 if (!prevRootBox->endsWithBreak() || !prevRootBox->lineBreakObj() || | 2100 if (!prevRootBox->endsWithBreak() || !prevRootBox->lineBreakObj() || |
| 2099 (prevRootBox->lineBreakObj().isText() && | 2101 (prevRootBox->lineBreakObj().isText() && |
| 2100 prevRootBox->lineBreakPos() >= | 2102 prevRootBox->lineBreakPos() >= |
| (...skipping 16 matching lines...) Expand all Loading... |
| 2117 } | 2119 } |
| 2118 | 2120 |
| 2119 unsigned numCleanFloats = 0; | 2121 unsigned numCleanFloats = 0; |
| 2120 if (!layoutState.floats().isEmpty()) { | 2122 if (!layoutState.floats().isEmpty()) { |
| 2121 // Restore floats from clean lines. | 2123 // Restore floats from clean lines. |
| 2122 RootInlineBox* line = firstRootBox(); | 2124 RootInlineBox* line = firstRootBox(); |
| 2123 while (line != curr) { | 2125 while (line != curr) { |
| 2124 if (Vector<LayoutBox*>* cleanLineFloats = line->floatsPtr()) { | 2126 if (Vector<LayoutBox*>* cleanLineFloats = line->floatsPtr()) { |
| 2125 for (auto* box : *cleanLineFloats) { | 2127 for (auto* box : *cleanLineFloats) { |
| 2126 FloatingObject* floatingObject = insertFloatingObject(*box); | 2128 FloatingObject* floatingObject = insertFloatingObject(*box); |
| 2127 ASSERT(!floatingObject->originatingLine()); | 2129 DCHECK(!floatingObject->originatingLine()); |
| 2128 floatingObject->setOriginatingLine(line); | 2130 floatingObject->setOriginatingLine(line); |
| 2129 LayoutUnit logicalTop = | 2131 LayoutUnit logicalTop = |
| 2130 logicalTopForChild(*box) - marginBeforeForChild(*box); | 2132 logicalTopForChild(*box) - marginBeforeForChild(*box); |
| 2131 placeNewFloats(logicalTop); | 2133 placeNewFloats(logicalTop); |
| 2132 ASSERT(layoutState.floats()[numCleanFloats].object == box); | 2134 DCHECK_EQ(layoutState.floats()[numCleanFloats].object, box); |
| 2133 numCleanFloats++; | 2135 numCleanFloats++; |
| 2134 } | 2136 } |
| 2135 } | 2137 } |
| 2136 line = line->nextRootBox(); | 2138 line = line->nextRootBox(); |
| 2137 } | 2139 } |
| 2138 } | 2140 } |
| 2139 layoutState.setFloatIndex(numCleanFloats); | 2141 layoutState.setFloatIndex(numCleanFloats); |
| 2140 | 2142 |
| 2141 layoutState.lineInfo().setFirstLine(!last); | 2143 layoutState.lineInfo().setFirstLine(!last); |
| 2142 layoutState.lineInfo().setPreviousLineBrokeCleanly(!last || | 2144 layoutState.lineInfo().setPreviousLineBrokeCleanly(!last || |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2175 ? curr->lastLeafChild() | 2177 ? curr->lastLeafChild() |
| 2176 : curr->firstLeafChild(); | 2178 : curr->firstLeafChild(); |
| 2177 return lastBox && lastBox->getLineLayoutItem().isBR() && | 2179 return lastBox && lastBox->getLineLayoutItem().isBR() && |
| 2178 lastBox->getLineLayoutItem().style()->clear() != EClear::kNone; | 2180 lastBox->getLineLayoutItem().style()->clear() != EClear::kNone; |
| 2179 } | 2181 } |
| 2180 | 2182 |
| 2181 void LayoutBlockFlow::determineEndPosition(LineLayoutState& layoutState, | 2183 void LayoutBlockFlow::determineEndPosition(LineLayoutState& layoutState, |
| 2182 RootInlineBox* startLine, | 2184 RootInlineBox* startLine, |
| 2183 InlineIterator& cleanLineStart, | 2185 InlineIterator& cleanLineStart, |
| 2184 BidiStatus& cleanLineBidiStatus) { | 2186 BidiStatus& cleanLineBidiStatus) { |
| 2185 ASSERT(!layoutState.endLine()); | 2187 DCHECK(!layoutState.endLine()); |
| 2186 RootInlineBox* last = nullptr; | 2188 RootInlineBox* last = nullptr; |
| 2187 for (RootInlineBox* curr = startLine->nextRootBox(); curr; | 2189 for (RootInlineBox* curr = startLine->nextRootBox(); curr; |
| 2188 curr = curr->nextRootBox()) { | 2190 curr = curr->nextRootBox()) { |
| 2189 if (!curr->isDirty() && lineBoxHasBRWithClearance(curr)) | 2191 if (!curr->isDirty() && lineBoxHasBRWithClearance(curr)) |
| 2190 return; | 2192 return; |
| 2191 | 2193 |
| 2192 if (curr->isDirty()) | 2194 if (curr->isDirty()) |
| 2193 last = nullptr; | 2195 last = nullptr; |
| 2194 else if (!last) | 2196 else if (!last) |
| 2195 last = curr; | 2197 last = curr; |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2300 return matched; | 2302 return matched; |
| 2301 } | 2303 } |
| 2302 } | 2304 } |
| 2303 | 2305 |
| 2304 return false; | 2306 return false; |
| 2305 } | 2307 } |
| 2306 | 2308 |
| 2307 bool LayoutBlockFlow::generatesLineBoxesForInlineChild(LayoutObject* inlineObj) | 2309 bool LayoutBlockFlow::generatesLineBoxesForInlineChild(LayoutObject* inlineObj) |
| 2308 | 2310 |
| 2309 { | 2311 { |
| 2310 ASSERT(inlineObj->parent() == this); | 2312 DCHECK_EQ(inlineObj->parent(), this); |
| 2311 | 2313 |
| 2312 InlineIterator it(LineLayoutBlockFlow(this), LineLayoutItem(inlineObj), 0); | 2314 InlineIterator it(LineLayoutBlockFlow(this), LineLayoutItem(inlineObj), 0); |
| 2313 // FIXME: We should pass correct value for WhitespacePosition. | 2315 // FIXME: We should pass correct value for WhitespacePosition. |
| 2314 while (!it.atEnd() && !requiresLineBox(it)) | 2316 while (!it.atEnd() && !requiresLineBox(it)) |
| 2315 it.increment(); | 2317 it.increment(); |
| 2316 | 2318 |
| 2317 return !it.atEnd(); | 2319 return !it.atEnd(); |
| 2318 } | 2320 } |
| 2319 | 2321 |
| 2320 void LayoutBlockFlow::addOverflowFromInlineChildren() { | 2322 void LayoutBlockFlow::addOverflowFromInlineChildren() { |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2409 *firstLineStyle(), ellipsisDirection)); | 2411 *firstLineStyle(), ellipsisDirection)); |
| 2410 } else { | 2412 } else { |
| 2411 selectedEllipsisStr = fullstopCharacterStr; | 2413 selectedEllipsisStr = fullstopCharacterStr; |
| 2412 firstLineEllipsisWidth = firstLineFont.width( | 2414 firstLineEllipsisWidth = firstLineFont.width( |
| 2413 constructTextRun(firstLineFont, fullStopString, fullStopStringLength, | 2415 constructTextRun(firstLineFont, fullStopString, fullStopStringLength, |
| 2414 *firstLineStyle(), ellipsisDirection)); | 2416 *firstLineStyle(), ellipsisDirection)); |
| 2415 } | 2417 } |
| 2416 ellipsisWidth = (font == firstLineFont) ? firstLineEllipsisWidth : 0; | 2418 ellipsisWidth = (font == firstLineFont) ? firstLineEllipsisWidth : 0; |
| 2417 | 2419 |
| 2418 if (!ellipsisWidth) { | 2420 if (!ellipsisWidth) { |
| 2419 ASSERT(font.primaryFont()); | 2421 DCHECK(font.primaryFont()); |
| 2420 if (font.primaryFont()->glyphForCharacter(horizontalEllipsisCharacter)) { | 2422 if (font.primaryFont()->glyphForCharacter(horizontalEllipsisCharacter)) { |
| 2421 ellipsisWidth = | 2423 ellipsisWidth = |
| 2422 font.width(constructTextRun(font, &horizontalEllipsisCharacter, 1, | 2424 font.width(constructTextRun(font, &horizontalEllipsisCharacter, 1, |
| 2423 styleRef(), ellipsisDirection)); | 2425 styleRef(), ellipsisDirection)); |
| 2424 } else { | 2426 } else { |
| 2425 selectedEllipsisStr = fullstopCharacterStr; | 2427 selectedEllipsisStr = fullstopCharacterStr; |
| 2426 ellipsisWidth = font.width( | 2428 ellipsisWidth = font.width( |
| 2427 constructTextRun(font, fullStopString, fullStopStringLength, | 2429 constructTextRun(font, fullStopString, fullStopStringLength, |
| 2428 styleRef(), ellipsisDirection)); | 2430 styleRef(), ellipsisDirection)); |
| 2429 } | 2431 } |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2607 logicalRightOffsetForLine(logicalHeight(), DoNotIndentText) - logicalLeft; | 2609 logicalRightOffsetForLine(logicalHeight(), DoNotIndentText) - logicalLeft; |
| 2608 updateLogicalWidthForAlignment(textAlign, 0, 0, logicalLeft, | 2610 updateLogicalWidthForAlignment(textAlign, 0, 0, logicalLeft, |
| 2609 totalLogicalWidth, availableLogicalWidth, 0); | 2611 totalLogicalWidth, availableLogicalWidth, 0); |
| 2610 | 2612 |
| 2611 if (!style()->isLeftToRightDirection()) | 2613 if (!style()->isLeftToRightDirection()) |
| 2612 return logicalWidth() - logicalLeft; | 2614 return logicalWidth() - logicalLeft; |
| 2613 return logicalLeft; | 2615 return logicalLeft; |
| 2614 } | 2616 } |
| 2615 | 2617 |
| 2616 void LayoutBlockFlow::setShouldDoFullPaintInvalidationForFirstLine() { | 2618 void LayoutBlockFlow::setShouldDoFullPaintInvalidationForFirstLine() { |
| 2617 ASSERT(childrenInline()); | 2619 DCHECK(childrenInline()); |
| 2618 if (RootInlineBox* firstRootBox = this->firstRootBox()) | 2620 if (RootInlineBox* firstRootBox = this->firstRootBox()) |
| 2619 firstRootBox->setShouldDoFullPaintInvalidationRecursively(); | 2621 firstRootBox->setShouldDoFullPaintInvalidationRecursively(); |
| 2620 } | 2622 } |
| 2621 | 2623 |
| 2622 bool LayoutBlockFlow::paintedOutputOfObjectHasNoEffectRegardlessOfSize() const { | 2624 bool LayoutBlockFlow::paintedOutputOfObjectHasNoEffectRegardlessOfSize() const { |
| 2623 // LayoutBlockFlow is in charge of paint invalidation of the first line. | 2625 // LayoutBlockFlow is in charge of paint invalidation of the first line. |
| 2624 if (firstLineBox()) | 2626 if (firstLineBox()) |
| 2625 return false; | 2627 return false; |
| 2626 | 2628 |
| 2627 return LayoutBlock::paintedOutputOfObjectHasNoEffectRegardlessOfSize(); | 2629 return LayoutBlock::paintedOutputOfObjectHasNoEffectRegardlessOfSize(); |
| 2628 } | 2630 } |
| 2629 | 2631 |
| 2630 } // namespace blink | 2632 } // namespace blink |
| OLD | NEW |