Changeset 250519 in webkit


Ignore:
Timestamp:
Sep 30, 2019 8:55:37 AM (5 years ago)
Author:
Antti Koivisto
Message:

RenderLineBreak should use LineLayoutTraversal
https://bugs.webkit.org/show_bug.cgi?id=202316

Reviewed by Zalan Bujtas.

Replace more path specific code with LineLayoutTraversal.

  • Headers.cmake:
  • rendering/RenderLineBreak.cpp:

(WebCore::RenderLineBreak::linesBoundingBox const):
(WebCore::RenderLineBreak::absoluteRects const):
(WebCore::RenderLineBreak::absoluteQuads const):
(WebCore::simpleLineLayout): Deleted.

  • rendering/RenderTreeAsText.cpp:

(WebCore::RenderTreeAsText::writeRenderObject):
(WebCore::writeTextBox):

  • rendering/SimpleLineLayoutFunctions.cpp:

(WebCore::SimpleLineLayout::computeBoundingBox): Deleted.
(WebCore::SimpleLineLayout::collectAbsoluteRects): Deleted.
(WebCore::SimpleLineLayout::rendererForPosition): Deleted.

  • rendering/SimpleLineLayoutFunctions.h:
  • rendering/line/LineLayoutTraversal.cpp:

(WebCore::LineLayoutTraversal::ElementBoxIterator::ElementBoxIterator):
(WebCore::LineLayoutTraversal::ElementBoxIterator::atEnd const):
(WebCore::LineLayoutTraversal::elementBoxFor):
(WebCore::LineLayoutTraversal::TextBox::rect const): Deleted.
(WebCore::LineLayoutTraversal::TextBox::logicalRect const): Deleted.
(WebCore::LineLayoutTraversal::TextBox::hasHyphen const): Deleted.
(WebCore::LineLayoutTraversal::TextBox::isLeftToRightDirection const): Deleted.
(WebCore::LineLayoutTraversal::TextBox::dirOverride const): Deleted.
(WebCore::LineLayoutTraversal::TextBox::text const): Deleted.
(WebCore::LineLayoutTraversal::TextBox::isLineBreak const): Deleted.
(WebCore::LineLayoutTraversal::TextBox::localStartOffset const): Deleted.
(WebCore::LineLayoutTraversal::TextBox::localEndOffset const): Deleted.
(WebCore::LineLayoutTraversal::TextBox::length const): Deleted.
(WebCore::LineLayoutTraversal::TextBox::isLastOnLine const): Deleted.
(WebCore::LineLayoutTraversal::TextBox::isLast const): Deleted.
(WebCore::LineLayoutTraversal::TextBox::iterator const): Deleted.

Move to header as templates.

  • rendering/line/LineLayoutTraversal.h:

(WebCore::LineLayoutTraversal::ElementBoxIterator::ElementBoxIterator):
(WebCore::LineLayoutTraversal::ElementBoxIterator::operator bool const):
(WebCore::LineLayoutTraversal::ElementBoxIterator::operator* const):
(WebCore::LineLayoutTraversal::ElementBoxIterator::operator-> const):

Add a new iterator type for element boxes.
It doesn't currently really iterate, is just allows testing for end.

(WebCore::LineLayoutTraversal::Box<Iterator>::rect const):
(WebCore::LineLayoutTraversal::Box<Iterator>::logicalRect const):
(WebCore::LineLayoutTraversal::Box<Iterator>::isLeftToRightDirection const):
(WebCore::LineLayoutTraversal::Box<Iterator>::dirOverride const):
(WebCore::LineLayoutTraversal::Box<Iterator>::isLineBreak const):
(WebCore::LineLayoutTraversal::Box<Iterator>::iterator const):

Split properties that all inline boxes have out from TextBox.
Make it a template class.

(WebCore::LineLayoutTraversal::TextBox<Iterator>::hasHyphen const):
(WebCore::LineLayoutTraversal::TextBox<Iterator>::text const):
(WebCore::LineLayoutTraversal::TextBox<Iterator>::localStartOffset const):
(WebCore::LineLayoutTraversal::TextBox<Iterator>::localEndOffset const):
(WebCore::LineLayoutTraversal::TextBox<Iterator>::length const):
(WebCore::LineLayoutTraversal::TextBox<Iterator>::isLastOnLine const):
(WebCore::LineLayoutTraversal::TextBox<Iterator>::isLast const):

Make a template class.

(WebCore::LineLayoutTraversal::hasTextBoxes): Deleted.

