Changeset 157950 in webkit


Ignore:
Timestamp:
Oct 24, 2013 1:31:11 PM (10 years ago)
Author:
Antti Koivisto
Message:

Simple line layout
https://bugs.webkit.org/show_bug.cgi?id=122458

Reviewed by Darin Adler.

Line box based inline layout is powerful but also rather slow and memory intensive. Simple line layout
is a compact alternative data structure and fast code path to cover common cases without requiring line
boxes.

This patch handles a case single left-aligned text renderer inside flow with no floats. Even this very basic
case is sufficiently common to handle up to 25% of all text lines on some popular new sites. The decision
which path to use is made per block flow (paragraph).

Simple line layout aims to produce pixel-exact rendering result when compared to the line box layout.

The goal is to handle everything that requires line level access in cases that allow use of simple lines.
This is not quite the case yet. For example selections and outline painting are not supported. In these
cases we seamlessly switch to the line boxes.

The simple line data structure currently uses 12 bytes per line. Lineboxes take ~160 bytes minimum per line.
Laying out the lines is also several times faster as is iterating over them.

  • CMakeLists.txt:
  • GNUmakefile.list.am:
  • WebCore.vcxproj/WebCore.vcxproj:
  • WebCore.xcodeproj/project.pbxproj:
  • dom/Position.cpp:

(WebCore::Position::upstream):
(WebCore::Position::downstream):
(WebCore::Position::getInlineBoxAndOffset):

Creating positions within a simple line flow causes switch to line boxes.

  • editing/TextIterator.cpp:

(WebCore::TextIterator::handleTextNode):

TextIterator traverses line boxes if available. In case simple line case we need to replicate the
same results (for compatibility but especially to avoid changing test results). This is done here
by just traversing the string without actually using the layout.

  • rendering/RenderBlock.cpp:

(WebCore::RenderBlock::RenderBlock):
(WebCore::RenderBlock::layoutShapeInsideInfo):

  • rendering/RenderBlock.h:
  • rendering/RenderBlockFlow.cpp:

(WebCore::RenderBlockFlow::layoutInlineChildren):

Select the layout path to use.

(WebCore::RenderBlockFlow::deleteLines):
(WebCore::RenderBlockFlow::hitTestInlineChildren):
(WebCore::RenderBlockFlow::adjustForBorderFit):
(WebCore::RenderBlockFlow::firstLineBaseline):
(WebCore::RenderBlockFlow::inlineBlockBaseline):
(WebCore::RenderBlockFlow::inlineSelectionGaps):
(WebCore::RenderBlockFlow::clearTruncation):
(WebCore::RenderBlockFlow::positionForPointWithInlineChildren):
(WebCore::RenderBlockFlow::addFocusRingRectsForInlineChildren):
(WebCore::RenderBlockFlow::paintInlineChildren):
(WebCore::RenderBlockFlow::hasLines):
(WebCore::RenderBlockFlow::layoutSimpleLines):

Do simple layout.

(WebCore::RenderBlockFlow::deleteLineBoxesBeforeSimpleLineLayout):
(WebCore::RenderBlockFlow::ensureLineBoxes):

This function switches from simple lines to line boxes. The switching can be done outside normal layout.
This is used to cover some cases that are not yet supported by simple lines (like selections).

  • rendering/RenderBlockFlow.h:

(WebCore::RenderBlockFlow::simpleLines):

  • rendering/RenderBlockLineLayout.cpp:

(WebCore::RenderBlockFlow::layoutLineBoxes):

Rename the line box layout function.

(WebCore::RenderBlockFlow::addOverflowFromInlineChildren):

  • rendering/RenderText.cpp:

(WebCore::RenderText::deleteLineBoxesBeforeSimpleLineLayout):
(WebCore::RenderText::absoluteRects):
(WebCore::RenderText::absoluteRectsForRange):
(WebCore::RenderText::absoluteQuadsClippedToEllipsis):
(WebCore::RenderText::absoluteQuads):
(WebCore::RenderText::absoluteQuadsForRange):
(WebCore::RenderText::positionForPoint):
(WebCore::RenderText::knownToHaveNoOverflowAndNoFallbackFonts):
(WebCore::RenderText::setSelectionState):
(WebCore::RenderText::setTextWithOffset):
(WebCore::RenderText::ensureLineBoxes):
(WebCore::RenderText::simpleLines):
(WebCore::RenderText::linesBoundingBox):
(WebCore::RenderText::linesVisualOverflowBoundingBox):
(WebCore::RenderText::selectionRectForRepaint):
(WebCore::RenderText::caretMinOffset):
(WebCore::RenderText::caretMaxOffset):
(WebCore::RenderText::countRenderedCharacterOffsetsUntil):
(WebCore::RenderText::containsRenderedCharacterOffset):
(WebCore::RenderText::containsCaretOffset):
(WebCore::RenderText::hasRenderedText):

  • rendering/RenderText.h:
  • rendering/RenderTreeAsText.cpp:

