Simple line layout should not be limited to RenderText.
[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
67         unsigned lineIndex() const;
68
69     private:
70         const Iterator& m_iterator;
71     };
72
73     class Iterator {
74     public:
75         Iterator(const RunResolver&, unsigned runIndex, unsigned lineIndex);
76
77         Iterator& operator++();
78
79         bool operator==(const Iterator&) const;
80         bool operator!=(const Iterator&) const;
81
82         Run operator*() const;
83
84         Iterator& advance();
85         Iterator& advanceLines(unsigned);
86
87         const RunResolver& resolver() const { return m_resolver; }
88         const SimpleLineLayout::Run& simpleRun() const;
89         unsigned lineIndex() const { return m_lineIndex; }
90
91     private:
92         const RunResolver& m_resolver;
93         unsigned m_runIndex;
94         unsigned m_lineIndex;
95     };
96
97     RunResolver(const RenderBlockFlow&, const Layout&);
98
99     Iterator begin() const;
100     Iterator end() const;
101
102     Range<Iterator> rangeForRect(const LayoutRect&) const;
103     Range<Iterator> rangeForRenderer(const RenderObject&) const;
104
105 private:
106     enum class IndexType { First, Last };
107     unsigned lineIndexForHeight(LayoutUnit, IndexType) const;
108
109     const Layout& m_layout;
110     const FlowContents m_flowContents;
111     const LayoutUnit m_lineHeight;
112     const LayoutUnit m_baseline;
113     const LayoutUnit m_borderAndPaddingBefore;
114     const float m_ascent;
115     const float m_descent;
116 };
117
118 class LineResolver {
119 public:
120     class Iterator;
121
122     class Iterator {
123     public:
124         explicit Iterator(RunResolver::Iterator);
125
126         Iterator& operator++();
127         bool operator==(const Iterator&) const;
128         bool operator!=(const Iterator&) const;
129
130         const LayoutRect operator*() const;
131
132     private:
133         RunResolver::Iterator m_runIterator;
134         LayoutRect m_rect;
135     };
136
137     LineResolver(const RenderBlockFlow&, const Layout&);
138
139     Iterator begin() const;
140     Iterator end() const;
141
142     Range<Iterator> rangeForRect(const LayoutRect&) const;
143
144 private:
145     RunResolver m_runResolver;
146 };
147
148 RunResolver runResolver(const RenderBlockFlow&, const Layout&);
149 LineResolver lineResolver(const RenderBlockFlow&, const Layout&);
150
151 inline unsigned RunResolver::Run::start() const
152 {
153     return m_iterator.simpleRun().start;
154 }
155
156 inline unsigned RunResolver::Run::end() const
157 {
158     return m_iterator.simpleRun().end;
159 }
160
161 inline unsigned RunResolver::Run::lineIndex() const
162 {
163     return m_iterator.lineIndex();
164 }
165
166 inline RunResolver::Iterator& RunResolver::Iterator::operator++()
167 {
168     return advance();
169 }
170
171 inline bool RunResolver::Iterator::operator==(const Iterator& other) const
172 {
173     ASSERT(&m_resolver == &other.m_resolver);
174     return m_runIndex == other.m_runIndex;
175 }
176
177 inline bool RunResolver::Iterator::operator!=(const Iterator& other) const
178 {
179     return !(*this == other);
180 }
181
182 inline RunResolver::Run RunResolver::Iterator::operator*() const
183 {
184     return Run(*this);
185 }
186
187 inline const SimpleLineLayout::Run& RunResolver::Iterator::simpleRun() const
188 {
189     return m_resolver.m_layout.runAt(m_runIndex);
190 }
191
192 inline RunResolver::Iterator RunResolver::begin() const
193 {
194     return Iterator(*this, 0, 0);
195 }
196
197 inline RunResolver::Iterator RunResolver::end() const
198 {
199     return Iterator(*this, m_layout.runCount(), m_layout.lineCount());
200 }
201
202 inline LineResolver::Iterator& LineResolver::Iterator::operator++()
203 {
204     m_runIterator.advanceLines(1);
205     return *this;
206 }
207
208 inline bool LineResolver::Iterator::operator==(const Iterator& other) const
209 {
210     return m_runIterator == other.m_runIterator;
211 }
212
213 inline bool LineResolver::Iterator::operator!=(const Iterator& other) const
214 {
215     return m_runIterator != other.m_runIterator;
216 }
217
218 inline LineResolver::Iterator LineResolver::begin() const
219 {
220     return Iterator(m_runResolver.begin());
221 }
222
223 inline LineResolver::Iterator LineResolver::end() const
224 {
225     return Iterator(m_runResolver.end());
226 }
227
228 inline Range<LineResolver::Iterator> LineResolver::rangeForRect(const LayoutRect& rect) const
229 {
230     auto runRange = m_runResolver.rangeForRect(rect);
231     return Range<Iterator>(Iterator(runRange.begin()), Iterator(runRange.end()));
232 }
233
234 inline RunResolver runResolver(const RenderBlockFlow& flow, const Layout& layout)
235 {
236     return RunResolver(flow, layout);
237 }
238
239 inline LineResolver lineResolver(const RenderBlockFlow& flow, const Layout& layout)
240 {
241     return LineResolver(flow, layout);
242 }
243
244 }
245 }
246
247 #endif