Modified: trunk/Source/WebCore/ChangeLog (250836 => 250837)
--- trunk/Source/WebCore/ChangeLog 2019-10-08 16:55:18 UTC (rev 250836)
+++ trunk/Source/WebCore/ChangeLog 2019-10-08 17:26:30 UTC (rev 250837)
@@ -1,3 +1,24 @@
+2019-10-08 Zalan Bujtas <za...@apple.com>
+
+ [LFC][Painting] Add very basic block and inline painting
+ https://bugs.webkit.org/show_bug.cgi?id=202697
+ <rdar://problem/56076562>
+
+ Reviewed by Antti Koivisto.
+
+ This is a very basic border/background painting with simple text. No phases/z-index/layers of any kind.
+
+ * layout/displaytree/DisplayBox.h: This seems to be getting out of hand.
+ (WebCore::Display::Box::moveBy):
+ * layout/displaytree/DisplayPainter.cpp:
+ (WebCore::Display::paintBlockLevelBoxDecoration):
+ (WebCore::Display::paintInlineContent):
+ (WebCore::Display::Painter::paint):
+ * layout/floats/FloatingContext.h:
+ * layout/inlineformatting/InlineFormattingState.h:
+ (WebCore::Layout::InlineFormattingState::inlineRuns const):
+ (WebCore::Layout::InlineFormattingState::lineBoxes const):
+
2019-10-08 Wenson Hsieh <wenson_hs...@apple.com>
Unreviewed, try to fix the WinCairo build after r250824
Modified: trunk/Source/WebCore/layout/displaytree/DisplayBox.h (250836 => 250837)
--- trunk/Source/WebCore/layout/displaytree/DisplayBox.h 2019-10-08 16:55:18 UTC (rev 250836)
+++ trunk/Source/WebCore/layout/displaytree/DisplayBox.h 2019-10-08 17:26:30 UTC (rev 250837)
@@ -36,34 +36,11 @@
class RenderStyle;
-namespace Layout {
-class BlockFormattingContext;
-class FloatAvoider;
-class FloatBox;
-class FormattingContext;
-class FloatingContext;
-class InlineFormattingContext;
-class LayoutContext;
-class LayoutState;
-class TableFormattingContext;
-}
-
namespace Display {
class Box {
WTF_MAKE_ISO_ALLOCATED(Box);
public:
- friend class Layout::BlockFormattingContext;
- friend class Layout::FloatAvoider;
- friend class Layout::FloatBox;
- friend class Layout::FormattingContext;
- friend class Layout::FloatingContext;
- friend class Layout::InlineFormattingContext;
- // This is temporary and should be removed when LayoutContext::run is no longer needed.
- friend class Layout::LayoutContext;
- friend class Layout::LayoutState;
- friend class Layout::TableFormattingContext;
-
Box(const RenderStyle&);
Box(const Box&);
~Box();
@@ -142,18 +119,12 @@
void setHasEstimatedMarginBefore() { m_hasEstimatedMarginBefore = true; }
#endif
-private:
- struct Style {
- Style(const RenderStyle&);
-
- BoxSizing boxSizing { BoxSizing::ContentBox };
- };
-
void setTopLeft(const LayoutPoint&);
void setTop(LayoutUnit);
void setLeft(LayoutUnit);
void moveHorizontally(LayoutUnit offset) { m_topLeft.move(offset, 0_lu); }
void moveVertically(LayoutUnit offset) { m_topLeft.move(0_lu, offset); }
+ void moveBy(LayoutPoint offset) { m_topLeft.moveBy(offset); }
void setContentBoxHeight(LayoutUnit);
void setContentBoxWidth(LayoutUnit);
@@ -166,6 +137,13 @@
void setBorder(Layout::Edges);
void setPadding(Optional<Layout::Edges>);
+private:
+ struct Style {
+ Style(const RenderStyle&);
+
+ BoxSizing boxSizing { BoxSizing::ContentBox };
+ };
+
#if !ASSERT_DISABLED
void invalidateMargin();
void invalidateBorder() { m_hasValidBorder = false; }
Modified: trunk/Source/WebCore/layout/displaytree/DisplayPainter.cpp (250836 => 250837)
--- trunk/Source/WebCore/layout/displaytree/DisplayPainter.cpp 2019-10-08 16:55:18 UTC (rev 250836)
+++ trunk/Source/WebCore/layout/displaytree/DisplayPainter.cpp 2019-10-08 17:26:30 UTC (rev 250837)
@@ -28,17 +28,121 @@
#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
+#include "Color.h"
+#include "DisplayBox.h"
#include "GraphicsContext.h"
+#include "InlineFormattingState.h"
+#include "LayoutContainer.h"
+#include "LayoutDescendantIterator.h"
#include "LayoutState.h"
+#include "RenderStyle.h"
+#include "TextRun.h"
namespace WebCore {
namespace Display {
-void Painter::paint(const Layout::LayoutState&, GraphicsContext&)
+static void paintBlockLevelBoxDecoration(GraphicsContext& context, const Box& absoluteDisplayBox, const RenderStyle& style)
{
+ auto borderBoxAbsoluteTopLeft = absoluteDisplayBox.topLeft();
+ // Background color
+ if (style.hasBackground())
+ context.fillRect({ borderBoxAbsoluteTopLeft, FloatSize { absoluteDisplayBox.borderBoxWidth(), absoluteDisplayBox.borderBoxHeight() } }, style.backgroundColor());
+
+ // Border
+ if (style.hasBorder()) {
+
+ auto drawBorderSide = [&](auto start, auto end, const auto& borderStyle) {
+ context.setStrokeColor(borderStyle.color());
+ context.setStrokeThickness(borderStyle.width());
+ context.drawLine(start, end);
+ };
+
+ context.setFillColor(Color::transparent);
+
+ auto borderBoxWidth = absoluteDisplayBox.borderBoxWidth();
+ auto borderBoxHeight = absoluteDisplayBox.borderBoxHeight();
+
+ // Top
+ {
+ auto borderWidth = style.borderTop().width();
+ auto start = LayoutPoint { borderBoxAbsoluteTopLeft };
+ auto end = LayoutPoint { start.x() + borderBoxWidth, start.y() + borderWidth };
+ drawBorderSide(start, end, style.borderTop());
+ }
+
+ // Right
+ {
+ auto borderWidth = style.borderRight().width();
+ auto start = LayoutPoint { borderBoxAbsoluteTopLeft.x() + borderBoxWidth - borderWidth, borderBoxAbsoluteTopLeft.y() };
+ auto end = LayoutPoint { start.x() + borderWidth, borderBoxAbsoluteTopLeft.y() + borderBoxHeight };
+ drawBorderSide(start, end, style.borderRight());
+ }
+
+ // Bottom
+ {
+ auto borderWidth = style.borderBottom().width();
+ auto start = LayoutPoint { borderBoxAbsoluteTopLeft.x(), borderBoxAbsoluteTopLeft.y() + borderBoxHeight - borderWidth };
+ auto end = LayoutPoint { start.x() + borderBoxWidth, start.y() + borderWidth };
+ drawBorderSide(start, end, style.borderBottom());
+ }
+
+ // Left
+ {
+ auto borderWidth = style.borderLeft().width();
+ auto start = borderBoxAbsoluteTopLeft;
+ auto end = LayoutPoint { start.x() + borderWidth, borderBoxAbsoluteTopLeft.y() + borderBoxHeight };
+ drawBorderSide(start, end, style.borderLeft());
+ }
+ }
}
+static void paintInlineContent(GraphicsContext& context, const Box& absoluteDisplayBox, const RenderStyle& style, const String& content, 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;
+ 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() });
+ }
}
+
+void Painter::paint(const Layout::LayoutState& layoutState, GraphicsContext& context)
+{
+ auto absoluteDisplayBox = [&](const auto& layoutBox) {
+ auto absoluteBox = Box { layoutState.displayBoxForLayoutBox(layoutBox) };
+ for (auto* container = layoutBox.containingBlock(); container != &layoutBox.initialContainingBlock(); container = container->containingBlock())
+ absoluteBox.moveBy(layoutState.displayBoxForLayoutBox(*container).topLeft());
+ return absoluteBox;
+ };
+
+ auto& layoutRoot = layoutState.root();
+ auto& rootDisplayBox = layoutState.displayBoxForLayoutBox(layoutRoot);
+ context.fillRect({ FloatPoint { }, FloatSize { rootDisplayBox.borderBoxWidth(), rootDisplayBox.borderBoxHeight() } }, Color::white);
+
+ for (auto& layoutBox : Layout::descendantsOfType<Layout::Box>(layoutRoot)) {
+ if (layoutBox.isBlockLevelBox()) {
+ paintBlockLevelBoxDecoration(context, absoluteDisplayBox(layoutBox), layoutBox.style());
+ 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);
+
+ }
+ }
}
+}
+}
+
#endif
Modified: trunk/Source/WebCore/layout/floats/FloatingContext.h (250836 => 250837)
--- trunk/Source/WebCore/layout/floats/FloatingContext.h 2019-10-08 16:55:18 UTC (rev 250836)
+++ trunk/Source/WebCore/layout/floats/FloatingContext.h 2019-10-08 17:26:30 UTC (rev 250837)
@@ -35,6 +35,7 @@
namespace Layout {
class FloatAvoider;
+class FloatBox;
class FormattingContext;
class Box;
class LayoutState;
Modified: trunk/Source/WebCore/layout/inlineformatting/InlineFormattingState.h (250836 => 250837)
--- trunk/Source/WebCore/layout/inlineformatting/InlineFormattingState.h 2019-10-08 16:55:18 UTC (rev 250836)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineFormattingState.h 2019-10-08 17:26:30 UTC (rev 250837)
@@ -52,9 +52,11 @@
const InlineItems& inlineItems() const { return m_inlineItems; }
void addInlineItem(std::unique_ptr<InlineItem>&& inlineItem) { m_inlineItems.append(WTFMove(inlineItem)); }
+ const InlineRuns& inlineRuns() const { return m_inlineRuns; }
InlineRuns& inlineRuns() { return m_inlineRuns; }
void addInlineRun(const Display::Run& inlineRun) { m_inlineRuns.append(inlineRun); }
+ const LineBoxes& lineBoxes() const { return m_lineBoxes; }
LineBoxes& lineBoxes() { return m_lineBoxes; }
void addLineBox(LineBox lineBox) { m_lineBoxes.append(lineBox); }