[ContentChangeObserver] Content observation should be limited to the current document.
[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 #pragma once
27
28 #include "LayoutRect.h"
29 #include "RenderBlockFlow.h"
30 #include "SimpleLineLayout.h"
31 #include "SimpleLineLayoutFlowContents.h"
32 #include <wtf/IteratorRange.h>
33 #include <wtf/text/WTFString.h>
34
35 namespace WebCore {
36 namespace SimpleLineLayout {
37
38 class RunResolver {
39     WTF_MAKE_FAST_ALLOCATED;
40 public:
41     class Iterator;
42
43     class Run {
44     public:
45         explicit Run(const Iterator&);
46
47         // Position relative to the enclosing flow block.
48         unsigned start() const;
49         unsigned end() const;
50         // Position relative to the actual renderer.
51         unsigned localStart() const;
52         unsigned localEnd() const;
53
54         float logicalLeft() const;
55         float logicalRight() const;
56
57         FloatRect rect() const;
58         float expansion() const;
59         ExpansionBehavior expansionBehavior() const;
60         int baselinePosition() const;
61         StringView text() const;
62         String textWithHyphen() const;
63         const RenderObject& renderer() const;
64         bool isEndOfLine() const;
65         bool hasHyphen() const { return m_iterator.simpleRun().hasHyphen; }
66         const SimpleLineLayout::Run& simpleRun() const { return m_iterator.simpleRun(); }
67
68         unsigned lineIndex() const;
69
70     private:
71         float computeBaselinePosition() const;
72         void constructStringForHyphenIfNeeded();
73
74         const Iterator& m_iterator;
75     };
76
77     class Iterator {
78     friend class Run;
79     friend class RunResolver;
80     friend class LineResolver;
81     public:
82         Iterator(const RunResolver&, unsigned runIndex, unsigned lineIndex);
83
84         Iterator& operator++();
85         Iterator& operator--();
86
87         bool operator==(const Iterator&) const;
88         bool operator!=(const Iterator&) const;
89
90         Run operator*() const;
91
92     private:
93         const SimpleLineLayout::Run& simpleRun() const;
94         unsigned lineIndex() const { return m_lineIndex; }
95         Iterator& advance();
96         Iterator& advanceLines(unsigned);
97         const RunResolver& resolver() const { return m_resolver; }
98         bool inQuirksMode() const { return m_resolver.m_inQuirksMode; }
99
100         const RunResolver& m_resolver;
101         unsigned m_runIndex;
102         unsigned m_lineIndex;
103     };
104
105     RunResolver(const RenderBlockFlow&, const Layout&);
106
107     const RenderBlockFlow& flow() const { return m_flowRenderer; }
108     const FlowContents& flowContents() const { return m_flowContents; }
109     Iterator begin() const;
110     Iterator end() const;
111
112     WTF::IteratorRange<Iterator> rangeForRect(const LayoutRect&) const;
113     WTF::IteratorRange<Iterator> rangeForRenderer(const RenderObject&) const;
114     WTF::IteratorRange<Iterator> rangeForLine(unsigned lineIndex) const;
115     Iterator runForPoint(const LayoutPoint&) const;
116     WTF::IteratorRange<Iterator> rangeForRendererWithOffsets(const RenderObject&, unsigned start, unsigned end) const;
117
118 private:
119     enum class IndexType { First, Last };
120     unsigned lineIndexForHeight(LayoutUnit, IndexType) const;
121     unsigned adjustLineIndexForStruts(LayoutUnit, IndexType, unsigned lineIndexCandidate) const;
122
123     const RenderBlockFlow& m_flowRenderer;
124     const Layout& m_layout;
125     const FlowContents m_flowContents;
126     const LayoutUnit m_lineHeight;
127     const LayoutUnit m_baseline;
128     const LayoutUnit m_borderAndPaddingBefore;
129     const float m_ascent;
130     const float m_descent;
131     const float m_visualOverflowOffset;
132     const bool m_inQuirksMode;
133 };
134
135 class LineResolver {
136 public:
137     class Iterator {
138     public:
139         explicit Iterator(RunResolver::Iterator);
140
141         Iterator& operator++();
142         bool operator==(const Iterator&) const;
143         bool operator!=(const Iterator&) const;
144
145         FloatRect operator*() const;
146         // FIXME: Use a list to support multiple renderers per line.
147         const RenderObject& renderer() const;
148
149     private:
150         RunResolver::Iterator m_runIterator;
151     };
152
153     LineResolver(const RunResolver&);
154
155     Iterator begin() const;
156     Iterator end() const;
157
158     WTF::IteratorRange<Iterator> rangeForRect(const LayoutRect&) const;
159
160 private:
161     const RunResolver& m_runResolver;
162 };
163
164 RunResolver runResolver(const RenderBlockFlow&, const Layout&);
165 LineResolver lineResolver(const RunResolver&);
166
167 inline unsigned RunResolver::Run::start() const
168 {
169     return m_iterator.simpleRun().start;
170 }
171
172 inline unsigned RunResolver::Run::end() const
173 {
174     return m_iterator.simpleRun().end;
175 }
176
177 inline float RunResolver::Run::logicalLeft() const
178 {
179     return m_iterator.simpleRun().logicalLeft;
180 }
181
182 inline float RunResolver::Run::logicalRight() const
183 {
184     return m_iterator.simpleRun().logicalRight;
185 }
186
187 inline float RunResolver::Run::expansion() const
188 {
189     return m_iterator.simpleRun().expansion;
190 }
191
192 inline ExpansionBehavior RunResolver::Run::expansionBehavior() const
193 {
194     return m_iterator.simpleRun().expansionBehavior;
195 }
196
197 inline int RunResolver::Run::baselinePosition() const
198 {
199     return roundToInt(computeBaselinePosition());
200 }
201
202 inline bool RunResolver::Run::isEndOfLine() const
203 {
204     return m_iterator.simpleRun().isEndOfLine;
205 }
206
207 inline unsigned RunResolver::Run::lineIndex() const
208 {
209     return m_iterator.lineIndex();
210 }
211
212 inline RunResolver::Iterator& RunResolver::Iterator::operator++()
213 {
214     return advance();
215 }
216
217 inline float RunResolver::Run::computeBaselinePosition() const
218 {
219     auto& resolver = m_iterator.resolver();
220     auto offset = resolver.m_borderAndPaddingBefore + resolver.m_lineHeight * lineIndex();
221     if (!resolver.m_layout.hasLineStruts())
222         return offset + resolver.m_baseline;
223     for (auto& strutEntry : resolver.m_layout.struts()) {
224         if (strutEntry.lineBreak > lineIndex())
225             break;
226         offset += strutEntry.offset;
227     }
228     return offset + resolver.m_baseline;
229 }
230
231 inline RunResolver::Iterator& RunResolver::Iterator::operator--()
232 {
233     --m_runIndex;
234     if (simpleRun().isEndOfLine)
235         --m_lineIndex;
236     return *this;
237 }
238
239 inline bool RunResolver::Iterator::operator==(const Iterator& other) const
240 {
241     ASSERT(&m_resolver == &other.m_resolver);
242     return m_runIndex == other.m_runIndex;
243 }
244
245 inline bool RunResolver::Iterator::operator!=(const Iterator& other) const
246 {
247     return !(*this == other);
248 }
249
250 inline RunResolver::Run RunResolver::Iterator::operator*() const
251 {
252     return Run(*this);
253 }
254
255 inline const SimpleLineLayout::Run& RunResolver::Iterator::simpleRun() const
256 {
257     return m_resolver.m_layout.runAt(m_runIndex);
258 }
259
260 inline RunResolver::Iterator RunResolver::begin() const
261 {
262     return Iterator(*this, 0, 0);
263 }
264
265 inline RunResolver::Iterator RunResolver::end() const
266 {
267     return Iterator(*this, m_layout.runCount(), m_layout.lineCount());
268 }
269
270 inline LineResolver::Iterator& LineResolver::Iterator::operator++()
271 {
272     m_runIterator.advanceLines(1);
273     return *this;
274 }
275
276 inline bool LineResolver::Iterator::operator==(const Iterator& other) const
277 {
278     return m_runIterator == other.m_runIterator;
279 }
280
281 inline bool LineResolver::Iterator::operator!=(const Iterator& other) const
282 {
283     return m_runIterator != other.m_runIterator;
284 }
285
286 inline LineResolver::Iterator LineResolver::begin() const
287 {
288     return Iterator(m_runResolver.begin());
289 }
290
291 inline LineResolver::Iterator LineResolver::end() const
292 {
293     return Iterator(m_runResolver.end());
294 }
295
296 inline WTF::IteratorRange<LineResolver::Iterator> LineResolver::rangeForRect(const LayoutRect& rect) const
297 {
298     auto runRange = m_runResolver.rangeForRect(rect);
299     return { Iterator(runRange.begin()), Iterator(runRange.end()) };
300 }
301
302 inline RunResolver runResolver(const RenderBlockFlow& flow, const Layout& layout)
303 {
304     return RunResolver(flow, layout);
305 }
306
307 inline LineResolver lineResolver(const RunResolver& runResolver)
308 {
309     return LineResolver(runResolver);
310 }
311
312 }
313 }