4ea743304001d4d0a7149055bb734bdf891877d0
[WebKit-https.git] / Source / WebCore / layout / inlineformatting / textlayout / Runs.h
1 /*
2  * Copyright (C) 2018 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 #if ENABLE(LAYOUT_FORMATTING_CONTEXT)
29
30 #include "TextFlags.h"
31
32 namespace WebCore {
33 namespace Layout {
34
35 using ContentPosition = unsigned;
36 using ItemPosition = unsigned;
37
38 struct TextRun {
39 public:
40     enum class Type {
41         Whitespace,
42         NonWhitespace,
43         SoftLineBreak,
44         HardLineBreak,
45         Invalid
46     };
47     static TextRun createWhitespaceRun(ContentPosition start, ContentPosition end, float width, bool isCollapsed);
48     static TextRun createNonWhitespaceRun(ContentPosition start, ContentPosition end, float width);
49     static TextRun createSoftLineBreakRun(ContentPosition);
50     static TextRun createHardLineBreakRun(ContentPosition);
51
52     TextRun() = default;
53     TextRun(ContentPosition start, ContentPosition end, Type, float width = 0, bool isCollapsed = false);
54
55     ContentPosition start() const;
56     ContentPosition end() const;
57     unsigned length() const;
58
59     float width() const;
60
61     bool isWhitespace() const { return m_type == Type::Whitespace; }
62     bool isNonWhitespace() const { return m_type == Type::NonWhitespace; }
63     bool isLineBreak() const { return isSoftLineBreak() || isHardLineBreak(); }
64     bool isSoftLineBreak() const { return m_type == Type::SoftLineBreak; }
65     bool isHardLineBreak() const { return m_type == Type::HardLineBreak; }
66     bool isValid() const { return m_type != Type::Invalid; }
67     bool isCollapsed() const { return m_isCollapsed; }
68     Type type() const { return m_type; }
69
70     void setIsCollapsed(bool isCollapsed) { m_isCollapsed = isCollapsed; }
71     void setWidth(float width) { m_width = width; }
72
73 private:
74     ContentPosition m_start { 0 };
75     ContentPosition m_end { 0 };
76     Type m_type { Type::Invalid };
77     float m_width { 0 };
78     bool m_isCollapsed { false };
79 };
80
81 struct LayoutRun {
82 public:
83     LayoutRun(ContentPosition start, ContentPosition end, float left, float right);
84
85     ContentPosition start() const { return m_start; }
86     ContentPosition end() const { return m_end; }
87     unsigned length() const { return end() - start(); }
88
89     float left() const { return m_left; }
90     float right() const { return m_right; }
91     float width() const { return right() - left(); }
92
93     bool isEndOfLine() const { return m_isEndOfLine; }
94
95     void setEnd(ContentPosition end) { m_end = end; }
96     void setLeft(float left) { m_left = left; }
97     void setRight(float right) { m_right = right; }
98     void setIsEndOfLine() { m_isEndOfLine = true; }
99
100     void setExpansion(ExpansionBehavior, float expansion);
101
102 private:
103     ContentPosition m_start { 0 };
104     ContentPosition m_end { 0 };
105     float m_left { 0 };
106     float m_right { 0 };
107     bool m_isEndOfLine { false };
108     float m_expansion { 0 };
109     ExpansionBehavior m_expansionBehavior { ForbidLeadingExpansion | ForbidTrailingExpansion };
110 };
111
112 template<typename T>
113 class ConstVectorIterator {
114 public:
115     ConstVectorIterator(const Vector<T>&);
116
117     const T* current() const;
118     ConstVectorIterator<T>& operator++();
119     void reset() { m_index = 0; }
120
121 private:
122     const Vector<T>& m_content;
123     unsigned m_index { 0 };
124 };
125
126 template<typename T>
127 inline ConstVectorIterator<T>::ConstVectorIterator(const Vector<T>& content)
128     : m_content(content)
129 {
130 }
131
132 template<typename T>
133 inline const T* ConstVectorIterator<T>::current() const
134 {
135     if (m_index == m_content.size())
136         return nullptr;
137     return &m_content[m_index];
138 }
139
140 template<typename T>
141 inline ConstVectorIterator<T>& ConstVectorIterator<T>::operator++()
142 {
143     ++m_index;
144     return *this;
145 }
146
147 inline LayoutRun::LayoutRun(ContentPosition start, ContentPosition end, float left, float right)
148     : m_start(start)
149     , m_end(end)
150     , m_left(left)
151     , m_right(right)
152 {
153 }
154
155 inline void LayoutRun::setExpansion(ExpansionBehavior expansionBehavior, float expansion)
156 {
157     m_expansionBehavior = expansionBehavior;
158     m_expansion = expansion;
159 }
160
161 inline TextRun TextRun::createWhitespaceRun(ContentPosition start, ContentPosition end, float width, bool isCollapsed)
162 {
163     return { start, end, Type::Whitespace, width, isCollapsed };
164 }
165
166 inline TextRun TextRun::createNonWhitespaceRun(ContentPosition start, ContentPosition end, float width)
167 {
168     return { start, end, Type::NonWhitespace, width };
169 }
170
171 inline TextRun TextRun::createSoftLineBreakRun(ContentPosition position)
172 {
173     return { position, position + 1, Type::SoftLineBreak };
174 }
175
176 inline TextRun TextRun::createHardLineBreakRun(ContentPosition position)
177 {
178     return { position, position, Type::HardLineBreak };
179 }
180
181 inline TextRun::TextRun(ContentPosition start, ContentPosition end, Type type, float width, bool isCollapsed)
182     : m_start(start)
183     , m_end(end)
184     , m_type(type)
185     , m_width(width)
186     , m_isCollapsed(isCollapsed)
187 {
188 }
189
190 inline ContentPosition TextRun::start() const
191 {
192     ASSERT(type() != Type::Invalid);
193     return m_start;
194 }
195
196 inline ContentPosition TextRun::end() const
197 {
198     ASSERT(type() != Type::Invalid);
199     return m_end;
200 }
201
202 inline unsigned TextRun::length() const
203 {
204     ASSERT(type() != Type::Invalid);
205     return m_end - m_start;
206 }
207
208 inline float TextRun::width() const
209 {
210     ASSERT(type() != Type::Invalid);
211     return m_width;
212 }
213
214 }
215 }
216 #endif