Changeset 294383 in webkit


Ignore:
Timestamp:
May 17, 2022, 11:26:53 PM (3 years ago)
Author:
Antti Koivisto
Message:

Template TextBoxPainter on line layout path
https://bugs.webkit.org/show_bug.cgi?id=240416

Reviewed by Alan Bujtas.

Painting currently goes via a line layout path agnostic iterator.
This is inefficient since we always know what sort of layout we are painting.

  • Source/WebCore/layout/integration/inline/InlineIteratorBox.cpp:

(WebCore::InlineIterator::Box::visualRect const):

  • Source/WebCore/layout/integration/inline/InlineIteratorBox.h:

(WebCore::InlineIterator::Box::containingBlock const):
(WebCore::InlineIterator::Box::visualRect const): Deleted.

  • Source/WebCore/layout/integration/inline/InlineIteratorBoxLegacyPath.h:

(WebCore::InlineIterator::BoxLegacyPath::containingBlock const):
(WebCore::InlineIterator::BoxLegacyPath::direction const):
(WebCore::InlineIterator::BoxLegacyPath::isFirstLine const):

  • Source/WebCore/layout/integration/inline/InlineIteratorBoxModernPath.h:

(WebCore::InlineIterator::BoxModernPath::containingBlock const):
(WebCore::InlineIterator::BoxModernPath::direction const):
(WebCore::InlineIterator::BoxModernPath::isFirstLine const):
(WebCore::InlineIterator::BoxModernPath::renderText const):

  • Source/WebCore/layout/integration/inline/LayoutIntegrationLineLayout.cpp:

(WebCore::LayoutIntegration::LineLayout::paint):

  • Source/WebCore/rendering/GlyphDisplayListCache.h:

(WebCore::GlyphDisplayListCache::singleton):

  • Source/WebCore/rendering/InlineBoxPainter.cpp:

(WebCore::InlineBoxPainter::paintMask):
(WebCore::InlineBoxPainter::paintDecorations):

  • Source/WebCore/rendering/LegacyInlineFlowBox.cpp:

(WebCore::LegacyInlineFlowBox::addTextBoxVisualOverflow):

  • Source/WebCore/rendering/LegacyInlineTextBox.cpp:

(WebCore::LegacyInlineTextBox::paint):

  • Source/WebCore/rendering/LegacyInlineTextBox.h:
  • Source/WebCore/rendering/RenderBoxModelObject.cpp:

(WebCore::RenderBoxModelObject::paintMaskForTextFillBox):

  • Source/WebCore/rendering/TextBoxPainter.cpp:

(WebCore::LegacyTextBoxPainter::LegacyTextBoxPainter):
(WebCore::ModernTextBoxPainter::ModernTextBoxPainter):
(WebCore::TextBoxPainter<TextBoxPath>::TextBoxPainter):
(WebCore::TextBoxPainter<TextBoxPath>::~TextBoxPainter):
(WebCore::TextBoxPainter<TextBoxPath>::makeIterator const):
(WebCore::TextBoxPainter<TextBoxPath>::paint):
(WebCore::TextBoxPainter<TextBoxPath>::createMarkedTextFromSelectionInBox):
(WebCore::TextBoxPainter<TextBoxPath>::paintBackground):
(WebCore::TextBoxPainter<TextBoxPath>::paintForegroundAndDecorations):
(WebCore::TextBoxPainter<TextBoxPath>::paintCompositionBackground):
(WebCore::TextBoxPainter<TextBoxPath>::paintForeground):
(WebCore::TextBoxPainter<TextBoxPath>::createDecorationPainter):
(WebCore::TextBoxPainter<TextBoxPath>::paintBackgroundDecorations):
(WebCore::TextBoxPainter<TextBoxPath>::paintForegroundDecorations):
(WebCore::TextBoxPainter<TextBoxPath>::paintCompositionUnderlines):
(WebCore::TextBoxPainter<TextBoxPath>::textPosition):
(WebCore::TextBoxPainter<TextBoxPath>::paintCompositionUnderline):
(WebCore::TextBoxPainter<TextBoxPath>::paintPlatformDocumentMarkers):
(WebCore::LegacyTextBoxPainter::calculateUnionOfAllDocumentMarkerBounds):
(WebCore::TextBoxPainter<TextBoxPath>::paintPlatformDocumentMarker):
(WebCore::TextBoxPainter<TextBoxPath>::computePaintRect):
(WebCore::calculateDocumentMarkerBounds):
(WebCore::TextBoxPainter<TextBoxPath>::computeHaveSelection const):
(WebCore::TextBoxPainter<TextBoxPath>::fontCascade const):
(WebCore::TextBoxPainter<TextBoxPath>::textOriginFromPaintRect const):
(WebCore::TextBoxPainter<TextBoxPath>::debugTextShadow const):
(WebCore::TextBoxPainter::TextBoxPainter): Deleted.
(WebCore::TextBoxPainter::~TextBoxPainter): Deleted.
(WebCore::TextBoxPainter::paint): Deleted.
(WebCore::TextBoxPainter::createMarkedTextFromSelectionInBox): Deleted.
(WebCore::TextBoxPainter::paintBackground): Deleted.
(WebCore::TextBoxPainter::paintForegroundAndDecorations): Deleted.
(WebCore::TextBoxPainter::paintCompositionBackground): Deleted.
(WebCore::TextBoxPainter::paintForeground): Deleted.
(WebCore::TextBoxPainter::createDecorationPainter): Deleted.
(WebCore::TextBoxPainter::paintBackgroundDecorations): Deleted.
(WebCore::TextBoxPainter::paintForegroundDecorations): Deleted.
(WebCore::TextBoxPainter::paintCompositionUnderlines): Deleted.
(WebCore::textPosition): Deleted.
(WebCore::TextBoxPainter::paintCompositionUnderline): Deleted.
(WebCore::TextBoxPainter::paintPlatformDocumentMarkers): Deleted.
(WebCore::TextBoxPainter::calculateUnionOfAllDocumentMarkerBounds): Deleted.
(WebCore::TextBoxPainter::paintPlatformDocumentMarker): Deleted.
(WebCore::TextBoxPainter::computePaintRect): Deleted.
(WebCore::TextBoxPainter::calculateDocumentMarkerBounds): Deleted.
(WebCore::TextBoxPainter::computeHaveSelection const): Deleted.
(WebCore::TextBoxPainter::fontCascade const): Deleted.
(WebCore::TextBoxPainter::textOriginFromPaintRect const): Deleted.
(WebCore::TextBoxPainter::debugTextShadow const): Deleted.

  • Source/WebCore/rendering/TextBoxPainter.h:

