source: webkit/trunk/Source/WebCore/rendering/LegacyEllipsisBox.cpp

Last change on this file was 294607, checked in by [email protected], 3 years ago

Convert ExpansionBehavior to a struct of left/right expansion behaviors
https://bugs.webkit.org/show_bug.cgi?id=240554

Patch by Kiet Ho <Kiet Ho> on 2022-05-20
Reviewed by Myles C. Maxfield.

  • Tools/TestWebKitAPI/Tests/WebCore/ComplexTextController.cpp:

(TestWebKitAPI::TEST_F):

  • Source/WebKit/WebProcess/WebCoreSupport/win/WebPopupMenuWin.cpp:

(WebKit::WebPopupMenu::setUpPlatformData):

No new tests, no functional changes made.

  • Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp:

(WebCore::CanvasRenderingContext2D::measureText):
(WebCore::CanvasRenderingContext2D::drawTextInternal):

  • Source/WebCore/html/canvas/CanvasRenderingContext2DBase.cpp:

(WebCore::CanvasRenderingContext2DBase::drawText):
(WebCore::CanvasRenderingContext2DBase::measureTextInternal):

  • Source/WebCore/layout/formattingContexts/inline/InlineLine.cpp:

(WebCore::Layout::Line::applyRunExpansion):

  • Source/WebCore/layout/formattingContexts/inline/display/InlineDisplayBox.h:
  • Source/WebCore/layout/formattingContexts/inline/text/TextUtil.cpp:

(WebCore::Layout::TextUtil::fallbackFontsForText):

  • Source/WebCore/platform/graphics/ComplexTextController.cpp:

(WebCore::ComplexTextController::adjustGlyphsAndAdvances):

  • Source/WebCore/platform/graphics/FontCascade.cpp:

(WebCore::FontCascade::expansionOpportunityCountInternal):

  • Source/WebCore/platform/graphics/TextRun.h:

(WebCore::TextRun::TextRun):

  • Source/WebCore/platform/graphics/WidthIterator.cpp:

(WebCore::WidthIterator::WidthIterator):
(WebCore::WidthIterator::calculateAdditionalWidth const):

  • Source/WebCore/platform/text/TextFlags.h:

(WebCore::ExpansionBehavior::ExpansionBehavior):
(WebCore::ExpansionBehavior::allowLeftOnly):
(WebCore::ExpansionBehavior::forceLeftOnly):
(WebCore::ExpansionBehavior::allowRightOnly):

  • Source/WebCore/platform/win/PopupMenuWin.cpp:

(WebCore::PopupMenuWin::paint):

  • Source/WebCore/rendering/LegacyEllipsisBox.cpp:

(WebCore::LegacyEllipsisBox::paint):
(WebCore::LegacyEllipsisBox::selectionRect const):
(WebCore::LegacyEllipsisBox::paintSelection):

  • Source/WebCore/rendering/LegacyInlineTextBox.cpp:

(WebCore::LegacyInlineTextBox::expansionBehavior const):

  • Source/WebCore/rendering/LegacyLineLayout.cpp:

(WebCore::expansionBehaviorForInlineTextBox):
(WebCore::applyExpansionBehavior):

  • Source/WebCore/rendering/RenderBlock.h:
  • Source/WebCore/rendering/RenderFileUploadControl.cpp:

(WebCore::RenderFileUploadControl::paintObject):
(WebCore::RenderFileUploadControl::computeIntrinsicLogicalWidths const):

  • Source/WebCore/rendering/RenderImage.cpp:

(WebCore::RenderImage::paintReplaced):

  • Source/WebCore/rendering/RenderListBox.cpp:

(WebCore::RenderListBox::updateFromElement):
(WebCore::RenderListBox::paintItemForeground):

  • Source/WebCore/rendering/RenderTextControl.cpp:

(WebCore::RenderTextControl::getAverageCharWidth):

  • Source/WebCore/rendering/svg/SVGInlineTextBox.cpp:

(WebCore::SVGInlineTextBox::constructTextRun const):

  • Source/WebCore/rendering/svg/SVGTextMetrics.cpp:

(WebCore::SVGTextMetrics::constructTextRun):

Canonical link: https://commits.webkit.org/250833@main

  • Property svn:eol-style set to native
