Changeset 250910 in webkit


Ignore:
Timestamp:
Oct 9, 2019 7:07:21 AM (5 years ago)
Author:
Alan Bujtas
Message:

[LFC][Painting] Decouple content and decoration painting
https://bugs.webkit.org/show_bug.cgi?id=202718
<rdar://problem/56104661>

Reviewed by Antti Koivisto.

This patch adds support for individual run painting <div><span style="background-color: red">red</span>black</div>.
This is pretty much all we can do with the current data structures (lack of context).

  • layout/displaytree/DisplayPainter.cpp:

(WebCore::Display::paintBoxDecoration):
(WebCore::Display::paintInlineContent):
(WebCore::Display::Painter::paint):
(WebCore::Display::paintBlockLevelBoxDecoration): Deleted.

  • layout/inlineformatting/InlineLine.cpp:

(WebCore::Layout::Line::appendInlineContainerStart):
(WebCore::Layout::Line::appendInlineContainerEnd):

Location:
trunk/Source/WebCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r250906 r250910  
     12019-10-09  Zalan Bujtas  <zalan@apple.com>
     2
     3        [LFC][Painting] Decouple content and decoration painting
     4        https://bugs.webkit.org/show_bug.cgi?id=202718
     5        <rdar://problem/56104661>
     6
     7        Reviewed by Antti Koivisto.
     8
     9        This patch adds support for individual run painting <div><span style="background-color: red">red</span>black</div>.
     10        This is pretty much all we can do with the current data structures (lack of context).
     11
     12        * layout/displaytree/DisplayPainter.cpp:
     13        (WebCore::Display::paintBoxDecoration):
     14        (WebCore::Display::paintInlineContent):
     15        (WebCore::Display::Painter::paint):
     16        (WebCore::Display::paintBlockLevelBoxDecoration): Deleted.
     17        * layout/inlineformatting/InlineLine.cpp:
     18        (WebCore::Layout::Line::appendInlineContainerStart):
     19        (WebCore::Layout::Line::appendInlineContainerEnd):
     20
    1212019-10-09  Fujii Hironori  <Hironori.Fujii@sony.com>
    222
  • trunk/Source/WebCore/layout/displaytree/DisplayPainter.cpp

    r250837 r250910  
    3333#include "GraphicsContext.h"
    3434#include "InlineFormattingState.h"
     35#include "InlineTextItem.h"
    3536#include "LayoutContainer.h"
    3637#include "LayoutDescendantIterator.h"
     
    4243namespace Display {
    4344
    44 static void paintBlockLevelBoxDecoration(GraphicsContext& context, const Box& absoluteDisplayBox, const RenderStyle& style)
     45static void paintBoxDecoration(GraphicsContext& context, const Box& absoluteDisplayBox, const RenderStyle& style)
    4546{
    4647    auto borderBoxAbsoluteTopLeft = absoluteDisplayBox.topLeft();
     
    9798}
    9899
    99 static void paintInlineContent(GraphicsContext& context, const Box& absoluteDisplayBox, const RenderStyle& style, const String& content, const Layout::InlineFormattingState& formattingState)
     100static void paintInlineContent(GraphicsContext& context, const Box& rootAbsoluteDisplayBox, const Layout::InlineFormattingState& formattingState)
    100101{
    101     // FIXME: Only very simple text painting for now.
    102     auto& lineBox = formattingState.lineBoxes()[0];
    103     for (auto& run : formattingState.inlineRuns()) {
    104         if (!run.textContext())
    105             continue;
     102    auto& inlineRuns = formattingState.inlineRuns();
     103    if (inlineRuns.isEmpty())
     104        return;
     105    // FIXME: We should be able to paint runs independently from inline items.
     106    unsigned runIndex = 0;
     107    for (auto& inlineItem : formattingState.inlineItems()) {
     108        auto& style = inlineItem->style();
    106109        context.setStrokeColor(style.color());
    107110        context.setFillColor(style.color());
    108         auto logicalTopLeft = absoluteDisplayBox.topLeft() + run.logicalTopLeft();
    109         auto textContext = run.textContext().value();
    110         auto runContent = content.substring(textContext.start(), textContext.length());
    111         context.drawText(style.fontCascade(), TextRun { runContent }, { logicalTopLeft.x(), logicalTopLeft.y() + lineBox.baselineOffset() });
     111
     112        if (inlineItem->isText()) {
     113            auto& inlineTextItem = downcast<Layout::InlineTextItem>(*inlineItem);
     114            auto inlineContent = inlineTextItem.layoutBox().textContent();
     115            while (true) {
     116                auto& run = inlineRuns[runIndex++];
     117                auto textContext = run.textContext().value();
     118                auto runContent = inlineContent.substring(textContext.start(), textContext.length());
     119                auto logicalTopLeft = rootAbsoluteDisplayBox.topLeft() + run.logicalTopLeft();
     120                context.drawText(style.fontCascade(), TextRun { runContent }, { logicalTopLeft.x(), logicalTopLeft.y() + formattingState.lineBoxes()[0].baselineOffset() });
     121                if (inlineTextItem.end() == textContext.end())
     122                    break;
     123                if (runIndex == inlineRuns.size())
     124                    return;
     125            }
     126            continue;
     127        }
     128
     129        if (inlineItem->isBox()) {
     130            auto& run = inlineRuns[runIndex++];
     131            auto logicalTopLeft = rootAbsoluteDisplayBox.topLeft() + run.logicalTopLeft();
     132            context.fillRect({ logicalTopLeft, FloatSize { run.logicalWidth(), run.logicalHeight() } });
     133            continue;
     134        }
    112135    }
    113136}
     
    126149    context.fillRect({ FloatPoint { }, FloatSize { rootDisplayBox.borderBoxWidth(), rootDisplayBox.borderBoxHeight() } }, Color::white);
    127150
     151    // 1. Paint box decoration (both block and inline).
    128152    for (auto& layoutBox : Layout::descendantsOfType<Layout::Box>(layoutRoot)) {
    129         if (layoutBox.isBlockLevelBox()) {
    130             paintBlockLevelBoxDecoration(context, absoluteDisplayBox(layoutBox), layoutBox.style());
     153        if (layoutBox.isAnonymous())
    131154            continue;
    132         }
    133         // FIXME: This only covers the most simple cases like <div>inline content</div>
    134         // Find a way to conect inline runs and the inline content.
    135         if (layoutBox.isInlineLevelBox() && layoutBox.isAnonymous()) {
    136             ASSERT(layoutBox.hasTextContent());
    137             auto& containingBlock = *layoutBox.containingBlock();
    138             auto& inlineFormattingState = downcast<Layout::InlineFormattingState>(layoutState.establishedFormattingState(containingBlock));
    139             paintInlineContent(context, absoluteDisplayBox(containingBlock), layoutBox.style(), layoutBox.textContent(), inlineFormattingState);
     155        paintBoxDecoration(context, absoluteDisplayBox(layoutBox), layoutBox.style());
     156    }
    140157
     158    // 2. Paint content
     159    for (auto& layoutBox : Layout::descendantsOfType<Layout::Box>(layoutRoot)) {
     160        if (layoutBox.establishesInlineFormattingContext()) {
     161            auto& container = downcast<Layout::Container>(layoutBox);
     162            paintInlineContent(context, absoluteDisplayBox(container), downcast<Layout::InlineFormattingState>(layoutState.establishedFormattingState(container)));
     163            continue;
    141164        }
    142165    }
  • trunk/Source/WebCore/layout/inlineformatting/InlineLine.cpp

    r250487 r250910  
    291291void Line::appendInlineContainerStart(const InlineItem& inlineItem, LayoutUnit logicalWidth)
    292292{
    293     auto logicalRect = Display::Rect { };
    294     logicalRect.setLeft(contentLogicalWidth());
    295     logicalRect.setWidth(logicalWidth);
     293    // This is really just a placeholder to mark the start of the inline level container <span>.
     294    auto logicalRect = Display::Rect { 0, contentLogicalWidth(), logicalWidth, 0 };
    296295
    297296    if (!m_skipAlignment) {
     
    305304void Line::appendInlineContainerEnd(const InlineItem& inlineItem, LayoutUnit logicalWidth)
    306305{
    307     // This is really just a placeholder to mark the end of the inline level container.
    308     auto logicalRect = Display::Rect { 0, contentLogicalRight(), logicalWidth, 0 };
     306    // This is really just a placeholder to mark the end of the inline level container </span>.
     307    auto logicalRect = Display::Rect { 0, contentLogicalRight(), logicalWidth, inlineItemContentHeight(inlineItem) };
    309308    appendNonBreakableSpace(inlineItem, logicalRect);
    310309}
Note: See TracChangeset for help on using the changeset viewer.