Location:
trunk/Source/WebCore
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r250515 r250519  
     12019-09-30  Antti Koivisto  <antti@apple.com>
     2
     3        RenderLineBreak should use LineLayoutTraversal
     4        https://bugs.webkit.org/show_bug.cgi?id=202316
     5
     6        Reviewed by Zalan Bujtas.
     7
     8        Replace more path specific code with LineLayoutTraversal.
     9
     10        * Headers.cmake:
     11        * rendering/RenderLineBreak.cpp:
     12        (WebCore::RenderLineBreak::linesBoundingBox const):
     13        (WebCore::RenderLineBreak::absoluteRects const):
     14        (WebCore::RenderLineBreak::absoluteQuads const):
     15        (WebCore::simpleLineLayout): Deleted.
     16        * rendering/RenderTreeAsText.cpp:
     17        (WebCore::RenderTreeAsText::writeRenderObject):
     18        (WebCore::writeTextBox):
     19        * rendering/SimpleLineLayoutFunctions.cpp:
     20        (WebCore::SimpleLineLayout::computeBoundingBox): Deleted.
     21        (WebCore::SimpleLineLayout::collectAbsoluteRects): Deleted.
     22        (WebCore::SimpleLineLayout::rendererForPosition): Deleted.
     23        * rendering/SimpleLineLayoutFunctions.h:
     24        * rendering/line/LineLayoutTraversal.cpp:
     25        (WebCore::LineLayoutTraversal::ElementBoxIterator::ElementBoxIterator):
     26        (WebCore::LineLayoutTraversal::ElementBoxIterator::atEnd const):
     27        (WebCore::LineLayoutTraversal::elementBoxFor):
     28        (WebCore::LineLayoutTraversal::TextBox::rect const): Deleted.
     29        (WebCore::LineLayoutTraversal::TextBox::logicalRect const): Deleted.
     30        (WebCore::LineLayoutTraversal::TextBox::hasHyphen const): Deleted.
     31        (WebCore::LineLayoutTraversal::TextBox::isLeftToRightDirection const): Deleted.
     32        (WebCore::LineLayoutTraversal::TextBox::dirOverride const): Deleted.
     33        (WebCore::LineLayoutTraversal::TextBox::text const): Deleted.
     34        (WebCore::LineLayoutTraversal::TextBox::isLineBreak const): Deleted.
     35        (WebCore::LineLayoutTraversal::TextBox::localStartOffset const): Deleted.
     36        (WebCore::LineLayoutTraversal::TextBox::localEndOffset const): Deleted.
     37        (WebCore::LineLayoutTraversal::TextBox::length const): Deleted.
     38        (WebCore::LineLayoutTraversal::TextBox::isLastOnLine const): Deleted.
     39        (WebCore::LineLayoutTraversal::TextBox::isLast const): Deleted.
     40        (WebCore::LineLayoutTraversal::TextBox::iterator const): Deleted.
     41
     42        Move to header as templates.
     43
     44        * rendering/line/LineLayoutTraversal.h:
     45        (WebCore::LineLayoutTraversal::ElementBoxIterator::ElementBoxIterator):
     46        (WebCore::LineLayoutTraversal::ElementBoxIterator::operator bool const):
     47        (WebCore::LineLayoutTraversal::ElementBoxIterator::operator* const):
     48        (WebCore::LineLayoutTraversal::ElementBoxIterator::operator-> const):
     49
     50        Add a new iterator type for element boxes.
     51        It doesn't currently really iterate, is just allows testing for end.
     52
     53        (WebCore::LineLayoutTraversal::Box<Iterator>::rect const):
     54        (WebCore::LineLayoutTraversal::Box<Iterator>::logicalRect const):
     55        (WebCore::LineLayoutTraversal::Box<Iterator>::isLeftToRightDirection const):
     56        (WebCore::LineLayoutTraversal::Box<Iterator>::dirOverride const):
     57        (WebCore::LineLayoutTraversal::Box<Iterator>::isLineBreak const):
     58        (WebCore::LineLayoutTraversal::Box<Iterator>::iterator const):
     59
     60        Split properties that all inline boxes have out from TextBox.
     61        Make it a template class.
     62
     63        (WebCore::LineLayoutTraversal::TextBox<Iterator>::hasHyphen const):
     64        (WebCore::LineLayoutTraversal::TextBox<Iterator>::text const):
     65        (WebCore::LineLayoutTraversal::TextBox<Iterator>::localStartOffset const):
     66        (WebCore::LineLayoutTraversal::TextBox<Iterator>::localEndOffset const):
     67        (WebCore::LineLayoutTraversal::TextBox<Iterator>::length const):
     68        (WebCore::LineLayoutTraversal::TextBox<Iterator>::isLastOnLine const):
     69        (WebCore::LineLayoutTraversal::TextBox<Iterator>::isLast const):
     70
     71        Make a template class.
     72
     73        (WebCore::LineLayoutTraversal::hasTextBoxes): Deleted.
     74
    1752019-09-30  Rob Buis  <rbuis@igalia.com>
    276
  • trunk/Source/WebCore/Headers.cmake

    r250343 r250519  
    12521252    rendering/HitTestResult.h
    12531253    rendering/InlineBox.h
     1254    rendering/InlineElementBox.h
    12541255    rendering/InlineFlowBox.h
     1256    rendering/InlineTextBox.h
    12551257    rendering/LayerAncestorClippingStack.h
    12561258    rendering/LayerFragment.h
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r250490 r250519  
    36583658                B562DB6117D3CD660010AF96 /* SVGElementTypeHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = B562DB5F17D3CD560010AF96 /* SVGElementTypeHelpers.h */; };
    36593659                B56579B51824D12A00E79F23 /* RenderChildIterator.h in Headers */ = {isa = PBXBuildFile; fileRef = B56579B41824D12A00E79F23 /* RenderChildIterator.h */; };
    3660                 B57CB52E182A3EFC0079A647 /* InlineElementBox.h in Headers */ = {isa = PBXBuildFile; fileRef = B57CB52B182A37F60079A647 /* InlineElementBox.h */; };
     3660                B57CB52E182A3EFC0079A647 /* InlineElementBox.h in Headers */ = {isa = PBXBuildFile; fileRef = B57CB52B182A37F60079A647 /* InlineElementBox.h */; settings = {ATTRIBUTES = (Private, ); }; };
    36613661                B595FF471824CEE300FF51CD /* RenderIterator.h in Headers */ = {isa = PBXBuildFile; fileRef = B595FF461824CEE300FF51CD /* RenderIterator.h */; };
    36623662                B59DD699119029E5007E9684 /* JSDatabaseCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = B59DD697119029E5007E9684 /* JSDatabaseCallback.h */; };
  • trunk/Source/WebCore/rendering/RenderLineBreak.cpp

    r248846 r250519  
    2828#include "HTMLWBRElement.h"
    2929#include "InlineElementBox.h"
     30#include "LineLayoutTraversal.h"
    3031#include "LogicalSelectionOffsetCaches.h"
    3132#include "RenderBlock.h"
    3233#include "RenderView.h"
    3334#include "RootInlineBox.h"
    34 #include "SimpleLineLayoutFunctions.h"
    3535#include "VisiblePosition.h"
    3636#include <wtf/IsoMallocInlines.h>
     
    4545
    4646static const int invalidLineHeight = -1;
    47 
    48 static const SimpleLineLayout::Layout* simpleLineLayout(const RenderLineBreak& renderer)
    49 {
    50     if (!is<RenderBlockFlow>(*renderer.parent()))
    51         return nullptr;
    52     return downcast<RenderBlockFlow>(*renderer.parent()).simpleLineLayout();
    53 }
    5447
    5548RenderLineBreak::RenderLineBreak(HTMLElement& element, RenderStyle&& style)
     
    184177IntRect RenderLineBreak::linesBoundingBox() const
    185178{
    186     if (auto* layout = simpleLineLayout(*this))
    187         return SimpleLineLayout::computeBoundingBox(*this, *layout);
    188 
    189     if (!m_inlineBoxWrapper)
    190         return IntRect();
    191 
    192     float logicalLeftSide = m_inlineBoxWrapper->logicalLeft();
    193     float logicalRightSide = m_inlineBoxWrapper->logicalRight();
    194 
    195     bool isHorizontal = style().isHorizontalWritingMode();
    196 
    197     float x = isHorizontal ? logicalLeftSide : m_inlineBoxWrapper->x();
    198     float y = isHorizontal ? m_inlineBoxWrapper->y() : logicalLeftSide;
    199     float width = isHorizontal ? logicalRightSide - logicalLeftSide : m_inlineBoxWrapper->logicalBottom() - x;
    200     float height = isHorizontal ? m_inlineBoxWrapper->logicalBottom() - y : logicalRightSide - logicalLeftSide;
    201     return enclosingIntRect(FloatRect(x, y, width, height));
     179    auto box = LineLayoutTraversal::elementBoxFor(*this);
     180    if (!box)
     181        return { };
     182
     183    return enclosingIntRect(box->rect());
    202184}
    203185
    204186void RenderLineBreak::absoluteRects(Vector<IntRect>& rects, const LayoutPoint& accumulatedOffset) const
    205187{
    206     if (auto* layout = simpleLineLayout(*this)) {
    207         rects.appendVector(SimpleLineLayout::collectAbsoluteRects(*this, *layout, accumulatedOffset));
    208         return;
    209     }
    210 
    211     if (!m_inlineBoxWrapper)
    212         return;
    213     rects.append(enclosingIntRect(FloatRect(accumulatedOffset + m_inlineBoxWrapper->topLeft(), m_inlineBoxWrapper->size())));
     188    auto box = LineLayoutTraversal::elementBoxFor(*this);
     189    if (!box)
     190        return;
     191
     192    auto rect = box->rect();
     193    rects.append(enclosingIntRect(FloatRect(accumulatedOffset + rect.location(), rect.size())));
    214194}
    215195
    216196void RenderLineBreak::absoluteQuads(Vector<FloatQuad>& quads, bool* wasFixed) const
    217197{
    218     if (auto* layout = simpleLineLayout(*this)) {
    219         quads.appendVector(SimpleLineLayout::collectAbsoluteQuads(*this, *layout, wasFixed));
    220         return;
    221     }
    222     if (!m_inlineBoxWrapper)
    223         return;
    224     quads.append(localToAbsoluteQuad(FloatRect(m_inlineBoxWrapper->topLeft(), m_inlineBoxWrapper->size()), UseTransforms, wasFixed));
     198    auto box = LineLayoutTraversal::elementBoxFor(*this);
     199    if (!box)
     200        return;
     201
     202    auto rect = box->rect();
     203    quads.append(localToAbsoluteQuad(FloatRect(rect.location(), rect.size()), UseTransforms, wasFixed));
    225204}
    226205
  • trunk/Source/WebCore/rendering/RenderTreeAsText.cpp

    r250390 r250519  
    203203        const RenderText& text = downcast<RenderText>(o);
    204204        r = IntRect(text.firstRunLocation(), text.linesBoundingBox().size());
    205         if (!LineLayoutTraversal::hasTextBoxes(text))
     205        if (!LineLayoutTraversal::firstTextBoxFor(text))
    206206            adjustForTableCells = false;
    207207    } else if (o.isBR()) {
     
    478478}
    479479
    480 static void writeTextBox(TextStream& ts, const RenderText& o, const LineLayoutTraversal::TextBox& textBox)
     480static void writeTextBox(TextStream& ts, const RenderText& o, const LineLayoutTraversal::TextBoxIterator::BoxType& textBox)
    481481{
    482482    auto rect = textBox.rect();
  • trunk/Source/WebCore/rendering/SimpleLineLayoutFunctions.cpp

    r250390 r250519  
    184184}
    185185
    186 IntRect computeBoundingBox(const RenderObject& renderer, const Layout& layout)
    187 {
    188     auto& resolver = layout.runResolver();
    189     FloatRect boundingBoxRect;
    190     for (auto run : resolver.rangeForRenderer(renderer)) {
    191         FloatRect rect = run.rect();
    192         if (boundingBoxRect == FloatRect())
    193             boundingBoxRect = rect;
    194         else
    195             boundingBoxRect.uniteEvenIfEmpty(rect);
    196     }
    197     return enclosingIntRect(boundingBoxRect);
    198 }
    199 
    200 Vector<IntRect> collectAbsoluteRects(const RenderObject& renderer, const Layout& layout, const LayoutPoint& accumulatedOffset)
    201 {
    202     Vector<IntRect> rects;
    203     auto& resolver = layout.runResolver();
    204     for (auto run : resolver.rangeForRenderer(renderer)) {
    205         FloatRect rect = run.rect();
    206         rects.append(enclosingIntRect(FloatRect(accumulatedOffset + rect.location(), rect.size())));
    207     }
    208     return rects;
    209 }
    210 
    211186Vector<FloatQuad> collectAbsoluteQuads(const RenderObject& renderer, const Layout& layout, bool* wasFixed)
    212187{
     
    261236    }
    262237    return quads;
    263 }
    264 
    265 const RenderObject& rendererForPosition(const FlowContents& flowContents, unsigned position)
    266 {
    267     return flowContents.segmentForPosition(position).renderer;
    268238}
    269239
  • trunk/Source/WebCore/rendering/SimpleLineLayoutFunctions.h

    r250390 r250519  
    5050void collectFlowOverflow(RenderBlockFlow&, const Layout&);
    5151
    52 IntRect computeBoundingBox(const RenderObject&, const Layout&);
    53 
    54 Vector<IntRect> collectAbsoluteRects(const RenderObject&, const Layout&, const LayoutPoint& accumulatedOffset);
    5552Vector<FloatQuad> collectAbsoluteQuads(const RenderObject&, const Layout&, bool* wasFixed);
    5653unsigned textOffsetForPoint(const LayoutPoint&, const RenderText&, const Layout&);
     
    6259bool canUseForLineBoxTree(RenderBlockFlow&, const Layout&);
    6360void generateLineBoxTree(RenderBlockFlow&, const Layout&);
    64 
    65 const RenderObject& rendererForPosition(const FlowContents&, unsigned);
    6661
    6762void simpleLineLayoutWillBeDeleted(const Layout&);
  • trunk/Source/WebCore/rendering/line/LineLayoutTraversal.cpp

    r250390 r250519  
    2727#include "LineLayoutTraversal.h"
    2828
    29 #include "InlineTextBox.h"
    30 #include "RenderText.h"
    31 #include "SimpleLineLayoutResolver.h"
     29#include "RenderLineBreak.h"
    3230
    3331namespace WebCore {
    3432namespace LineLayoutTraversal {
    35 
    36 FloatRect TextBox::rect() const
    37 {
    38     auto simple = [](const TextBoxIterator::SimplePath& path) {
    39         return (*path.iterator).rect();
    40     };
    41 
    42     auto complex = [](const TextBoxIterator::ComplexPath& path) {
    43         return path.inlineTextBox->frameRect();
    44     };
    45 
    46     return WTF::switchOn(iterator().m_pathVariant, simple, complex);
    47 }
    48 
    49 FloatRect TextBox::logicalRect() const
    50 {
    51     auto simple = [](const TextBoxIterator::SimplePath& path) {
    52         return (*path.iterator).rect();
    53     };
    54 
    55     auto complex = [](const TextBoxIterator::ComplexPath& path) {
    56         return path.inlineTextBox->logicalFrameRect();
    57     };
    58 
    59     return WTF::switchOn(iterator().m_pathVariant, simple, complex);
    60 }
    61 
    62 bool TextBox::hasHyphen() const
    63 {
    64     auto simple = [](const TextBoxIterator::SimplePath& path) {
    65         return (*path.iterator).hasHyphen();
    66     };
    67 
    68     auto complex = [](const TextBoxIterator::ComplexPath& path) {
    69         return path.inlineTextBox->hasHyphen();
    70     };
    71 
    72     return WTF::switchOn(iterator().m_pathVariant, simple, complex);
    73 }
    74 
    75 bool TextBox::isLeftToRightDirection() const
    76 {
    77     auto simple = [](const TextBoxIterator::SimplePath&) {
    78         return true;
    79     };
    80 
    81     auto complex = [](const TextBoxIterator::ComplexPath& path) {
    82         return path.inlineTextBox->isLeftToRightDirection();
    83     };
    84 
    85     return WTF::switchOn(iterator().m_pathVariant, simple, complex);
    86 }
    87 
    88 bool TextBox::dirOverride() const
    89 {
    90     auto simple = [](const TextBoxIterator::SimplePath&) {
    91         return false;
    92     };
    93 
    94     auto complex = [](const TextBoxIterator::ComplexPath& path) {
    95         return path.inlineTextBox->dirOverride();
    96     };
    97 
    98     return WTF::switchOn(iterator().m_pathVariant, simple, complex);
    99 }
    100 
    101 StringView TextBox::text() const
    102 {
    103     auto simple = [](const TextBoxIterator::SimplePath& path) {
    104         return (*path.iterator).text();
    105     };
    106 
    107     auto complex = [](const TextBoxIterator::ComplexPath& path) {
    108         return StringView(path.inlineTextBox->renderer().text()).substring(path.inlineTextBox->start(), path.inlineTextBox->len());
    109     };
    110 
    111     return WTF::switchOn(iterator().m_pathVariant, simple, complex);
    112 }
    113 
    114 bool TextBox::isLineBreak() const
    115 {
    116     auto simple = [](const TextBoxIterator::SimplePath& path) {
    117         return (*path.iterator).isLineBreak();
    118     };
    119 
    120     auto complex = [](const TextBoxIterator::ComplexPath& path) {
    121         return path.inlineTextBox->isLineBreak();
    122     };
    123 
    124     return WTF::switchOn(iterator().m_pathVariant, simple, complex);
    125 }
    126 
    127 unsigned TextBox::localStartOffset() const
    128 {
    129     auto simple = [](const TextBoxIterator::SimplePath& path) {
    130         return (*path.iterator).localStart();
    131     };
    132 
    133     auto complex = [](const TextBoxIterator::ComplexPath& path) {
    134         return path.inlineTextBox->start();
    135     };
    136 
    137     return WTF::switchOn(iterator().m_pathVariant, simple, complex);
    138 }
    139 
    140 unsigned TextBox::localEndOffset() const
    141 {
    142     auto simple = [](const TextBoxIterator::SimplePath& path) {
    143         return (*path.iterator).localEnd();
    144     };
    145 
    146     auto complex = [](const TextBoxIterator::ComplexPath& path) {
    147         return path.inlineTextBox->end();
    148     };
    149 
    150     return WTF::switchOn(iterator().m_pathVariant, simple, complex);
    151 }
    152 
    153 unsigned TextBox::length() const
    154 {
    155     auto simple = [](const TextBoxIterator::SimplePath& path) {
    156         return (*path.iterator).end() - (*path.iterator).start();
    157     };
    158 
    159     auto complex = [](const TextBoxIterator::ComplexPath& path) {
    160         return path.inlineTextBox->len();
    161     };
    162 
    163     return WTF::switchOn(iterator().m_pathVariant, simple, complex);
    164 }
    165 
    166 bool TextBox::isLastOnLine() const
    167 {
    168     auto simple = [](const TextBoxIterator::SimplePath& path) {
    169         auto next = path.iterator;
    170         ++next;
    171         return next == path.end || (*path.iterator).lineIndex() != (*next).lineIndex();
    172     };
    173 
    174     auto complex = [](const TextBoxIterator::ComplexPath& path) {
    175         auto* next = path.nextInlineTextBoxInTextOrder();
    176         return !next || &path.inlineTextBox->root() != &next->root();
    177     };
    178 
    179     return WTF::switchOn(iterator().m_pathVariant, simple, complex);
    180 }
    181 
    182 bool TextBox::isLast() const
    183 {
    184     auto simple = [](const TextBoxIterator::SimplePath& path) {
    185         auto next = path.iterator;
    186         ++next;
    187         return next == path.end;
    188     };
    189 
    190     auto complex = [](const TextBoxIterator::ComplexPath& path) {
    191         return !path.nextInlineTextBoxInTextOrder();
    192     };
    193 
    194     return WTF::switchOn(iterator().m_pathVariant, simple, complex);
    195 }
    196 
    197 
    198 inline const TextBoxIterator& TextBox::iterator() const
    199 {
    200     return static_cast<const TextBoxIterator&>(*this);
    201 }
    20233
    20334TextBoxIterator::TextBoxIterator(const InlineTextBox* inlineTextBox)
     
    22253
    22354    auto complex = [](ComplexPath& path) {
    224         path.inlineTextBox = path.inlineTextBox->nextTextBox();
     55        path.inlineBox = path.inlineBox->nextTextBox();
    22556    };
    22657
     
    23768        return nullptr;
    23869    }
    239     return inlineTextBox->nextTextBox();
     70    return inlineBox->nextTextBox();
    24071}
    24172
     
    24778
    24879    auto complex = [](ComplexPath& path) {
    249         path.inlineTextBox = path.nextInlineTextBoxInTextOrder();
     80        path.inlineBox = path.nextInlineTextBoxInTextOrder();
    25081        if (!path.sortedInlineTextBoxes.isEmpty())
    25182            ++path.sortedInlineTextBoxIndex;
     
    26798
    26899    auto complex = [&](const ComplexPath& path) {
    269         return path.inlineTextBox == WTF::get<ComplexPath>(other.m_pathVariant).inlineTextBox;
     100        return path.inlineBox == WTF::get<ComplexPath>(other.m_pathVariant).inlineBox;
    270101    };
    271102
     
    280111
    281112    auto complex = [&](const ComplexPath& path) {
    282         return !path.inlineTextBox;
     113        return !path.inlineBox;
    283114    };
    284115
     
    314145}
    315146
     147ElementBoxIterator::ElementBoxIterator(const InlineElementBox* inlineElementBox)
     148    : m_pathVariant(ComplexPath { inlineElementBox })
     149{
     150}
     151ElementBoxIterator::ElementBoxIterator(SimpleLineLayout::RunResolver::Iterator iterator, SimpleLineLayout::RunResolver::Iterator end)
     152    : m_pathVariant(SimplePath { iterator, end })
     153{
     154}
     155
     156bool ElementBoxIterator::atEnd() const
     157{
     158    auto simple = [&](const SimplePath& path) {
     159        return path.iterator == path.end;
     160    };
     161
     162    auto complex = [&](const ComplexPath& path) {
     163        return !path.inlineBox;
     164    };
     165
     166    return WTF::switchOn(m_pathVariant, simple, complex);
     167}
     168
     169ElementBoxIterator elementBoxFor(const RenderLineBreak& renderElement)
     170{
     171    if (auto& parent = *renderElement.parent(); is<RenderBlockFlow>(parent)) {
     172        if (auto* simpleLineLayout = downcast<RenderBlockFlow>(parent).simpleLineLayout()) {
     173            auto range = simpleLineLayout->runResolver().rangeForRenderer(renderElement);
     174            return { range.begin(), range.end() };
     175        }
     176    }
     177
     178    return ElementBoxIterator { renderElement.inlineBoxWrapper() };
     179}
     180
    316181}
    317182}
  • trunk/Source/WebCore/rendering/line/LineLayoutTraversal.h

    r250390 r250519  
    2727
    2828#include "FloatRect.h"
     29#include "InlineElementBox.h"
     30#include "InlineTextBox.h"
     31#include "RenderText.h"
    2932#include "SimpleLineLayoutResolver.h"
    3033#include <wtf/HashMap.h>
     
    3538namespace WebCore {
    3639
    37 class InlineTextBox;
     40class RenderLineBreak;
    3841class RenderText;
    3942
     
    4548struct EndIterator { };
    4649
    47 class TextBox {
     50template<class Iterator>
     51class Box {
    4852public:
    4953    FloatRect rect() const;
    5054    FloatRect logicalRect() const;
    5155
    52     bool hasHyphen() const;
    5356    bool isLeftToRightDirection() const;
    5457    bool dirOverride() const;
    55 
     58    bool isLineBreak() const;
     59
     60protected:
     61    Box() = default;
     62    Box(const Box&) = default;
     63    Box(Box&&) = default;
     64    ~Box() = default;
     65    Box& operator=(const Box&) = default;
     66    Box& operator=(Box&&) = default;
     67
     68    const Iterator& iterator() const;
     69};
     70
     71template<class Iterator>
     72class TextBox : public Box<Iterator> {
     73public:
     74    bool hasHyphen() const;
    5675    StringView text() const;
    57     bool isLineBreak() const;
    5876
    5977    // These offsets are relative to the text renderer (not flow).
     
    7391    TextBox& operator=(TextBox&&) = default;
    7492
    75 private:
    76     const TextBoxIterator& iterator() const;
    77 };
    78 
    79 class TextBoxIterator : private TextBox {
     93    using Box<Iterator>::iterator;
     94};
     95
     96class TextBoxIterator : private TextBox<TextBoxIterator> {
    8097public:
    8198    TextBoxIterator() : m_pathVariant(ComplexPath { nullptr, { } }) { };
     99
    82100    explicit TextBoxIterator(const InlineTextBox*);
    83101    TextBoxIterator(Vector<const InlineTextBox*>&& sorted, size_t index);
    84    
    85102    TextBoxIterator(SimpleLineLayout::RunResolver::Iterator, SimpleLineLayout::RunResolver::Iterator end);
    86103
     
    102119    bool atEnd() const;
    103120
     121    using BoxType = TextBox<TextBoxIterator>;
     122
    104123private:
    105     friend class TextBox;
     124    friend class Box<TextBoxIterator>;
     125    friend class TextBox<TextBoxIterator>;
    106126
    107127    struct SimplePath {
     
    110130    };
    111131    struct ComplexPath {
    112         const InlineTextBox* inlineTextBox;
     132        const InlineTextBox* inlineBox;
    113133        Vector<const InlineTextBox*> sortedInlineTextBoxes;
    114134        size_t sortedInlineTextBoxIndex { 0 };
    115135
    116136        const InlineTextBox* nextInlineTextBoxInTextOrder() const;
     137    };
     138    Variant<SimplePath, ComplexPath> m_pathVariant;
     139};
     140
     141class ElementBoxIterator : private Box<ElementBoxIterator> {
     142public:
     143    ElementBoxIterator() : m_pathVariant(ComplexPath { nullptr }) { };
     144
     145    explicit ElementBoxIterator(const InlineElementBox*);
     146    ElementBoxIterator(SimpleLineLayout::RunResolver::Iterator, SimpleLineLayout::RunResolver::Iterator end);
     147
     148    explicit operator bool() const { return !atEnd(); }
     149
     150    const Box& operator*() const { return *this; }
     151    const Box* operator->() const { return this; }
     152
     153    bool atEnd() const;
     154
     155    using BoxType = Box<ElementBoxIterator>;
     156
     157private:
     158    friend class Box<ElementBoxIterator>;
     159
     160    struct SimplePath {
     161        SimpleLineLayout::RunResolver::Iterator iterator;
     162        SimpleLineLayout::RunResolver::Iterator end;
     163    };
     164    struct ComplexPath {
     165        const InlineElementBox* inlineBox;
    117166    };
    118167    Variant<SimplePath, ComplexPath> m_pathVariant;
     
    136185TextBoxIterator firstTextBoxInTextOrderFor(const RenderText&);
    137186TextBoxRange textBoxesFor(const RenderText&);
    138 
    139 inline bool hasTextBoxes(const RenderText& text) { return !firstTextBoxFor(text).atEnd(); }
    140 
    141 }
    142 }
     187ElementBoxIterator elementBoxFor(const RenderLineBreak&);
     188
     189// -----------------------------------------------
     190
     191template<class Iterator> inline FloatRect Box<Iterator>::rect() const
     192{
     193    auto simple = [](const typename Iterator::SimplePath& path) {
     194        return (*path.iterator).rect();
     195    };
     196
     197    auto complex = [](const typename Iterator::ComplexPath& path) {
     198        return path.inlineBox->frameRect();
     199    };
     200
     201    return WTF::switchOn(iterator().m_pathVariant, simple, complex);
     202}
     203
     204template<class Iterator> inline FloatRect Box<Iterator>::logicalRect() const
     205{
     206    auto simple = [](const typename Iterator::SimplePath& path) {
     207        return (*path.iterator).rect();
     208    };
     209
     210    auto complex = [](const typename Iterator::ComplexPath& path) {
     211        return path.inlineBox->logicalFrameRect();
     212    };
     213
     214    return WTF::switchOn(iterator().m_pathVariant, simple, complex);
     215}
     216
     217template<class Iterator> inline bool Box<Iterator>::isLeftToRightDirection() const
     218{
     219    auto simple = [](const typename Iterator::SimplePath&) {
     220        return true;
     221    };
     222
     223    auto complex = [](const typename Iterator::ComplexPath& path) {
     224        return path.inlineBox->isLeftToRightDirection();
     225    };
     226
     227    return WTF::switchOn(iterator().m_pathVariant, simple, complex);
     228}
     229
     230template<class Iterator> inline bool Box<Iterator>::dirOverride() const
     231{
     232    auto simple = [](const typename Iterator::SimplePath&) {
     233        return false;
     234    };
     235
     236    auto complex = [](const typename Iterator::ComplexPath& path) {
     237        return path.inlineBox->dirOverride();
     238    };
     239
     240    return WTF::switchOn(iterator().m_pathVariant, simple, complex);
     241}
     242
     243template<class Iterator> inline bool Box<Iterator>::isLineBreak() const
     244{
     245    auto simple = [](const typename Iterator::SimplePath& path) {
     246        return (*path.iterator).isLineBreak();
     247    };
     248
     249    auto complex = [](const typename Iterator::ComplexPath& path) {
     250        return path.inlineBox->isLineBreak();
     251    };
     252
     253    return WTF::switchOn(iterator().m_pathVariant, simple, complex);
     254}
     255
     256template<class Iterator> inline const Iterator& Box<Iterator>::iterator() const
     257{
     258    return static_cast<const Iterator&>(*this);
     259}
     260
     261template<class Iterator> inline bool TextBox<Iterator>::hasHyphen() const
     262{
     263    auto simple = [](const typename Iterator::SimplePath& path) {
     264        return (*path.iterator).hasHyphen();
     265    };
     266
     267    auto complex = [](const typename Iterator::ComplexPath& path) {
     268        return path.inlineBox->hasHyphen();
     269    };
     270
     271    return WTF::switchOn(iterator().m_pathVariant, simple, complex);
     272}
     273
     274template<class Iterator> inline StringView TextBox<Iterator>::text() const
     275{
     276    auto simple = [](const typename Iterator::SimplePath& path) {
     277        return (*path.iterator).text();
     278    };
     279
     280    auto complex = [](const typename Iterator::ComplexPath& path) {
     281        return StringView(path.inlineBox->renderer().text()).substring(path.inlineBox->start(), path.inlineBox->len());
     282    };
     283
     284    return WTF::switchOn(iterator().m_pathVariant, simple, complex);
     285}
     286
     287template<class Iterator> inline unsigned TextBox<Iterator>::localStartOffset() const
     288{
     289    auto simple = [](const typename Iterator::SimplePath& path) {
     290        return (*path.iterator).localStart();
     291    };
     292
     293    auto complex = [](const typename Iterator::ComplexPath& path) {
     294        return path.inlineBox->start();
     295    };
     296
     297    return WTF::switchOn(iterator().m_pathVariant, simple, complex);
     298}
     299
     300template<class Iterator> inline unsigned TextBox<Iterator>::localEndOffset() const
     301{
     302    auto simple = [](const typename Iterator::SimplePath& path) {
     303        return (*path.iterator).localEnd();
     304    };
     305
     306    auto complex = [](const typename Iterator::ComplexPath& path) {
     307        return path.inlineBox->end();
     308    };
     309
     310    return WTF::switchOn(iterator().m_pathVariant, simple, complex);
     311}
     312
     313template<class Iterator> inline unsigned TextBox<Iterator>::length() const
     314{
     315    auto simple = [](const typename Iterator::SimplePath& path) {
     316        return (*path.iterator).end() - (*path.iterator).start();
     317    };
     318
     319    auto complex = [](const typename Iterator::ComplexPath& path) {
     320        return path.inlineBox->len();
     321    };
     322
     323    return WTF::switchOn(iterator().m_pathVariant, simple, complex);
     324}
     325
     326template<class Iterator> inline bool TextBox<Iterator>::isLastOnLine() const
     327{
     328    auto simple = [](const typename Iterator::SimplePath& path) {
     329        auto next = path.iterator;
     330        ++next;
     331        return next == path.end || (*path.iterator).lineIndex() != (*next).lineIndex();
     332    };
     333
     334    auto complex = [](const typename Iterator::ComplexPath& path) {
     335        auto* next = path.nextInlineTextBoxInTextOrder();
     336        return !next || &path.inlineBox->root() != &next->root();
     337    };
     338
     339    return WTF::switchOn(iterator().m_pathVariant, simple, complex);
     340}
     341
     342template<class Iterator> inline bool TextBox<Iterator>::isLast() const
     343{
     344    auto simple = [](const typename Iterator::SimplePath& path) {
     345        auto next = path.iterator;
     346        ++next;
     347        return next == path.end;
     348    };
     349
     350    auto complex = [](const typename Iterator::ComplexPath& path) {
     351        return !path.nextInlineTextBoxInTextOrder();
     352    };
     353
     354    return WTF::switchOn(iterator().m_pathVariant, simple, complex);
     355}
     356
     357}
     358}
Note: See TracChangeset for help on using the changeset viewer.