source: webkit/trunk/Source/WebCore/rendering/RenderTextControl.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: 9.2 KB
Line 
1/**
2 * Copyright (C) 2006, 2007, 2014 Apple Inc. All rights reserved.
3 * (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB. If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 *
20 */
21
22#include "config.h"
23#include "RenderTextControl.h"
24
25#include "HTMLTextFormControlElement.h"
26#include "HitTestResult.h"
27#include "RenderText.h"
28#include "RenderTextControlSingleLine.h"
29#include "RenderTheme.h"
30#include "ScrollbarTheme.h"
31#include "StyleInheritedData.h"
32#include "StyleProperties.h"
33#include "TextControlInnerElements.h"
34#include "VisiblePosition.h"
35#include <wtf/IsoMallocInlines.h>
36#include <wtf/unicode/CharacterNames.h>
37
38namespace WebCore {
39
40WTF_MAKE_ISO_ALLOCATED_IMPL(RenderTextControl);
41WTF_MAKE_ISO_ALLOCATED_IMPL(RenderTextControlInnerContainer);
42
43RenderTextControl::RenderTextControl(HTMLTextFormControlElement& element, RenderStyle&& style)
44 : RenderBlockFlow(element, WTFMove(style))
45{
46}
47
48RenderTextControl::~RenderTextControl() = default;
49
50HTMLTextFormControlElement& RenderTextControl::textFormControlElement() const
51{
52 return downcast<HTMLTextFormControlElement>(nodeForNonAnonymous());
53}
54
55RefPtr<TextControlInnerTextElement> RenderTextControl::innerTextElement() const
56{
57 return textFormControlElement().innerTextElement();
58}
59
60void RenderTextControl::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
61{
62 RenderBlockFlow::styleDidChange(diff, oldStyle);
63 auto innerText = innerTextElement();
64 if (!innerText)
65 return;
66 RenderTextControlInnerBlock* innerTextRenderer = innerText->renderer();
67 if (innerTextRenderer && oldStyle) {
68 // FIXME: The height property of the inner text block style may be mutated by RenderTextControlSingleLine::layout.
69 // See if the original has changed before setting it and triggering a layout.
70 auto newInnerTextStyle = textFormControlElement().createInnerTextStyle(style());
71 auto oldInnerTextStyle = textFormControlElement().createInnerTextStyle(*oldStyle);
72 if (newInnerTextStyle != oldInnerTextStyle)
73 innerTextRenderer->setStyle(WTFMove(newInnerTextStyle));
74 else if (diff == StyleDifference::RepaintIfText || diff == StyleDifference::Repaint) {
75 // Repaint is expected to be propagated down to the shadow tree when non-inherited style property changes
76 // (e.g. text-decoration-color) since that's where the value actually takes effect.
77 innerTextRenderer->repaint();
78 }
79 }
80 textFormControlElement().updatePlaceholderVisibility();
81}
82
83int RenderTextControl::textBlockLogicalHeight() const
84{
85 return logicalHeight() - borderAndPaddingLogicalHeight();
86}
87
88int RenderTextControl::textBlockLogicalWidth() const
89{
90 auto innerText = innerTextElement();
91 ASSERT(innerText);
92
93 LayoutUnit unitWidth = logicalWidth() - borderAndPaddingLogicalWidth();
94 if (innerText->renderer())
95 unitWidth -= innerText->renderBox()->paddingStart() + innerText->renderBox()->paddingEnd();
96
97 return unitWidth;
98}
99
100int RenderTextControl::scrollbarThickness() const
101{
102 // FIXME: We should get the size of the scrollbar from the RenderTheme instead.
103 return ScrollbarTheme::theme().scrollbarThickness();
104}
105
106RenderBox::LogicalExtentComputedValues RenderTextControl::computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logicalTop) const
107{
108 auto innerText = innerTextElement();
109 ASSERT(innerText);
110 if (RenderBox* innerTextBox = innerText->renderBox()) {
111 LayoutUnit nonContentHeight = innerTextBox->verticalBorderAndPaddingExtent() + innerTextBox->verticalMarginExtent();
112 logicalHeight = computeControlLogicalHeight(innerTextBox->lineHeight(true, HorizontalLine, PositionOfInteriorLineBoxes), nonContentHeight);
113
114 // We are able to have a horizontal scrollbar if the overflow style is scroll, or if its auto and there's no word wrap.
115 if ((isHorizontalWritingMode() && (style().overflowX() == Overflow::Scroll || (style().overflowX() == Overflow::Auto && innerText->renderer()->style().overflowWrap() == OverflowWrap::Normal)))
116 || (!isHorizontalWritingMode() && (style().overflowY() == Overflow::Scroll || (style().overflowY() == Overflow::Auto && innerText->renderer()->style().overflowWrap() == OverflowWrap::Normal))))
117 logicalHeight += scrollbarThickness();
118
119 // FIXME: The logical height of the inner text box should have been added
120 // before calling computeLogicalHeight to avoid this hack.
121 cacheIntrinsicContentLogicalHeightForFlexItem(logicalHeight);
122
123 logicalHeight += verticalBorderAndPaddingExtent();
124 }
125
126 return RenderBox::computeLogicalHeight(logicalHeight, logicalTop);
127}
128
129void RenderTextControl::hitInnerTextElement(HitTestResult& result, const LayoutPoint& pointInContainer, const LayoutPoint& accumulatedOffset)
130{
131 auto innerText = innerTextElement();
132 if (!innerText->renderer())
133 return;
134
135 LayoutPoint adjustedLocation = accumulatedOffset + location();
136 LayoutPoint localPoint = pointInContainer - toLayoutSize(adjustedLocation + innerText->renderBox()->location()) + toLayoutSize(scrollPosition());
137 result.setInnerNode(innerText.get());
138 result.setInnerNonSharedNode(innerText.get());
139 result.setLocalPoint(localPoint);
140}
141
142float RenderTextControl::getAverageCharWidth()
143{
144 float width;
145 if (style().fontCascade().fastAverageCharWidthIfAvailable(width))
146 return width;
147
148 const UChar ch = '0';
149 const String str = String(&ch, 1);
150 const FontCascade& font = style().fontCascade();
151 TextRun textRun = constructTextRun(str, style(), ExpansionBehavior::allowRightOnly());
152 return font.width(textRun);
153}
154
155float RenderTextControl::scaleEmToUnits(int x) const
156{
157 // This matches the unitsPerEm value for MS Shell Dlg and Courier New from the "head" font table.
158 float unitsPerEm = 2048.0f;
159 return roundf(style().fontCascade().size() * x / unitsPerEm);
160}
161
162void RenderTextControl::computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const
163{
164 if (shouldApplySizeContainment())
165 return;
166 // Use average character width. Matches IE.
167 maxLogicalWidth = preferredContentLogicalWidth(const_cast<RenderTextControl*>(this)->getAverageCharWidth());
168 if (RenderBox* innerTextRenderBox = innerTextElement()->renderBox())
169 maxLogicalWidth += innerTextRenderBox->paddingStart() + innerTextRenderBox->paddingEnd();
170 if (!style().logicalWidth().isPercentOrCalculated())
171 minLogicalWidth = maxLogicalWidth;
172}
173
174void RenderTextControl::computePreferredLogicalWidths()
175{
176 ASSERT(preferredLogicalWidthsDirty());
177
178 m_minPreferredLogicalWidth = 0;
179 m_maxPreferredLogicalWidth = 0;
180
181 if (style().logicalWidth().isFixed() && style().logicalWidth().value() >= 0)
182 m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = adjustContentBoxLogicalWidthForBoxSizing(style().logicalWidth());
183 else
184 computeIntrinsicLogicalWidths(m_minPreferredLogicalWidth, m_maxPreferredLogicalWidth);
185
186 RenderBox::computePreferredLogicalWidths(style().logicalMinWidth(), style().logicalMaxWidth(), borderAndPaddingLogicalWidth());
187
188 setPreferredLogicalWidthsDirty(false);
189}
190
191void RenderTextControl::addFocusRingRects(Vector<LayoutRect>& rects, const LayoutPoint& additionalOffset, const RenderLayerModelObject*)
192{
193 if (!size().isEmpty())
194 rects.append(LayoutRect(additionalOffset, size()));
195}
196
197void RenderTextControl::layoutExcludedChildren(bool relayoutChildren)
198{
199 RenderBlockFlow::layoutExcludedChildren(relayoutChildren);
200
201 HTMLElement* placeholder = textFormControlElement().placeholderElement();
202 RenderElement* placeholderRenderer = placeholder ? placeholder->renderer() : 0;
203 if (!placeholderRenderer)
204 return;
205 placeholderRenderer->setIsExcludedFromNormalLayout(true);
206
207 if (relayoutChildren) {
208 // The markParents arguments should be false because this function is
209 // called from layout() of the parent and the placeholder layout doesn't
210 // affect the parent layout.
211 placeholderRenderer->setChildNeedsLayout(MarkOnlyThis);
212 }
213}
214
215#if PLATFORM(IOS_FAMILY)
216bool RenderTextControl::canScroll() const
217{
218 auto innerText = innerTextElement();
219 return innerText && innerText->renderer() && innerText->renderer()->hasNonVisibleOverflow();
220}
221
222int RenderTextControl::innerLineHeight() const
223{
224 auto innerText = innerTextElement();
225 if (innerText && innerText->renderer())
226 return innerText->renderer()->style().computedLineHeight();
227 return style().computedLineHeight();
228}
229#endif
230
231} // namespace WebCore
Note: See TracBrowser for help on using the repository browser.