(WebCore::RenderTreeAsText::writeRenderObject):
(WebCore::writeSimpleLine):
(WebCore::write):

  • rendering/SimpleLineLayout.cpp: Added.

(WebCore::SimpleLineLayout::canUseFor):

This check for the cases supported by the simple line layout path.

(WebCore::SimpleLineLayout::isWhitespace):
(WebCore::SimpleLineLayout::skipWhitespaces):
(WebCore::SimpleLineLayout::textWidth):
(WebCore::SimpleLineLayout::createLines):

The main layout functions that breaks text to lines. It only handles the cases allowed by
SimpleLineLayout::canUseFor. What it handles it aims to break exactly as line box layout does.

  • rendering/SimpleLineLayout.h: Added.
  • rendering/SimpleLineLayoutFunctions.cpp: Added.

(WebCore::SimpleLineLayout::paintFlow):
(WebCore::SimpleLineLayout::hitTestFlow):
(WebCore::SimpleLineLayout::collectFlowOverflow):
(WebCore::SimpleLineLayout::computeTextBoundingBox):

  • rendering/SimpleLineLayoutFunctions.h: Added.

(WebCore::SimpleLineLayout::computeFlowHeight):
(WebCore::SimpleLineLayout::computeFlowFirstLineBaseline):
(WebCore::SimpleLineLayout::computeFlowLastLineBaseline):
(WebCore::SimpleLineLayout::findTextCaretMinimumOffset):
(WebCore::SimpleLineLayout::findTextCaretMaximumOffset):
(WebCore::SimpleLineLayout::containsTextCaretOffset):
(WebCore::SimpleLineLayout::isTextRendered):
(WebCore::SimpleLineLayout::lineHeightFromFlow):

Support functions called from RenderBlockFlow and RenderText. They are equivalent to
similar line box functions.

(WebCore::SimpleLineLayout::baselineFromFlow):

  • rendering/SimpleLineLayoutResolver.h: Added.

(WebCore::SimpleLineLayout::Resolver::Line::Line):
(WebCore::SimpleLineLayout::Resolver::Line::rect):
(WebCore::SimpleLineLayout::Resolver::Line::baseline):
(WebCore::SimpleLineLayout::Resolver::Line::text):
(WebCore::SimpleLineLayout::Resolver::Iterator::Iterator):
(WebCore::SimpleLineLayout::Resolver::Iterator::operator++):
(WebCore::SimpleLineLayout::Resolver::Iterator::operator--):
(WebCore::SimpleLineLayout::Resolver::Iterator::operator==):
(WebCore::SimpleLineLayout::Resolver::Iterator::operator!=):
(WebCore::SimpleLineLayout::Resolver::Iterator::operator*):

Lazy iterator for deriving line metrics. This keeps the line data structure small as
we don't need to keep easily derived values around.

(WebCore::SimpleLineLayout::Resolver::Resolver):
(WebCore::SimpleLineLayout::Resolver::size):
(WebCore::SimpleLineLayout::Resolver::begin):
(WebCore::SimpleLineLayout::Resolver::end):
(WebCore::SimpleLineLayout::Resolver::last):
(WebCore::SimpleLineLayout::Resolver::operator[]):