File size: 8.4 KB
Line 
1/**
2 * Copyright (C) 2003, 2006 Apple Inc.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public License
15 * along with this library; see the file COPYING.LIB. If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
20#include "config.h"
21#include "LegacyEllipsisBox.h"
22
23#include "Document.h"
24#include "FontCascade.h"
25#include "GraphicsContext.h"
26#include "HitTestResult.h"
27#include "LegacyInlineTextBox.h"
28#include "LegacyRootInlineBox.h"
29#include "PaintInfo.h"
30#include "TextRun.h"
31#include <wtf/IsoMallocInlines.h>
32
33namespace WebCore {
34
35WTF_MAKE_ISO_ALLOCATED_IMPL(LegacyEllipsisBox);
36
37LegacyEllipsisBox::LegacyEllipsisBox(RenderBlockFlow& renderer, const AtomString& ellipsisStr, LegacyInlineFlowBox* parent, int width, int height, int y, bool firstLine, bool isHorizontal, LegacyInlineBox* markupBox)
38 : LegacyInlineElementBox(renderer, FloatPoint(0, y), width, firstLine, true, false, false, isHorizontal, 0, 0, parent)
39 , m_shouldPaintMarkupBox(markupBox)
40 , m_height(height)
41 , m_str(ellipsisStr)
42{
43#if !ASSERT_WITH_SECURITY_IMPLICATION_DISABLED
44 m_isEverInChildList = false;
45#endif
46}
47
48void LegacyEllipsisBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset, LayoutUnit lineTop, LayoutUnit lineBottom)
49{
50 GraphicsContext& context = paintInfo.context();
51 const RenderStyle& lineStyle = this->lineStyle();
52 Color textColor = lineStyle.visitedDependentColorWithColorFilter(CSSPropertyWebkitTextFillColor);
53 if (textColor != context.fillColor())
54 context.setFillColor(textColor);
55 bool setShadow = false;
56 if (lineStyle.textShadow()) {
57 Color shadowColor = lineStyle.colorByApplyingColorFilter(lineStyle.textShadow()->color());
58 context.setShadow(LayoutSize(lineStyle.textShadow()->x().value(), lineStyle.textShadow()->y().value()), lineStyle.textShadow()->radius().value(), shadowColor);
59 setShadow = true;
60 }
61
62 const FontCascade& font = lineStyle.fontCascade();
63 if (selectionState() != RenderObject::HighlightState::None) {
64 paintSelection(context, paintOffset, lineStyle, font);
65
66 // Select the correct color for painting the text.
67 Color foreground = paintInfo.forceTextColor() ? paintInfo.forcedTextColor() : blockFlow().selectionForegroundColor();
68 if (foreground.isValid() && foreground != textColor)
69 context.setFillColor(foreground);
70 }
71
72 // FIXME: Why is this always LTR? Fix by passing correct text run flags below.
73 context.drawText(font, RenderBlock::constructTextRun(m_str, lineStyle, ExpansionBehavior::allowRightOnly()), LayoutPoint(x() + paintOffset.x(), y() + paintOffset.y() + lineStyle.metricsOfPrimaryFont().ascent()));
74
75 // Restore the regular fill color.
76 if (textColor != context.fillColor())
77 context.setFillColor(textColor);
78
79 if (setShadow)
80 context.clearShadow();
81
82 paintMarkupBox(paintInfo, paintOffset, lineTop, lineBottom, lineStyle);
83}
84
85LegacyInlineBox* LegacyEllipsisBox::markupBox() const
86{
87 if (!m_shouldPaintMarkupBox)
88 return 0;
89
90 LegacyRootInlineBox* lastLine = blockFlow().lastRootBox();
91 if (!lastLine)
92 return 0;
93
94 // If the last line-box on the last line of a block is a link, -webkit-line-clamp paints that box after the ellipsis.
95 // It does not actually move the link.
96 LegacyInlineBox* anchorBox = lastLine->lastLeafDescendant();
97 if (!anchorBox || !anchorBox->renderer().style().isLink())
98 return 0;
99
100 return anchorBox;
101}
102
103void LegacyEllipsisBox::paintMarkupBox(PaintInfo& paintInfo, const LayoutPoint& paintOffset, LayoutUnit lineTop, LayoutUnit lineBottom, const RenderStyle& style)
104{
105 LegacyInlineBox* markupBox = this->markupBox();
106 if (!markupBox)
107 return;
108
109 LayoutPoint adjustedPaintOffset = paintOffset;
110 adjustedPaintOffset.move(x() + logicalWidth() - markupBox->x(),
111 y() + style.metricsOfPrimaryFont().ascent() - (markupBox->y() + markupBox->lineStyle().metricsOfPrimaryFont().ascent()));
112 markupBox->paint(paintInfo, adjustedPaintOffset, lineTop, lineBottom);
113}
114
115IntRect LegacyEllipsisBox::selectionRect() const
116{
117 const RenderStyle& lineStyle = this->lineStyle();
118 const FontCascade& font = lineStyle.fontCascade();
119 const LegacyRootInlineBox& rootBox = root();
120 // FIXME: Why is this always LTR? Fix by passing correct text run flags below.
121 LayoutRect selectionRect { LayoutUnit(x()), LayoutUnit(y() + rootBox.selectionTopAdjustedForPrecedingBlock()), 0_lu, rootBox.selectionHeightAdjustedForPrecedingBlock() };
122 font.adjustSelectionRectForText(RenderBlock::constructTextRun(m_str, lineStyle, ExpansionBehavior::allowRightOnly()), selectionRect);
123 // FIXME: use directional pixel snapping instead.
124 return enclosingIntRect(selectionRect);
125}
126
127void LegacyEllipsisBox::paintSelection(GraphicsContext& context, const LayoutPoint& paintOffset, const RenderStyle& style, const FontCascade& font)
128{
129 Color textColor = style.visitedDependentColorWithColorFilter(CSSPropertyColor);
130 Color c = blockFlow().selectionBackgroundColor();
131 if (!c.isVisible())
132 return;
133
134 // If the text color ends up being the same as the selection background, invert the selection
135 // background.
136 if (textColor == c)
137 c = c.invertedColorWithAlpha(1.0);
138
139 const LegacyRootInlineBox& rootBox = root();
140 GraphicsContextStateSaver stateSaver(context);
141 // FIXME: Why is this always LTR? Fix by passing correct text run flags below.
142 LayoutRect selectionRect { LayoutUnit(x() + paintOffset.x()), rootBox.selectionTop() + paintOffset.y(), 0_lu, rootBox.selectionHeight() };
143 TextRun run = RenderBlock::constructTextRun(m_str, style, ExpansionBehavior::allowRightOnly());
144 font.adjustSelectionRectForText(run, selectionRect);
145 context.fillRect(snapRectToDevicePixelsWithWritingDirection(selectionRect, renderer().document().deviceScaleFactor(), run.ltr()), c);
146}
147
148bool LegacyEllipsisBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, LayoutUnit lineTop, LayoutUnit lineBottom, HitTestAction hitTestAction)
149{
150 LayoutPoint adjustedLocation = accumulatedOffset + LayoutPoint(topLeft());
151
152 // Hit test the markup box.
153 if (LegacyInlineBox* markupBox = this->markupBox()) {
154 const RenderStyle& lineStyle = this->lineStyle();
155 LayoutUnit mtx { adjustedLocation.x() + logicalWidth() - markupBox->x() };
156 LayoutUnit mty { adjustedLocation.y() + lineStyle.metricsOfPrimaryFont().ascent() - (markupBox->y() + markupBox->lineStyle().metricsOfPrimaryFont().ascent()) };
157 if (markupBox->nodeAtPoint(request, result, locationInContainer, LayoutPoint(mtx, mty), lineTop, lineBottom, hitTestAction)) {
158 blockFlow().updateHitTestResult(result, locationInContainer.point() - LayoutSize(mtx, mty));
159 return true;
160 }
161 }
162
163 auto boundsRect = LayoutRect { adjustedLocation, LayoutSize(LayoutUnit(logicalWidth()), m_height) };
164 if (renderer().visibleToHitTesting(request) && locationInContainer.intersects(boundsRect)) {
165 blockFlow().updateHitTestResult(result, locationInContainer.point() - toLayoutSize(adjustedLocation));
166 if (result.addNodeToListBasedTestResult(blockFlow().nodeForHitTest(), request, locationInContainer, boundsRect) == HitTestProgress::Stop)
167 return true;
168 }
169
170 return false;
171}
172
173RenderObject::HighlightState LegacyEllipsisBox::selectionState() const
174{
175 auto* lastSelectedBox = root().lastSelectedBox();
176 if (!is<LegacyInlineTextBox>(lastSelectedBox))
177 return RenderObject::HighlightState::None;
178
179 auto& textBox = downcast<LegacyInlineTextBox>(*lastSelectedBox);
180
181 auto truncation = textBox.truncation();
182 auto [selectionStart, selectionEnd] = textBox.selectionStartEnd();
183
184 if (truncation && selectionEnd >= *truncation && selectionStart <= *truncation)
185 return RenderObject::HighlightState::Inside;
186
187 return RenderObject::HighlightState::None;
188}
189
190} // namespace WebCore
Note: See TracBrowser for help on using the repository browser.