Skip to content

Commit

Permalink
[LFC][IFC] Introduce InlineDisplay::Box:isVisible
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=244957

Reviewed by Antti Koivisto.

Let's propagate RenderStyle::visibility bit to InlineDisplay::Box and combine it with text-overflow truncation. It is used for both painting and hittesting.
This patch also flips isVisuallyHidden to isVisible.

* Source/WebCore/layout/formattingContexts/inline/display/InlineDisplayBox.h:
(WebCore::InlineDisplay::Box::Text::partiallyVisibleContentLength const):
(WebCore::InlineDisplay::Box::Box):
(WebCore::InlineDisplay::Box::isVisible const):
(WebCore::InlineDisplay::Box::Text::Text):
(WebCore::InlineDisplay::Box::Text::visuallyVisibleLength const): Deleted.
(WebCore::InlineDisplay::Box::isVisuallyHidden const): Deleted.
* Source/WebCore/layout/formattingContexts/inline/display/InlineDisplayContentBuilder.cpp:
(WebCore::Layout::InlineDisplayContentBuilder::appendTextDisplayBox):
(WebCore::Layout::InlineDisplayContentBuilder::appendAtomicInlineLevelDisplayBox):
(WebCore::Layout::InlineDisplayContentBuilder::appendInlineBoxDisplayBox):
(WebCore::Layout::InlineDisplayContentBuilder::appendSpanningInlineBoxDisplayBox):
(WebCore::Layout::InlineDisplayContentBuilder::appendInlineDisplayBoxAtBidiBoundary):
* Source/WebCore/layout/integration/inline/InlineIteratorBoxModernPath.h:
(WebCore::InlineIterator::BoxModernPath::selectableRange const):
* Source/WebCore/layout/integration/inline/LayoutIntegrationInlineContentPainter.cpp:
(WebCore::LayoutIntegration::InlineContentPainter::paintDisplayBox):
* Source/WebCore/layout/integration/inline/LayoutIntegrationLineLayout.cpp:
(WebCore::LayoutIntegration::LineLayout::hitTest):

Canonical link: https://commits.webkit.org/254325@main
  • Loading branch information
