Coverage Report

Created: 2018-09-25 14:53

/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 &range;
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 &range;
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_