Title: [281377] trunk/Source/WebCore
Revision
281377
Author
[email protected]
Date
2021-08-21 11:19:40 -0700 (Sat, 21 Aug 2021)

Log Message

[IFC][Integration] Add painting support for vertical text content
https://bugs.webkit.org/show_bug.cgi?id=228940

Reviewed by Antti Koivisto.

Translate the logical layout coordinates to physical paint coordinates by taking the writing mode into account.
(e.g. writing-mode: vertical-rl;
  run logical rect: [0, 0][20x18]
  in a flipped block box: [10, 10][100x50]
  with the paint offset: [8, 8]

  translates to: [90, 8][20x18]
)

* layout/integration/LayoutIntegrationLineLayout.cpp:
(WebCore::LayoutIntegration::LineLayout::paint):
(WebCore::LayoutIntegration::LineLayout::paintTextRunUsingPhysicalCoordinates):
* layout/integration/LayoutIntegrationLineLayout.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (281376 => 281377)


--- trunk/Source/WebCore/ChangeLog	2021-08-21 18:15:15 UTC (rev 281376)
+++ trunk/Source/WebCore/ChangeLog	2021-08-21 18:19:40 UTC (rev 281377)
@@ -1,3 +1,24 @@
+2021-08-21  Alan Bujtas  <[email protected]>
+
+        [IFC][Integration] Add painting support for vertical text content
+        https://bugs.webkit.org/show_bug.cgi?id=228940
+
+        Reviewed by Antti Koivisto.
+
+        Translate the logical layout coordinates to physical paint coordinates by taking the writing mode into account.
+        (e.g. writing-mode: vertical-rl;
+          run logical rect: [0, 0][20x18]
+          in a flipped block box: [10, 10][100x50]
+          with the paint offset: [8, 8]
+
+          translates to: [90, 8][20x18]
+        )
+
+        * layout/integration/LayoutIntegrationLineLayout.cpp:
+        (WebCore::LayoutIntegration::LineLayout::paint):
+        (WebCore::LayoutIntegration::LineLayout::paintTextRunUsingPhysicalCoordinates):
+        * layout/integration/LayoutIntegrationLineLayout.h:
+
 2021-08-21  Zalan Bujtas  <[email protected]>
 
         [IFC][Integration] Do not scan the content for overflowing glyph when line-box-contain is set to glyph

Modified: trunk/Source/WebCore/layout/integration/LayoutIntegrationLineLayout.cpp (281376 => 281377)


--- trunk/Source/WebCore/layout/integration/LayoutIntegrationLineLayout.cpp	2021-08-21 18:15:15 UTC (rev 281376)
+++ trunk/Source/WebCore/layout/integration/LayoutIntegrationLineLayout.cpp	2021-08-21 18:19:40 UTC (rev 281377)
@@ -454,71 +454,17 @@
     if (paintInfo.phase != PaintPhase::Foreground && paintInfo.phase != PaintPhase::EventRegion)
         return;
 
-    auto& inlineContent = *m_inlineContent;
-    float deviceScaleFactor = flow().document().deviceScaleFactor();
-
     auto paintRect = paintInfo.rect;
     paintRect.moveBy(-paintOffset);
 
