Simple line layout: Add support for pagination.
[WebKit-https.git] / Source / WebCore / rendering / SimpleLineLayoutFunctions.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 "RenderText.h"
31 #include <wtf/text/WTFString.h>
32
33 namespace WebCore {
34
35 class HitTestLocation;
36 class HitTestRequest;
37 class HitTestResult;
38 class RenderBlockFlow;
39 struct PaintInfo;
40
41 namespace SimpleLineLayout {
42
43 LayoutUnit computeFlowHeight(const RenderBlockFlow&, const Layout&);
44 LayoutUnit computeFlowFirstLineBaseline(const RenderBlockFlow&, const Layout&);
45 LayoutUnit computeFlowLastLineBaseline(const RenderBlockFlow&, const Layout&);
46
47 void paintFlow(const RenderBlockFlow&, const Layout&, PaintInfo&, const LayoutPoint& paintOffset);
48 bool hitTestFlow(const RenderBlockFlow&, const Layout&, const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction);
49 void collectFlowOverflow(RenderBlockFlow&, const Layout&);
50
51 bool isTextRendered(const RenderText&, const Layout&);
52 bool containsCaretOffset(const RenderObject&, const Layout&, unsigned);
53 unsigned findCaretMinimumOffset(const RenderObject&, const Layout&);
54 unsigned findCaretMaximumOffset(const RenderObject&, const Layout&);
55 IntRect computeBoundingBox(const RenderObject&, const Layout&);
56 IntPoint computeFirstRunLocation(const RenderObject&, const Layout&);
57
58 Vector<IntRect> collectAbsoluteRects(const RenderObject&, const Layout&, const LayoutPoint& accumulatedOffset);
59 Vector<FloatQuad> collectAbsoluteQuads(const RenderObject&, const Layout&, bool* wasFixed);
60
61 LayoutUnit lineHeightFromFlow(const RenderBlockFlow&);
62 LayoutUnit baselineFromFlow(const RenderBlockFlow&);
63
64 #if ENABLE(TREE_DEBUGGING)
65 void showLineLayoutForFlow(const RenderBlockFlow&, const Layout&, int depth);
66 #endif
67
68 }
69
70 namespace SimpleLineLayout {
71
72 inline LayoutUnit computeFlowHeight(const RenderBlockFlow& flow, const Layout& layout)
73 {
74     auto flowHeight = lineHeightFromFlow(flow) * layout.lineCount();
75     if (!layout.isPaginated())
76         return flowHeight;
77     for (auto& strutEntry : layout.struts())
78         flowHeight += strutEntry.offset;
79     return flowHeight;
80 }
81
82 inline LayoutUnit computeFlowFirstLineBaseline(const RenderBlockFlow& flow, const Layout& layout)
83 {
84     ASSERT_UNUSED(layout, layout.lineCount());
85     return flow.borderAndPaddingBefore() + baselineFromFlow(flow);
86 }
87
88 inline LayoutUnit computeFlowLastLineBaseline(const RenderBlockFlow& flow, const Layout& layout)
89 {
90     ASSERT(layout.lineCount());
91     return flow.borderAndPaddingBefore() + lineHeightFromFlow(flow) * (layout.lineCount() - 1) + baselineFromFlow(flow);
92 }
93
94 inline unsigned findCaretMinimumOffset(const RenderText&, const Layout& layout)
95 {
96     if (!layout.runCount())
97         return 0;
98     return layout.runAt(0).start;
99 }
100
101 inline unsigned findCaretMaximumOffset(const RenderText& renderer, const Layout& layout)
102 {
103     if (!layout.runCount())
104         return renderer.textLength();
105     auto& last = layout.runAt(layout.runCount() - 1);
106     return last.end;
107 }
108
109 inline bool containsCaretOffset(const RenderText&, const Layout& layout, unsigned offset)
110 {
111     for (unsigned i = 0; i < layout.runCount(); ++i) {
112         auto& run = layout.runAt(i);
113         if (offset < run.start)
114             return false;
115         if (offset <= run.end)
116             return true;
117     }
118     return false;
119 }
120
121 inline bool isTextRendered(const RenderText&, const Layout& layout)
122 {
123     for (unsigned i = 0; i < layout.runCount(); ++i) {
124         auto& run = layout.runAt(i);
125         if (run.end > run.start)
126             return true;
127     }
128     return false;
129 }
130
131 inline LayoutUnit lineHeightFromFlow(const RenderBlockFlow& flow)
132 {
133     return flow.lineHeight(false, HorizontalLine, PositionOfInteriorLineBoxes);
134 }
135
136 inline LayoutUnit baselineFromFlow(const RenderBlockFlow& flow)
137 {
138     return flow.baselinePosition(AlphabeticBaseline, false, HorizontalLine, PositionOfInteriorLineBoxes);
139 }
140
141 }
142 }