alanbaradlay committed Sep 9, 2022
1 parent 1787f66 commit 652e0bf
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 24 deletions.
Expand Up @@ -39,12 +39,12 @@ struct Box {
struct Text {
WTF_MAKE_STRUCT_FAST_ALLOCATED;
public:
Text(size_t position, size_t length, const String& originalContent, String adjustedContentToRender = String(), bool hasHyphen = false, std::optional<size_t> visuallyVisibleLength = std::nullopt);
Text(size_t position, size_t length, const String& originalContent, String adjustedContentToRender = String(), bool hasHyphen = false, std::optional<size_t> partiallyVisibleContentLength = std::nullopt);

size_t start() const { return m_start; }
size_t end() const { return start() + length(); }
size_t length() const { return m_length; }
std::optional<size_t> visuallyVisibleLength() const { return m_visuallyVisibleLength; }
std::optional<size_t> partiallyVisibleContentLength() const { return m_partiallyVisibleContentLength; }
StringView originalContent() const { return StringView(m_originalContent).substring(m_start, m_length); }
StringView renderedContent() const { return m_adjustedContentToRender.isNull() ? originalContent() : m_adjustedContentToRender; }

Expand All @@ -55,7 +55,7 @@ struct Box {

size_t m_start { 0 };
size_t m_length { 0 };
std::optional<size_t> m_visuallyVisibleLength { };
std::optional<size_t> m_partiallyVisibleContentLength { };
bool m_hasHyphen { false };
String m_originalContent;
String m_adjustedContentToRender;
Expand All @@ -77,8 +77,7 @@ struct Box {
First = 1 << 0,
Last = 1 << 1
};
enum class IsVisuallyHidden : uint8_t { Yes, No, Partially };
Box(size_t lineIndex, Type, const Layout::Box&, UBiDiLevel, const FloatRect&, const FloatRect& inkOverflow, Expansion, std::optional<Text> = std::nullopt, bool hasContent = true, IsVisuallyHidden isVisuallyHidden = IsVisuallyHidden::No, OptionSet<PositionWithinInlineLevelBox> = { });
Box(size_t lineIndex, Type, const Layout::Box&, UBiDiLevel, const FloatRect&, const FloatRect& inkOverflow, Expansion, std::optional<Text> = std::nullopt, bool hasContent = true, bool isFullyTruncated = false, OptionSet<PositionWithinInlineLevelBox> = { });

bool isText() const { return m_type == Type::Text || isWordSeparator(); }
bool isWordSeparator() const { return m_type == Type::WordSeparator; }
Expand All @@ -100,7 +99,7 @@ struct Box {
bool isHorizontal() const { return style().isHorizontalWritingMode(); }

bool hasContent() const { return m_hasContent; }
IsVisuallyHidden isVisuallyHidden() const { return m_isVisuallyHidden; }
bool isVisible() const { return !m_isFullyTruncated && style().visibility() == Visibility::Visible; }

const FloatRect& visualRectIgnoringBlockDirection() const { return m_unflippedVisualRect; }
const FloatRect& inkOverflow() const { return m_inkOverflow; }
Expand Down Expand Up @@ -186,12 +185,12 @@ struct Box {
bool m_hasContent : 1;
bool m_isFirstForLayoutBox : 1;
bool m_isLastForLayoutBox : 1;
IsVisuallyHidden m_isVisuallyHidden { IsVisuallyHidden::No };
bool m_isFullyTruncated : 1;
Expansion m_expansion;
std::optional<Text> m_text;
};

inline Box::Box(size_t lineIndex, Type type, const Layout::Box& layoutBox, UBiDiLevel bidiLevel, const FloatRect& physicalRect, const FloatRect& inkOverflow, Expansion expansion, std::optional<Text> text, bool hasContent, IsVisuallyHidden isVisuallyHidden, OptionSet<PositionWithinInlineLevelBox> positionWithinInlineLevelBox)
inline Box::Box(size_t lineIndex, Type type, const Layout::Box& layoutBox, UBiDiLevel bidiLevel, const FloatRect& physicalRect, const FloatRect& inkOverflow, Expansion expansion, std::optional<Text> text, bool hasContent, bool isFullyTruncated, OptionSet<PositionWithinInlineLevelBox> positionWithinInlineLevelBox)
: m_lineIndex(lineIndex)
, m_type(type)
, m_layoutBox(layoutBox)
Expand All @@ -201,16 +200,16 @@ inline Box::Box(size_t lineIndex, Type type, const Layout::Box& layoutBox, UBiDi
, m_hasContent(hasContent)
, m_isFirstForLayoutBox(positionWithinInlineLevelBox.contains(PositionWithinInlineLevelBox::First))
, m_isLastForLayoutBox(positionWithinInlineLevelBox.contains(PositionWithinInlineLevelBox::Last))
, m_isVisuallyHidden(isVisuallyHidden)
, m_isFullyTruncated(isFullyTruncated)
, m_expansion(expansion)
, m_text(text)
{
}

inline Box::Text::Text(size_t start, size_t length, const String& originalContent, String adjustedContentToRender, bool hasHyphen, std::optional<size_t> visuallyVisibleLength)
inline Box::Text::Text(size_t start, size_t length, const String& originalContent, String adjustedContentToRender, bool hasHyphen, std::optional<size_t> partiallyVisibleContentLength)
: m_start(start)
, m_length(length)
, m_visuallyVisibleLength(visuallyVisibleLength)
, m_partiallyVisibleContentLength(partiallyVisibleContentLength)
, m_hasHyphen(hasHyphen)
, m_originalContent(originalContent)
, m_adjustedContentToRender(adjustedContentToRender)
Expand Down
Expand Up @@ -186,17 +186,19 @@ void InlineDisplayContentBuilder::appendTextDisplayBox(const Line::Run& lineRun,
auto adjustedContentToRender = [&] {
return text->needsHyphen ? makeString(StringView(content).substring(text->start, text->length), style.hyphenString()) : String();
};
auto isVisuallyHidden = !lineRun.isTruncated() ? InlineDisplay::Box::IsVisuallyHidden::No : !text->partiallyVisibleContent.has_value() ? InlineDisplay::Box::IsVisuallyHidden::Yes : InlineDisplay::Box::IsVisuallyHidden::Partially;
auto isFullyTruncated = lineRun.isTruncated() && !text->partiallyVisibleContent;
auto partiallyVisibleContentLength = !isFullyTruncated && text->partiallyVisibleContent ? std::make_optional(text->partiallyVisibleContent->length): std::nullopt;

boxes.append({ m_lineIndex
, lineRun.isWordSeparator() ? InlineDisplay::Box::Type::WordSeparator : InlineDisplay::Box::Type::Text
, layoutBox
, lineRun.bidiLevel()
, textRunRect
, inkOverflow()
, lineRun.expansion()
, InlineDisplay::Box::Text { text->start, text->length, content, adjustedContentToRender(), text->needsHyphen, isVisuallyHidden == InlineDisplay::Box::IsVisuallyHidden::Partially ? std::make_optional(text->partiallyVisibleContent->length) : std::nullopt }
, InlineDisplay::Box::Text { text->start, text->length, content, adjustedContentToRender(), text->needsHyphen, partiallyVisibleContentLength }
, true
, isVisuallyHidden
, isFullyTruncated
, { }
});
}
Expand Down Expand Up @@ -243,13 +245,15 @@ void InlineDisplayContentBuilder::appendAtomicInlineLevelDisplayBox(const Line::
ASSERT(lineRun.layoutBox().isAtomicInlineLevelBox());

auto& layoutBox = lineRun.layoutBox();
auto& style = !m_lineIndex ? layoutBox.firstLineStyle() : layoutBox.style();
auto inkOverflow = [&] {
auto inkOverflow = FloatRect { borderBoxRect };
computeInkOverflowForInlineLevelBox(!m_lineIndex ? layoutBox.firstLineStyle() : layoutBox.style(), inkOverflow);
computeInkOverflowForInlineLevelBox(style, inkOverflow);
// Atomic inline box contribute to their inline box parents ink overflow at all times (e.g. <span><img></span>).
m_contentHasInkOverflow = m_contentHasInkOverflow || &layoutBox.parent() != &root();
return inkOverflow;
};

boxes.append({ m_lineIndex
, InlineDisplay::Box::Type::AtomicInlineLevelBox
, layoutBox
Expand All @@ -259,7 +263,7 @@ void InlineDisplayContentBuilder::appendAtomicInlineLevelDisplayBox(const Line::
, lineRun.expansion()
, { }
, true
, lineRun.isTruncated() ? InlineDisplay::Box::IsVisuallyHidden::Yes : InlineDisplay::Box::IsVisuallyHidden::No
, lineRun.isTruncated()
});
// Note that inline boxes are relative to the line and their top position can be negative.
// Atomic inline boxes are all set. Their margin/border/content box geometries are already computed. We just have to position them here.
Expand Down Expand Up @@ -310,11 +314,13 @@ void InlineDisplayContentBuilder::appendInlineBoxDisplayBox(const Line::Run& lin
return;
}

auto& style = !m_lineIndex ? layoutBox.firstLineStyle() : layoutBox.style();
auto inkOverflow = [&] {
auto inkOverflow = FloatRect { inlineBoxBorderBox };
m_contentHasInkOverflow = computeInkOverflowForInlineBox(inlineBox, !m_lineIndex ? layoutBox.firstLineStyle() : layoutBox.style(), inkOverflow) || m_contentHasInkOverflow;
m_contentHasInkOverflow = computeInkOverflowForInlineBox(inlineBox, style, inkOverflow) || m_contentHasInkOverflow;
return inkOverflow;
};

ASSERT(inlineBox.isFirstBox());
boxes.append({ m_lineIndex
, InlineDisplay::Box::Type::NonRootInlineBox
Expand All @@ -325,7 +331,7 @@ void InlineDisplayContentBuilder::appendInlineBoxDisplayBox(const Line::Run& lin
, { }
, { }
, inlineBox.hasContent()
, lineRun.isTruncated() ? InlineDisplay::Box::IsVisuallyHidden::Yes : InlineDisplay::Box::IsVisuallyHidden::No
, lineRun.isTruncated()
, isFirstLastBox(inlineBox)
});
// This inline box showed up first on this line.
Expand All @@ -336,14 +342,16 @@ void InlineDisplayContentBuilder::appendSpanningInlineBoxDisplayBox(const Line::
{
ASSERT(lineRun.layoutBox().isInlineBox());
ASSERT(inlineBox.isInlineBox());
ASSERT(!inlineBox.isFirstBox());

auto& layoutBox = lineRun.layoutBox();
auto& style = !m_lineIndex ? layoutBox.firstLineStyle() : layoutBox.style();
auto inkOverflow = [&] {
auto inkOverflow = FloatRect { inlineBoxBorderBox };
m_contentHasInkOverflow = computeInkOverflowForInlineBox(inlineBox, !m_lineIndex ? layoutBox.firstLineStyle() : layoutBox.style(), inkOverflow) || m_contentHasInkOverflow;
m_contentHasInkOverflow = computeInkOverflowForInlineBox(inlineBox, style, inkOverflow) || m_contentHasInkOverflow;
return inkOverflow;
};
ASSERT(!inlineBox.isFirstBox());

boxes.append({ m_lineIndex
, InlineDisplay::Box::Type::NonRootInlineBox
, layoutBox
Expand All @@ -353,7 +361,7 @@ void InlineDisplayContentBuilder::appendSpanningInlineBoxDisplayBox(const Line::
, { }
, { }
, inlineBox.hasContent()
, lineRun.isTruncated() ? InlineDisplay::Box::IsVisuallyHidden::Yes : InlineDisplay::Box::IsVisuallyHidden::No
, lineRun.isTruncated()
, isFirstLastBox(inlineBox)
});
// Middle or end of the inline box. Let's stretch the box as needed.
Expand Down
Expand Up @@ -73,7 +73,7 @@ class BoxModernPath {
length(),
box().text()->hasHyphen() ? box().style().hyphenString().length() : 0,
box().isLineBreak(),
box().text()->visuallyVisibleLength()
box().text()->partiallyVisibleContentLength()
};
}

Expand Down
Expand Up @@ -67,8 +67,7 @@ void InlineContentPainter::paintDisplayBox(const InlineDisplay::Box& box)
return m_damageRect.maxY() > rect.y() && m_damageRect.y() < rect.maxY();
};

auto isVisuallyHidden = box.isVisuallyHidden() == InlineDisplay::Box::IsVisuallyHidden::Yes || box.style().visibility() != Visibility::Visible;
if (isVisuallyHidden || box.isLineBreak())
if (!box.isVisible() || box.isLineBreak())
return;

if (box.isInlineBox()) {
Expand Down
Expand Up @@ -806,6 +806,9 @@ bool LineLayout::hitTest(const HitTestRequest& request, HitTestResult& result, c
LayerPaintScope layerPaintScope(m_boxTree, layerRenderer);

for (auto& box : makeReversedRange(boxRange)) {
if (!box.isVisible())
continue;

auto& renderer = m_boxTree.rendererForLayoutBox(box.layoutBox());

if (!layerPaintScope.includes(box))
Expand Down

0 comments on commit 652e0bf

Please sign in to comment.