Simple line layout: Split fragments on renderer boundary on the fly.
[WebKit-https.git] / Source / WebCore / rendering / SimpleLineLayout.cpp
1 /*
2  * Copyright (C) 2013 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "SimpleLineLayout.h"
28
29 #include "FontCache.h"
30 #include "Frame.h"
31 #include "GraphicsContext.h"
32 #include "HTMLTextFormControlElement.h"
33 #include "HitTestLocation.h"
34 #include "HitTestRequest.h"
35 #include "HitTestResult.h"
36 #include "InlineTextBox.h"
37 #include "LineWidth.h"
38 #include "PaintInfo.h"
39 #include "RenderBlockFlow.h"
40 #include "RenderChildIterator.h"
41 #include "RenderStyle.h"
42 #include "RenderText.h"
43 #include "RenderTextControl.h"
44 #include "RenderView.h"
45 #include "Settings.h"
46 #include "SimpleLineLayoutFlowContents.h"
47 #include "SimpleLineLayoutFunctions.h"
48 #include "SimpleLineLayoutTextFragmentIterator.h"
49 #include "Text.h"
50 #include "TextPaintStyle.h"
51
52 namespace WebCore {
53 namespace SimpleLineLayout {
54
55 template <typename CharacterType>
56 static bool canUseForText(const CharacterType* text, unsigned length, const Font& font)
57 {
58     // FIXME: <textarea maxlength=0> generates empty text node.
59     if (!length)
60         return false;
61     for (unsigned i = 0; i < length; ++i) {
62         UChar character = text[i];
63         if (character == ' ')
64             continue;
65
66         // These would be easy to support.
67         if (character == noBreakSpace)
68             return false;
69         if (character == softHyphen)
70             return false;
71
72         UCharDirection direction = u_charDirection(character);
73         if (direction == U_RIGHT_TO_LEFT || direction == U_RIGHT_TO_LEFT_ARABIC
74             || direction == U_RIGHT_TO_LEFT_EMBEDDING || direction == U_RIGHT_TO_LEFT_OVERRIDE
75             || direction == U_LEFT_TO_RIGHT_EMBEDDING || direction == U_LEFT_TO_RIGHT_OVERRIDE
76             || direction == U_POP_DIRECTIONAL_FORMAT || direction == U_BOUNDARY_NEUTRAL)
77             return false;
78
79         if (!font.glyphForCharacter(character))
80             return false;
81     }
82     return true;
83 }
84
85 static bool canUseForText(const RenderText& textRenderer, const Font& font)
86 {
87     if (textRenderer.is8Bit())
88         return canUseForText(textRenderer.characters8(), textRenderer.textLength(), font);
89     return canUseForText(textRenderer.characters16(), textRenderer.textLength(), font);
90 }
91
92 bool canUseFor(const RenderBlockFlow& flow)
93 {
94     if (!flow.frame().settings().simpleLineLayoutEnabled())
95         return false;
96     if (!flow.firstChild())
97         return false;
98     // This currently covers <blockflow>#text</blockflow> and mutiple (sibling) RenderText cases.
99     // The <blockflow><inline>#text</inline></blockflow> case is also popular and should be relatively easy to cover.
100     for (const auto& renderer : childrenOfType<RenderObject>(flow)) {
101         if (!is<RenderText>(renderer))
102             return false;
103     }
104     if (!flow.isHorizontalWritingMode())
105         return false;
106     if (flow.flowThreadState() != RenderObject::NotInsideFlowThread)
107         return false;
108     // Printing does pagination without a flow thread.
109     if (flow.document().paginated())
110         return false;
111     if (flow.hasOutline())
112         return false;
113     if (flow.isRubyText() || flow.isRubyBase())
114         return false;
115     if (flow.parent()->isDeprecatedFlexibleBox())
116         return false;
117     // FIXME: Implementation of wrap=hard looks into lineboxes.
118     if (flow.parent()->isTextArea() && flow.parent()->element()->fastHasAttribute(HTMLNames::wrapAttr))
119         return false;
120     // FIXME: Placeholders do something strange.
121     if (is<RenderTextControl>(*flow.parent()) && downcast<RenderTextControl>(*flow.parent()).textFormControlElement().placeholderElement())
122         return false;
123     const RenderStyle& style = flow.style();
124     if (style.textDecorationsInEffect() != TextDecorationNone)
125         return false;
126     if (style.textAlign() == JUSTIFY)
127         return false;
128     // Non-visible overflow should be pretty easy to support.
129     if (style.overflowX() != OVISIBLE || style.overflowY() != OVISIBLE)
130         return false;
131     if (!style.textIndent().isZero())
132         return false;
133     if (!style.wordSpacing().isZero() || style.letterSpacing())
134         return false;
135     if (!style.isLeftToRightDirection())
136         return false;
137     if (style.lineBoxContain() != RenderStyle::initialLineBoxContain())
138         return false;
139     if (style.writingMode() != TopToBottomWritingMode)
140         return false;
141     if (style.lineBreak() != LineBreakAuto)
142         return false;
143     if (style.wordBreak() != NormalWordBreak)
144         return false;
145     if (style.unicodeBidi() != UBNormal || style.rtlOrdering() != LogicalOrder)
146         return false;
147     if (style.lineAlign() != LineAlignNone || style.lineSnap() != LineSnapNone)
148         return false;
149     if (style.hyphens() == HyphensAuto)
150         return false;
151     if (style.textEmphasisFill() != TextEmphasisFillFilled || style.textEmphasisMark() != TextEmphasisMarkNone)
152         return false;
153     if (style.textShadow())
154         return false;
155     if (style.textOverflow() || (flow.isAnonymousBlock() && flow.parent()->style().textOverflow()))
156         return false;
157     if (style.hasPseudoStyle(FIRST_LINE) || style.hasPseudoStyle(FIRST_LETTER))
158         return false;
159     if (style.hasTextCombine())
160         return false;
161     if (style.backgroundClip() == TextFillBox)
162         return false;
163     if (style.borderFit() == BorderFitLines)
164         return false;
165     if (style.lineBreak() != LineBreakAuto)
166         return false;
167 #if ENABLE(CSS_TRAILING_WORD)
168     if (style.trailingWord() != TrailingWord::Auto)
169         return false;
170 #endif
171
172     // We can't use the code path if any lines would need to be shifted below floats. This is because we don't keep per-line y coordinates.
173     if (flow.containsFloats()) {
174         float minimumWidthNeeded = std::numeric_limits<float>::max();
175         for (const auto& textRenderer : childrenOfType<RenderText>(flow)) {
176             minimumWidthNeeded = std::min(minimumWidthNeeded, textRenderer.minLogicalWidth());
177
178             for (auto& floatingObject : *flow.floatingObjectSet()) {
179                 ASSERT(floatingObject);
180 #if ENABLE(CSS_SHAPES)
181                 // if a float has a shape, we cannot tell if content will need to be shifted until after we lay it out,
182                 // since the amount of space is not uniform for the height of the float.
183                 if (floatingObject->renderer().shapeOutsideInfo())
184                     return false;
185 #endif
186                 float availableWidth = flow.availableLogicalWidthForLine(floatingObject->y(), false);
187                 if (availableWidth < minimumWidthNeeded)
188                     return false;
189             }
190         }
191     }
192     if (style.fontCascade().primaryFont().isSVGFont())
193         return false;
194     // We assume that all lines have metrics based purely on the primary font.
195     auto& primaryFont = style.fontCascade().primaryFont();
196     if (primaryFont.isLoading())
197         return false;
198     for (const auto& textRenderer : childrenOfType<RenderText>(flow)) {
199         if (textRenderer.isCombineText() || textRenderer.isCounter() || textRenderer.isQuote() || textRenderer.isTextFragment()
200             || textRenderer.isSVGInlineText())
201             return false;
202         if (style.fontCascade().codePath(TextRun(textRenderer.text())) != FontCascade::Simple)
203             return false;
204         if (!canUseForText(textRenderer, primaryFont))
205             return false;
206     }
207     return true;
208 }
209
210 static float computeLineLeft(ETextAlign textAlign, float availableWidth, float committedWidth, float logicalLeftOffset)
211 {
212     float remainingWidth = availableWidth - committedWidth;
213     float left = logicalLeftOffset;
214     switch (textAlign) {
215     case LEFT:
216     case WEBKIT_LEFT:
217     case TASTART:
218         return left;
219     case RIGHT:
220     case WEBKIT_RIGHT:
221     case TAEND:
222         return left + std::max<float>(remainingWidth, 0);
223     case CENTER:
224     case WEBKIT_CENTER:
225         return left + std::max<float>(remainingWidth / 2, 0);
226     case JUSTIFY:
227         ASSERT_NOT_REACHED();
228         break;
229     }
230     ASSERT_NOT_REACHED();
231     return 0;
232 }
233
234 static void revertRuns(Layout::RunVector& runs, unsigned length, float width)
235 {
236     while (length) {
237         ASSERT(runs.size());
238         Run& lastRun = runs.last();
239         unsigned lastRunLength = lastRun.end - lastRun.start;
240         if (lastRunLength > length) {
241             lastRun.logicalRight -= width;
242             lastRun.end -= length;
243             break;
244         }
245         length -= lastRunLength;
246         width -= (lastRun.logicalRight - lastRun.logicalLeft);
247         runs.removeLast();
248     }
249 }
250
251 class LineState {
252 public:
253     void setAvailableWidth(float width) { m_availableWidth = width; }
254     void setCollapedWhitespaceWidth(float width) { m_collapsedWhitespaceWidth = width; }
255     void setLogicalLeftOffset(float offset) { m_logicalLeftOffset = offset; }
256     void setOverflowedFragment(const TextFragmentIterator::TextFragment& fragment) { m_overflowedFragment = fragment; }
257
258     float availableWidth() const { return m_availableWidth; }
259     float logicalLeftOffset() const { return m_logicalLeftOffset; }
260     const TextFragmentIterator::TextFragment& overflowedFragment() const { return m_overflowedFragment; }
261     bool hasTrailingWhitespace() const { return m_trailingWhitespaceLength; }
262     TextFragmentIterator::TextFragment lastFragment() const { return m_fragments.last(); }
263     bool isWhitespaceOnly() const { return m_trailingWhitespaceWidth && m_runsWidth == m_trailingWhitespaceWidth; }
264     bool fits(float extra) const { return m_availableWidth >= m_runsWidth + extra; }
265     bool firstCharacterFits() const { return m_firstCharacterFits; }
266     float width() const { return m_runsWidth; }
267     bool isEmpty() const
268     {
269         if (!m_fragments.size())
270             return true;
271         if (!m_lastCompleteFragment.isEmpty())
272             return false;
273         return m_fragments.last().overlapsToNextRenderer();
274     }
275
276     void appendFragmentAndCreateRunIfNeeded(const TextFragmentIterator::TextFragment& fragment, Layout::RunVector& runs)
277     {
278         // Adjust end position while collapsing.
279         unsigned endPosition = fragment.isCollapsed() ? fragment.start() + 1 : fragment.end();
280         // New line needs new run.
281         if (!m_runsWidth)
282             runs.append(Run(fragment.start(), endPosition, m_runsWidth, m_runsWidth + fragment.width(), false));
283         else {
284             const auto& lastFragment = m_fragments.last();
285             // Advance last completed fragment when the previous fragment is all set (including multiple parts across renderers)
286             if ((lastFragment.type() != fragment.type()) || !lastFragment.overlapsToNextRenderer())
287                 m_lastCompleteFragment = lastFragment;
288             // Collapse neighbouring whitespace, if they are across multiple renderers and are not collapsed yet.
289             if (lastFragment.isCollapsible() && fragment.isCollapsible()) {
290                 ASSERT(lastFragment.isLastInRenderer());
291                 if (!lastFragment.isCollapsed()) {
292                     // Line width needs to be reset so that now it takes collapsing into consideration.
293                     m_runsWidth -= (lastFragment.width() - m_collapsedWhitespaceWidth);
294                 }
295                 // This fragment is collapsed completely. No run is needed.
296                 return;
297             }
298             if (lastFragment.isLastInRenderer() || lastFragment.isCollapsed())
299                 runs.append(Run(fragment.start(), endPosition, m_runsWidth, m_runsWidth + fragment.width(), false));
300             else {
301                 Run& lastRun = runs.last();
302                 lastRun.end = endPosition;
303                 lastRun.logicalRight += fragment.width();
304             }
305         }
306         m_fragments.append(fragment);
307         m_runsWidth += fragment.width();
308
309         if (fragment.type() == TextFragmentIterator::TextFragment::Whitespace) {
310             m_trailingWhitespaceLength += endPosition - fragment.start();
311             m_trailingWhitespaceWidth += fragment.width();
312         } else {
313             m_trailingWhitespaceLength = 0;
314             m_trailingWhitespaceWidth = 0;
315         }
316
317         if (!m_firstCharacterFits)
318             m_firstCharacterFits = fragment.start() + 1 > endPosition || m_runsWidth <= m_availableWidth;
319     }
320
321     TextFragmentIterator::TextFragment revertToLastCompleteFragment(Layout::RunVector& runs)
322     {
323         ASSERT(m_fragments.size());
324         unsigned revertLength = 0;
325         float revertWidth = 0;
326         while (m_fragments.size()) {
327             const auto& current = m_fragments.last();
328             if (current == m_lastCompleteFragment)
329                 break;
330             revertLength += current.end() - current.start();
331             revertWidth += current.width();
332             m_fragments.removeLast();
333         }
334         m_runsWidth -= revertWidth;
335         if (revertLength)
336             revertRuns(runs, revertLength, revertWidth);
337         return m_lastCompleteFragment;
338     }
339
340     void removeTrailingWhitespace(Layout::RunVector& runs)
341     {
342         // FIXME: sync m_fragment, but it's ok for now as we don't use m_fragment anymore after removeTrailingWhitespace.
343         if (!m_trailingWhitespaceLength)
344             return;
345         revertRuns(runs, m_trailingWhitespaceLength, m_trailingWhitespaceWidth);
346         m_runsWidth -= m_trailingWhitespaceWidth;
347         m_trailingWhitespaceLength = 0;
348         m_trailingWhitespaceWidth = 0;
349     }
350
351 private:
352     float m_availableWidth { 0 };
353     float m_logicalLeftOffset { 0 };
354     TextFragmentIterator::TextFragment m_overflowedFragment;
355     float m_runsWidth { 0 };
356     TextFragmentIterator::TextFragment m_lastCompleteFragment;
357     float m_trailingWhitespaceWidth { 0 }; // Use this to remove trailing whitespace without re-mesuring the text.
358     unsigned m_trailingWhitespaceLength { 0 };
359     float m_collapsedWhitespaceWidth { 0 };
360     // Having one character on the line does not necessarily mean it actually fits.
361     // First character of the first fragment might be forced on to the current line even if it does not fit.
362     bool m_firstCharacterFits { false };
363     Vector<TextFragmentIterator::TextFragment> m_fragments;
364 };
365
366 class FragmentForwardIterator : public std::iterator<std::forward_iterator_tag, unsigned> {
367 public:
368     FragmentForwardIterator(unsigned fragmentIndex)
369         : m_fragmentIndex(fragmentIndex)
370     {
371     }
372
373     FragmentForwardIterator& operator++()
374     {
375         ++m_fragmentIndex;
376         return *this;
377     }
378
379     bool operator!=(const FragmentForwardIterator& other) const { return m_fragmentIndex != other.m_fragmentIndex; }
380     unsigned operator*() const { return m_fragmentIndex; }
381
382 private:
383     unsigned m_fragmentIndex { 0 };
384 };
385
386 static FragmentForwardIterator begin(const TextFragmentIterator::TextFragment& fragment)  { return FragmentForwardIterator(fragment.start()); }
387 static FragmentForwardIterator end(const TextFragmentIterator::TextFragment& fragment)  { return FragmentForwardIterator(fragment.end()); }
388
389 static bool preWrap(const TextFragmentIterator::Style& style)
390 {
391     return style.wrapLines && !style.collapseWhitespace;
392 }
393     
394 static void removeTrailingWhitespace(LineState& lineState, Layout::RunVector& runs, const TextFragmentIterator& textFragmentIterator)
395 {
396     if (!lineState.hasTrailingWhitespace())
397         return;
398     
399     // Remove collapsed whitespace, or non-collapsed pre-wrap whitespace, unless it's the only content on the line -so removing the whitesapce would produce an empty line.
400     const auto& style = textFragmentIterator.style();
401     bool collapseWhitespace = style.collapseWhitespace | preWrap(style);
402     if (!collapseWhitespace)
403         return;
404
405     if (preWrap(style) && lineState.isWhitespaceOnly())
406         return;
407
408     lineState.removeTrailingWhitespace(runs);
409 }
410
411 static void updateLineConstrains(const RenderBlockFlow& flow, LineState& line)
412 {
413     LayoutUnit height = flow.logicalHeight();
414     LayoutUnit logicalHeight = flow.minLineHeightForReplacedRenderer(false, 0);
415     float logicalRightOffset = flow.logicalRightOffsetForLine(height, false, logicalHeight);
416     line.setLogicalLeftOffset(flow.logicalLeftOffsetForLine(height, false, logicalHeight));
417     line.setAvailableWidth(std::max<float>(0, logicalRightOffset - line.logicalLeftOffset()));
418 }
419
420 static TextFragmentIterator::TextFragment splitFragmentToFitLine(TextFragmentIterator::TextFragment& fragmentToSplit, float availableWidth, bool keepAtLeastOneCharacter, const TextFragmentIterator& textFragmentIterator)
421 {
422     // FIXME: add surrogate pair support.
423     unsigned start = fragmentToSplit.start();
424     auto it = std::upper_bound(begin(fragmentToSplit), end(fragmentToSplit), availableWidth, [&textFragmentIterator, start](float availableWidth, unsigned index) {
425         // FIXME: use the actual left position of the line (instead of 0) to calculated width. It might give false width for tab characters.
426         return availableWidth < textFragmentIterator.textWidth(start, index + 1, 0);
427     });
428     unsigned splitPosition = (*it);
429     if (keepAtLeastOneCharacter && splitPosition == fragmentToSplit.start())
430         ++splitPosition;
431     return fragmentToSplit.split(splitPosition, textFragmentIterator);
432 }
433
434 static TextFragmentIterator::TextFragment firstFragment(TextFragmentIterator& textFragmentIterator, const LineState& previousLine)
435 {
436     // Handle overflowed fragment from previous line.
437     TextFragmentIterator::TextFragment firstFragment(previousLine.overflowedFragment());
438     const auto& style = textFragmentIterator.style();
439
440     if (firstFragment.isEmpty())
441         firstFragment = textFragmentIterator.nextTextFragment();
442     else {
443         // Special overflow pre-wrap whitespace handling: ignore the overflowed whitespace if we managed to fit at least one character on the previous line.
444         // When the line is too short to fit one character (thought it still stays on the line) we continue with the overflow whitespace content on this line.
445         if (firstFragment.type() == TextFragmentIterator::TextFragment::Whitespace && preWrap(style) && previousLine.firstCharacterFits()) {
446             firstFragment = textFragmentIterator.nextTextFragment();
447             // If skipping the whitespace puts us on a hard newline, skip the newline too as we already wrapped the line.
448             if (firstFragment.type() == TextFragmentIterator::TextFragment::LineBreak)
449                 firstFragment = textFragmentIterator.nextTextFragment();
450         }
451     }
452
453     // Check if we need to skip the leading whitespace.
454     if (style.collapseWhitespace) {
455         while (firstFragment.type() == TextFragmentIterator::TextFragment::Whitespace)
456             firstFragment = textFragmentIterator.nextTextFragment();
457     }
458     return firstFragment;
459 }
460
461 static void forceFragmentToLine(LineState& line, TextFragmentIterator& textFragmentIterator, Layout::RunVector& runs, const TextFragmentIterator::TextFragment& fragment)
462 {
463     line.appendFragmentAndCreateRunIfNeeded(fragment, runs);
464     // Check if there are more fragments to add to the current line.
465     if (!fragment.overlapsToNextRenderer())
466         return;
467     auto nextFragment = textFragmentIterator.nextTextFragment();
468     while (true) {
469         if (nextFragment.type() != fragment.type())
470             break;
471         line.appendFragmentAndCreateRunIfNeeded(nextFragment, runs);
472         // Does it overlap to the next segment?
473         if (!nextFragment.overlapsToNextRenderer())
474             return;
475         nextFragment = textFragmentIterator.nextTextFragment();
476     }
477     line.setOverflowedFragment(nextFragment);
478 }
479
480 static bool createLineRuns(LineState& line, const LineState& previousLine, Layout::RunVector& runs, TextFragmentIterator& textFragmentIterator)
481 {
482     const auto& style = textFragmentIterator.style();
483     line.setCollapedWhitespaceWidth(style.spaceWidth);
484     bool lineCanBeWrapped = style.wrapLines || style.breakWordOnOverflow;
485     auto fragment = firstFragment(textFragmentIterator, previousLine);
486     while (fragment.type() != TextFragmentIterator::TextFragment::ContentEnd) {
487         // Hard linebreak.
488         if (fragment.type() == TextFragmentIterator::TextFragment::LineBreak) {
489             // Add the new line fragment only if there's nothing on the line. (otherwise the extra new line character would show up at the end of the content.)
490             if (!line.width())
491                 line.appendFragmentAndCreateRunIfNeeded(fragment, runs);
492             break;
493         }
494         if (lineCanBeWrapped && !line.fits(fragment.width())) {
495             // Overflow wrapping behaviour:
496             // 1. Whitesapce collapse on: whitespace is skipped. Jump to next line.
497             // 2. Whitespace collapse off: whitespace is wrapped.
498             // 3. First, non-whitespace fragment is either wrapped or kept on the line. (depends on overflow-wrap)
499             // 4. Non-whitespace fragment when there's already another fragment on the line gets pushed to the next line.
500             bool emptyLine = line.isEmpty();
501             // Whitespace fragment.
502             if (fragment.type() == TextFragmentIterator::TextFragment::Whitespace) {
503                 if (!style.collapseWhitespace) {
504                     // Split the fragment; (modified)fragment stays on this line, overflowedFragment is pushed to next line.
505                     line.setOverflowedFragment(splitFragmentToFitLine(fragment, line.availableWidth() - line.width(), emptyLine, textFragmentIterator));
506                     line.appendFragmentAndCreateRunIfNeeded(fragment, runs);
507                 }
508                 // When whitespace collapse is on, whitespace that doesn't fit is simply skipped.
509                 break;
510             }
511             // Non-whitespace fragment. (!style.wrapLines: bug138102(preserve existing behavior)
512             if ((emptyLine && style.breakWordOnOverflow) || !style.wrapLines) {
513                 // Split the fragment; (modified)fragment stays on this line, overflowedFragment is pushed to next line.
514                 line.setOverflowedFragment(splitFragmentToFitLine(fragment, line.availableWidth() - line.width(), emptyLine, textFragmentIterator));
515                 line.appendFragmentAndCreateRunIfNeeded(fragment, runs);
516                 break;
517             }
518             // Non-breakable non-whitespace first fragment. Add it to the current line. -it overflows though.
519             ASSERT(fragment.type() == TextFragmentIterator::TextFragment::NonWhitespace);
520             if (emptyLine) {
521                 forceFragmentToLine(line, textFragmentIterator, runs, fragment);
522                 break;
523             }
524             // Non-breakable non-whitespace fragment when there's already content on the line. Push it to the next line.
525             if (line.lastFragment().overlapsToNextRenderer()) {
526                 // Check if this fragment is a continuation of a previous segment. In such cases, we need to remove them all.
527                 const auto& currentFragment = line.revertToLastCompleteFragment(runs);
528                 textFragmentIterator.revertToFragment(currentFragment);
529                 break;
530             }
531             line.setOverflowedFragment(fragment);
532             break;
533         }
534         line.appendFragmentAndCreateRunIfNeeded(fragment, runs);
535         // Find the next text fragment.
536         fragment = textFragmentIterator.nextTextFragment(line.width());
537     }
538     return (fragment.type() == TextFragmentIterator::TextFragment::ContentEnd && line.overflowedFragment().isEmpty()) || line.overflowedFragment().type() == TextFragmentIterator::TextFragment::ContentEnd;
539 }
540
541 static void closeLineEndingAndAdjustRuns(LineState& line, Layout::RunVector& runs, unsigned previousRunCount, unsigned& lineCount, const TextFragmentIterator& textFragmentIterator)
542 {
543     if (previousRunCount == runs.size())
544         return;
545     ASSERT(runs.size());
546     removeTrailingWhitespace(line, runs, textFragmentIterator);
547     if (!runs.size())
548         return;
549     // Adjust runs' position by taking line's alignment into account.
550     if (float lineLogicalLeft = computeLineLeft(textFragmentIterator.style().textAlign, line.availableWidth(), line.width(), line.logicalLeftOffset())) {
551         for (unsigned i = previousRunCount; i < runs.size(); ++i) {
552             runs[i].logicalLeft += lineLogicalLeft;
553             runs[i].logicalRight += lineLogicalLeft;
554         }
555     }
556     runs.last().isEndOfLine = true;
557     ++lineCount;
558 }
559
560 static void createTextRuns(Layout::RunVector& runs, RenderBlockFlow& flow, unsigned& lineCount)
561 {
562     LayoutUnit borderAndPaddingBefore = flow.borderAndPaddingBefore();
563     LayoutUnit lineHeight = lineHeightFromFlow(flow);
564     LineState line;
565     bool isEndOfContent = false;
566     TextFragmentIterator textFragmentIterator = TextFragmentIterator(flow);
567
568     do {
569         flow.setLogicalHeight(lineHeight * lineCount + borderAndPaddingBefore);
570         LineState previousLine = line;
571         unsigned previousRunCount = runs.size();
572         line = LineState();
573         updateLineConstrains(flow, line);
574         isEndOfContent = createLineRuns(line, previousLine, runs, textFragmentIterator);
575         closeLineEndingAndAdjustRuns(line, runs, previousRunCount, lineCount, textFragmentIterator);
576     } while (!isEndOfContent);
577 }
578
579 std::unique_ptr<Layout> create(RenderBlockFlow& flow)
580 {
581     unsigned lineCount = 0;
582     Layout::RunVector runs;
583
584     createTextRuns(runs, flow, lineCount);
585     for (auto& renderer : childrenOfType<RenderObject>(flow)) {
586         ASSERT(is<RenderText>(renderer));
587         renderer.clearNeedsLayout();
588     }
589     return Layout::create(runs, lineCount);
590 }
591
592 std::unique_ptr<Layout> Layout::create(const RunVector& runVector, unsigned lineCount)
593 {
594     void* slot = WTF::fastMalloc(sizeof(Layout) + sizeof(Run) * runVector.size());
595     return std::unique_ptr<Layout>(new (NotNull, slot) Layout(runVector, lineCount));
596 }
597
598 Layout::Layout(const RunVector& runVector, unsigned lineCount)
599     : m_lineCount(lineCount)
600     , m_runCount(runVector.size())
601 {
602     memcpy(m_runs, runVector.data(), m_runCount * sizeof(Run));
603 }
604
605 }
606 }