-    for (auto& run : inlineContent.runsForRect(paintRect)) {
-        if (!run.textContent()) {
-            auto& renderer = m_boxTree.rendererForLayoutBox(run.layoutBox());
-            if (renderer.isReplaced() && is<RenderBox>(renderer)) {
-                auto& renderBox = downcast<RenderBox>(renderer);
-                if (renderBox.hasSelfPaintingLayer())
-                    continue;
-                if (!paintInfo.shouldPaintWithinRoot(renderBox))
-                    continue;
+    for (auto& run : m_inlineContent->runsForRect(paintRect)) {
+        if (run.textContent())
+            paintTextRunUsingPhysicalCoordinates(paintInfo, paintOffset, m_inlineContent->lineForRun(run), run);
+        else if (auto& renderer = m_boxTree.rendererForLayoutBox(run.layoutBox()); is<RenderBox>(renderer) && renderer.isReplaced()) {
+            auto& renderBox = downcast<RenderBox>(renderer);
+            if (!renderBox.hasSelfPaintingLayer() && paintInfo.shouldPaintWithinRoot(renderBox))
                 renderBox.paintAsInlineBlock(paintInfo, paintOffset);
-            }
-            continue;
         }
-
-        auto& textContent = *run.textContent();
-        if (!textContent.length())
-            continue;
-
-        auto& style = run.style();
-        if (style.visibility() != Visibility::Visible)
-            continue;
-
-        auto rect = FloatRect { run.rect() };
-        auto visualOverflowRect = FloatRect { run.inkOverflow() };
-        if (paintRect.y() > visualOverflowRect.maxY() || paintRect.maxY() < visualOverflowRect.y())
-            continue;
-
-        if (paintInfo.eventRegionContext) {
-            if (style.pointerEvents() != PointerEvents::None) {
-                visualOverflowRect.moveBy(paintOffset);
-                paintInfo.eventRegionContext->unite(enclosingIntRect(visualOverflowRect), style);
-            }
-            continue;
-        }
-
-        auto& line = inlineContent.lineForRun(run);
-        auto expansion = run.expansion();
-        // TextRun expects the xPos to be adjusted with the aligment offset (e.g. when the line is center aligned
-        // and the run starts at 100px, due to the horizontal aligment, the xpos is supposed to be at 0px).
-        auto& fontCascade = style.fontCascade();
-        auto xPos = rect.x() - (line.lineBoxLeft() + line.contentLeft());
-        WebCore::TextRun textRun { textContent.renderedContent(), xPos, expansion.horizontalExpansion, expansion.behavior };
-        textRun.setTabSize(!style.collapseWhiteSpace(), style.tabSize());
-
-        TextPainter textPainter(paintInfo.context());
-        textPainter.setFont(fontCascade);
-        textPainter.setStyle(computeTextPaintStyle(flow().frame(), style, paintInfo));
-        textPainter.setGlyphDisplayListIfNeeded(run, paintInfo, fontCascade, paintInfo.context(), textRun);
-
-        auto textOrigin = FloatPoint { paintOffset.x() + rect.x(), roundToDevicePixel(paintOffset.y() + rect.y() + fontCascade.fontMetrics().ascent(), deviceScaleFactor) };
-        textPainter.paint(textRun, rect, textOrigin);
-
-        if (!style.textDecorationsInEffect().isEmpty()) {
-            auto& textRenderer = downcast<RenderText>(m_boxTree.rendererForLayoutBox(run.layoutBox()));
-            auto decorationPainter = TextDecorationPainter { paintInfo.context(), style.textDecorationsInEffect(), textRenderer, false, fontCascade };
-            decorationPainter.setTextRunIterator(inlineContent.iteratorForTextRun(run));
-            decorationPainter.setWidth(rect.width());
-            decorationPainter.paintTextDecoration(textRun, textOrigin, rect.location() + paintOffset);
-        }
     }
 }
 
@@ -602,6 +548,85 @@
     m_inlineFormattingState.inlineItems().clear();
 }
 
