Diff
Modified: trunk/Source/WebCore/ChangeLog (282529 => 282530)
--- trunk/Source/WebCore/ChangeLog 2021-09-16 10:09:36 UTC (rev 282529)
+++ trunk/Source/WebCore/ChangeLog 2021-09-16 10:32:28 UTC (rev 282530)
@@ -1,3 +1,43 @@
+2021-09-16 Antti Koivisto <[email protected]>
+
+ Use std::optional for truncation
+ https://bugs.webkit.org/show_bug.cgi?id=230311
+
+ Reviewed by Myles Maxfield.
+
+ Replace the constants.
+ Use 0 truncation value for "full" truncation.
+
+ * rendering/LegacyEllipsisBox.cpp:
+ (WebCore::LegacyEllipsisBox::selectionState const):
+ * rendering/LegacyInlineTextBox.cpp:
+ (WebCore::LegacyInlineTextBox::placeEllipsisBox):
+ (WebCore::LegacyInlineTextBox::nodeAtPoint):
+ (WebCore::LegacyInlineTextBox::paint):
+ (WebCore::LegacyInlineTextBox::selectableRange const):
+ * rendering/LegacyInlineTextBox.h:
+ (WebCore::LegacyInlineTextBox::truncation const):
+ * rendering/RenderText.cpp:
+ (WebCore::ellipsisRectForTextRun):
+ * rendering/TextBoxPainter.cpp:
+ (WebCore::TextBoxPainter::paintForegroundAndDecorations):
+ (WebCore::TextBoxPainter::paintDecoration):
+
+ Remove various full truncation checks. Zero truncation value will make them not paint without needing extra checks.
+
+ (WebCore::TextBoxPainter::paintCompositionUnderlines):
+ (WebCore::TextBoxPainter::paintCompositionUnderline):
+ (WebCore::TextBoxPainter::paintPlatformDocumentMarker):
+ (WebCore::TextBoxPainter::computePaintRect):
+ * rendering/TextBoxSelectableRange.h:
+ (WebCore::TextBoxSelectableRange::clamp const):
+
+ Maintain the behavior where fully truncated text is selectable so fast/text/scroll-text-overflow-ellipsis.html keeps passing.
+
+ * rendering/svg/SVGInlineTextBox.cpp:
+ (WebCore::SVGInlineTextBox::paintSelectionBackground):
+ (WebCore::SVGInlineTextBox::paint):
+
2021-09-16 Youenn Fablet <[email protected]>
Support RTCPeerConnection lastCreatedOffer/lastCreatedAnswer
Modified: trunk/Source/WebCore/rendering/LegacyEllipsisBox.cpp (282529 => 282530)
--- trunk/Source/WebCore/rendering/LegacyEllipsisBox.cpp 2021-09-16 10:09:36 UTC (rev 282529)
+++ trunk/Source/WebCore/rendering/LegacyEllipsisBox.cpp 2021-09-16 10:32:28 UTC (rev 282530)
@@ -178,8 +178,10 @@
auto& textBox = downcast<LegacyInlineTextBox>(*lastSelectedBox);
+ auto truncation = textBox.truncation();
auto [selectionStart, selectionEnd] = textBox.selectionStartEnd();
- if (selectionEnd >= textBox.truncation() && selectionStart <= textBox.truncation())
+
+ if (truncation && selectionEnd >= *truncation && selectionStart <= *truncation)
return RenderObject::HighlightState::Inside;
return RenderObject::HighlightState::None;
Modified: trunk/Source/WebCore/rendering/LegacyInlineTextBox.cpp (282529 => 282530)
--- trunk/Source/WebCore/rendering/LegacyInlineTextBox.cpp 2021-09-16 10:09:36 UTC (rev 282529)
+++ trunk/Source/WebCore/rendering/LegacyInlineTextBox.cpp 2021-09-16 10:32:28 UTC (rev 282530)
@@ -69,9 +69,9 @@
WTF_MAKE_ISO_ALLOCATED_IMPL(LegacyInlineTextBox);
struct SameSizeAsLegacyInlineTextBox : public LegacyInlineBox {
- unsigned variables[1];
- unsigned short variables2[2];
void* pointers[2];
+ unsigned variables[2];
+ unsigned short variables2;
};
COMPILE_ASSERT(sizeof(LegacyInlineTextBox) == sizeof(SameSizeAsLegacyInlineTextBox), LegacyInlineTextBox_should_stay_small);
@@ -234,7 +234,7 @@
float LegacyInlineTextBox::placeEllipsisBox(bool flowIsLTR, float visibleLeftEdge, float visibleRightEdge, float ellipsisWidth, float &truncatedWidth, bool& foundBox)
{
if (foundBox) {
- m_truncation = cFullTruncation;
+ m_truncation = 0;
return -1;
}
@@ -248,7 +248,7 @@
bool rtlFullTruncation = !flowIsLTR && ellipsisX >= left() + logicalWidth();
if (ltrFullTruncation || rtlFullTruncation) {
// Too far. Just set full truncation, but return -1 and let the ellipsis just be placed at the edge of the box.
- m_truncation = cFullTruncation;
+ m_truncation = 0;
foundBox = true;
return -1;
}
@@ -272,7 +272,7 @@
if (!offset) {
// No characters should be rendered. Set ourselves to full truncation and place the ellipsis at the min of our start
// and the ellipsis edge.
- m_truncation = cFullTruncation;
+ m_truncation = 0;
truncatedWidth += ellipsisWidth;
return flowIsLTR ? std::min(ellipsisX, x()) : std::max(ellipsisX, right() - ellipsisWidth);
}
@@ -313,13 +313,13 @@
if (isLineBreak())
return false;
- if (m_truncation == cFullTruncation)
+ if (m_truncation && !*m_truncation)
return false;
FloatRect rect(locationIncludingFlipping(), size());
// Make sure truncated text is ignored while hittesting.
- if (m_truncation != cNoTruncation) {
- LayoutUnit widthOfVisibleText { renderer().width(m_start, m_truncation, textPos(), isFirstLine()) };
+ if (m_truncation) {
+ LayoutUnit widthOfVisibleText { renderer().width(m_start, *m_truncation, textPos(), isFirstLine()) };
if (isHorizontal())
renderer().style().isLeftToRightDirection() ? rect.setWidth(widthOfVisibleText) : rect.shiftXEdgeTo(right() - widthOfVisibleText);
@@ -381,7 +381,7 @@
void LegacyInlineTextBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset, LayoutUnit /*lineTop*/, LayoutUnit /*lineBottom*/)
{
if (isLineBreak() || !paintInfo.shouldPaintWithinRoot(renderer()) || renderer().style().visibility() != Visibility::Visible
- || m_truncation == cFullTruncation || paintInfo.phase == PaintPhase::Outline || !hasTextContent())
+ || (m_truncation && !*m_truncation) || paintInfo.phase == PaintPhase::Outline || !hasTextContent())
return;
ASSERT(paintInfo.phase != PaintPhase::SelfOutline && paintInfo.phase != PaintPhase::ChildOutlines);
@@ -414,20 +414,12 @@
return 0u;
}();
- auto truncation = [&]() -> std::optional<unsigned> {
- if (m_truncation == cNoTruncation)
- return { };
- if (m_truncation == cFullTruncation)
- return std::numeric_limits<unsigned>::max();
- return m_truncation;
- }();
-
return {
m_start,
m_len,
additionalLengthAtEnd,
isLineBreak(),
- truncation
+ m_truncation
};
}
Modified: trunk/Source/WebCore/rendering/LegacyInlineTextBox.h (282529 => 282530)
--- trunk/Source/WebCore/rendering/LegacyInlineTextBox.h 2021-09-16 10:09:36 UTC (rev 282529)
+++ trunk/Source/WebCore/rendering/LegacyInlineTextBox.h 2021-09-16 10:32:28 UTC (rev 282530)
@@ -31,9 +31,6 @@
class RenderCombineText;
-const unsigned short cNoTruncation = USHRT_MAX;
-const unsigned short cFullTruncation = USHRT_MAX - 1;
-
class LegacyInlineTextBox : public LegacyInlineBox {
WTF_MAKE_ISO_ALLOCATED(LegacyInlineTextBox);
public:
@@ -70,7 +67,7 @@
void offsetRun(int d) { ASSERT(!isDirty()); ASSERT(d > 0 || m_start >= static_cast<unsigned>(-d)); m_start += d; }
- unsigned short truncation() const { return m_truncation; }
+ auto truncation() const { return m_truncation; }
TextBoxSelectableRange selectableRange() const;
@@ -130,7 +127,7 @@
RenderObject::HighlightState selectionState() const final;
private:
- void clearTruncation() final { m_truncation = cNoTruncation; }
+ void clearTruncation() final { m_truncation = { }; }
float placeEllipsisBox(bool flowIsLTR, float visibleLeftEdge, float visibleRightEdge, float ellipsisWidth, float &truncatedWidth, bool& foundBox) final;
public:
@@ -172,12 +169,11 @@
LegacyInlineTextBox* m_prevTextBox { nullptr }; // The previous box that also uses our RenderObject
LegacyInlineTextBox* m_nextTextBox { nullptr }; // The next box that also uses our RenderObject
+ // Where to truncate when text overflow is applied.
+ std::optional<unsigned short> m_truncation;
+
unsigned m_start { 0 };
unsigned short m_len { 0 };
-
- // Where to truncate when text overflow is applied. We use special constants to
- // denote no truncation (the whole run paints) and full truncation (nothing paints at all).
- unsigned short m_truncation { cNoTruncation };
};
LayoutRect snappedSelectionRect(const LayoutRect&, float logicalRight, float selectionTop, float selectionHeight, bool isHorizontal);
Modified: trunk/Source/WebCore/rendering/RenderText.cpp (282529 => 282530)
--- trunk/Source/WebCore/rendering/RenderText.cpp 2021-09-16 10:09:36 UTC (rev 282529)
+++ trunk/Source/WebCore/rendering/RenderText.cpp 2021-09-16 10:32:28 UTC (rev 282530)
@@ -402,8 +402,8 @@
auto& box = *run.legacyInlineBox();
- unsigned short truncation = box.truncation();
- if (truncation == cNoTruncation)
+ auto truncation = box.truncation();
+ if (!truncation)
return { };
auto ellipsis = box.root().ellipsisBox();
@@ -416,7 +416,7 @@
// The ellipsis should be considered to be selected if the end of
// the selection is past the beginning of the truncation and the
// beginning of the selection is before or at the beginning of the truncation.
- if (ellipsisEndPosition < truncation && ellipsisStartPosition > truncation)
+ if (ellipsisEndPosition < *truncation && ellipsisStartPosition > *truncation)
return { };
return ellipsis->selectionRect();
Modified: trunk/Source/WebCore/rendering/TextBoxPainter.cpp (282529 => 282530)
--- trunk/Source/WebCore/rendering/TextBoxPainter.cpp 2021-09-16 10:09:36 UTC (rev 282529)
+++ trunk/Source/WebCore/rendering/TextBoxPainter.cpp 2021-09-16 10:32:28 UTC (rev 282530)
@@ -179,9 +179,7 @@
bool lineDecorations = !textDecorations.isEmpty();
if ((lineDecorations || highlightDecorations) && m_paintInfo.phase != PaintPhase::Selection) {
TextRun textRun = m_textBox.createTextRun();
- unsigned length = textRun.length();
- if (m_textBox.truncation() != cNoTruncation)
- length = m_textBox.truncation();
+ unsigned length = m_textBox.truncation().value_or(textRun.length());
unsigned selectionStart = 0;
unsigned selectionEnd = 0;
if (m_haveSelection)
@@ -327,7 +325,10 @@
void TextBoxPainter::paintDecoration(const StyledMarkedText& markedText, const FloatRect& clipOutRect)
{
- if (m_textBox.truncation() == cFullTruncation)
+ // 1. Compute text selection
+ unsigned startOffset = markedText.startOffset;
+ unsigned endOffset = markedText.endOffset;
+ if (startOffset >= endOffset)
return;
GraphicsContext& context = m_paintInfo.context();
@@ -340,12 +341,6 @@
if (isCombinedText)
context.concatCTM(rotation(m_paintRect, Clockwise));
- // 1. Compute text selection
- unsigned startOffset = markedText.startOffset;
- unsigned endOffset = markedText.endOffset;
- if (startOffset >= endOffset)
- return;
-
// Note that if the text is truncated, we let the thing being painted in the truncation
// draw its own decoration.
TextRun textRun = m_textBox.createTextRun();
@@ -390,9 +385,6 @@
void TextBoxPainter::paintCompositionUnderlines()
{
- if (m_textBox.truncation() == cFullTruncation)
- return;
-
for (auto& underline : m_renderer.frame().editor().customCompositionUnderlines()) {
if (underline.endOffset <= m_textBox.start()) {
// Underline is completely before this run. This might be an underline that sits
@@ -435,8 +427,8 @@
paintEnd = std::min(paintEnd, (unsigned)underline.endOffset);
useWholeWidth = false;
}
- if (m_textBox.truncation() != cNoTruncation) {
- paintEnd = std::min(paintEnd, m_textBox.start() + m_textBox.truncation());
+ if (m_textBox.truncation()) {
+ paintEnd = std::min(paintEnd, m_textBox.start() + *m_textBox.truncation());
useWholeWidth = false;
}
if (!useWholeWidth) {
@@ -489,9 +481,6 @@
if (m_document.printing())
return;
- if (m_textBox.truncation() == cFullTruncation)
- return;
-
auto bounds = calculateDocumentMarkerBounds(m_textBox, markedText);
auto lineStyleForMarkedTextType = [&]() -> DocumentMarkerLineStyle {
@@ -524,7 +513,7 @@
{
FloatPoint localPaintOffset(paintOffset);
- if (textBox.truncation() != cNoTruncation) {
+ if (textBox.truncation()) {
auto& renderer = textBox.renderer();
if (renderer.containingBlock()->style().isLeftToRightDirection() != textBox.isLeftToRightDirection()) {
// Make the visible fragment of text hug the edge closest to the rest of the run by moving the origin
@@ -535,7 +524,7 @@
// farther to the right.
// NOTE: WebKit's behavior differs from that of IE which appears to just overlay the ellipsis on top of the
// truncated string i.e. |Hello|CBA| -> |...lo|CBA|
- LayoutUnit widthOfVisibleText { renderer.width(textBox.start(), textBox.truncation(), textBox.textPos(), textBox.isFirstLine()) };
+ LayoutUnit widthOfVisibleText { renderer.width(textBox.start(), *textBox.truncation(), textBox.textPos(), textBox.isFirstLine()) };
LayoutUnit widthOfHiddenText { textBox.logicalWidth() - widthOfVisibleText };
LayoutSize truncationOffset(textBox.isLeftToRightDirection() ? widthOfHiddenText : -widthOfHiddenText, 0_lu);
localPaintOffset.move(textBox.isHorizontal() ? truncationOffset : truncationOffset.transposedSize());
Modified: trunk/Source/WebCore/rendering/TextBoxSelectableRange.h (282529 => 282530)
--- trunk/Source/WebCore/rendering/TextBoxSelectableRange.h 2021-09-16 10:09:36 UTC (rev 282529)
+++ trunk/Source/WebCore/rendering/TextBoxSelectableRange.h 2021-09-16 10:32:28 UTC (rev 282530)
@@ -39,7 +39,8 @@
{
auto clampedOffset = std::clamp(offset, start, start + length) - start;
- if (truncation)
+ // FIXME: For some reason we allow the caret move to (invisible) fully truncated text. The zero test is to keep that behavior.
+ if (truncation && *truncation)
return std::min<unsigned>(clampedOffset, *truncation);
if (clampedOffset == length)
Modified: trunk/Source/WebCore/rendering/svg/SVGInlineTextBox.cpp (282529 => 282530)
--- trunk/Source/WebCore/rendering/svg/SVGInlineTextBox.cpp 2021-09-16 10:09:36 UTC (rev 282529)
+++ trunk/Source/WebCore/rendering/svg/SVGInlineTextBox.cpp 2021-09-16 10:32:28 UTC (rev 282530)
@@ -180,7 +180,7 @@
{
ASSERT(paintInfo.shouldPaintWithinRoot(renderer()));
ASSERT(paintInfo.phase == PaintPhase::Foreground || paintInfo.phase == PaintPhase::Selection);
- ASSERT(truncation() == cNoTruncation);
+ ASSERT(!truncation());
if (renderer().style().visibility() != Visibility::Visible)
return;
@@ -236,7 +236,7 @@
{
ASSERT(paintInfo.shouldPaintWithinRoot(renderer()));
ASSERT(paintInfo.phase == PaintPhase::Foreground || paintInfo.phase == PaintPhase::Selection);
- ASSERT(truncation() == cNoTruncation);
+ ASSERT(!truncation());
if (renderer().style().visibility() != Visibility::Visible)
return;