Changeset 157950 in webkit
- Timestamp:
- Oct 24, 2013 1:31:11 PM (10 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 5 added
- 15 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/CMakeLists.txt
r157936 r157950 2176 2176 rendering/RootInlineBox.cpp 2177 2177 rendering/ScrollBehavior.cpp 2178 rendering/SimpleLineLayout.cpp 2179 rendering/SimpleLineLayoutFunctions.cpp 2178 2180 rendering/TextAutosizer.cpp 2179 2181 rendering/TextPaintStyle.cpp -
trunk/Source/WebCore/ChangeLog
r157948 r157950 1 2013-10-24 Antti Koivisto <antti@apple.com> 2 3 Simple line layout 4 https://bugs.webkit.org/show_bug.cgi?id=122458 5 6 Reviewed by Darin Adler. 7 8 Line box based inline layout is powerful but also rather slow and memory intensive. Simple line layout 9 is a compact alternative data structure and fast code path to cover common cases without requiring line 10 boxes. 11 12 This patch handles a case single left-aligned text renderer inside flow with no floats. Even this very basic 13 case is sufficiently common to handle up to 25% of all text lines on some popular new sites. The decision 14 which path to use is made per block flow (paragraph). 15 16 Simple line layout aims to produce pixel-exact rendering result when compared to the line box layout. 17 18 The goal is to handle everything that requires line level access in cases that allow use of simple lines. 19 This is not quite the case yet. For example selections and outline painting are not supported. In these 20 cases we seamlessly switch to the line boxes. 21 22 The simple line data structure currently uses 12 bytes per line. Lineboxes take ~160 bytes minimum per line. 23 Laying out the lines is also several times faster as is iterating over them. 24 25 * CMakeLists.txt: 26 * GNUmakefile.list.am: 27 * WebCore.vcxproj/WebCore.vcxproj: 28 * WebCore.xcodeproj/project.pbxproj: 29 * dom/Position.cpp: 30 (WebCore::Position::upstream): 31 (WebCore::Position::downstream): 32 (WebCore::Position::getInlineBoxAndOffset): 33 34 Creating positions within a simple line flow causes switch to line boxes. 35 36 * editing/TextIterator.cpp: 37 (WebCore::TextIterator::handleTextNode): 38 39 TextIterator traverses line boxes if available. In case simple line case we need to replicate the 40 same results (for compatibility but especially to avoid changing test results). This is done here 41 by just traversing the string without actually using the layout. 42 43 * rendering/RenderBlock.cpp: 44 (WebCore::RenderBlock::RenderBlock): 45 (WebCore::RenderBlock::layoutShapeInsideInfo): 46 * rendering/RenderBlock.h: 47 * rendering/RenderBlockFlow.cpp: 48 (WebCore::RenderBlockFlow::layoutInlineChildren): 49 50 Select the layout path to use. 51 52 (WebCore::RenderBlockFlow::deleteLines): 53 (WebCore::RenderBlockFlow::hitTestInlineChildren): 54 (WebCore::RenderBlockFlow::adjustForBorderFit): 55 (WebCore::RenderBlockFlow::firstLineBaseline): 56 (WebCore::RenderBlockFlow::inlineBlockBaseline): 57 (WebCore::RenderBlockFlow::inlineSelectionGaps): 58 (WebCore::RenderBlockFlow::clearTruncation): 59 (WebCore::RenderBlockFlow::positionForPointWithInlineChildren): 60 (WebCore::RenderBlockFlow::addFocusRingRectsForInlineChildren): 61 (WebCore::RenderBlockFlow::paintInlineChildren): 62 (WebCore::RenderBlockFlow::hasLines): 63 (WebCore::RenderBlockFlow::layoutSimpleLines): 64 65 Do simple layout. 66 67 (WebCore::RenderBlockFlow::deleteLineBoxesBeforeSimpleLineLayout): 68 (WebCore::RenderBlockFlow::ensureLineBoxes): 69 70 This function switches from simple lines to line boxes. The switching can be done outside normal layout. 71 This is used to cover some cases that are not yet supported by simple lines (like selections). 72 73 * rendering/RenderBlockFlow.h: 74 (WebCore::RenderBlockFlow::simpleLines): 75 * rendering/RenderBlockLineLayout.cpp: 76 (WebCore::RenderBlockFlow::layoutLineBoxes): 77 78 Rename the line box layout function. 79 80 (WebCore::RenderBlockFlow::addOverflowFromInlineChildren): 81 * rendering/RenderText.cpp: 82 (WebCore::RenderText::deleteLineBoxesBeforeSimpleLineLayout): 83 (WebCore::RenderText::absoluteRects): 84 (WebCore::RenderText::absoluteRectsForRange): 85 (WebCore::RenderText::absoluteQuadsClippedToEllipsis): 86 (WebCore::RenderText::absoluteQuads): 87 (WebCore::RenderText::absoluteQuadsForRange): 88 (WebCore::RenderText::positionForPoint): 89 (WebCore::RenderText::knownToHaveNoOverflowAndNoFallbackFonts): 90 (WebCore::RenderText::setSelectionState): 91 (WebCore::RenderText::setTextWithOffset): 92 (WebCore::RenderText::ensureLineBoxes): 93 (WebCore::RenderText::simpleLines): 94 (WebCore::RenderText::linesBoundingBox): 95 (WebCore::RenderText::linesVisualOverflowBoundingBox): 96 (WebCore::RenderText::selectionRectForRepaint): 97 (WebCore::RenderText::caretMinOffset): 98 (WebCore::RenderText::caretMaxOffset): 99 (WebCore::RenderText::countRenderedCharacterOffsetsUntil): 100 (WebCore::RenderText::containsRenderedCharacterOffset): 101 (WebCore::RenderText::containsCaretOffset): 102 (WebCore::RenderText::hasRenderedText): 103 * rendering/RenderText.h: 104 * rendering/RenderTreeAsText.cpp: 105 (WebCore::RenderTreeAsText::writeRenderObject): 106 (WebCore::writeSimpleLine): 107 (WebCore::write): 108 * rendering/SimpleLineLayout.cpp: Added. 109 (WebCore::SimpleLineLayout::canUseFor): 110 111 This check for the cases supported by the simple line layout path. 112 113 (WebCore::SimpleLineLayout::isWhitespace): 114 (WebCore::SimpleLineLayout::skipWhitespaces): 115 (WebCore::SimpleLineLayout::textWidth): 116 (WebCore::SimpleLineLayout::createLines): 117 118 The main layout functions that breaks text to lines. It only handles the cases allowed by 119 SimpleLineLayout::canUseFor. What it handles it aims to break exactly as line box layout does. 120 121 * rendering/SimpleLineLayout.h: Added. 122 * rendering/SimpleLineLayoutFunctions.cpp: Added. 123 (WebCore::SimpleLineLayout::paintFlow): 124 (WebCore::SimpleLineLayout::hitTestFlow): 125 (WebCore::SimpleLineLayout::collectFlowOverflow): 126 (WebCore::SimpleLineLayout::computeTextBoundingBox): 127 * rendering/SimpleLineLayoutFunctions.h: Added. 128 (WebCore::SimpleLineLayout::computeFlowHeight): 129 (WebCore::SimpleLineLayout::computeFlowFirstLineBaseline): 130 (WebCore::SimpleLineLayout::computeFlowLastLineBaseline): 131 (WebCore::SimpleLineLayout::findTextCaretMinimumOffset): 132 (WebCore::SimpleLineLayout::findTextCaretMaximumOffset): 133 (WebCore::SimpleLineLayout::containsTextCaretOffset): 134 (WebCore::SimpleLineLayout::isTextRendered): 135 (WebCore::SimpleLineLayout::lineHeightFromFlow): 136 137 Support functions called from RenderBlockFlow and RenderText. They are equivalent to 138 similar line box functions. 139 140 (WebCore::SimpleLineLayout::baselineFromFlow): 141 * rendering/SimpleLineLayoutResolver.h: Added. 142 (WebCore::SimpleLineLayout::Resolver::Line::Line): 143 (WebCore::SimpleLineLayout::Resolver::Line::rect): 144 (WebCore::SimpleLineLayout::Resolver::Line::baseline): 145 (WebCore::SimpleLineLayout::Resolver::Line::text): 146 (WebCore::SimpleLineLayout::Resolver::Iterator::Iterator): 147 (WebCore::SimpleLineLayout::Resolver::Iterator::operator++): 148 (WebCore::SimpleLineLayout::Resolver::Iterator::operator--): 149 (WebCore::SimpleLineLayout::Resolver::Iterator::operator==): 150 (WebCore::SimpleLineLayout::Resolver::Iterator::operator!=): 151 (WebCore::SimpleLineLayout::Resolver::Iterator::operator*): 152 153 Lazy iterator for deriving line metrics. This keeps the line data structure small as 154 we don't need to keep easily derived values around. 155 156 (WebCore::SimpleLineLayout::Resolver::Resolver): 157 (WebCore::SimpleLineLayout::Resolver::size): 158 (WebCore::SimpleLineLayout::Resolver::begin): 159 (WebCore::SimpleLineLayout::Resolver::end): 160 (WebCore::SimpleLineLayout::Resolver::last): 161 (WebCore::SimpleLineLayout::Resolver::operator[]): 162 1 163 2013-10-24 Myles C. Maxfield <mmaxfield@apple.com> 2 164 -
trunk/Source/WebCore/GNUmakefile.list.am
r157936 r157950 4484 4484 Source/WebCore/rendering/ScrollBehavior.cpp \ 4485 4485 Source/WebCore/rendering/ScrollBehavior.h \ 4486 Source/WebCore/rendering/SimpleLineLayout.cpp \ 4487 Source/WebCore/rendering/SimpleLineLayout.h \ 4488 Source/WebCore/rendering/SimpleLineLayoutFunctions.cpp \ 4489 Source/WebCore/rendering/SimpleLineLayoutFunctions.h \ 4490 Source/WebCore/rendering/SimpleLineLayoutResolver.h \ 4486 4491 Source/WebCore/rendering/TextAutosizer.cpp \ 4487 4492 Source/WebCore/rendering/TextAutosizer.h \ -
trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj
r157928 r157950 10913 10913 <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Production|x64'">true</ExcludedFromBuild> 10914 10914 </ClCompile> 10915 <ClCompile Include="..\rendering\SimpleLineLayout.cpp" /> 10916 <ClCompile Include="..\rendering\SimpleLineLayoutFunctions.cpp" /> 10915 10917 <ClCompile Include="..\rendering\TextPaintStyle.cpp" /> 10916 10918 <ClCompile Include="..\rendering\shapes\PolygonShape.cpp" /> … … 19683 19685 <ClInclude Include="..\rendering\RootInlineBox.h" /> 19684 19686 <ClInclude Include="..\rendering\ScrollBehavior.h" /> 19687 <ClInclude Include="..\rendering\SimpleLineLayout.h" /> 19688 <ClInclude Include="..\rendering\SimpleLineLayoutFunctions.h" /> 19689 <ClInclude Include="..\rendering\SimpleLineLayoutResolver.h" /> 19685 19690 <ClInclude Include="..\rendering\svg\SVGMarkerData.h" /> 19686 19691 <ClInclude Include="..\rendering\svg\SVGPathData.h" /> -
trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj
r157936 r157950 5682 5682 E47E276516036ED200EE2AFB /* DocumentStyleSheetCollection.h in Headers */ = {isa = PBXBuildFile; fileRef = E47E276416036ED200EE2AFB /* DocumentStyleSheetCollection.h */; settings = {ATTRIBUTES = (Private, ); }; }; 5683 5683 E47E276816036EDC00EE2AFB /* DocumentStyleSheetCollection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E47E276716036EDC00EE2AFB /* DocumentStyleSheetCollection.cpp */; }; 5684 E48944A2180B57D800F165D8 /* SimpleLineLayout.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E48944A0180B57D800F165D8 /* SimpleLineLayout.cpp */; }; 5685 E48944A3180B57D800F165D8 /* SimpleLineLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = E48944A1180B57D800F165D8 /* SimpleLineLayout.h */; settings = {ATTRIBUTES = (Private, ); }; }; 5684 5686 E4946EAE156E64DD00D3297F /* StyleRuleImport.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4946EAC156E64DD00D3297F /* StyleRuleImport.cpp */; }; 5685 5687 E4946EAF156E64DD00D3297F /* StyleRuleImport.h in Headers */ = {isa = PBXBuildFile; fileRef = E4946EAD156E64DD00D3297F /* StyleRuleImport.h */; }; … … 5718 5720 E4DEAA1717A93DC3000E0430 /* StyleResolveTree.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4DEAA1517A93DC3000E0430 /* StyleResolveTree.cpp */; }; 5719 5721 E4DEAA1817A93DC3000E0430 /* StyleResolveTree.h in Headers */ = {isa = PBXBuildFile; fileRef = E4DEAA1617A93DC3000E0430 /* StyleResolveTree.h */; settings = {ATTRIBUTES = (Private, ); }; }; 5722 E4E9B1191810916F003ACCDF /* SimpleLineLayoutResolver.h in Headers */ = {isa = PBXBuildFile; fileRef = E4E9B1181810916F003ACCDF /* SimpleLineLayoutResolver.h */; }; 5723 E4E9B11B18145692003ACCDF /* SimpleLineLayoutFunctions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4E9B11A18145692003ACCDF /* SimpleLineLayoutFunctions.cpp */; }; 5724 E4E9B11D1814569C003ACCDF /* SimpleLineLayoutFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = E4E9B11C1814569C003ACCDF /* SimpleLineLayoutFunctions.h */; }; 5720 5725 E4F9EEF2156D9FFA00D23E7E /* StyleSheetContents.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4F9EEF0156D84C400D23E7E /* StyleSheetContents.cpp */; }; 5721 5726 E4F9EEF3156DA00700D23E7E /* StyleSheetContents.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F9EEF1156D84C400D23E7E /* StyleSheetContents.h */; }; … … 12670 12675 E47E276416036ED200EE2AFB /* DocumentStyleSheetCollection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DocumentStyleSheetCollection.h; sourceTree = "<group>"; }; 12671 12676 E47E276716036EDC00EE2AFB /* DocumentStyleSheetCollection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DocumentStyleSheetCollection.cpp; sourceTree = "<group>"; }; 12677 E48944A0180B57D800F165D8 /* SimpleLineLayout.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SimpleLineLayout.cpp; sourceTree = "<group>"; }; 12678 E48944A1180B57D800F165D8 /* SimpleLineLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SimpleLineLayout.h; sourceTree = "<group>"; }; 12672 12679 E4946EAC156E64DD00D3297F /* StyleRuleImport.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StyleRuleImport.cpp; sourceTree = "<group>"; }; 12673 12680 E4946EAD156E64DD00D3297F /* StyleRuleImport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StyleRuleImport.h; sourceTree = "<group>"; }; … … 12723 12730 E4DEAA1517A93DC3000E0430 /* StyleResolveTree.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StyleResolveTree.cpp; sourceTree = "<group>"; }; 12724 12731 E4DEAA1617A93DC3000E0430 /* StyleResolveTree.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StyleResolveTree.h; sourceTree = "<group>"; }; 12732 E4E9B1181810916F003ACCDF /* SimpleLineLayoutResolver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SimpleLineLayoutResolver.h; sourceTree = "<group>"; }; 12733 E4E9B11A18145692003ACCDF /* SimpleLineLayoutFunctions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SimpleLineLayoutFunctions.cpp; sourceTree = "<group>"; }; 12734 E4E9B11C1814569C003ACCDF /* SimpleLineLayoutFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SimpleLineLayoutFunctions.h; sourceTree = "<group>"; }; 12725 12735 E4F9EEF0156D84C400D23E7E /* StyleSheetContents.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StyleSheetContents.cpp; sourceTree = "<group>"; }; 12726 12736 E4F9EEF1156D84C400D23E7E /* StyleSheetContents.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StyleSheetContents.h; sourceTree = "<group>"; }; … … 20769 20779 5D925B660F64D4DD00B847F0 /* ScrollBehavior.h */, 20770 20780 A8CFF04C0A154F09000A4234 /* TableLayout.h */, 20781 E48944A0180B57D800F165D8 /* SimpleLineLayout.cpp */, 20782 E48944A1180B57D800F165D8 /* SimpleLineLayout.h */, 20783 E4E9B11A18145692003ACCDF /* SimpleLineLayoutFunctions.cpp */, 20784 E4E9B11C1814569C003ACCDF /* SimpleLineLayoutFunctions.h */, 20785 E4E9B1181810916F003ACCDF /* SimpleLineLayoutResolver.h */, 20771 20786 E4C91A0F1802343900A17F6D /* TextPaintStyle.cpp */, 20772 20787 E4C91A0D1802343100A17F6D /* TextPaintStyle.h */, … … 22574 22589 0F580B0D0F12A2690051D689 /* GraphicsLayer.h in Headers */, 22575 22590 499B3ED7128CD31400E726C2 /* GraphicsLayerCA.h in Headers */, 22591 E4E9B1191810916F003ACCDF /* SimpleLineLayoutResolver.h in Headers */, 22576 22592 0F580B0E0F12A2690051D689 /* GraphicsLayerClient.h in Headers */, 22577 22593 CDAB6D2E17C814EE00C60B34 /* JSMediaControlsHost.h in Headers */, … … 23634 23650 D0FF2A5E11F8C45A007E74E0 /* PingLoader.h in Headers */, 23635 23651 377C4CDF1014E9F600B9AE42 /* PlaceholderDocument.h in Headers */, 23652 E4E9B11D1814569C003ACCDF /* SimpleLineLayoutFunctions.h in Headers */, 23636 23653 499B3EDD128DB50200E726C2 /* PlatformCAAnimation.h in Headers */, 23637 23654 0F13163E16ED0CC80035CC04 /* PlatformCAFilters.h in Headers */, … … 23820 23837 CD3A496217A9D01B00274E42 /* SourceBuffer.h in Headers */, 23821 23838 436708CB12D9CA4B00044234 /* RenderSVGModelObject.h in Headers */, 23839 E48944A3180B57D800F165D8 /* SimpleLineLayout.h in Headers */, 23822 23840 ADDF1AD71257CD9A0003A759 /* RenderSVGPath.h in Headers */, 23823 23841 A10BB5851484E3A700B2E87A /* RenderSVGRect.h in Headers */, … … 26604 26622 BE8EF04A171C9014009B48C3 /* JSVideoTrack.cpp in Sources */, 26605 26623 BE6DF70B171CA2C500DD52B8 /* JSVideoTrackCustom.cpp in Sources */, 26624 E4E9B11B18145692003ACCDF /* SimpleLineLayoutFunctions.cpp in Sources */, 26606 26625 BE8EF04C171C9014009B48C3 /* JSVideoTrackList.cpp in Sources */, 26607 26626 BE6DF70D171CA2C500DD52B8 /* JSVideoTrackListCustom.cpp in Sources */, … … 26846 26865 F34742DC134362F000531BC2 /* PageDebuggerAgent.cpp in Sources */, 26847 26866 9302B0BD0D79F82900C7EE83 /* PageGroup.cpp in Sources */, 26867 E48944A2180B57D800F165D8 /* SimpleLineLayout.cpp in Sources */, 26848 26868 7A674BDB0F9EBF4E006CF099 /* PageGroupLoadDeferrer.cpp in Sources */, 26849 26869 1C26497C0D7E24EC00BD10F2 /* PageMac.cpp in Sources */, -
trunk/Source/WebCore/dom/Position.cpp
r157517 r157950 645 645 646 646 // return current position if it is in rendered text 647 if (renderer->isText() && toRenderText(renderer)->firstTextBox()) { 647 if (renderer->isText()) { 648 auto& textRenderer = toRenderText(*renderer); 649 textRenderer.ensureLineBoxes(); 650 651 if (!textRenderer.firstTextBox()) 652 continue; 648 653 if (currentNode != startNode) { 649 654 // This assertion fires in layout tests in the case-transform.html test because … … 656 661 657 662 unsigned textOffset = currentPos.offsetInLeafNode(); 658 RenderText* textRenderer = toRenderText(renderer); 659 InlineTextBox* lastTextBox = textRenderer->lastTextBox(); 660 for (InlineTextBox* box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) { 663 auto lastTextBox = textRenderer.lastTextBox(); 664 for (auto box = textRenderer.firstTextBox(); box; box = box->nextTextBox()) { 661 665 if (textOffset <= box->start() + box->len()) { 662 666 if (textOffset > box->start()) … … 677 681 if (!otherBox) 678 682 break; 679 if (otherBox == lastTextBox || (&otherBox->renderer() == textRenderer && static_cast<InlineTextBox*>(otherBox)->start() > textOffset))683 if (otherBox == lastTextBox || (&otherBox->renderer() == &textRenderer && static_cast<InlineTextBox*>(otherBox)->start() > textOffset)) 680 684 continuesOnNextLine = false; 681 685 } … … 686 690 if (!otherBox) 687 691 break; 688 if (otherBox == lastTextBox || (&otherBox->renderer() == textRenderer && static_cast<InlineTextBox*>(otherBox)->start() > textOffset))692 if (otherBox == lastTextBox || (&otherBox->renderer() == &textRenderer && static_cast<InlineTextBox*>(otherBox)->start() > textOffset)) 689 693 continuesOnNextLine = false; 690 694 } … … 773 777 774 778 // return current position if it is in rendered text 775 if (renderer->isText() && toRenderText(renderer)->firstTextBox()) { 779 if (renderer->isText()) { 780 auto& textRenderer = toRenderText(*renderer); 781 textRenderer.ensureLineBoxes(); 782 783 if (!textRenderer.firstTextBox()) 784 continue; 776 785 if (currentNode != startNode) { 777 786 ASSERT(currentPos.atStartOfNode()); … … 780 789 781 790 unsigned textOffset = currentPos.offsetInLeafNode(); 782 RenderText* textRenderer = toRenderText(renderer); 783 InlineTextBox* lastTextBox = textRenderer->lastTextBox(); 784 for (InlineTextBox* box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) { 791 auto lastTextBox = textRenderer.lastTextBox(); 792 for (auto box = textRenderer.firstTextBox(); box; box = box->nextTextBox()) { 785 793 if (textOffset <= box->end()) { 786 794 if (textOffset >= box->start()) … … 801 809 if (!otherBox) 802 810 break; 803 if (otherBox == lastTextBox || (&otherBox->renderer() == textRenderer && static_cast<InlineTextBox*>(otherBox)->start() >= textOffset))811 if (otherBox == lastTextBox || (&otherBox->renderer() == &textRenderer && static_cast<InlineTextBox*>(otherBox)->start() >= textOffset)) 804 812 continuesOnNextLine = false; 805 813 } … … 810 818 if (!otherBox) 811 819 break; 812 if (otherBox == lastTextBox || (&otherBox->renderer() == textRenderer && static_cast<InlineTextBox*>(otherBox)->start() >= textOffset))820 if (otherBox == lastTextBox || (&otherBox->renderer() == &textRenderer && static_cast<InlineTextBox*>(otherBox)->start() >= textOffset)) 813 821 continuesOnNextLine = false; 814 822 } … … 1155 1163 inlineBox = !caretOffset ? toRenderLineBreak(renderer)->inlineBoxWrapper() : nullptr; 1156 1164 else if (renderer->isText()) { 1157 RenderText* textRenderer = toRenderText(renderer); 1165 auto textRenderer = toRenderText(renderer); 1166 textRenderer->ensureLineBoxes(); 1158 1167 1159 1168 InlineTextBox* box; -
trunk/Source/WebCore/editing/TextIterator.cpp
r157694 r157950 520 520 emitText(m_node, runStart, runEnd); 521 521 return true; 522 } 523 524 if (renderer->simpleLines()) { 525 if (renderer->style()->visibility() != VISIBLE && !m_ignoresStyleVisibility) 526 return true; 527 // This code aims to produce same results as handleTextBox() below so test results don't change. It does not make much logical sense. 528 unsigned runEnd = m_offset; 529 unsigned runStart = m_offset; 530 while (runEnd < str.length() && (isCollapsibleWhitespace(str[runEnd]) || str[runEnd] == '\t')) 531 ++runEnd; 532 bool addSpaceForPrevious = m_lastTextNodeEndedWithCollapsedSpace && m_lastCharacter && !isCollapsibleWhitespace(m_lastCharacter); 533 if (runEnd > runStart || addSpaceForPrevious) { 534 if (runEnd == str.length()) { 535 m_lastTextNodeEndedWithCollapsedSpace = true; 536 return true; 537 } 538 bool addSpaceForCurrent = runStart || (m_lastCharacter && !isCollapsibleWhitespace(m_lastCharacter)); 539 if (addSpaceForCurrent || addSpaceForPrevious) { 540 emitCharacter(' ', m_node, 0, runStart, runEnd); 541 m_offset = runEnd; 542 return false; 543 } 544 runStart = runEnd; 545 } 546 while (runEnd < str.length() && !isCollapsibleWhitespace(str[runEnd])) 547 ++runEnd; 548 if (runStart < str.length()) 549 emitText(m_node, renderer, runStart, runEnd); 550 m_offset = runEnd; 551 return runEnd == str.length(); 522 552 } 523 553 -
trunk/Source/WebCore/rendering/RenderBlock.cpp
r157828 r157950 153 153 , m_hasMarkupTruncation(false) 154 154 , m_hasBorderOrPaddingLogicalWidthChanged(false) 155 , m_forceLineBoxLayout(false) 155 156 #if ENABLE(IOS_TEXT_AUTOSIZING) 156 157 , m_widthForTextAutosizing(-1) … … 168 169 , m_hasMarkupTruncation(false) 169 170 , m_hasBorderOrPaddingLogicalWidthChanged(false) 171 , m_forceLineBoxLayout(false) 170 172 #if ENABLE(IOS_TEXT_AUTOSIZING) 171 173 , m_widthForTextAutosizing(-1) … … 1384 1386 ShapeInsideInfo* RenderBlock::layoutShapeInsideInfo() const 1385 1387 { 1388 // This may be called outside layout when switching from SimpleLineLayout to line boxes. This case never has shape info. 1389 if (!view().layoutState()) 1390 return nullptr; 1391 1386 1392 ShapeInsideInfo* shapeInsideInfo = view().layoutState()->shapeInsideInfo(); 1387 1393 -
trunk/Source/WebCore/rendering/RenderBlock.h
r157907 r157950 752 752 OwnPtr<RenderBlockRareData> m_rareData; 753 753 754 mutable signed m_lineHeight : 2 7;754 mutable signed m_lineHeight : 26; 755 755 unsigned m_hasMarginBeforeQuirk : 1; // Note these quirk values can't be put in RenderBlockRareData since they are set too frequently. 756 756 unsigned m_hasMarginAfterQuirk : 1; … … 758 758 unsigned m_hasMarkupTruncation : 1; 759 759 unsigned m_hasBorderOrPaddingLogicalWidthChanged : 1; 760 unsigned m_forceLineBoxLayout : 1; 760 761 761 762 #if ENABLE(IOS_TEXT_AUTOSIZING) -
trunk/Source/WebCore/rendering/RenderBlockFlow.cpp
r157828 r157950 34 34 #include "RenderLayer.h" 35 35 #include "RenderNamedFlowFragment.h" 36 #include "RenderText.h" 36 37 #include "RenderView.h" 38 #include "SimpleLineLayoutFunctions.h" 37 39 #include "VerticalPositionCache.h" 38 40 #include "VisiblePosition.h" … … 517 519 // determining the correct collapsed bottom margin information. 518 520 handleAfterSideOfBlock(beforeEdge, afterEdge, marginInfo); 521 } 522 523 void RenderBlockFlow::layoutInlineChildren(bool relayoutChildren, LayoutUnit& repaintLogicalTop, LayoutUnit& repaintLogicalBottom) 524 { 525 bool canUseSimpleLineLayout = !m_forceLineBoxLayout && SimpleLineLayout::canUseFor(*this); 526 if (canUseSimpleLineLayout) { 527 deleteLineBoxesBeforeSimpleLineLayout(); 528 layoutSimpleLines(repaintLogicalTop, repaintLogicalBottom); 529 return; 530 } 531 532 m_simpleLines = nullptr; 533 layoutLineBoxes(relayoutChildren, repaintLogicalTop, repaintLogicalBottom); 519 534 } 520 535 … … 1633 1648 m_floatingObjects->clearLineBoxTreePointers(); 1634 1649 1635 m_lineBoxes.deleteLineBoxTree(renderArena()); 1650 if (m_simpleLines) { 1651 ASSERT(!m_lineBoxes.firstLineBox()); 1652 m_simpleLines = nullptr; 1653 } else 1654 m_lineBoxes.deleteLineBoxTree(renderArena()); 1636 1655 1637 1656 RenderBlock::deleteLines(); … … 2414 2433 { 2415 2434 ASSERT(childrenInline()); 2435 2436 if (m_simpleLines) 2437 return SimpleLineLayout::hitTestFlow(*this, *m_simpleLines, request, result, locationInContainer, accumulatedOffset, hitTestAction); 2438 2416 2439 return m_lineBoxes.hitTest(this, request, result, locationInContainer, accumulatedOffset, hitTestAction); 2417 2440 } … … 2425 2448 // for either overflow or translations via relative positioning. 2426 2449 if (childrenInline()) { 2450 const_cast<RenderBlockFlow&>(*this).ensureLineBoxes(); 2451 2427 2452 for (auto box = firstRootBox(); box; box = box->nextRootBox()) { 2428 2453 if (box->firstChild()) … … 2513 2538 return RenderBlock::firstLineBaseline(); 2514 2539 2515 if (firstLineBox()) 2516 return firstLineBox()->logicalTop() + firstLineStyle()->fontMetrics().ascent(firstRootBox()->baselineType()); 2517 2518 return -1; 2540 if (!hasLines()) 2541 return -1; 2542 2543 if (m_simpleLines) 2544 return SimpleLineLayout::computeFlowFirstLineBaseline(*this, *m_simpleLines); 2545 2546 ASSERT(firstLineBox()); 2547 return firstLineBox()->logicalTop() + firstLineStyle()->fontMetrics().ascent(firstRootBox()->baselineType()); 2519 2548 } 2520 2549 … … 2536 2565 } 2537 2566 2567 if (m_simpleLines) 2568 return SimpleLineLayout::computeFlowLastLineBaseline(*this, *m_simpleLines); 2569 2538 2570 bool isFirstLine = lastLineBox() == firstLineBox(); 2539 2571 RenderStyle* style = isFirstLine ? firstLineStyle() : this->style(); … … 2544 2576 LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const LogicalSelectionOffsetCaches& cache, const PaintInfo* paintInfo) 2545 2577 { 2578 ASSERT(!m_simpleLines); 2579 2546 2580 GapRects result; 2547 2581 … … 2753 2787 2754 2788 if (childrenInline() && hasMarkupTruncation()) { 2789 ensureLineBoxes(); 2790 2755 2791 setHasMarkupTruncation(false); 2756 2792 for (auto box = firstRootBox(); box; box = box->nextRootBox()) … … 2793 2829 { 2794 2830 ASSERT(childrenInline()); 2831 2832 ensureLineBoxes(); 2795 2833 2796 2834 if (!firstRootBox()) … … 2880 2918 void RenderBlockFlow::addFocusRingRectsForInlineChildren(Vector<IntRect>& rects, const LayoutPoint& additionalOffset, const RenderLayerModelObject*) 2881 2919 { 2920 ASSERT(childrenInline()); 2921 2922 ensureLineBoxes(); 2923 2882 2924 for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) { 2883 2925 LayoutUnit top = max<LayoutUnit>(curr->lineTop(), curr->top()); … … 2892 2934 { 2893 2935 ASSERT(childrenInline()); 2936 2937 if (m_simpleLines) { 2938 SimpleLineLayout::paintFlow(*this, *m_simpleLines, paintInfo, paintOffset); 2939 return; 2940 } 2894 2941 m_lineBoxes.paint(this, paintInfo, paintOffset); 2895 2942 } … … 2947 2994 } 2948 2995 2996 bool RenderBlockFlow::hasLines() const 2997 { 2998 ASSERT(childrenInline()); 2999 3000 if (m_simpleLines) 3001 return !m_simpleLines->isEmpty(); 3002 3003 return lineBoxes().firstLineBox(); 3004 } 3005 3006 void RenderBlockFlow::layoutSimpleLines(LayoutUnit& repaintLogicalTop, LayoutUnit& repaintLogicalBottom) 3007 { 3008 ASSERT(!m_lineBoxes.firstLineBox()); 3009 3010 m_simpleLines = SimpleLineLayout::createLines(*this); 3011 3012 LayoutUnit lineLayoutHeight = SimpleLineLayout::computeFlowHeight(*this, *m_simpleLines); 3013 LayoutUnit lineLayoutTop = borderAndPaddingBefore(); 3014 3015 repaintLogicalTop = lineLayoutTop; 3016 repaintLogicalBottom = lineLayoutTop + lineLayoutHeight; 3017 3018 setLogicalHeight(lineLayoutTop + lineLayoutHeight + borderAndPaddingAfter()); 3019 } 3020 3021 void RenderBlockFlow::deleteLineBoxesBeforeSimpleLineLayout() 3022 { 3023 ASSERT(!m_forceLineBoxLayout); 3024 lineBoxes().deleteLineBoxes(renderArena()); 3025 toRenderText(firstChild())->deleteLineBoxesBeforeSimpleLineLayout(); 3026 } 3027 3028 void RenderBlockFlow::ensureLineBoxes() 3029 { 3030 m_forceLineBoxLayout = true; 3031 3032 if (!m_simpleLines) 3033 return; 3034 m_simpleLines = nullptr; 3035 3036 #if !ASSERT_DISABLED 3037 LayoutUnit oldHeight = logicalHeight(); 3038 #endif 3039 bool didNeedLayout = needsLayout(); 3040 3041 bool relayoutChildren = false; 3042 LayoutUnit repaintLogicalTop; 3043 LayoutUnit repaintLogicalBottom; 3044 layoutLineBoxes(relayoutChildren, repaintLogicalTop, repaintLogicalBottom); 3045 3046 updateLogicalHeight(); 3047 ASSERT(didNeedLayout || logicalHeight() == oldHeight); 3048 3049 if (!didNeedLayout) 3050 clearNeedsLayout(); 3051 } 3052 2949 3053 #ifndef NDEBUG 2950 3054 void RenderBlockFlow::showLineTreeAndMark(const InlineBox* markedBox1, const char* markedLabel1, const InlineBox* markedBox2, const char* markedLabel2, const RenderObject* obj) const -
trunk/Source/WebCore/rendering/RenderBlockFlow.h
r157907 r157950 26 26 #include "RenderBlock.h" 27 27 #include "RenderLineBoxList.h" 28 #include "SimpleLineLayout.h" 28 29 29 30 namespace WebCore { … … 54 55 void layoutBlockChildren(bool relayoutChildren, LayoutUnit& maxFloatLogicalBottom); 55 56 void layoutInlineChildren(bool relayoutChildren, LayoutUnit& repaintLogicalTop, LayoutUnit& repaintLogicalBottom); 56 57 57 58 // RenderBlockFlows override these methods, since they are the only class that supports margin collapsing. 58 59 virtual LayoutUnit collapsedMarginBefore() const OVERRIDE FINAL { return maxPositiveMarginBefore() - maxNegativeMarginBefore(); } … … 311 312 RootInlineBox* lastRootBox() const { return static_cast<RootInlineBox*>(lastLineBox()); } 312 313 313 virtual bool hasLines() const OVERRIDE FINAL { return firstLineBox(); }314 virtual bool hasLines() const OVERRIDE FINAL; 314 315 315 316 // Helper methods for computing line counts and heights for line counts. … … 323 324 324 325 bool containsNonZeroBidiLevel() const; 326 327 const SimpleLineLayout::Lines* simpleLines() const { return m_simpleLines.get(); } 328 void deleteLineBoxesBeforeSimpleLineLayout(); 329 void ensureLineBoxes(); 325 330 326 331 #ifndef NDEBUG … … 428 433 429 434 private: 435 void layoutLineBoxes(bool relayoutChildren, LayoutUnit& repaintLogicalTop, LayoutUnit& repaintLogicalBottom); 436 void layoutSimpleLines(LayoutUnit& repaintLogicalTop, LayoutUnit& repaintLogicalBottom); 437 430 438 virtual RootInlineBox* createRootInlineBox(); // Subclassed by SVG and Ruby. 431 439 InlineFlowBox* createLineBoxes(RenderObject*, const LineInfo&, InlineBox* childBox, bool startsNewSegment); … … 480 488 OwnPtr<RenderBlockFlowRareData> m_rareData; 481 489 RenderLineBoxList m_lineBoxes; 490 std::unique_ptr<SimpleLineLayout::Lines> m_simpleLines; 482 491 483 492 friend class BreakingContext; -
trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp
r157851 r157950 46 46 #include "RenderView.h" 47 47 #include "Settings.h" 48 #include "SimpleLineLayoutFunctions.h" 48 49 #include "TrailingFloatsRootInlineBox.h" 49 50 #include "VerticalPositionCache.h" … … 1834 1835 } 1835 1836 1836 void RenderBlockFlow::layoutInlineChildren(bool relayoutChildren, LayoutUnit& repaintLogicalTop, LayoutUnit& repaintLogicalBottom) 1837 { 1837 void RenderBlockFlow::layoutLineBoxes(bool relayoutChildren, LayoutUnit& repaintLogicalTop, LayoutUnit& repaintLogicalBottom) 1838 { 1839 ASSERT(!m_simpleLines); 1840 1838 1841 setLogicalHeight(borderAndPaddingBefore()); 1839 1842 … … 3511 3514 void RenderBlockFlow::addOverflowFromInlineChildren() 3512 3515 { 3516 if (auto lines = simpleLines()) { 3517 ASSERT(!hasOverflowClip()); 3518 SimpleLineLayout::collectFlowOverflow(*this, *lines); 3519 return; 3520 } 3513 3521 LayoutUnit endPadding = hasOverflowClip() ? paddingEnd() : LayoutUnit(); 3514 3522 // FIXME: Need to find another way to do this, since scrollbars could show when we don't want them to. -
trunk/Source/WebCore/rendering/RenderText.cpp
r157517 r157950 40 40 #include "RenderView.h" 41 41 #include "Settings.h" 42 #include "SimpleLineLayoutFunctions.h" 42 43 #include "Text.h" 43 44 #include "TextBreakIterator.h" … … 266 267 } 267 268 269 void RenderText::deleteLineBoxesBeforeSimpleLineLayout() 270 { 271 m_lineBoxes.deleteAll(*this); 272 } 273 268 274 String RenderText::originalText() const 269 275 { … … 273 279 void RenderText::absoluteRects(Vector<IntRect>& rects, const LayoutPoint& accumulatedOffset) const 274 280 { 281 // FIXME: These will go away when simple layout can do everything. 282 const_cast<RenderText&>(*this).ensureLineBoxes(); 283 275 284 rects.appendVector(m_lineBoxes.absoluteRects(accumulatedOffset)); 276 285 } … … 278 287 Vector<IntRect> RenderText::absoluteRectsForRange(unsigned start, unsigned end, bool useSelectionHeight, bool* wasFixed) const 279 288 { 289 const_cast<RenderText&>(*this).ensureLineBoxes(); 290 280 291 // Work around signed/unsigned issues. This function takes unsigneds, and is often passed UINT_MAX 281 292 // to mean "all the way to the end". InlineTextBox coordinates are unsigneds, so changing this … … 293 304 Vector<FloatQuad> RenderText::absoluteQuadsClippedToEllipsis() const 294 305 { 306 const_cast<RenderText&>(*this).ensureLineBoxes(); 307 295 308 return m_lineBoxes.absoluteQuads(*this, nullptr, RenderTextLineBoxes::ClipToEllipsis); 296 309 } … … 298 311 void RenderText::absoluteQuads(Vector<FloatQuad>& quads, bool* wasFixed) const 299 312 { 313 const_cast<RenderText&>(*this).ensureLineBoxes(); 314 300 315 quads.appendVector(m_lineBoxes.absoluteQuads(*this, wasFixed, RenderTextLineBoxes::NoClipping)); 301 316 } … … 303 318 Vector<FloatQuad> RenderText::absoluteQuadsForRange(unsigned start, unsigned end, bool useSelectionHeight, bool* wasFixed) const 304 319 { 320 const_cast<RenderText&>(*this).ensureLineBoxes(); 321 305 322 // Work around signed/unsigned issues. This function takes unsigneds, and is often passed UINT_MAX 306 323 // to mean "all the way to the end". InlineTextBox coordinates are unsigneds, so changing this … … 318 335 VisiblePosition RenderText::positionForPoint(const LayoutPoint& point) 319 336 { 337 ensureLineBoxes(); 338 320 339 return m_lineBoxes.positionForPoint(*this, point); 321 340 } … … 492 511 } 493 512 513 bool RenderText::knownToHaveNoOverflowAndNoFallbackFonts() const 514 { 515 if (preferredLogicalWidthsDirty()) 516 const_cast<RenderText*>(this)->computePreferredLogicalWidths(0); 517 518 return m_knownToHaveNoOverflowAndNoFallbackFonts; 519 } 520 494 521 void RenderText::computePreferredLogicalWidths(float leadWidth) 495 522 { … … 837 864 void RenderText::setSelectionState(SelectionState state) 838 865 { 866 if (state != SelectionNone) 867 ensureLineBoxes(); 868 839 869 RenderObject::setSelectionState(state); 840 870 … … 856 886 unsigned end = len ? offset + len - 1 : offset; 857 887 858 m_linesDirty = m_lineBoxes.dirtyRange(*this, offset, end, delta);888 m_linesDirty = simpleLines() || m_lineBoxes.dirtyRange(*this, offset, end, delta); 859 889 860 890 setText(text, force || m_linesDirty); … … 1024 1054 1025 1055 m_containsReversedText |= !textBox->isLeftToRightDirection(); 1056 } 1057 1058 void RenderText::ensureLineBoxes() 1059 { 1060 if (!parent()->isRenderBlockFlow()) 1061 return; 1062 toRenderBlockFlow(parent())->ensureLineBoxes(); 1063 } 1064 1065 const SimpleLineLayout::Lines* RenderText::simpleLines() const 1066 { 1067 if (!parent()->isRenderBlockFlow()) 1068 return nullptr; 1069 return toRenderBlockFlow(parent())->simpleLines(); 1026 1070 } 1027 1071 … … 1076 1120 IntRect RenderText::linesBoundingBox() const 1077 1121 { 1122 if (auto lines = simpleLines()) 1123 return SimpleLineLayout::computeTextBoundingBox(*this, *lines); 1124 1078 1125 return m_lineBoxes.boundingBox(*this); 1079 1126 } … … 1081 1128 LayoutRect RenderText::linesVisualOverflowBoundingBox() const 1082 1129 { 1130 ASSERT(!simpleLines()); 1083 1131 return m_lineBoxes.visualOverflowBoundingBox(*this); 1084 1132 } … … 1103 1151 { 1104 1152 ASSERT(!needsLayout()); 1153 ASSERT(!simpleLines()); 1105 1154 1106 1155 if (selectionState() == SelectionNone) … … 1144 1193 int RenderText::caretMinOffset() const 1145 1194 { 1195 if (auto lines = simpleLines()) 1196 return SimpleLineLayout::findTextCaretMinimumOffset(*this, *lines); 1146 1197 return m_lineBoxes.caretMinOffset(); 1147 1198 } … … 1149 1200 int RenderText::caretMaxOffset() const 1150 1201 { 1202 if (auto lines = simpleLines()) 1203 return SimpleLineLayout::findTextCaretMaximumOffset(*this, *lines); 1151 1204 return m_lineBoxes.caretMaxOffset(*this); 1152 1205 } … … 1154 1207 unsigned RenderText::countRenderedCharacterOffsetsUntil(unsigned offset) const 1155 1208 { 1209 ASSERT(!simpleLines()); 1156 1210 return m_lineBoxes.countCharacterOffsetsUntil(offset); 1157 1211 } … … 1159 1213 bool RenderText::containsRenderedCharacterOffset(unsigned offset) const 1160 1214 { 1215 ASSERT(!simpleLines()); 1161 1216 return m_lineBoxes.containsOffset(*this, offset, RenderTextLineBoxes::CharacterOffset); 1162 1217 } … … 1164 1219 bool RenderText::containsCaretOffset(unsigned offset) const 1165 1220 { 1221 if (auto layout = simpleLines()) 1222 return SimpleLineLayout::containsTextCaretOffset(*this, *layout, offset); 1166 1223 return m_lineBoxes.containsOffset(*this, offset, RenderTextLineBoxes::CaretOffset); 1167 1224 } … … 1169 1226 bool RenderText::hasRenderedText() const 1170 1227 { 1228 if (auto lines = simpleLines()) 1229 return SimpleLineLayout::isTextRendered(*this, *lines); 1171 1230 return m_lineBoxes.hasRenderedText(); 1172 1231 } -
trunk/Source/WebCore/rendering/RenderText.h
r157907 r157950 26 26 #include "RenderElement.h" 27 27 #include "RenderTextLineBoxes.h" 28 #include "SimpleLineLayout.h" 28 29 #include "Text.h" 29 30 #include <wtf/Forward.h> … … 140 141 141 142 bool canUseSimpleFontCodePath() const { return m_canUseSimpleFontCodePath; } 142 bool knownToHaveNoOverflowAndNoFallbackFonts() const { return m_knownToHaveNoOverflowAndNoFallbackFonts; }143 bool knownToHaveNoOverflowAndNoFallbackFonts() const; 143 144 144 145 void removeAndDestroyTextBoxes(); … … 152 153 void setCandidateComputedTextSize(float s) { m_candidateComputedTextSize = s; } 153 154 #endif 155 156 void ensureLineBoxes(); 157 void deleteLineBoxesBeforeSimpleLineLayout(); 158 const SimpleLineLayout::Lines* simpleLines() const; 154 159 155 160 protected: … … 198 203 mutable bool m_knownToHaveNoOverflowAndNoFallbackFonts : 1; 199 204 bool m_useBackslashAsYenSymbol : 1; 200 205 201 206 #if ENABLE(IOS_TEXT_AUTOSIZING) 202 207 // FIXME: This should probably be part of the text sizing structures in Document instead. That would save some memory. -
trunk/Source/WebCore/rendering/RenderTreeAsText.cpp
r157793 r157950 37 37 #include "PrintContext.h" 38 38 #include "PseudoElement.h" 39 #include "RenderBlockFlow.h" 39 40 #include "RenderDetailsMarker.h" 40 41 #include "RenderFileUploadControl.h" … … 50 51 #include "RenderWidget.h" 51 52 #include "ShadowRoot.h" 53 #include "SimpleLineLayoutResolver.h" 52 54 #include "StylePropertySet.h" 53 55 #include <wtf/HexNumber.h> … … 245 247 const RenderText& text = toRenderText(o); 246 248 IntRect linesBox = text.linesBoundingBox(); 247 r = IntRect(text.firstRunX(), text.firstRunY(), linesBox.width(), linesBox.height()); 249 if (text.simpleLines()) { 250 int y = linesBox.y(); 251 if (text.containingBlock()->isTableCell()) 252 y -= toRenderTableCell(o.containingBlock())->intrinsicPaddingBefore(); 253 r = IntRect(linesBox.x(), y, linesBox.width(), linesBox.height()); 254 } else 255 r = IntRect(text.firstRunX(), text.firstRunY(), linesBox.width(), linesBox.height()); 248 256 if (adjustForTableCells && !text.firstTextBox()) 249 257 adjustForTableCells = false; … … 527 535 } 528 536 537 static void writeSimpleLine(TextStream& ts, const RenderText& o, const LayoutRect& rect, const String& text) 538 { 539 int x = rect.x(); 540 int y = rect.y(); 541 int logicalWidth = ceilf(rect.x() + rect.width()) - x; 542 543 if (o.containingBlock()->isTableCell()) 544 y -= toRenderTableCell(o.containingBlock())->intrinsicPaddingBefore(); 545 546 ts << "text run at (" << x << "," << y << ") width " << logicalWidth; 547 ts << ": " 548 << quoteAndEscapeNonPrintables(text); 549 ts << "\n"; 550 } 551 529 552 void write(TextStream& ts, const RenderObject& o, int indent, RenderAsTextBehavior behavior) 530 553 { … … 570 593 571 594 if (o.isText()) { 572 const RenderText& text = toRenderText(o); 573 for (InlineTextBox* box = text.firstTextBox(); box; box = box->nextTextBox()) { 574 writeIndent(ts, indent + 1); 575 writeTextRun(ts, text, *box); 576 } 595 auto& text = toRenderText(o); 596 if (auto lines = text.simpleLines()) { 597 ASSERT(!text.firstTextBox()); 598 SimpleLineLayout::Resolver resolver(*lines, toRenderBlockFlow(*text.parent())); 599 for (auto it = resolver.begin(), end = resolver.end(); it != end; ++it) { 600 auto line = *it; 601 writeIndent(ts, indent + 1); 602 writeSimpleLine(ts, text, line.rect(), line.text()); 603 } 604 } else { 605 for (auto box = text.firstTextBox(); box; box = box->nextTextBox()) { 606 writeIndent(ts, indent + 1); 607 writeTextRun(ts, text, *box); 608 } 609 } 610 577 611 } else { 578 612 if (!toRenderElement(o).isRenderNamedFlowFragmentContainer()) {
Note: See TracChangeset
for help on using the changeset viewer.