+void LineLayout::paintTextRunUsingPhysicalCoordinates(PaintInfo& paintInfo, const LayoutPoint& paintOffset, const Line& line, const Run& run)
+{
+    auto& style = run.style();
+    if (run.style().visibility() != Visibility::Visible)
+        return;
+
+    auto& textContent = *run.textContent();
+    if (!textContent.length())
+        return;
+
+    auto& formattingContextRoot = flow();
+    auto blockIsHorizontalWriting = formattingContextRoot.style().isHorizontalWritingMode();
+    auto physicalPaintOffset = paintOffset;
+    if (!blockIsHorizontalWriting) {
+        // FIXME: Figure out why this translate is required.
+        physicalPaintOffset.move({ 0, -run.rect().height() });
+    }
+
+    auto physicalRect = [&](const auto& rect) {
+        if (!style.isFlippedBlocksWritingMode())
+            return rect;
+        if (!blockIsHorizontalWriting)
+            return FloatRect { formattingContextRoot.width() - rect.maxY(), rect.x() , rect.width(), rect.height() };
+        ASSERT_NOT_IMPLEMENTED_YET();
+        return rect;
+    };
+
+    auto visualOverflowRect = physicalRect(run.inkOverflow());
+
+    auto damagedRect = paintInfo.rect;
+    damagedRect.moveBy(-physicalPaintOffset);
+    if (damagedRect.y() > visualOverflowRect.maxY() || damagedRect.maxY() < visualOverflowRect.y())
+        return;
+
+    if (paintInfo.eventRegionContext) {
+        if (style.pointerEvents() != PointerEvents::None) {
+            visualOverflowRect.moveBy(physicalPaintOffset);
+            paintInfo.eventRegionContext->unite(enclosingIntRect(visualOverflowRect), style);
+        }
+        return;
+    }
+
+    auto& paintContext = paintInfo.context();
+    auto expansion = run.expansion();
+    // TextRun expects the xPos to be adjusted with the aligment offset (e.g. when the line is center aligned
+    // and the run starts at 100px, due to the horizontal aligment, the xpos is supposed to be at 0px).
+    auto& fontCascade = style.fontCascade();
+    auto xPos = run.rect().x() - (line.lineBoxLeft() + line.contentLeft());
+    auto textRun = WebCore::TextRun { textContent.renderedContent(), xPos, expansion.horizontalExpansion, expansion.behavior };
+    textRun.setTabSize(!style.collapseWhiteSpace(), style.tabSize());
+
+    auto textPainter = TextPainter { paintContext };
+    textPainter.setFont(fontCascade);
+    textPainter.setStyle(computeTextPaintStyle(formattingContextRoot.frame(), style, paintInfo));
+    textPainter.setGlyphDisplayListIfNeeded(run, paintInfo, fontCascade, paintContext, textRun);
+
+    // Painting uses only physical coordinates.
+    {
+        auto runRect = physicalRect(run.rect());
+        auto boxRect = FloatRect { FloatPoint { physicalPaintOffset.x() + runRect.x(), physicalPaintOffset.y() + runRect.y() }, runRect.size() };
+        auto textOrigin = FloatPoint { boxRect.x(), roundToDevicePixel(boxRect.y() + fontCascade.fontMetrics().ascent(), formattingContextRoot.document().deviceScaleFactor()) };
+
+        auto shouldRotate = !blockIsHorizontalWriting;
+        if (shouldRotate)
+            paintContext.concatCTM(rotation(boxRect, Clockwise));
+        textPainter.paint(textRun, runRect, textOrigin);
+
+        if (!style.textDecorationsInEffect().isEmpty()) {
+            auto& textRenderer = downcast<RenderText>(m_boxTree.rendererForLayoutBox(run.layoutBox()));
+            auto decorationPainter = TextDecorationPainter { paintContext, style.textDecorationsInEffect(), textRenderer, false, fontCascade };
+            decorationPainter.setTextRunIterator(m_inlineContent->iteratorForTextRun(run));
+            decorationPainter.setWidth(runRect.width());
+            decorationPainter.paintTextDecoration(textRun, textOrigin, runRect.location() + physicalPaintOffset);
+        }
+        if (shouldRotate)
+            paintInfo.context().concatCTM(rotation(boxRect, Counterclockwise));
+    }
+}
+
 #if ENABLE(TREE_DEBUGGING)
 void LineLayout::outputLineTree(WTF::TextStream& stream, size_t depth) const
 {

Modified: trunk/Source/WebCore/layout/integration/LayoutIntegrationLineLayout.h (281376 => 281377)


--- trunk/Source/WebCore/layout/integration/LayoutIntegrationLineLayout.h	2021-08-21 18:15:15 UTC (rev 281376)
+++ trunk/Source/WebCore/layout/integration/LayoutIntegrationLineLayout.h	2021-08-21 18:19:40 UTC (rev 281377)
@@ -115,6 +115,8 @@
     InlineContent& ensureInlineContent();
     void updateLayoutBoxDimensions(const RenderBox&);
 
+    void paintTextRunUsingPhysicalCoordinates(PaintInfo&, const LayoutPoint& paintOffset, const Line&, const Run&);
+
     const Layout::ContainerBox& rootLayoutBox() const;
     Layout::ContainerBox& rootLayoutBox();
     void releaseInlineItemCache();
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to