[iOS] REGRESSION(r254699) : fast/forms/interactive-validation-remove-node-in-handler...
[WebKit-https.git] / Source / WebCore / rendering / RenderText.h
1 /*
2  * (C) 1999 Lars Knoll (knoll@kde.org)
3  * (C) 2000 Dirk Mueller (mueller@kde.org)
4  * Copyright (C) 2004-2017 Apple Inc. All rights reserved.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public License
17  * along with this library; see the file COPYING.LIB.  If not, write to
18  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  *
21  */
22
23 #pragma once
24
25 #include "RenderElement.h"
26 #include "RenderTextLineBoxes.h"
27 #include "SimpleLineLayout.h"
28 #include "Text.h"
29 #include <wtf/Forward.h>
30 #include <wtf/text/TextBreakIterator.h>
31
32 namespace WebCore {
33
34 class Font;
35 class InlineTextBox;
36 struct GlyphOverflow;
37
38 namespace LayoutIntegration {
39 class LineLayout;
40 }
41
42 class RenderText : public RenderObject {
43     WTF_MAKE_ISO_ALLOCATED(RenderText);
44 public:
45     RenderText(Text&, const String&);
46     RenderText(Document&, const String&);
47
48     virtual ~RenderText();
49
50     WEBCORE_EXPORT Text* textNode() const;
51
52     virtual bool isTextFragment() const;
53
54     const RenderStyle& style() const;
55     const RenderStyle& firstLineStyle() const;
56     const RenderStyle* getCachedPseudoStyle(PseudoId, const RenderStyle* parentStyle = nullptr) const;
57
58     Color selectionBackgroundColor() const;
59     Color selectionForegroundColor() const;
60     Color selectionEmphasisMarkColor() const;
61     std::unique_ptr<RenderStyle> selectionPseudoStyle() const;
62
63     virtual String originalText() const;
64
65     void extractTextBox(InlineTextBox& box) { m_lineBoxes.extract(box); }
66     void attachTextBox(InlineTextBox& box) { m_lineBoxes.attach(box); }
67     void removeTextBox(InlineTextBox& box) { m_lineBoxes.remove(box); }
68
69     StringImpl& text() const { return *m_text.impl(); } // Since m_text can never be null, returning this type means callers won't null check.
70     String textWithoutConvertingBackslashToYenSymbol() const;
71
72     InlineTextBox* createInlineTextBox() { return m_lineBoxes.createAndAppendLineBox(*this); }
73     void dirtyLineBoxes(bool fullLayout);
74
75     void absoluteRects(Vector<IntRect>&, const LayoutPoint& accumulatedOffset) const final;
76     Vector<IntRect> absoluteRectsForRange(unsigned startOffset = 0, unsigned endOffset = UINT_MAX, bool useSelectionHeight = false, bool* wasFixed = nullptr) const;
77 #if PLATFORM(IOS_FAMILY)
78     void collectSelectionRects(Vector<SelectionRect>&, unsigned startOffset = 0, unsigned endOffset = std::numeric_limits<unsigned>::max()) final;
79 #endif
80
81     void absoluteQuads(Vector<FloatQuad>&, bool* wasFixed) const final;
82     Vector<FloatQuad> absoluteQuadsForRange(unsigned startOffset = 0, unsigned endOffset = UINT_MAX, bool useSelectionHeight = false, bool ignoreEmptyTextSelections = false, bool* wasFixed = nullptr) const;
83
84     Vector<FloatQuad> absoluteQuadsClippedToEllipsis() const;
85
86     Position positionForPoint(const LayoutPoint&) final;
87
88     UChar characterAt(unsigned) const;
89     unsigned length() const final { return text().length(); }
90
91     void positionLineBox(InlineTextBox&);
92
93     virtual float width(unsigned from, unsigned length, const FontCascade&, float xPos, HashSet<const Font*>* fallbackFonts = nullptr, GlyphOverflow* = nullptr) const;
94     virtual float width(unsigned from, unsigned length, float xPos, bool firstLine = false, HashSet<const Font*>* fallbackFonts = nullptr, GlyphOverflow* = nullptr) const;
95
96     float minLogicalWidth() const;
97     float maxLogicalWidth() const;
98
99     struct Widths {
100         float min { 0 };
101         float max { 0 };
102         float beginMin { 0 };
103         float endMin { 0 };
104         float beginMax { 0 };
105         float endMax { 0 };
106         bool beginWS { false };
107         bool endWS { false };
108         bool hasBreakableChar { false };
109         bool hasBreak { false };
110     };
111     Widths trimmedPreferredWidths(float leadWidth, bool& stripFrontSpaces);
112
113     float hangablePunctuationStartWidth(unsigned index) const;
114     float hangablePunctuationEndWidth(unsigned index) const;
115     unsigned firstCharacterIndexStrippingSpaces() const;
116     unsigned lastCharacterIndexStrippingSpaces() const;
117     static bool isHangableStopOrComma(UChar);
118     
119     WEBCORE_EXPORT virtual IntRect linesBoundingBox() const;
120     LayoutRect linesVisualOverflowBoundingBox() const;
121
122     WEBCORE_EXPORT IntPoint firstRunLocation() const;
123
124     virtual void setText(const String&, bool force = false);
125     void setTextWithOffset(const String&, unsigned offset, unsigned len, bool force = false);
126
127     bool canBeSelectionLeaf() const override { return true; }
128
129     LayoutRect collectSelectionRectsForLineBoxes(const RenderLayerModelObject* repaintContainer, bool clipToVisibleContent, Vector<LayoutRect>&);
130
131     LayoutUnit marginLeft() const { return minimumValueForLength(style().marginLeft(), 0); }
132     LayoutUnit marginRight() const { return minimumValueForLength(style().marginRight(), 0); }
133
134     InlineTextBox* firstTextBox() const { return m_lineBoxes.first(); }
135     InlineTextBox* lastTextBox() const { return m_lineBoxes.last(); }
136
137     int caretMinOffset() const final;
138     int caretMaxOffset() const final;
139     unsigned countRenderedCharacterOffsetsUntil(unsigned) const;
140     bool containsRenderedCharacterOffset(unsigned) const;
141     bool containsCaretOffset(unsigned) const;
142     bool hasRenderedText() const;
143
144     // FIXME: These should return unsigneds.
145     int previousOffset(int current) const final;
146     int previousOffsetForBackwardDeletion(int current) const final;
147     int nextOffset(int current) const final;
148
149     bool containsReversedText() const { return m_containsReversedText; }
150
151     void momentarilyRevealLastTypedCharacter(unsigned offsetAfterLastTypedCharacter);
152
153     InlineTextBox* findNextInlineTextBox(int offset, int& pos) const { return m_lineBoxes.findNext(offset, pos); }
154
155     bool isAllCollapsibleWhitespace() const;
156
157     bool canUseSimpleFontCodePath() const { return m_canUseSimpleFontCodePath; }
158
159     void removeAndDestroyTextBoxes();
160
161     virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
162
163     virtual std::unique_ptr<InlineTextBox> createTextBox();
164
165 #if ENABLE(TEXT_AUTOSIZING)
166     float candidateComputedTextSize() const { return m_candidateComputedTextSize; }
167     void setCandidateComputedTextSize(float size) { m_candidateComputedTextSize = size; }
168 #endif
169
170     void ensureLineBoxes();
171     const SimpleLineLayout::Layout* simpleLineLayout() const;
172 #if ENABLE(LAYOUT_FORMATTING_CONTEXT)
173     const LayoutIntegration::LineLayout* layoutFormattingContextLineLayout() const;
174 #endif
175     bool usesComplexLineLayoutPath() const;
176
177     StringView stringView(unsigned start = 0, Optional<unsigned> stop = WTF::nullopt) const;
178
179     LayoutUnit topOfFirstText() const;
180     
181     bool containsOnlyHTMLWhitespace(unsigned from, unsigned length) const;
182     
183     bool canUseSimplifiedTextMeasuring() const { return m_canUseSimplifiedTextMeasuring; }
184
185     Vector<std::pair<unsigned, unsigned>> draggedContentRangesBetweenOffsets(unsigned startOffset, unsigned endOffset) const;
186
187     RenderInline* inlineWrapperForDisplayContents();
188     void setInlineWrapperForDisplayContents(RenderInline*);
189
190     static RenderText* findByDisplayContentsInlineWrapperCandidate(RenderElement&);
191
192 protected:
193     virtual void computePreferredLogicalWidths(float leadWidth);
194     void willBeDestroyed() override;
195
196     virtual void setRenderedText(const String&);
197     virtual UChar previousCharacter() const;
198
199     RenderTextLineBoxes m_lineBoxes;
200
201 private:
202     RenderText(Node&, const String&);
203
204     const char* renderName() const override;
205
206     bool canHaveChildren() const final { return false; }
207
208     VisiblePosition positionForPoint(const LayoutPoint&, const RenderFragmentContainer*) override;
209
210     void setSelectionState(SelectionState) final;
211     LayoutRect selectionRectForRepaint(const RenderLayerModelObject* repaintContainer, bool clipToVisibleContent = true) final;
212     LayoutRect localCaretRect(InlineBox*, unsigned caretOffset, LayoutUnit* extraWidthToEndOfLine = nullptr) override;
213     LayoutRect clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const final;
214
215     void computePreferredLogicalWidths(float leadWidth, HashSet<const Font*>& fallbackFonts, GlyphOverflow&);
216
217     bool computeCanUseSimpleFontCodePath() const;
218     
219     bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation&, const LayoutPoint&, HitTestAction) final { ASSERT_NOT_REACHED(); return false; }
220
221     float widthFromCache(const FontCascade&, unsigned start, unsigned len, float xPos, HashSet<const Font*>* fallbackFonts, GlyphOverflow*, const RenderStyle&) const;
222     bool computeUseBackslashAsYenSymbol() const;
223
224     void secureText(UChar mask);
225
226     LayoutRect collectSelectionRectsForLineBoxes(const RenderLayerModelObject* repaintContainer, bool clipToVisibleContent, Vector<LayoutRect>*);
227     bool computeCanUseSimplifiedTextMeasuring() const;
228
229     void node() const = delete;
230     void container() const = delete; // Use parent() instead.
231     void container(const RenderLayerModelObject&, bool&) const = delete; // Use parent() instead.
232
233     // We put the bitfield first to minimize padding on 64-bit.
234     unsigned m_hasBreakableChar : 1; // Whether or not we can be broken into multiple lines.
235     unsigned m_hasBreak : 1; // Whether or not we have a hard break (e.g., <pre> with '\n').
236     unsigned m_hasTab : 1; // Whether or not we have a variable width tab character (e.g., <pre> with '\t').
237     unsigned m_hasBeginWS : 1; // Whether or not we begin with WS (only true if we aren't pre)
238     unsigned m_hasEndWS : 1; // Whether or not we end with WS (only true if we aren't pre)
239     unsigned m_linesDirty : 1; // This bit indicates that the text run has already dirtied specific
240                            // line boxes, and this hint will enable layoutInlineChildren to avoid
241                            // just dirtying everything when character data is modified (e.g., appended/inserted
242                            // or removed).
243     unsigned m_containsReversedText : 1;
244     unsigned m_isAllASCII : 1;
245     unsigned m_canUseSimpleFontCodePath : 1;
246     mutable unsigned m_knownToHaveNoOverflowAndNoFallbackFonts : 1;
247     unsigned m_useBackslashAsYenSymbol : 1;
248     unsigned m_originalTextDiffersFromRendered : 1;
249     unsigned m_hasInlineWrapperForDisplayContents : 1;
250     unsigned m_canUseSimplifiedTextMeasuring : 1;
251
252 #if ENABLE(TEXT_AUTOSIZING)
253     // FIXME: This should probably be part of the text sizing structures in Document instead. That would save some memory.
254     float m_candidateComputedTextSize { 0 };
255 #endif
256     float m_minWidth { -1 };
257     float m_maxWidth { -1 };
258     float m_beginMinWidth { 0 };
259     float m_endMinWidth { 0 };
260
261     String m_text;
262 };
263
264 String applyTextTransform(const RenderStyle&, const String&, UChar previousCharacter);
265 String capitalize(const String&, UChar previousCharacter);
266 LineBreakIteratorMode mapLineBreakToIteratorMode(LineBreak);
267
268 inline UChar RenderText::characterAt(unsigned i) const
269 {
270     return i >= length() ? 0 : text()[i];
271 }
272
273 inline const RenderStyle& RenderText::style() const
274 {
275     return parent()->style();
276 }
277
278 inline const RenderStyle& RenderText::firstLineStyle() const
279 {
280     return parent()->firstLineStyle();
281 }
282
283 inline const RenderStyle* RenderText::getCachedPseudoStyle(PseudoId pseudoId, const RenderStyle* parentStyle) const
284 {
285     return parent()->getCachedPseudoStyle(pseudoId, parentStyle);
286 }
287
288 inline Color RenderText::selectionBackgroundColor() const
289 {
290     return parent()->selectionBackgroundColor();
291 }
292
293 inline Color RenderText::selectionForegroundColor() const
294 {
295     return parent()->selectionForegroundColor();
296 }
297
298 inline Color RenderText::selectionEmphasisMarkColor() const
299 {
300     return parent()->selectionEmphasisMarkColor();
301 }
302
303 inline std::unique_ptr<RenderStyle> RenderText::selectionPseudoStyle() const
304 {
305     return parent()->selectionPseudoStyle();
306 }
307
308 inline RenderText* Text::renderer() const
309 {
310     return downcast<RenderText>(Node::renderer());
311 }
312
313 } // namespace WebCore
314
315 SPECIALIZE_TYPE_TRAITS_RENDER_OBJECT(RenderText, isText())