Modified: trunk/Source/WebCore/ChangeLog (250909 => 250910)
--- trunk/Source/WebCore/ChangeLog 2019-10-09 11:33:12 UTC (rev 250909)
+++ trunk/Source/WebCore/ChangeLog 2019-10-09 14:07:21 UTC (rev 250910)
@@ -1,3 +1,23 @@
+2019-10-09 Zalan Bujtas <za...@apple.com>
+
+ [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):
+
2019-10-09 Fujii Hironori <hironori.fu...@sony.com>
Unreviewed build fix for Windows ports
Modified: trunk/Source/WebCore/layout/displaytree/DisplayPainter.cpp (250909 => 250910)
--- trunk/Source/WebCore/layout/displaytree/DisplayPainter.cpp 2019-10-09 11:33:12 UTC (rev 250909)
+++ trunk/Source/WebCore/layout/displaytree/DisplayPainter.cpp 2019-10-09 14:07:21 UTC (rev 250910)
@@ -32,6 +32,7 @@
#include "DisplayBox.h"
#include "GraphicsContext.h"
#include "InlineFormattingState.h"
+#include "InlineTextItem.h"
#include "LayoutContainer.h"
#include "LayoutDescendantIterator.h"
#include "LayoutState.h"
@@ -41,7 +42,7 @@
namespace WebCore {
namespace Display {
-static void paintBlockLevelBoxDecoration(GraphicsContext& context, const Box& absoluteDisplayBox, const RenderStyle& style)
+static void paintBoxDecoration(GraphicsContext& context, const Box& absoluteDisplayBox, const RenderStyle& style)
{
auto borderBoxAbsoluteTopLeft = absoluteDisplayBox.topLeft();
// Background color
@@ -96,19 +97,41 @@
}
}
-static void paintInlineContent(GraphicsContext& context, const Box& absoluteDisplayBox, const RenderStyle& style, const String& content, const Layout::InlineFormattingState& formattingState)
+static void paintInlineContent(GraphicsContext& context, const Box& rootAbsoluteDisplayBox, const Layout::InlineFormattingState& formattingState)
{
- // FIXME: Only very simple text painting for now.
- auto& lineBox = formattingState.lineBoxes()[0];
- for (auto& run : formattingState.inlineRuns()) {
- if (!run.textContext())
- continue;
+ auto& inlineRuns = formattingState.inlineRuns();
+ if (inlineRuns.isEmpty())
+ return;
+ // FIXME: We should be able to paint runs independently from inline items.
+ unsigned runIndex = 0;
+ for (auto& inlineItem : formattingState.inlineItems()) {
+ auto& style = inlineItem->style();
context.setStrokeColor(style.color());
context.setFillColor(style.color());
- auto logicalTopLeft = absoluteDisplayBox.topLeft() + run.logicalTopLeft();
- auto textContext = run.textContext().value();
- auto runContent = content.substring(textContext.start(), textContext.length());
- context.drawText(style.fontCascade(), TextRun { runContent }, { logicalTopLeft.x(), logicalTopLeft.y() + lineBox.baselineOffset() });
+
+ if (inlineItem->isText()) {
+ auto& inlineTextItem = downcast<Layout::InlineTextItem>(*inlineItem);
+ auto inlineContent = inlineTextItem.layoutBox().textContent();
+ while (true) {
+ auto& run = inlineRuns[runIndex++];
+ auto textContext = run.textContext().value();
+ auto runContent = inlineContent.substring(textContext.start(), textContext.length());
+ auto logicalTopLeft = rootAbsoluteDisplayBox.topLeft() + run.logicalTopLeft();
+ context.drawText(style.fontCascade(), TextRun { runContent }, { logicalTopLeft.x(), logicalTopLeft.y() + formattingState.lineBoxes()[0].baselineOffset() });
+ if (inlineTextItem.end() == textContext.end())
+ break;
+ if (runIndex == inlineRuns.size())
+ return;
+ }
+ continue;
+ }
+
+ if (inlineItem->isBox()) {
+ auto& run = inlineRuns[runIndex++];
+ auto logicalTopLeft = rootAbsoluteDisplayBox.topLeft() + run.logicalTopLeft();
+ context.fillRect({ logicalTopLeft, FloatSize { run.logicalWidth(), run.logicalHeight() } });
+ continue;
+ }
}
}
@@ -125,19 +148,19 @@
auto& rootDisplayBox = layoutState.displayBoxForLayoutBox(layoutRoot);
context.fillRect({ FloatPoint { }, FloatSize { rootDisplayBox.borderBoxWidth(), rootDisplayBox.borderBoxHeight() } }, Color::white);
+ // 1. Paint box decoration (both block and inline).
for (auto& layoutBox : Layout::descendantsOfType<Layout::Box>(layoutRoot)) {
- if (layoutBox.isBlockLevelBox()) {
- paintBlockLevelBoxDecoration(context, absoluteDisplayBox(layoutBox), layoutBox.style());
+ if (layoutBox.isAnonymous())
continue;
- }
- // FIXME: This only covers the most simple cases like <div>inline content</div>
- // Find a way to conect inline runs and the inline content.
- if (layoutBox.isInlineLevelBox() && layoutBox.isAnonymous()) {
- ASSERT(layoutBox.hasTextContent());
- auto& containingBlock = *layoutBox.containingBlock();
- auto& inlineFormattingState = downcast<Layout::InlineFormattingState>(layoutState.establishedFormattingState(containingBlock));
- paintInlineContent(context, absoluteDisplayBox(containingBlock), layoutBox.style(), layoutBox.textContent(), inlineFormattingState);
+ paintBoxDecoration(context, absoluteDisplayBox(layoutBox), layoutBox.style());
+ }
+ // 2. Paint content
+ for (auto& layoutBox : Layout::descendantsOfType<Layout::Box>(layoutRoot)) {
+ if (layoutBox.establishesInlineFormattingContext()) {
+ auto& container = downcast<Layout::Container>(layoutBox);
+ paintInlineContent(context, absoluteDisplayBox(container), downcast<Layout::InlineFormattingState>(layoutState.establishedFormattingState(container)));
+ continue;
}
}
}
Modified: trunk/Source/WebCore/layout/inlineformatting/InlineLine.cpp (250909 => 250910)
--- trunk/Source/WebCore/layout/inlineformatting/InlineLine.cpp 2019-10-09 11:33:12 UTC (rev 250909)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineLine.cpp 2019-10-09 14:07:21 UTC (rev 250910)
@@ -290,9 +290,8 @@
void Line::appendInlineContainerStart(const InlineItem& inlineItem, LayoutUnit logicalWidth)
{
- auto logicalRect = Display::Rect { };
- logicalRect.setLeft(contentLogicalWidth());
- logicalRect.setWidth(logicalWidth);
+ // This is really just a placeholder to mark the start of the inline level container <span>.
+ auto logicalRect = Display::Rect { 0, contentLogicalWidth(), logicalWidth, 0 };
if (!m_skipAlignment) {
auto logicalHeight = inlineItemContentHeight(inlineItem);
@@ -304,8 +303,8 @@
void Line::appendInlineContainerEnd(const InlineItem& inlineItem, LayoutUnit logicalWidth)
{
- // This is really just a placeholder to mark the end of the inline level container.
- auto logicalRect = Display::Rect { 0, contentLogicalRight(), logicalWidth, 0 };
+ // This is really just a placeholder to mark the end of the inline level container </span>.
+ auto logicalRect = Display::Rect { 0, contentLogicalRight(), logicalWidth, inlineItemContentHeight(inlineItem) };
appendNonBreakableSpace(inlineItem, logicalRect);
}