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