/work/obj-fuzz/dist/include/mozilla/TextRange.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
2 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
3 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
4 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
5 | | |
6 | | #ifndef mozilla_TextRage_h_ |
7 | | #define mozilla_TextRage_h_ |
8 | | |
9 | | #include <stdint.h> |
10 | | |
11 | | #include "mozilla/EventForwards.h" |
12 | | |
13 | | #include "nsColor.h" |
14 | | #include "nsISelectionController.h" |
15 | | #include "nsITextInputProcessor.h" |
16 | | #include "nsStyleConsts.h" |
17 | | #include "nsTArray.h" |
18 | | |
19 | | namespace mozilla { |
20 | | |
21 | | /****************************************************************************** |
22 | | * mozilla::TextRangeStyle |
23 | | ******************************************************************************/ |
24 | | |
25 | | struct TextRangeStyle |
26 | | { |
27 | | enum |
28 | | { |
29 | | LINESTYLE_NONE = NS_STYLE_TEXT_DECORATION_STYLE_NONE, |
30 | | LINESTYLE_SOLID = NS_STYLE_TEXT_DECORATION_STYLE_SOLID, |
31 | | LINESTYLE_DOTTED = NS_STYLE_TEXT_DECORATION_STYLE_DOTTED, |
32 | | LINESTYLE_DASHED = NS_STYLE_TEXT_DECORATION_STYLE_DASHED, |
33 | | LINESTYLE_DOUBLE = NS_STYLE_TEXT_DECORATION_STYLE_DOUBLE, |
34 | | LINESTYLE_WAVY = NS_STYLE_TEXT_DECORATION_STYLE_WAVY |
35 | | }; |
36 | | |
37 | | enum |
38 | | { |
39 | | DEFINED_NONE = 0x00, |
40 | | DEFINED_LINESTYLE = 0x01, |
41 | | DEFINED_FOREGROUND_COLOR = 0x02, |
42 | | DEFINED_BACKGROUND_COLOR = 0x04, |
43 | | DEFINED_UNDERLINE_COLOR = 0x08 |
44 | | }; |
45 | | |
46 | | // Initialize all members, because TextRange instances may be compared by |
47 | | // memcomp. |
48 | | TextRangeStyle() |
49 | 0 | { |
50 | 0 | Clear(); |
51 | 0 | } |
52 | | |
53 | | void Clear() |
54 | 0 | { |
55 | 0 | mDefinedStyles = DEFINED_NONE; |
56 | 0 | mLineStyle = LINESTYLE_NONE; |
57 | 0 | mIsBoldLine = false; |
58 | 0 | mForegroundColor = mBackgroundColor = mUnderlineColor = NS_RGBA(0, 0, 0, 0); |
59 | 0 | } |
60 | | |
61 | 0 | bool IsDefined() const { return mDefinedStyles != DEFINED_NONE; } |
62 | | |
63 | | bool IsLineStyleDefined() const |
64 | 0 | { |
65 | 0 | return (mDefinedStyles & DEFINED_LINESTYLE) != 0; |
66 | 0 | } |
67 | | |
68 | | bool IsForegroundColorDefined() const |
69 | 0 | { |
70 | 0 | return (mDefinedStyles & DEFINED_FOREGROUND_COLOR) != 0; |
71 | 0 | } |
72 | | |
73 | | bool IsBackgroundColorDefined() const |
74 | 0 | { |
75 | 0 | return (mDefinedStyles & DEFINED_BACKGROUND_COLOR) != 0; |
76 | 0 | } |
77 | | |
78 | | bool IsUnderlineColorDefined() const |
79 | 0 | { |
80 | 0 | return (mDefinedStyles & DEFINED_UNDERLINE_COLOR) != 0; |
81 | 0 | } |
82 | | |
83 | | bool IsNoChangeStyle() const |
84 | 0 | { |
85 | 0 | return !IsForegroundColorDefined() && !IsBackgroundColorDefined() && |
86 | 0 | IsLineStyleDefined() && mLineStyle == LINESTYLE_NONE; |
87 | 0 | } |
88 | | |
89 | | bool Equals(const TextRangeStyle& aOther) const |
90 | 0 | { |
91 | 0 | if (mDefinedStyles != aOther.mDefinedStyles) |
92 | 0 | return false; |
93 | 0 | if (IsLineStyleDefined() && (mLineStyle != aOther.mLineStyle || |
94 | 0 | !mIsBoldLine != !aOther.mIsBoldLine)) |
95 | 0 | return false; |
96 | 0 | if (IsForegroundColorDefined() && |
97 | 0 | (mForegroundColor != aOther.mForegroundColor)) |
98 | 0 | return false; |
99 | 0 | if (IsBackgroundColorDefined() && |
100 | 0 | (mBackgroundColor != aOther.mBackgroundColor)) |
101 | 0 | return false; |
102 | 0 | if (IsUnderlineColorDefined() && |
103 | 0 | (mUnderlineColor != aOther.mUnderlineColor)) |
104 | 0 | return false; |
105 | 0 | return true; |
106 | 0 | } |
107 | | |
108 | | bool operator !=(const TextRangeStyle &aOther) const |
109 | 0 | { |
110 | 0 | return !Equals(aOther); |
111 | 0 | } |
112 | | |
113 | | bool operator ==(const TextRangeStyle &aOther) const |
114 | 0 | { |
115 | 0 | return Equals(aOther); |
116 | 0 | } |
117 | | |
118 | | uint8_t mDefinedStyles; |
119 | | uint8_t mLineStyle; // DEFINED_LINESTYLE |
120 | | |
121 | | bool mIsBoldLine; // DEFINED_LINESTYLE |
122 | | |
123 | | nscolor mForegroundColor; // DEFINED_FOREGROUND_COLOR |
124 | | nscolor mBackgroundColor; // DEFINED_BACKGROUND_COLOR |
125 | | nscolor mUnderlineColor; // DEFINED_UNDERLINE_COLOR |
126 | | }; |
127 | | |
128 | | /****************************************************************************** |
129 | | * mozilla::TextRange |
130 | | ******************************************************************************/ |
131 | | |
132 | | enum class TextRangeType : RawTextRangeType |
133 | | { |
134 | | eUninitialized = 0x00, |
135 | | eCaret = 0x01, |
136 | | eRawClause = nsITextInputProcessor::ATTR_RAW_CLAUSE, |
137 | | eSelectedRawClause = nsITextInputProcessor::ATTR_SELECTED_RAW_CLAUSE, |
138 | | eConvertedClause = nsITextInputProcessor::ATTR_CONVERTED_CLAUSE, |
139 | | eSelectedClause = nsITextInputProcessor::ATTR_SELECTED_CLAUSE |
140 | | }; |
141 | | |
142 | | bool IsValidRawTextRangeValue(RawTextRangeType aRawTextRangeValue); |
143 | | RawTextRangeType ToRawTextRangeType(TextRangeType aTextRangeType); |
144 | | TextRangeType ToTextRangeType(RawTextRangeType aRawTextRangeType); |
145 | | const char* ToChar(TextRangeType aTextRangeType); |
146 | | SelectionType ToSelectionType(TextRangeType aTextRangeType); |
147 | | |
148 | | struct TextRange |
149 | | { |
150 | | TextRange() |
151 | | : mStartOffset(0) |
152 | | , mEndOffset(0) |
153 | | , mRangeType(TextRangeType::eUninitialized) |
154 | 0 | { |
155 | 0 | } |
156 | | |
157 | | uint32_t mStartOffset; |
158 | | // XXX Storing end offset makes the initializing code very complicated. |
159 | | // We should replace it with mLength. |
160 | | uint32_t mEndOffset; |
161 | | |
162 | | TextRangeStyle mRangeStyle; |
163 | | |
164 | | TextRangeType mRangeType; |
165 | | |
166 | 0 | uint32_t Length() const { return mEndOffset - mStartOffset; } |
167 | | |
168 | | bool IsClause() const |
169 | 0 | { |
170 | 0 | return mRangeType != TextRangeType::eCaret; |
171 | 0 | } |
172 | | |
173 | | bool Equals(const TextRange& aOther) const |
174 | 0 | { |
175 | 0 | return mStartOffset == aOther.mStartOffset && |
176 | 0 | mEndOffset == aOther.mEndOffset && |
177 | 0 | mRangeType == aOther.mRangeType && |
178 | 0 | mRangeStyle == aOther.mRangeStyle; |
179 | 0 | } |
180 | | |
181 | | void RemoveCharacter(uint32_t aOffset) |
182 | 0 | { |
183 | 0 | if (mStartOffset > aOffset) { |
184 | 0 | --mStartOffset; |
185 | 0 | --mEndOffset; |
186 | 0 | } else if (mEndOffset > aOffset) { |
187 | 0 | --mEndOffset; |
188 | 0 | } |
189 | 0 | } |
190 | | }; |
191 | | |
192 | | /****************************************************************************** |
193 | | * mozilla::TextRangeArray |
194 | | ******************************************************************************/ |
195 | | class TextRangeArray final : public AutoTArray<TextRange, 10> |
196 | | { |
197 | | friend class WidgetCompositionEvent; |
198 | | |
199 | 0 | ~TextRangeArray() {} |
200 | | |
201 | | NS_INLINE_DECL_REFCOUNTING(TextRangeArray) |
202 | | |
203 | | const TextRange* GetTargetClause() const |
204 | 0 | { |
205 | 0 | for (uint32_t i = 0; i < Length(); ++i) { |
206 | 0 | const TextRange& range = ElementAt(i); |
207 | 0 | if (range.mRangeType == TextRangeType::eSelectedRawClause || |
208 | 0 | range.mRangeType == TextRangeType::eSelectedClause) { |
209 | 0 | return ⦥ |
210 | 0 | } |
211 | 0 | } |
212 | 0 | return nullptr; |
213 | 0 | } |
214 | | |
215 | | // Returns target clause offset. If there are selected clauses, this returns |
216 | | // the first selected clause offset. Otherwise, 0. |
217 | | uint32_t TargetClauseOffset() const |
218 | 0 | { |
219 | 0 | const TextRange* range = GetTargetClause(); |
220 | 0 | return range ? range->mStartOffset : 0; |
221 | 0 | } |
222 | | |
223 | | // Returns target clause length. If there are selected clauses, this returns |
224 | | // the first selected clause length. Otherwise, UINT32_MAX. |
225 | | uint32_t TargetClauseLength() const |
226 | 0 | { |
227 | 0 | const TextRange* range = GetTargetClause(); |
228 | 0 | return range ? range->Length() : UINT32_MAX; |
229 | 0 | } |
230 | | |
231 | | public: |
232 | | bool IsComposing() const |
233 | 0 | { |
234 | 0 | for (uint32_t i = 0; i < Length(); ++i) { |
235 | 0 | if (ElementAt(i).IsClause()) { |
236 | 0 | return true; |
237 | 0 | } |
238 | 0 | } |
239 | 0 | return false; |
240 | 0 | } |
241 | | |
242 | | bool Equals(const TextRangeArray& aOther) const |
243 | 0 | { |
244 | 0 | size_t len = Length(); |
245 | 0 | if (len != aOther.Length()) { |
246 | 0 | return false; |
247 | 0 | } |
248 | 0 | for (size_t i = 0; i < len; i++) { |
249 | 0 | if (!ElementAt(i).Equals(aOther.ElementAt(i))) { |
250 | 0 | return false; |
251 | 0 | } |
252 | 0 | } |
253 | 0 | return true; |
254 | 0 | } |
255 | | |
256 | | void RemoveCharacter(uint32_t aOffset) |
257 | 0 | { |
258 | 0 | for (size_t i = 0, len = Length(); i < len; i++) { |
259 | 0 | ElementAt(i).RemoveCharacter(aOffset); |
260 | 0 | } |
261 | 0 | } |
262 | | |
263 | | bool HasCaret() const |
264 | 0 | { |
265 | 0 | for (const TextRange& range : *this) { |
266 | 0 | if (range.mRangeType == TextRangeType::eCaret) { |
267 | 0 | return true; |
268 | 0 | } |
269 | 0 | } |
270 | 0 | return false; |
271 | 0 | } |
272 | | |
273 | | bool HasClauses() const |
274 | 0 | { |
275 | 0 | for (const TextRange& range : *this) { |
276 | 0 | if (range.IsClause()) { |
277 | 0 | return true; |
278 | 0 | } |
279 | 0 | } |
280 | 0 | return false; |
281 | 0 | } |
282 | | |
283 | | uint32_t GetCaretPosition() const |
284 | 0 | { |
285 | 0 | for (const TextRange& range : *this) { |
286 | 0 | if (range.mRangeType == TextRangeType::eCaret) { |
287 | 0 | return range.mStartOffset; |
288 | 0 | } |
289 | 0 | } |
290 | 0 | return UINT32_MAX; |
291 | 0 | } |
292 | | |
293 | | const TextRange* GetFirstClause() const |
294 | 0 | { |
295 | 0 | for (const TextRange& range : *this) { |
296 | 0 | // Look for the range of a clause whose start offset is 0 because the |
297 | 0 | // first clause's start offset is always 0. |
298 | 0 | if (range.IsClause() && !range.mStartOffset) { |
299 | 0 | return ⦥ |
300 | 0 | } |
301 | 0 | } |
302 | 0 | MOZ_ASSERT(!HasClauses()); |
303 | 0 | return nullptr; |
304 | 0 | } |
305 | | }; |
306 | | |
307 | | } // namespace mozilla |
308 | | |
309 | | #endif // mozilla_TextRage_h_ |