Simple line layout: Introduce text fragment continuation.
[WebKit-https.git] / Source / WebCore / rendering / SimpleLineLayoutFlowContents.h
1 /*
2  * Copyright (C) 2014 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 #ifndef SimpleLineLayoutFlowContents_h
27 #define SimpleLineLayoutFlowContents_h
28
29 #include "Font.h"
30 #include "RenderStyle.h"
31 #include "TextBreakIterator.h"
32 #include "break_lines.h"
33
34 namespace WebCore {
35 class RenderBlockFlow;
36
37 namespace SimpleLineLayout {
38
39 class FlowContents {
40 public:
41     FlowContents(const RenderBlockFlow&);
42
43     unsigned findNextBreakablePosition(unsigned position) const;
44     unsigned findNextNonWhitespacePosition(unsigned position, unsigned& spaceCount) const;
45
46     float textWidth(unsigned from, unsigned to, float xPosition) const;
47
48     bool isNewlineCharacter(unsigned position) const;
49     bool isEndOfContent(unsigned position) const;
50
51     bool resolveRendererPositions(const RenderText&, unsigned& startPosition, unsigned& endPosition) const;
52     const RenderText* renderer(unsigned position, unsigned* startPosition = nullptr) const;
53
54     class Style {
55     public:
56         Style(const RenderStyle& style)
57             : font(style.font())
58             , textAlign(style.textAlign())
59             , collapseWhitespace(style.collapseWhiteSpace())
60             , preserveNewline(style.preserveNewline())
61             , wrapLines(style.autoWrap())
62             , breakWordOnOverflow(style.overflowWrap() == BreakOverflowWrap && (wrapLines || preserveNewline))
63             , spaceWidth(font.width(TextRun(&space, 1)))
64             , tabWidth(collapseWhitespace ? 0 : style.tabSize())
65         {
66         }
67
68         const Font& font;
69         ETextAlign textAlign;
70         bool collapseWhitespace;
71         bool preserveNewline;
72         bool wrapLines;
73         bool breakWordOnOverflow;
74         float spaceWidth;
75         unsigned tabWidth;
76     };
77     const Style& style() const { return m_style; }
78
79 private:
80     bool appendNextRendererContentIfNeeded(unsigned position) const;
81     unsigned nextNonWhitespacePosition(unsigned position, unsigned& spaceCount) const;
82     float runWidth(const RenderText&, unsigned from, unsigned to, float xPosition) const;
83
84     const RenderBlockFlow& m_flow;
85     const Style m_style;
86     mutable LazyLineBreakIterator m_lineBreakIterator;
87     Vector<std::pair<unsigned, const RenderText*>> m_textRanges;
88     mutable unsigned m_lastRendererIndex;
89 };
90
91 inline bool FlowContents::isNewlineCharacter(unsigned position) const
92 {
93     appendNextRendererContentIfNeeded(position);
94     ASSERT(position < m_lineBreakIterator.string().length());
95     return m_lineBreakIterator.string().at(position) == '\n';
96 }
97
98 inline bool FlowContents::isEndOfContent(unsigned position) const
99 {
100     return position >= m_lineBreakIterator.string().length() && !renderer(position);
101 }
102
103 }
104 }
105
106 #endif