(WebCore::TextBoxPainter::textBox const):

Location:
trunk/Source/WebCore
Files:
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/layout/integration/inline/InlineIteratorBox.cpp

    r294279 r294383  
    9595}
    9696
     97FloatRect Box::visualRect() const
     98{
     99    auto rect = visualRectIgnoringBlockDirection();
     100    containingBlock().flipForWritingMode(rect);
     101    return rect;
     102}
     103
    97104RenderObject::HighlightState Box::selectionState() const
    98105{
  • trunk/Source/WebCore/layout/integration/inline/InlineIteratorBox.h

    r294279 r294383  
    6161    bool isRootInlineBox() const;
    6262
    63     FloatRect visualRect(float formattingRootSizeInBlockDirection) const;
     63    FloatRect visualRect() const;
    6464    FloatRect visualRectIgnoringBlockDirection() const;
    6565
     
    8686
    8787    const RenderObject& renderer() const;
     88    const RenderBlockFlow& containingBlock() const;
    8889    const RenderStyle& style() const;
    8990
     
    100101
    101102    LineBoxIterator lineBox() const;
     103
     104#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
     105    const BoxModernPath& modernPath() const;
     106#endif
     107    const BoxLegacyPath& legacyPath() const;
    102108
    103109protected:
     
    107113    friend class TextBoxIterator;
    108114
    109     // To help with debugging.
    110 #if ENABLE(LAYOUT_FORMATTING_CONTEXT)
    111     const BoxModernPath& modernPath() const;
    112 #endif
    113     const BoxLegacyPath& legacyPath() const;
    114 
    115115    PathVariant m_pathVariant;
    116116};
     
    185185}
    186186
    187 inline FloatRect Box::visualRect(float formattingRootSizeInBlockDirection) const
    188 {
    189     auto visualRect = visualRectIgnoringBlockDirection();
    190     if (!style().isFlippedBlocksWritingMode())
    191         return visualRect;
    192 
    193     if (style().isHorizontalWritingMode())
    194         visualRect.setY(formattingRootSizeInBlockDirection - visualRect.maxY());
    195     else
    196         visualRect.setX(formattingRootSizeInBlockDirection - visualRect.maxX());
    197     return visualRect;
    198 }
    199 
    200187inline FloatRect Box::visualRectIgnoringBlockDirection() const
    201188{
     
    244231    return WTF::switchOn(m_pathVariant, [](auto& path) -> const RenderObject& {
    245232        return path.renderer();
     233    });
     234}
     235
     236inline const RenderBlockFlow& Box::containingBlock() const
     237{
     238    return WTF::switchOn(m_pathVariant, [](auto& path) -> const RenderBlockFlow& {
     239        return path.containingBlock();
    246240    });
    247241}
  • trunk/Source/WebCore/layout/integration/inline/InlineIteratorBoxLegacyPath.h

    r294279 r294383  
    7777    }
    7878
     79    const RenderBlockFlow& containingBlock() const
     80    {
     81        return m_inlineBox->root().blockFlow();
     82    }
     83
    7984    const RenderStyle& style() const
    8085    {
     
    114119    }
    115120
     121    TextDirection direction() const { return bidiLevel() % 2 ? TextDirection::RTL : TextDirection::LTR; }
     122    bool isFirstLine() const { return !rootInlineBox().prevRootBox(); }
     123
    116124    bool operator==(const BoxLegacyPath& other) const { return m_inlineBox == other.m_inlineBox; }
    117125
  • trunk/Source/WebCore/layout/integration/inline/InlineIteratorBoxModernPath.h

    r294279 r294383  
    104104    }
    105105
     106    const RenderBlockFlow& containingBlock() const
     107    {
     108        return m_inlineContent->containingBlock();
     109    }
     110
    106111    const RenderStyle& style() const
    107112    {
     
    208213    }
    209214
     215    TextDirection direction() const { return bidiLevel() % 2 ? TextDirection::RTL : TextDirection::LTR; }
     216    bool isFirstLine() const { return !box().lineIndex(); }
     217
    210218    bool operator==(const BoxModernPath& other) const { return m_inlineContent == other.m_inlineContent && m_boxIndex == other.m_boxIndex; }
    211219
     
    273281
    274282    const RenderText& renderText() const { return downcast<RenderText>(renderer()); }
    275     TextDirection direction() const { return bidiLevel() % 2 ? TextDirection::RTL : TextDirection::LTR; }
    276283
    277284    WeakPtr<const LayoutIntegration::InlineContent> m_inlineContent;
  • trunk/Source/WebCore/layout/integration/inline/LayoutIntegrationLineLayout.cpp

    r294279 r294383  
    801801                continue;
    802802
    803             TextBoxPainter painter(*m_inlineContent, box, paintInfo, paintOffset);
     803            ModernTextBoxPainter painter(*m_inlineContent, box, paintInfo, paintOffset);
    804804            painter.paint();
    805805            continue;
  • trunk/Source/WebCore/rendering/GlyphDisplayListCache.h

    r293951 r294383  
    3636namespace WebCore {
    3737
     38class LegacyInlineTextBox;
     39
     40namespace InlineDisplay {
     41struct Box;
     42}
     43
    3844template<typename LayoutRun>
    3945class GlyphDisplayListCache {
     
    4349    static GlyphDisplayListCache& singleton()
    4450    {
     51        static_assert(std::is_same_v<LayoutRun, LegacyInlineTextBox> || std::is_same_v<LayoutRun, InlineDisplay::Box>);
    4552        static NeverDestroyed<GlyphDisplayListCache> cache;
    4653        return cache;
  • trunk/Source/WebCore/rendering/InlineBoxPainter.cpp

    r294279 r294383  
    142142
    143143    // Move x/y to our coordinates.
    144     auto localRect = LayoutRect { m_inlineBox.visualRect(m_inlineBox.lineBox()->containingBlock().logicalHeight()) };
     144    auto localRect = LayoutRect { m_inlineBox.visualRect() };
    145145    LayoutPoint adjustedPaintOffset = m_paintOffset + localRect.location();
    146146
     
    218218
    219219    // Move x/y to our coordinates.
    220     auto localRect = LayoutRect { m_inlineBox.visualRect(m_inlineBox.lineBox()->containingBlock().logicalHeight()) };
     220    auto localRect = LayoutRect { m_inlineBox.visualRect() };
    221221    LayoutPoint adjustedPaintoffset = m_paintOffset + localRect.location();
    222222    GraphicsContext& context = m_paintInfo.context();
  • trunk/Source/WebCore/rendering/LegacyInlineFlowBox.cpp

    r294279 r294383  
    927927    logicalVisualOverflow = LayoutRect(logicalLeftVisualOverflow, logicalTopVisualOverflow, logicalRightVisualOverflow - logicalLeftVisualOverflow, logicalBottomVisualOverflow - logicalTopVisualOverflow);
    928928
    929     auto documentMarkerBounds = TextBoxPainter::calculateUnionOfAllDocumentMarkerBounds(textBox);
     929    auto documentMarkerBounds = LegacyTextBoxPainter::calculateUnionOfAllDocumentMarkerBounds(textBox);
    930930    documentMarkerBounds.move(textBox.logicalLeft(), textBox.logicalTop());
    931931    logicalVisualOverflow = unionRect(logicalVisualOverflow, LayoutRect(documentMarkerBounds));
  • trunk/Source/WebCore/rendering/LegacyInlineTextBox.cpp

    r294279 r294383  
    398398        return;
    399399
    400     TextBoxPainter textBoxPainter(*this, paintInfo, paintOffset);
     400    LegacyTextBoxPainter textBoxPainter(*this, paintInfo, paintOffset);
    401401    textBoxPainter.paint();
    402402}
  • trunk/Source/WebCore/rendering/LegacyInlineTextBox.h

    r294279 r294383  
    151151private:
    152152    friend class InlineIterator::BoxLegacyPath;
    153     friend class TextBoxPainter;
    154153
    155154    const RenderCombineText* combinedText() const;
  • trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp

    r294279 r294383  
    728728            if (!box->isText())
    729729                continue;
    730             TextBoxPainter textBoxPainter(downcast<InlineIterator::TextBoxIterator>(box), maskInfo, paintOffset);
     730            if (auto* legacyTextBox = downcast<LegacyInlineTextBox>(box->legacyInlineBox())) {
     731                LegacyTextBoxPainter textBoxPainter(*legacyTextBox, maskInfo, paintOffset);
     732                textBoxPainter.paint();
     733                continue;
     734            }
     735            ModernTextBoxPainter textBoxPainter(box->modernPath().inlineContent(), box->modernPath().box(), maskInfo, paintOffset);
    731736            textBoxPainter.paint();
    732737        }
  • trunk/Source/WebCore/rendering/TextBoxPainter.cpp

    r294279 r294383  
    4646namespace WebCore {
    4747
    48 TextBoxPainter::TextBoxPainter(const LegacyInlineTextBox& textBox, PaintInfo& paintInfo, const LayoutPoint& paintOffset)
    49     : TextBoxPainter(InlineIterator::textBoxFor(&textBox), paintInfo, paintOffset)
     48static FloatRect calculateDocumentMarkerBounds(const InlineIterator::TextBoxIterator&, const MarkedText&);
     49
     50LegacyTextBoxPainter::LegacyTextBoxPainter(const LegacyInlineTextBox& textBox, PaintInfo& paintInfo, const LayoutPoint& paintOffset)
     51    : TextBoxPainter(InlineIterator::BoxLegacyPath { &textBox }, paintInfo, paintOffset)
    5052{
    5153    m_emphasisMarkExistsAndIsAbove = textBox.emphasisMarkExistsAndIsAbove(m_style);
     
    5355
    5456#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
    55 TextBoxPainter::TextBoxPainter(const LayoutIntegration::InlineContent& inlineContent, const InlineDisplay::Box& box, PaintInfo& paintInfo, const LayoutPoint& paintOffset)
    56     : TextBoxPainter(InlineIterator::textBoxFor(inlineContent, box), paintInfo, paintOffset)
     57ModernTextBoxPainter::ModernTextBoxPainter(const LayoutIntegration::InlineContent& inlineContent, const InlineDisplay::Box& box, PaintInfo& paintInfo, const LayoutPoint& paintOffset)
     58    : TextBoxPainter(InlineIterator::BoxModernPath { inlineContent, inlineContent.indexForBox(box) }, paintInfo, paintOffset)
    5759{
    5860}
    5961#endif
    6062
    61 TextBoxPainter::TextBoxPainter(const InlineIterator::TextBoxIterator& textBox, PaintInfo& paintInfo, const LayoutPoint& paintOffset)
    62     : m_textBox(textBox)
    63     , m_renderer(m_textBox->renderer())
     63template<typename TextBoxPath>
     64TextBoxPainter<TextBoxPath>::TextBoxPainter(TextBoxPath&& textBox, PaintInfo& paintInfo, const LayoutPoint& paintOffset)
     65    : m_textBox(WTFMove(textBox))
     66    , m_renderer(downcast<RenderText>(m_textBox.renderer()))
    6467    , m_document(m_renderer.document())
    65     , m_style(m_textBox->style())
    66     , m_paintTextRun(m_textBox->createTextRun())
     68    , m_style(m_textBox.style())
     69    , m_logicalRect(m_textBox.isHorizontal() ? m_textBox.visualRectIgnoringBlockDirection() : m_textBox.visualRectIgnoringBlockDirection().transposedRect())
     70    , m_paintTextRun(m_textBox.createTextRun(InlineIterator::CreateTextRunMode::Painting))
    6771    , m_paintInfo(paintInfo)
    68     , m_selectableRange(m_textBox->selectableRange())
     72    , m_selectableRange(m_textBox.selectableRange())
    6973    , m_paintRect(computePaintRect(paintOffset))
    70     , m_isFirstLine(m_textBox->lineBox()->isFirst())
     74    , m_isFirstLine(m_textBox.isFirstLine())
     75    , m_isCombinedText(is<RenderCombineText>(m_renderer) && downcast<RenderCombineText>(m_renderer).isCombined())
    7176    , m_isPrinting(m_document.printing())
    7277    , m_haveSelection(computeHaveSelection())
     
    7782}
    7883
    79 TextBoxPainter::~TextBoxPainter()
    80 {
    81 }
    82 
    83 void TextBoxPainter::paint()
     84template<typename TextBoxPath>
     85TextBoxPainter<TextBoxPath>::~TextBoxPainter()
     86{
     87}
     88
     89template<typename TextBoxPath>
     90InlineIterator::TextBoxIterator TextBoxPainter<TextBoxPath>::makeIterator() const
     91{
     92    auto pathCopy = m_textBox;
     93    return InlineIterator::TextBoxIterator { WTFMove(pathCopy) };
     94}
     95
     96template<typename TextBoxPath>
     97void TextBoxPainter<TextBoxPath>::paint()
    8498{
    8599    if (m_paintInfo.phase == PaintPhase::Selection && !m_haveSelection)
     
    92106    }
    93107
    94     bool shouldRotate = !textBox().isHorizontal() && !textBox().isCombinedText();
     108    bool shouldRotate = !textBox().isHorizontal() && !m_isCombinedText;
    95109    if (shouldRotate)
    96110        m_paintInfo.context().concatCTM(rotation(m_paintRect, Clockwise));
     
    116130}
    117131
    118 MarkedText TextBoxPainter::createMarkedTextFromSelectionInBox()
     132template<typename TextBoxPath>
     133MarkedText TextBoxPainter<TextBoxPath>::createMarkedTextFromSelectionInBox()
    119134{
    120135    auto [selectionStart, selectionEnd] = m_renderer.view().selection().rangeForTextBox(m_renderer, m_selectableRange);
     
    124139}
    125140
    126 void TextBoxPainter::paintBackground()
     141template<typename TextBoxPath>
     142void TextBoxPainter<TextBoxPath>::paintBackground()
    127143{
    128144    auto shouldPaintCompositionBackground = m_containsComposition && !m_useCustomUnderlines;
     
    170186}
    171187
    172 void TextBoxPainter::paintForegroundAndDecorations()
     188template<typename TextBoxPath>
     189void TextBoxPainter<TextBoxPath>::paintForegroundAndDecorations()
    173190{
    174191    auto shouldPaintSelectionForeground = m_haveSelection && !m_useCustomUnderlines;
     
    232249
    233250    if (hasDecoration && m_paintInfo.phase != PaintPhase::Selection) {
    234         TextRun textRun = textBox().createTextRun();
    235         unsigned length = m_selectableRange.truncation.value_or(textRun.length());
     251        unsigned length = m_selectableRange.truncation.value_or(m_paintTextRun.length());
    236252        unsigned selectionStart = 0;
    237253        unsigned selectionEnd = 0;
     
    288304}
    289305
    290 void TextBoxPainter::paintCompositionBackground()
     306template<typename TextBoxPath>
     307void TextBoxPainter<TextBoxPath>::paintCompositionBackground()
    291308{
    292309    auto& editor = m_renderer.frame().editor();
     
    315332}
    316333
    317 void TextBoxPainter::paintBackground(const StyledMarkedText& markedText)
    318 {
    319     paintBackground(markedText.startOffset, markedText.endOffset, markedText.style.backgroundColor);
    320 }
    321 
    322 void TextBoxPainter::paintBackground(unsigned startOffset, unsigned endOffset, const Color& color, BackgroundStyle backgroundStyle)
     334template<typename TextBoxPath>
     335void TextBoxPainter<TextBoxPath>::paintBackground(const StyledMarkedText& markedText)
     336{
     337    paintBackground(markedText.startOffset, markedText.endOffset, markedText.style.backgroundColor, BackgroundStyle::Normal);
     338}
     339
     340template<typename TextBoxPath>
     341void TextBoxPainter<TextBoxPath>::paintBackground(unsigned startOffset, unsigned endOffset, const Color& color, BackgroundStyle backgroundStyle)
    323342{
    324343    if (startOffset >= endOffset)
     
    331350    // Note that if the text is truncated, we let the thing being painted in the truncation
    332351    // draw its own highlight.
    333     auto lineBox = textBox().lineBox();
     352    auto lineBox = makeIterator()->lineBox();
    334353    auto selectionBottom = LineSelection::logicalBottom(*lineBox);
    335354    auto selectionTop = LineSelection::logicalTopAdjustedForPrecedingBlock(*lineBox);
    336355    // Use same y positioning and height as for selection, so that when the selection and this subrange are on
    337356    // the same word there are no pieces sticking out.
    338     auto deltaY = LayoutUnit { m_style.isFlippedLinesWritingMode() ? selectionBottom - textBox().logicalBottom() : textBox().logicalTop() - selectionTop };
     357    auto deltaY = LayoutUnit { m_style.isFlippedLinesWritingMode() ? selectionBottom - m_logicalRect.maxY() : m_logicalRect.y() - selectionTop };
    339358    auto selectionHeight = LayoutUnit { std::max(0.f, selectionBottom - selectionTop) };
    340     auto selectionRect = LayoutRect { LayoutUnit(m_paintRect.x()), LayoutUnit(m_paintRect.y() - deltaY), LayoutUnit(textBox().logicalWidth()), selectionHeight };
     359    auto selectionRect = LayoutRect { LayoutUnit(m_paintRect.x()), LayoutUnit(m_paintRect.y() - deltaY), LayoutUnit(m_logicalRect.width()), selectionHeight };
    341360    fontCascade().adjustSelectionRectForText(m_paintTextRun, selectionRect, startOffset, endOffset);
    342361
     
    353372}
    354373
    355 void TextBoxPainter::paintForeground(const StyledMarkedText& markedText)
     374template<typename TextBoxPath>
     375void TextBoxPainter<TextBoxPath>::paintForeground(const StyledMarkedText& markedText)
    356376{
    357377    if (markedText.startOffset >= markedText.endOffset)
     
    374394            textPainter.setShadowColorFilter(&m_style.appleColorFilter());
    375395    }
    376     textPainter.setEmphasisMark(emphasisMark, emphasisMarkOffset, textBox().isCombinedText() ? &downcast<RenderCombineText>(m_renderer) : nullptr);
     396    textPainter.setEmphasisMark(emphasisMark, emphasisMarkOffset, m_isCombinedText ? &downcast<RenderCombineText>(m_renderer) : nullptr);
    377397    if (auto* debugShadow = debugTextShadow())
    378398        textPainter.setShadow(debugShadow);
     
    383403    updateGraphicsContext(context, markedText.style.textStyles);
    384404
    385     if (auto* legacyInlineBox = textBox().legacyInlineBox())
    386         textPainter.setGlyphDisplayListIfNeeded(*legacyInlineBox, m_paintInfo, m_paintTextRun);
     405    if constexpr (std::is_same_v<TextBoxPath, InlineIterator::BoxLegacyPath>)
     406        textPainter.setGlyphDisplayListIfNeeded(downcast<LegacyInlineTextBox>(*textBox().legacyInlineBox()), m_paintInfo, m_paintTextRun);
    387407#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
    388408    else
    389         textPainter.setGlyphDisplayListIfNeeded(*textBox().inlineBox(), m_paintInfo, m_paintTextRun);
     409        textPainter.setGlyphDisplayListIfNeeded(textBox().box(), m_paintInfo, m_paintTextRun);
    390410#endif
    391411
     
    394414}
    395415
    396 TextDecorationPainter TextBoxPainter::createDecorationPainter(const StyledMarkedText& markedText, const FloatRect& clipOutRect, const FloatRect& snappedSelectionRect)
     416template<typename TextBoxPath>
     417TextDecorationPainter TextBoxPainter<TextBoxPath>::createDecorationPainter(const StyledMarkedText& markedText, const FloatRect& clipOutRect, const FloatRect& snappedSelectionRect)
    397418{
    398419    GraphicsContext& context = m_paintInfo.context();
     
    417438    textDecorations.add(TextDecorationPainter::textDecorationsInEffectForStyle(markedText.style.textDecorationStyles));
    418439    TextDecorationPainter decorationPainter { context, textDecorations, m_renderer, m_isFirstLine, font, markedText.style.textDecorationStyles };
    419     decorationPainter.setTextBox(m_textBox);
     440    decorationPainter.setTextBox(makeIterator());
    420441    decorationPainter.setWidth(snappedSelectionRect.width());
    421442    decorationPainter.setIsHorizontal(textBox().isHorizontal());
     
    429450}
    430451
    431 void TextBoxPainter::paintBackgroundDecorations(TextDecorationPainter& decorationPainter, const StyledMarkedText& markedText, const FloatRect& snappedSelectionRect)
    432 {
    433     bool isCombinedText = textBox().isCombinedText();
    434     if (isCombinedText)
     452template<typename TextBoxPath>
     453void TextBoxPainter<TextBoxPath>::paintBackgroundDecorations(TextDecorationPainter& decorationPainter, const StyledMarkedText& markedText, const FloatRect& snappedSelectionRect)
     454{
     455    if (m_isCombinedText)
    435456        m_paintInfo.context().concatCTM(rotation(m_paintRect, Clockwise));
    436457
    437458    decorationPainter.paintBackgroundDecorations(m_paintTextRun.subRun(markedText.startOffset, markedText.endOffset - markedText.startOffset), textOriginFromPaintRect(snappedSelectionRect), snappedSelectionRect.location());
    438459
    439     if (isCombinedText)
     460    if (m_isCombinedText)
    440461        m_paintInfo.context().concatCTM(rotation(m_paintRect, Counterclockwise));
    441462}
    442463
    443 void TextBoxPainter::paintForegroundDecorations(TextDecorationPainter& decorationPainter, const FloatRect& snappedSelectionRect)
    444 {
    445     bool isCombinedText = textBox().isCombinedText();
    446     if (isCombinedText)
     464template<typename TextBoxPath>
     465void TextBoxPainter<TextBoxPath>::paintForegroundDecorations(TextDecorationPainter& decorationPainter, const FloatRect& snappedSelectionRect)
     466{
     467    if (m_isCombinedText)
    447468        m_paintInfo.context().concatCTM(rotation(m_paintRect, Clockwise));
    448469
    449470    decorationPainter.paintForegroundDecorations(snappedSelectionRect.location());
    450471
    451     if (isCombinedText)
     472    if (m_isCombinedText)
    452473        m_paintInfo.context().concatCTM(rotation(m_paintRect, Counterclockwise));
    453474}
    454475
    455 void TextBoxPainter::paintCompositionUnderlines()
     476template<typename TextBoxPath>
     477void TextBoxPainter<TextBoxPath>::paintCompositionUnderlines()
    456478{
    457479    for (auto& underline : m_renderer.frame().editor().customCompositionUnderlines()) {
     
    481503}
    482504
    483 static float textPosition(const InlineIterator::TextBoxIterator& textBox)
     505template<typename TextBoxPath>
     506float TextBoxPainter<TextBoxPath>::textPosition()
    484507{
    485508    // When computing the width of a text run, RenderBlock::computeInlineDirectionPositionsForLine() doesn't include the actual offset
    486509    // from the containing block edge in its measurement. textPosition() should be consistent so the text are rendered in the same width.
    487     if (!textBox->logicalLeft())
     510    if (!m_logicalRect.x())
    488511        return 0;
    489     return textBox->logicalLeft() - textBox->lineBox()->contentLogicalLeft();
    490 }
    491 
    492 void TextBoxPainter::paintCompositionUnderline(const CompositionUnderline& underline)
     512    return m_logicalRect.x() - makeIterator()->lineBox()->contentLogicalLeft();
     513}
     514
     515template<typename TextBoxPath>
     516void TextBoxPainter<TextBoxPath>::paintCompositionUnderline(const CompositionUnderline& underline)
    493517{
    494518    float start = 0; // start of line to draw, relative to tx
    495     float width = textBox().logicalWidth(); // how much line to draw
     519    float width = m_logicalRect.width(); // how much line to draw
    496520    bool useWholeWidth = true;
    497521    unsigned paintStart = textBox().start();
     
    500524        paintStart = underline.startOffset;
    501525        useWholeWidth = false;
    502         start = m_renderer.width(textBox().start(), paintStart - textBox().start(), textPosition(m_textBox), m_isFirstLine);
     526        start = m_renderer.width(textBox().start(), paintStart - textBox().start(), textPosition(), m_isFirstLine);
    503527    }
    504528    if (paintEnd != underline.endOffset) {
     
    511535    }
    512536    if (!useWholeWidth) {
    513         width = m_renderer.width(paintStart, paintEnd - paintStart, textPosition(m_textBox) + start, m_isFirstLine);
    514         mirrorRTLSegment(textBox().logicalWidth(), textBox().direction(), start, width);
     537        width = m_renderer.width(paintStart, paintEnd - paintStart, textPosition() + start, m_isFirstLine);
     538        mirrorRTLSegment(m_logicalRect.width(), textBox().direction(), start, width);
    515539    }
    516540
     
    520544    int lineThickness = 1;
    521545    int baseline = m_style.metricsOfPrimaryFont().ascent();
    522     if (underline.thick && textBox().logicalHeight() - baseline >= 2)
     546    if (underline.thick && m_logicalRect.height() - baseline >= 2)
    523547        lineThickness = 2;
    524548
     
    534558    context.setStrokeColor(underlineColor);
    535559    context.setStrokeThickness(lineThickness);
    536     context.drawLineForText(FloatRect(m_paintRect.x() + start, m_paintRect.y() + textBox().logicalHeight() - lineThickness, width, lineThickness), m_document.printing());
    537 }
    538 
    539 void TextBoxPainter::paintPlatformDocumentMarkers()
     560    context.drawLineForText(FloatRect(m_paintRect.x() + start, m_paintRect.y() + m_logicalRect.height() - lineThickness, width, lineThickness), m_isPrinting);
     561}
     562
     563template<typename TextBoxPath>
     564void TextBoxPainter<TextBoxPath>::paintPlatformDocumentMarkers()
    540565{
    541566    auto markedTexts = MarkedText::collectForDocumentMarkers(m_renderer, m_selectableRange, MarkedText::PaintPhase::Decoration);
     
    544569}
    545570
    546 FloatRect TextBoxPainter::calculateUnionOfAllDocumentMarkerBounds(const LegacyInlineTextBox& textBox)
     571FloatRect LegacyTextBoxPainter::calculateUnionOfAllDocumentMarkerBounds(const LegacyInlineTextBox& textBox)
    547572{
    548573    // This must match paintPlatformDocumentMarkers().
     
    554579}
    555580
    556 void TextBoxPainter::paintPlatformDocumentMarker(const MarkedText& markedText)
     581template<typename TextBoxPath>
     582void TextBoxPainter<TextBoxPath>::paintPlatformDocumentMarker(const MarkedText& markedText)
    557583{
    558584    // Never print spelling/grammar markers (5327887)
     
    560586        return;
    561587
    562     auto bounds = calculateDocumentMarkerBounds(m_textBox, markedText);
     588    auto bounds = calculateDocumentMarkerBounds(makeIterator(), markedText);
    563589
    564590    auto lineStyleForMarkedTextType = [&]() -> DocumentMarkerLineStyle {
     
    588614}
    589615
    590 FloatRect TextBoxPainter::computePaintRect(const LayoutPoint& paintOffset)
     616template<typename TextBoxPath>
     617FloatRect TextBoxPainter<TextBoxPath>::computePaintRect(const LayoutPoint& paintOffset)
    591618{
    592619    FloatPoint localPaintOffset(paintOffset);
    593620
    594621    if (m_selectableRange.truncation) {
    595         if (m_renderer.containingBlock()->style().isLeftToRightDirection() != textBox().isLeftToRightDirection()) {
     622        if (m_renderer.containingBlock()->style().direction() != textBox().direction()) {
    596623            // Make the visible fragment of text hug the edge closest to the rest of the run by moving the origin
    597624            // at which we start drawing text.
     
    602629            // NOTE: WebKit's behavior differs from that of IE which appears to just overlay the ellipsis on top of the
    603630            // truncated string i.e.  |Hello|CBA| -> |...lo|CBA|
    604             LayoutUnit widthOfVisibleText { m_renderer.width(textBox().start(), *m_selectableRange.truncation, textPosition(m_textBox), m_isFirstLine) };
    605             LayoutUnit widthOfHiddenText { textBox().logicalWidth() - widthOfVisibleText };
    606             LayoutSize truncationOffset(textBox().isLeftToRightDirection() ? widthOfHiddenText : -widthOfHiddenText, 0_lu);
     631            LayoutUnit widthOfVisibleText { m_renderer.width(textBox().start(), *m_selectableRange.truncation, textPosition(), m_isFirstLine) };
     632            LayoutUnit widthOfHiddenText { m_logicalRect.width() - widthOfVisibleText };
     633            LayoutSize truncationOffset(textBox().direction() == TextDirection::LTR ? widthOfHiddenText : -widthOfHiddenText, 0_lu);
    607634            localPaintOffset.move(textBox().isHorizontal() ? truncationOffset : truncationOffset.transposedSize());
    608635        }
    609636    }
    610637
    611     localPaintOffset.move(0, m_style.isHorizontalWritingMode() ? 0 : -textBox().logicalHeight());
    612 
    613     auto boxOrigin = textBox().visualRect(textBox().lineBox()->containingBlock().logicalHeight()).location();
     638    localPaintOffset.move(0, m_style.isHorizontalWritingMode() ? 0 : -m_logicalRect.height());
     639
     640    auto visualRect = textBox().visualRectIgnoringBlockDirection();
     641    textBox().containingBlock().flipForWritingMode(visualRect);
     642
     643    auto boxOrigin = visualRect.location();
    614644    boxOrigin.moveBy(localPaintOffset);
    615     return { boxOrigin, FloatSize(textBox().logicalWidth(), textBox().logicalHeight()) };
    616 }
    617 
    618 FloatRect TextBoxPainter::calculateDocumentMarkerBounds(const InlineIterator::TextBoxIterator& textBox, const MarkedText& markedText)
     645    return { boxOrigin, FloatSize(m_logicalRect.width(), m_logicalRect.height()) };
     646}
     647
     648FloatRect calculateDocumentMarkerBounds(const InlineIterator::TextBoxIterator& textBox, const MarkedText& markedText)
    619649{
    620650    auto& font = textBox->fontCascade();
     
    635665}
    636666
    637 bool TextBoxPainter::computeHaveSelection() const
     667template<typename TextBoxPath>
     668bool TextBoxPainter<TextBoxPath>::computeHaveSelection() const
    638669{
    639670    if (m_isPrinting || m_paintInfo.phase == PaintPhase::TextClip)
     
    643674}
    644675
    645 const FontCascade& TextBoxPainter::fontCascade() const
    646 {
    647     return m_textBox->fontCascade();
    648 }
    649 
    650 FloatPoint TextBoxPainter::textOriginFromPaintRect(const FloatRect& paintRect) const
     676template<typename TextBoxPath>
     677const FontCascade& TextBoxPainter<TextBoxPath>::fontCascade() const
     678{
     679    if (m_isCombinedText)
     680        return downcast<RenderCombineText>(m_renderer).textCombineFont();
     681
     682    return m_textBox.style().fontCascade();
     683}
     684
     685template<typename TextBoxPath>
     686FloatPoint TextBoxPainter<TextBoxPath>::textOriginFromPaintRect(const FloatRect& paintRect) const
    651687{
    652688    FloatPoint textOrigin { paintRect.x(), paintRect.y() + fontCascade().metricsOfPrimaryFont().ascent() };
    653     if (textBox().isCombinedText()) {
     689    if (m_isCombinedText) {
    654690        if (auto newOrigin = downcast<RenderCombineText>(m_renderer).computeTextOrigin(paintRect))
    655691            textOrigin = newOrigin.value();
     
    662698}
    663699
    664 const ShadowData* TextBoxPainter::debugTextShadow() const
     700template<typename TextBoxPath>
     701const ShadowData* TextBoxPainter<TextBoxPath>::debugTextShadow() const
    665702{
    666703    if (!m_renderer.settings().legacyLineLayoutVisualCoverageEnabled())
    667704        return nullptr;
    668     if (!textBox().legacyInlineBox())
     705    if constexpr (std::is_same_v<TextBoxPath, InlineIterator::BoxModernPath>)
    669706        return nullptr;
    670707
     
    673710}
    674711
    675 }
     712template class TextBoxPainter<InlineIterator::BoxModernPath>;
     713template class TextBoxPainter<InlineIterator::BoxLegacyPath>;
     714
     715}
  • trunk/Source/WebCore/rendering/TextBoxPainter.h

    r294279 r294383  
    4646struct StyledMarkedText;
    4747
     48template<typename TextBoxPath>
    4849class TextBoxPainter {
    4950public:
    50     TextBoxPainter(const LegacyInlineTextBox&, PaintInfo&, const LayoutPoint& paintOffset);
    51 #if ENABLE(LAYOUT_FORMATTING_CONTEXT)
    52     TextBoxPainter(const LayoutIntegration::InlineContent&, const InlineDisplay::Box&, PaintInfo&, const LayoutPoint& paintOffset);
    53 #endif
    54     TextBoxPainter(const InlineIterator::TextBoxIterator&, PaintInfo&, const LayoutPoint& paintOffset);
    55 
     51    TextBoxPainter(TextBoxPath&&, PaintInfo&, const LayoutPoint& paintOffset);
    5652    ~TextBoxPainter();
    5753
    5854    void paint();
    5955
    60     static FloatRect calculateUnionOfAllDocumentMarkerBounds(const LegacyInlineTextBox&);
    61 
    62 private:
    63     auto& textBox() const { return *m_textBox; }
     56protected:
     57    auto& textBox() const { return m_textBox; }
     58    InlineIterator::TextBoxIterator makeIterator() const;
    6459
    6560    void paintBackground();
     
    7974    void paintPlatformDocumentMarker(const MarkedText&);
    8075
    81     static FloatRect calculateDocumentMarkerBounds(const InlineIterator::TextBoxIterator&, const MarkedText&);
    82 
     76    float textPosition();
    8377    FloatRect computePaintRect(const LayoutPoint& paintOffset);
    8478    bool computeHaveSelection() const;
     
    8983    const ShadowData* debugTextShadow() const;
    9084
    91     const InlineIterator::TextBoxIterator m_textBox;
     85    const TextBoxPath m_textBox;
    9286    const RenderText& m_renderer;
    9387    const Document& m_document;
    9488    const RenderStyle& m_style;
     89    const FloatRect m_logicalRect;
    9590    const TextRun m_paintTextRun;
    9691    PaintInfo& m_paintInfo;
     
    9893    const FloatRect m_paintRect;
    9994    const bool m_isFirstLine;
     95    const bool m_isCombinedText;
    10096    const bool m_isPrinting;
    10197    const bool m_haveSelection;
     
    105101};
    106102
     103class LegacyTextBoxPainter : public TextBoxPainter<InlineIterator::BoxLegacyPath> {
     104public:
     105    LegacyTextBoxPainter(const LegacyInlineTextBox&, PaintInfo&, const LayoutPoint& paintOffset);
     106
     107    static FloatRect calculateUnionOfAllDocumentMarkerBounds(const LegacyInlineTextBox&);
     108};
     109
     110#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
     111class ModernTextBoxPainter : public TextBoxPainter<InlineIterator::BoxModernPath> {
     112public:
     113    ModernTextBoxPainter(const LayoutIntegration::InlineContent&, const InlineDisplay::Box&, PaintInfo&, const LayoutPoint& paintOffset);
     114};
     115#endif
     116
    107117}
Note: See TracChangeset for help on using the changeset viewer.