Location:
trunk/Source/WebCore
Files:
5 added
15 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/CMakeLists.txt

    r157936 r157950  
    21762176    rendering/RootInlineBox.cpp
    21772177    rendering/ScrollBehavior.cpp
     2178    rendering/SimpleLineLayout.cpp
     2179    rendering/SimpleLineLayoutFunctions.cpp
    21782180    rendering/TextAutosizer.cpp
    21792181    rendering/TextPaintStyle.cpp
  • trunk/Source/WebCore/ChangeLog

    r157948 r157950  
     12013-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
    11632013-10-24  Myles C. Maxfield  <mmaxfield@apple.com>
    2164
  • trunk/Source/WebCore/GNUmakefile.list.am

    r157936 r157950  
    44844484        Source/WebCore/rendering/ScrollBehavior.cpp \
    44854485        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 \
    44864491        Source/WebCore/rendering/TextAutosizer.cpp \
    44874492        Source/WebCore/rendering/TextAutosizer.h \
  • trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj

    r157928 r157950  
    1091310913      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Production|x64'">true</ExcludedFromBuild>
    1091410914    </ClCompile>
     10915    <ClCompile Include="..\rendering\SimpleLineLayout.cpp" />
     10916    <ClCompile Include="..\rendering\SimpleLineLayoutFunctions.cpp" />
    1091510917    <ClCompile Include="..\rendering\TextPaintStyle.cpp" />
    1091610918    <ClCompile Include="..\rendering\shapes\PolygonShape.cpp" />
     
    1968319685    <ClInclude Include="..\rendering\RootInlineBox.h" />
    1968419686    <ClInclude Include="..\rendering\ScrollBehavior.h" />
     19687    <ClInclude Include="..\rendering\SimpleLineLayout.h" />
     19688    <ClInclude Include="..\rendering\SimpleLineLayoutFunctions.h" />
     19689    <ClInclude Include="..\rendering\SimpleLineLayoutResolver.h" />
    1968519690    <ClInclude Include="..\rendering\svg\SVGMarkerData.h" />
    1968619691    <ClInclude Include="..\rendering\svg\SVGPathData.h" />
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r157936 r157950  
    56825682                E47E276516036ED200EE2AFB /* DocumentStyleSheetCollection.h in Headers */ = {isa = PBXBuildFile; fileRef = E47E276416036ED200EE2AFB /* DocumentStyleSheetCollection.h */; settings = {ATTRIBUTES = (Private, ); }; };
    56835683                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, ); }; };
    56845686                E4946EAE156E64DD00D3297F /* StyleRuleImport.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4946EAC156E64DD00D3297F /* StyleRuleImport.cpp */; };
    56855687                E4946EAF156E64DD00D3297F /* StyleRuleImport.h in Headers */ = {isa = PBXBuildFile; fileRef = E4946EAD156E64DD00D3297F /* StyleRuleImport.h */; };
     
    57185720                E4DEAA1717A93DC3000E0430 /* StyleResolveTree.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4DEAA1517A93DC3000E0430 /* StyleResolveTree.cpp */; };
    57195721                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 */; };
    57205725                E4F9EEF2156D9FFA00D23E7E /* StyleSheetContents.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4F9EEF0156D84C400D23E7E /* StyleSheetContents.cpp */; };
    57215726                E4F9EEF3156DA00700D23E7E /* StyleSheetContents.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F9EEF1156D84C400D23E7E /* StyleSheetContents.h */; };
     
    1267012675                E47E276416036ED200EE2AFB /* DocumentStyleSheetCollection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DocumentStyleSheetCollection.h; sourceTree = "<group>"; };
    1267112676                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>"; };
    1267212679                E4946EAC156E64DD00D3297F /* StyleRuleImport.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StyleRuleImport.cpp; sourceTree = "<group>"; };
    1267312680                E4946EAD156E64DD00D3297F /* StyleRuleImport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StyleRuleImport.h; sourceTree = "<group>"; };
     
    1272312730                E4DEAA1517A93DC3000E0430 /* StyleResolveTree.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StyleResolveTree.cpp; sourceTree = "<group>"; };
    1272412731                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>"; };
    1272512735                E4F9EEF0156D84C400D23E7E /* StyleSheetContents.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StyleSheetContents.cpp; sourceTree = "<group>"; };
    1272612736                E4F9EEF1156D84C400D23E7E /* StyleSheetContents.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StyleSheetContents.h; sourceTree = "<group>"; };
     
    2076920779                                5D925B660F64D4DD00B847F0 /* ScrollBehavior.h */,
    2077020780                                A8CFF04C0A154F09000A4234 /* TableLayout.h */,
     20781                                E48944A0180B57D800F165D8 /* SimpleLineLayout.cpp */,
     20782                                E48944A1180B57D800F165D8 /* SimpleLineLayout.h */,
     20783                                E4E9B11A18145692003ACCDF /* SimpleLineLayoutFunctions.cpp */,
     20784                                E4E9B11C1814569C003ACCDF /* SimpleLineLayoutFunctions.h */,
     20785                                E4E9B1181810916F003ACCDF /* SimpleLineLayoutResolver.h */,
    2077120786                                E4C91A0F1802343900A17F6D /* TextPaintStyle.cpp */,
    2077220787                                E4C91A0D1802343100A17F6D /* TextPaintStyle.h */,
     
    2257422589                                0F580B0D0F12A2690051D689 /* GraphicsLayer.h in Headers */,
    2257522590                                499B3ED7128CD31400E726C2 /* GraphicsLayerCA.h in Headers */,
     22591                                E4E9B1191810916F003ACCDF /* SimpleLineLayoutResolver.h in Headers */,
    2257622592                                0F580B0E0F12A2690051D689 /* GraphicsLayerClient.h in Headers */,
    2257722593                                CDAB6D2E17C814EE00C60B34 /* JSMediaControlsHost.h in Headers */,
     
    2363423650                                D0FF2A5E11F8C45A007E74E0 /* PingLoader.h in Headers */,
    2363523651                                377C4CDF1014E9F600B9AE42 /* PlaceholderDocument.h in Headers */,
     23652                                E4E9B11D1814569C003ACCDF /* SimpleLineLayoutFunctions.h in Headers */,
    2363623653                                499B3EDD128DB50200E726C2 /* PlatformCAAnimation.h in Headers */,
    2363723654                                0F13163E16ED0CC80035CC04 /* PlatformCAFilters.h in Headers */,
     
    2382023837                                CD3A496217A9D01B00274E42 /* SourceBuffer.h in Headers */,
    2382123838                                436708CB12D9CA4B00044234 /* RenderSVGModelObject.h in Headers */,
     23839                                E48944A3180B57D800F165D8 /* SimpleLineLayout.h in Headers */,
    2382223840                                ADDF1AD71257CD9A0003A759 /* RenderSVGPath.h in Headers */,
    2382323841                                A10BB5851484E3A700B2E87A /* RenderSVGRect.h in Headers */,
     
    2660426622                                BE8EF04A171C9014009B48C3 /* JSVideoTrack.cpp in Sources */,
    2660526623                                BE6DF70B171CA2C500DD52B8 /* JSVideoTrackCustom.cpp in Sources */,
     26624                                E4E9B11B18145692003ACCDF /* SimpleLineLayoutFunctions.cpp in Sources */,
    2660626625                                BE8EF04C171C9014009B48C3 /* JSVideoTrackList.cpp in Sources */,
    2660726626                                BE6DF70D171CA2C500DD52B8 /* JSVideoTrackListCustom.cpp in Sources */,
     
    2684626865                                F34742DC134362F000531BC2 /* PageDebuggerAgent.cpp in Sources */,
    2684726866                                9302B0BD0D79F82900C7EE83 /* PageGroup.cpp in Sources */,
     26867                                E48944A2180B57D800F165D8 /* SimpleLineLayout.cpp in Sources */,
    2684826868                                7A674BDB0F9EBF4E006CF099 /* PageGroupLoadDeferrer.cpp in Sources */,
    2684926869                                1C26497C0D7E24EC00BD10F2 /* PageMac.cpp in Sources */,
  • trunk/Source/WebCore/dom/Position.cpp

    r157517 r157950  
    645645
    646646        // 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;
    648653            if (currentNode != startNode) {
    649654                // This assertion fires in layout tests in the case-transform.html test because
     
    656661
    657662            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()) {
    661665                if (textOffset <= box->start() + box->len()) {
    662666                    if (textOffset > box->start())
     
    677681                    if (!otherBox)
    678682                        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))
    680684                        continuesOnNextLine = false;
    681685                }
     
    686690                    if (!otherBox)
    687691                        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))
    689693                        continuesOnNextLine = false;
    690694                }
     
    773777
    774778        // 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;
    776785            if (currentNode != startNode) {
    777786                ASSERT(currentPos.atStartOfNode());
     
    780789
    781790            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()) {
    785793                if (textOffset <= box->end()) {
    786794                    if (textOffset >= box->start())
     
    801809                    if (!otherBox)
    802810                        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))
    804812                        continuesOnNextLine = false;
    805813                }
     
    810818                    if (!otherBox)
    811819                        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))
    813821                        continuesOnNextLine = false;
    814822                }
     
    11551163        inlineBox = !caretOffset ? toRenderLineBreak(renderer)->inlineBoxWrapper() : nullptr;
    11561164    else if (renderer->isText()) {
    1157         RenderText* textRenderer = toRenderText(renderer);
     1165        auto textRenderer = toRenderText(renderer);
     1166        textRenderer->ensureLineBoxes();
    11581167
    11591168        InlineTextBox* box;
  • trunk/Source/WebCore/editing/TextIterator.cpp

    r157694 r157950  
    520520        emitText(m_node, runStart, runEnd);
    521521        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();
    522552    }
    523553
  • trunk/Source/WebCore/rendering/RenderBlock.cpp

    r157828 r157950  
    153153    , m_hasMarkupTruncation(false)
    154154    , m_hasBorderOrPaddingLogicalWidthChanged(false)
     155    , m_forceLineBoxLayout(false)
    155156#if ENABLE(IOS_TEXT_AUTOSIZING)
    156157    , m_widthForTextAutosizing(-1)
     
    168169    , m_hasMarkupTruncation(false)
    169170    , m_hasBorderOrPaddingLogicalWidthChanged(false)
     171    , m_forceLineBoxLayout(false)
    170172#if ENABLE(IOS_TEXT_AUTOSIZING)
    171173    , m_widthForTextAutosizing(-1)
     
    13841386ShapeInsideInfo* RenderBlock::layoutShapeInsideInfo() const
    13851387{
     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
    13861392    ShapeInsideInfo* shapeInsideInfo = view().layoutState()->shapeInsideInfo();
    13871393
  • trunk/Source/WebCore/rendering/RenderBlock.h

    r157907 r157950  
    752752    OwnPtr<RenderBlockRareData> m_rareData;
    753753
    754     mutable signed m_lineHeight : 27;
     754    mutable signed m_lineHeight : 26;
    755755    unsigned m_hasMarginBeforeQuirk : 1; // Note these quirk values can't be put in RenderBlockRareData since they are set too frequently.
    756756    unsigned m_hasMarginAfterQuirk : 1;
     
    758758    unsigned m_hasMarkupTruncation : 1;
    759759    unsigned m_hasBorderOrPaddingLogicalWidthChanged : 1;
     760    unsigned m_forceLineBoxLayout : 1;
    760761
    761762#if ENABLE(IOS_TEXT_AUTOSIZING)
  • trunk/Source/WebCore/rendering/RenderBlockFlow.cpp

    r157828 r157950  
    3434#include "RenderLayer.h"
    3535#include "RenderNamedFlowFragment.h"
     36#include "RenderText.h"
    3637#include "RenderView.h"
     38#include "SimpleLineLayoutFunctions.h"
    3739#include "VerticalPositionCache.h"
    3840#include "VisiblePosition.h"
     
    517519    // determining the correct collapsed bottom margin information.
    518520    handleAfterSideOfBlock(beforeEdge, afterEdge, marginInfo);
     521}
     522
     523void 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);
    519534}
    520535
     
    16331648        m_floatingObjects->clearLineBoxTreePointers();
    16341649
    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());
    16361655
    16371656    RenderBlock::deleteLines();
     
    24142433{
    24152434    ASSERT(childrenInline());
     2435
     2436    if (m_simpleLines)
     2437        return SimpleLineLayout::hitTestFlow(*this, *m_simpleLines, request, result, locationInContainer, accumulatedOffset, hitTestAction);
     2438
    24162439    return m_lineBoxes.hitTest(this, request, result, locationInContainer, accumulatedOffset, hitTestAction);
    24172440}
     
    24252448    // for either overflow or translations via relative positioning.
    24262449    if (childrenInline()) {
     2450        const_cast<RenderBlockFlow&>(*this).ensureLineBoxes();
     2451
    24272452        for (auto box = firstRootBox(); box; box = box->nextRootBox()) {
    24282453            if (box->firstChild())
     
    25132538        return RenderBlock::firstLineBaseline();
    25142539
    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());
    25192548}
    25202549
     
    25362565    }
    25372566
     2567    if (m_simpleLines)
     2568        return SimpleLineLayout::computeFlowLastLineBaseline(*this, *m_simpleLines);
     2569
    25382570    bool isFirstLine = lastLineBox() == firstLineBox();
    25392571    RenderStyle* style = isFirstLine ? firstLineStyle() : this->style();
     
    25442576    LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const LogicalSelectionOffsetCaches& cache, const PaintInfo* paintInfo)
    25452577{
     2578    ASSERT(!m_simpleLines);
     2579
    25462580    GapRects result;
    25472581
     
    27532787
    27542788    if (childrenInline() && hasMarkupTruncation()) {
     2789        ensureLineBoxes();
     2790
    27552791        setHasMarkupTruncation(false);
    27562792        for (auto box = firstRootBox(); box; box = box->nextRootBox())
     
    27932829{
    27942830    ASSERT(childrenInline());
     2831
     2832    ensureLineBoxes();
    27952833
    27962834    if (!firstRootBox())
     
    28802918void RenderBlockFlow::addFocusRingRectsForInlineChildren(Vector<IntRect>& rects, const LayoutPoint& additionalOffset, const RenderLayerModelObject*)
    28812919{
     2920    ASSERT(childrenInline());
     2921
     2922    ensureLineBoxes();
     2923
    28822924    for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) {
    28832925        LayoutUnit top = max<LayoutUnit>(curr->lineTop(), curr->top());
     
    28922934{
    28932935    ASSERT(childrenInline());
     2936
     2937    if (m_simpleLines) {
     2938        SimpleLineLayout::paintFlow(*this, *m_simpleLines, paintInfo, paintOffset);
     2939        return;
     2940    }
    28942941    m_lineBoxes.paint(this, paintInfo, paintOffset);
    28952942}
     
    29472994}
    29482995
     2996bool RenderBlockFlow::hasLines() const
     2997{
     2998    ASSERT(childrenInline());
     2999
     3000    if (m_simpleLines)
     3001        return !m_simpleLines->isEmpty();
     3002
     3003    return lineBoxes().firstLineBox();
     3004}
     3005
     3006void 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
     3021void RenderBlockFlow::deleteLineBoxesBeforeSimpleLineLayout()
     3022{
     3023    ASSERT(!m_forceLineBoxLayout);
     3024    lineBoxes().deleteLineBoxes(renderArena());
     3025    toRenderText(firstChild())->deleteLineBoxesBeforeSimpleLineLayout();
     3026}
     3027
     3028void 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
    29493053#ifndef NDEBUG
    29503054void 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  
    2626#include "RenderBlock.h"
    2727#include "RenderLineBoxList.h"
     28#include "SimpleLineLayout.h"
    2829
    2930namespace WebCore {
     
    5455    void layoutBlockChildren(bool relayoutChildren, LayoutUnit& maxFloatLogicalBottom);
    5556    void layoutInlineChildren(bool relayoutChildren, LayoutUnit& repaintLogicalTop, LayoutUnit& repaintLogicalBottom);
    56    
     57
    5758    // RenderBlockFlows override these methods, since they are the only class that supports margin collapsing.
    5859    virtual LayoutUnit collapsedMarginBefore() const OVERRIDE FINAL { return maxPositiveMarginBefore() - maxNegativeMarginBefore(); }
     
    311312    RootInlineBox* lastRootBox() const { return static_cast<RootInlineBox*>(lastLineBox()); }
    312313
    313     virtual bool hasLines() const OVERRIDE FINAL { return firstLineBox(); }
     314    virtual bool hasLines() const OVERRIDE FINAL;
    314315
    315316    // Helper methods for computing line counts and heights for line counts.
     
    323324
    324325    bool containsNonZeroBidiLevel() const;
     326
     327    const SimpleLineLayout::Lines* simpleLines() const { return m_simpleLines.get(); }
     328    void deleteLineBoxesBeforeSimpleLineLayout();
     329    void ensureLineBoxes();
    325330
    326331#ifndef NDEBUG
     
    428433
    429434private:
     435    void layoutLineBoxes(bool relayoutChildren, LayoutUnit& repaintLogicalTop, LayoutUnit& repaintLogicalBottom);
     436    void layoutSimpleLines(LayoutUnit& repaintLogicalTop, LayoutUnit& repaintLogicalBottom);
     437
    430438    virtual RootInlineBox* createRootInlineBox(); // Subclassed by SVG and Ruby.
    431439    InlineFlowBox* createLineBoxes(RenderObject*, const LineInfo&, InlineBox* childBox, bool startsNewSegment);
     
    480488    OwnPtr<RenderBlockFlowRareData> m_rareData;
    481489    RenderLineBoxList m_lineBoxes;
     490    std::unique_ptr<SimpleLineLayout::Lines> m_simpleLines;
    482491
    483492    friend class BreakingContext;
  • trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp

    r157851 r157950  
    4646#include "RenderView.h"
    4747#include "Settings.h"
     48#include "SimpleLineLayoutFunctions.h"
    4849#include "TrailingFloatsRootInlineBox.h"
    4950#include "VerticalPositionCache.h"
     
    18341835}
    18351836
    1836 void RenderBlockFlow::layoutInlineChildren(bool relayoutChildren, LayoutUnit& repaintLogicalTop, LayoutUnit& repaintLogicalBottom)
    1837 {
     1837void RenderBlockFlow::layoutLineBoxes(bool relayoutChildren, LayoutUnit& repaintLogicalTop, LayoutUnit& repaintLogicalBottom)
     1838{
     1839    ASSERT(!m_simpleLines);
     1840
    18381841    setLogicalHeight(borderAndPaddingBefore());
    18391842   
     
    35113514void RenderBlockFlow::addOverflowFromInlineChildren()
    35123515{
     3516    if (auto lines = simpleLines()) {
     3517        ASSERT(!hasOverflowClip());
     3518        SimpleLineLayout::collectFlowOverflow(*this, *lines);
     3519        return;
     3520    }
    35133521    LayoutUnit endPadding = hasOverflowClip() ? paddingEnd() : LayoutUnit();
    35143522    // 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  
    4040#include "RenderView.h"
    4141#include "Settings.h"
     42#include "SimpleLineLayoutFunctions.h"
    4243#include "Text.h"
    4344#include "TextBreakIterator.h"
     
    266267}
    267268
     269void RenderText::deleteLineBoxesBeforeSimpleLineLayout()
     270{
     271    m_lineBoxes.deleteAll(*this);
     272}
     273
    268274String RenderText::originalText() const
    269275{
     
    273279void RenderText::absoluteRects(Vector<IntRect>& rects, const LayoutPoint& accumulatedOffset) const
    274280{
     281    // FIXME: These will go away when simple layout can do everything.
     282    const_cast<RenderText&>(*this).ensureLineBoxes();
     283
    275284    rects.appendVector(m_lineBoxes.absoluteRects(accumulatedOffset));
    276285}
     
    278287Vector<IntRect> RenderText::absoluteRectsForRange(unsigned start, unsigned end, bool useSelectionHeight, bool* wasFixed) const
    279288{
     289    const_cast<RenderText&>(*this).ensureLineBoxes();
     290
    280291    // Work around signed/unsigned issues. This function takes unsigneds, and is often passed UINT_MAX
    281292    // to mean "all the way to the end". InlineTextBox coordinates are unsigneds, so changing this
     
    293304Vector<FloatQuad> RenderText::absoluteQuadsClippedToEllipsis() const
    294305{
     306    const_cast<RenderText&>(*this).ensureLineBoxes();
     307
    295308    return m_lineBoxes.absoluteQuads(*this, nullptr, RenderTextLineBoxes::ClipToEllipsis);
    296309}
     
    298311void RenderText::absoluteQuads(Vector<FloatQuad>& quads, bool* wasFixed) const
    299312{
     313    const_cast<RenderText&>(*this).ensureLineBoxes();
     314
    300315    quads.appendVector(m_lineBoxes.absoluteQuads(*this, wasFixed, RenderTextLineBoxes::NoClipping));
    301316}
     
    303318Vector<FloatQuad> RenderText::absoluteQuadsForRange(unsigned start, unsigned end, bool useSelectionHeight, bool* wasFixed) const
    304319{
     320    const_cast<RenderText&>(*this).ensureLineBoxes();
     321
    305322    // Work around signed/unsigned issues. This function takes unsigneds, and is often passed UINT_MAX
    306323    // to mean "all the way to the end". InlineTextBox coordinates are unsigneds, so changing this
     
    318335VisiblePosition RenderText::positionForPoint(const LayoutPoint& point)
    319336{
     337    ensureLineBoxes();
     338
    320339    return m_lineBoxes.positionForPoint(*this, point);
    321340}
     
    492511}
    493512
     513bool RenderText::knownToHaveNoOverflowAndNoFallbackFonts() const
     514{
     515    if (preferredLogicalWidthsDirty())
     516        const_cast<RenderText*>(this)->computePreferredLogicalWidths(0);
     517
     518    return m_knownToHaveNoOverflowAndNoFallbackFonts;
     519}
     520
    494521void RenderText::computePreferredLogicalWidths(float leadWidth)
    495522{
     
    837864void RenderText::setSelectionState(SelectionState state)
    838865{
     866    if (state != SelectionNone)
     867        ensureLineBoxes();
     868
    839869    RenderObject::setSelectionState(state);
    840870
     
    856886    unsigned end = len ? offset + len - 1 : offset;
    857887
    858     m_linesDirty = m_lineBoxes.dirtyRange(*this, offset, end, delta);
     888    m_linesDirty = simpleLines() || m_lineBoxes.dirtyRange(*this, offset, end, delta);
    859889
    860890    setText(text, force || m_linesDirty);
     
    10241054
    10251055    m_containsReversedText |= !textBox->isLeftToRightDirection();
     1056}
     1057
     1058void RenderText::ensureLineBoxes()
     1059{
     1060    if (!parent()->isRenderBlockFlow())
     1061        return;
     1062    toRenderBlockFlow(parent())->ensureLineBoxes();
     1063}
     1064
     1065const SimpleLineLayout::Lines* RenderText::simpleLines() const
     1066{
     1067    if (!parent()->isRenderBlockFlow())
     1068        return nullptr;
     1069    return toRenderBlockFlow(parent())->simpleLines();
    10261070}
    10271071
     
    10761120IntRect RenderText::linesBoundingBox() const
    10771121{
     1122    if (auto lines = simpleLines())
     1123        return SimpleLineLayout::computeTextBoundingBox(*this, *lines);
     1124
    10781125    return m_lineBoxes.boundingBox(*this);
    10791126}
     
    10811128LayoutRect RenderText::linesVisualOverflowBoundingBox() const
    10821129{
     1130    ASSERT(!simpleLines());
    10831131    return m_lineBoxes.visualOverflowBoundingBox(*this);
    10841132}
     
    11031151{
    11041152    ASSERT(!needsLayout());
     1153    ASSERT(!simpleLines());
    11051154
    11061155    if (selectionState() == SelectionNone)
     
    11441193int RenderText::caretMinOffset() const
    11451194{
     1195    if (auto lines = simpleLines())
     1196        return SimpleLineLayout::findTextCaretMinimumOffset(*this, *lines);
    11461197    return m_lineBoxes.caretMinOffset();
    11471198}
     
    11491200int RenderText::caretMaxOffset() const
    11501201{
     1202    if (auto lines = simpleLines())
     1203        return SimpleLineLayout::findTextCaretMaximumOffset(*this, *lines);
    11511204    return m_lineBoxes.caretMaxOffset(*this);
    11521205}
     
    11541207unsigned RenderText::countRenderedCharacterOffsetsUntil(unsigned offset) const
    11551208{
     1209    ASSERT(!simpleLines());
    11561210    return m_lineBoxes.countCharacterOffsetsUntil(offset);
    11571211}
     
    11591213bool RenderText::containsRenderedCharacterOffset(unsigned offset) const
    11601214{
     1215    ASSERT(!simpleLines());
    11611216    return m_lineBoxes.containsOffset(*this, offset, RenderTextLineBoxes::CharacterOffset);
    11621217}
     
    11641219bool RenderText::containsCaretOffset(unsigned offset) const
    11651220{
     1221    if (auto layout = simpleLines())
     1222        return SimpleLineLayout::containsTextCaretOffset(*this, *layout, offset);
    11661223    return m_lineBoxes.containsOffset(*this, offset, RenderTextLineBoxes::CaretOffset);
    11671224}
     
    11691226bool RenderText::hasRenderedText() const
    11701227{
     1228    if (auto lines = simpleLines())
     1229        return SimpleLineLayout::isTextRendered(*this, *lines);
    11711230    return m_lineBoxes.hasRenderedText();
    11721231}
  • trunk/Source/WebCore/rendering/RenderText.h

    r157907 r157950  
    2626#include "RenderElement.h"
    2727#include "RenderTextLineBoxes.h"
     28#include "SimpleLineLayout.h"
    2829#include "Text.h"
    2930#include <wtf/Forward.h>
     
    140141
    141142    bool canUseSimpleFontCodePath() const { return m_canUseSimpleFontCodePath; }
    142     bool knownToHaveNoOverflowAndNoFallbackFonts() const { return m_knownToHaveNoOverflowAndNoFallbackFonts; }
     143    bool knownToHaveNoOverflowAndNoFallbackFonts() const;
    143144
    144145    void removeAndDestroyTextBoxes();
     
    152153    void setCandidateComputedTextSize(float s) { m_candidateComputedTextSize = s; }
    153154#endif
     155
     156    void ensureLineBoxes();
     157    void deleteLineBoxesBeforeSimpleLineLayout();
     158    const SimpleLineLayout::Lines* simpleLines() const;
    154159
    155160protected:
     
    198203    mutable bool m_knownToHaveNoOverflowAndNoFallbackFonts : 1;
    199204    bool m_useBackslashAsYenSymbol : 1;
    200    
     205
    201206#if ENABLE(IOS_TEXT_AUTOSIZING)
    202207    // 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  
    3737#include "PrintContext.h"
    3838#include "PseudoElement.h"
     39#include "RenderBlockFlow.h"
    3940#include "RenderDetailsMarker.h"
    4041#include "RenderFileUploadControl.h"
     
    5051#include "RenderWidget.h"
    5152#include "ShadowRoot.h"
     53#include "SimpleLineLayoutResolver.h"
    5254#include "StylePropertySet.h"
    5355#include <wtf/HexNumber.h>
     
    245247        const RenderText& text = toRenderText(o);
    246248        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());
    248256        if (adjustForTableCells && !text.firstTextBox())
    249257            adjustForTableCells = false;
     
    527535}
    528536
     537static 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
    529552void write(TextStream& ts, const RenderObject& o, int indent, RenderAsTextBehavior behavior)
    530553{
     
    570593
    571594    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
    577611    } else {
    578612        if (!toRenderElement(o).isRenderNamedFlowFragmentContainer()) {
Note: See TracChangeset for help on using the changeset viewer.