Simple line layout(regression): Calling innerText on RenderFlow with multiple childre...
[WebKit-https.git] / Source / WebCore / rendering / SimpleLineLayoutResolver.h
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 #ifndef SimpleLineLayoutResolver_h
27 #define SimpleLineLayoutResolver_h
28
29 #include "LayoutRect.h"
30 #include "RenderBlockFlow.h"
31 #include "SimpleLineLayoutFlowContents.h"
32 #include "SimpleLineLayoutFunctions.h"
33 #include <wtf/Vector.h>
34 #include <wtf/text/WTFString.h>
35
36 namespace WebCore {
37 namespace SimpleLineLayout {
38
39 template <class IteratorType>
40 class Range {
41 public:
42     Range(IteratorType begin, IteratorType end) : m_begin(begin), m_end(end) { }
43
44     IteratorType begin() const { return m_begin; }
45     IteratorType end() const { return m_end; }
46
47 private:
48     IteratorType m_begin;
49     IteratorType m_end;
50 };
51
52 class RunResolver {
53 public:
54     class Iterator;
55
56     class Run {
57     public:
58         explicit Run(const Iterator&);
59
60         unsigned start() const;
61         unsigned end() const;
62
63         LayoutRect rect() const;
64         FloatPoint baseline() const;
65         StringView text() const;
66         bool isEndOfLine() const;
67
68         unsigned lineIndex() const;
69
70     private:
71         const Iterator& m_iterator;
72     };
73
74     class Iterator {
75     friend class Run;
76     friend class RunResolver;
77     friend class LineResolver;
78     public:
79         Iterator(const RunResolver&, unsigned runIndex, unsigned lineIndex);
80
81         Iterator& operator++();
82
83         bool operator==(const Iterator&) const;
84         bool operator!=(const Iterator&) const;
85
86         Run operator*() const;
87
88     private:
89         const SimpleLineLayout::Run& simpleRun() const;
90         unsigned lineIndex() const { return m_lineIndex; }
91         Iterator& advance();
92         Iterator& advanceLines(unsigned);
93         const RunResolver& resolver() const { return m_resolver; }
94
95         const RunResolver& m_resolver;
96         unsigned m_runIndex;
97         unsigned m_lineIndex;
98     };
99
100     RunResolver(const RenderBlockFlow&, const Layout&);
101
102     const RenderBlockFlow& flow() const { return m_flowRenderer; }
103     Iterator begin() const;
104     Iterator end() const;
105
106     Range<Iterator> rangeForRect(const LayoutRect&) const;
107     Range<Iterator> rangeForRenderer(const RenderObject&) const;
108
109 private:
110     enum class IndexType { First, Last };
111     unsigned lineIndexForHeight(LayoutUnit, IndexType) const;
112
113     const RenderBlockFlow& m_flowRenderer;
114     const Layout& m_layout;
115     const FlowContents m_flowContents;
116     const LayoutUnit m_lineHeight;
117     const LayoutUnit m_baseline;
118     const LayoutUnit m_borderAndPaddingBefore;
119     const float m_ascent;
120     const float m_descent;
121 };
122
123 class LineResolver {
124 public:
125     class Iterator;
126
127     class Iterator {
128     public:
129         explicit Iterator(RunResolver::Iterator);
130
131         Iterator& operator++();
132         bool operator==(const Iterator&) const;
133         bool operator!=(const Iterator&) const;
134
135         const LayoutRect operator*() const;
136
137     private:
138         RunResolver::Iterator m_runIterator;
139         LayoutRect m_rect;
140     };
141
142     LineResolver(const RenderBlockFlow&, const Layout&);
143
144     Iterator begin() const;
145     Iterator end() const;
146
147     Range<Iterator> rangeForRect(const LayoutRect&) const;
148
149 private:
150     RunResolver m_runResolver;
151 };
152
153 RunResolver runResolver(const RenderBlockFlow&, const Layout&);
154 LineResolver lineResolver(const RenderBlockFlow&, const Layout&);
155
156 inline unsigned RunResolver::Run::start() const
157 {
158     return m_iterator.simpleRun().start;
159 }
160
161 inline unsigned RunResolver::Run::end() const
162 {
163     return m_iterator.simpleRun().end;
164 }
165
166 inline bool RunResolver::Run::isEndOfLine() const
167 {
168     return m_iterator.simpleRun().isEndOfLine;
169 }
170
171 inline unsigned RunResolver::Run::lineIndex() const
172 {
173     return m_iterator.lineIndex();
174 }
175
176 inline RunResolver::Iterator& RunResolver::Iterator::operator++()
177 {
178     return advance();
179 }
180
181 inline bool RunResolver::Iterator::operator==(const Iterator& other) const
182 {
183     ASSERT(&m_resolver == &other.m_resolver);
184     return m_runIndex == other.m_runIndex;
185 }
186
187 inline bool RunResolver::Iterator::operator!=(const Iterator& other) const
188 {
189     return !(*this == other);
190 }
191
192 inline RunResolver::Run RunResolver::Iterator::operator*() const
193 {
194     return Run(*this);
195 }
196
197 inline const SimpleLineLayout::Run& RunResolver::Iterator::simpleRun() const
198 {
199     return m_resolver.m_layout.runAt(m_runIndex);
200 }
201
202 inline RunResolver::Iterator RunResolver::begin() const
203 {
204     return Iterator(*this, 0, 0);
205 }
206
207 inline RunResolver::Iterator RunResolver::end() const
208 {
209     return Iterator(*this, m_layout.runCount(), m_layout.lineCount());
210 }
211
212 inline LineResolver::Iterator& LineResolver::Iterator::operator++()
213 {
214     m_runIterator.advanceLines(1);
215     return *this;
216 }
217
218 inline bool LineResolver::Iterator::operator==(const Iterator& other) const
219 {
220     return m_runIterator == other.m_runIterator;
221 }
222
223 inline bool LineResolver::Iterator::operator!=(const Iterator& other) const
224 {
225     return m_runIterator != other.m_runIterator;
226 }
227
228 inline LineResolver::Iterator LineResolver::begin() const
229 {
230     return Iterator(m_runResolver.begin());
231 }
232
233 inline LineResolver::Iterator LineResolver::end() const
234 {
235     return Iterator(m_runResolver.end());
236 }
237
238 inline Range<LineResolver::Iterator> LineResolver::rangeForRect(const LayoutRect& rect) const
239 {
240     auto runRange = m_runResolver.rangeForRect(rect);
241     return Range<Iterator>(Iterator(runRange.begin()), Iterator(runRange.end()));
242 }
243
244 inline RunResolver runResolver(const RenderBlockFlow& flow, const Layout& layout)
245 {
246     return RunResolver(flow, layout);
247 }
248
249 inline LineResolver lineResolver(const RenderBlockFlow& flow, const Layout& layout)
250 {
251     return LineResolver(flow, layout);
252 }
253
254 }
255 }
256
257 #endif