Bumping manifests a=b2g-bump
[gecko.git] / gfx / thebes / gfxSkipChars.h
blob6d7c1c0eda8fe07e6c36ada0315d39344868c003
1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
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/. */
6 #ifndef GFX_SKIP_CHARS_H
7 #define GFX_SKIP_CHARS_H
9 #include "nsTArray.h"
12 * gfxSkipChars is a data structure representing a list of characters that
13 * have been skipped. The initial string is called the "original string"
14 * and after skipping some characters, the result is called the "skipped string".
15 * gfxSkipChars provides efficient ways to translate between offsets in the
16 * original string and the skipped string. It is used by textrun code to keep
17 * track of offsets before and after text transformations such as whitespace
18 * compression and control code deletion.
21 /**
22 * The gfxSkipChars is represented as a sorted array of skipped ranges.
24 * A freshly-created gfxSkipChars means "all chars kept".
26 class gfxSkipChars
28 friend struct SkippedRangeStartComparator;
29 friend struct SkippedRangeOffsetComparator;
31 private:
32 class SkippedRange
34 public:
35 SkippedRange(uint32_t aOffset, uint32_t aLength, uint32_t aDelta)
36 : mOffset(aOffset), mLength(aLength), mDelta(aDelta)
37 { }
39 uint32_t Start() const
41 return mOffset;
44 uint32_t End() const
46 return mOffset + mLength;
49 uint32_t Length() const
51 return mLength;
54 uint32_t SkippedOffset() const
56 return mOffset - mDelta;
59 uint32_t Delta() const
61 return mDelta;
64 uint32_t NextDelta() const
66 return mDelta + mLength;
69 void Extend(uint32_t aChars)
71 mLength += aChars;
74 private:
75 uint32_t mOffset; // original-string offset at which we want to skip
76 uint32_t mLength; // number of skipped chars at this offset
77 uint32_t mDelta; // sum of lengths of preceding skipped-ranges
80 public:
81 gfxSkipChars()
82 : mCharCount(0)
83 { }
85 void SkipChars(uint32_t aChars)
87 NS_ASSERTION(mCharCount + aChars > mCharCount,
88 "Character count overflow");
89 uint32_t rangeCount = mRanges.Length();
90 uint32_t delta = 0;
91 if (rangeCount > 0) {
92 SkippedRange& lastRange = mRanges[rangeCount - 1];
93 if (lastRange.End() == mCharCount) {
94 lastRange.Extend(aChars);
95 mCharCount += aChars;
96 return;
98 delta = lastRange.NextDelta();
100 mRanges.AppendElement(SkippedRange(mCharCount, aChars, delta));
101 mCharCount += aChars;
104 void KeepChars(uint32_t aChars)
106 NS_ASSERTION(mCharCount + aChars > mCharCount,
107 "Character count overflow");
108 mCharCount += aChars;
111 void SkipChar()
113 SkipChars(1);
116 void KeepChar()
118 KeepChars(1);
121 void TakeFrom(gfxSkipChars* aSkipChars)
123 mRanges.SwapElements(aSkipChars->mRanges);
124 mCharCount = aSkipChars->mCharCount;
125 aSkipChars->mCharCount = 0;
128 int32_t GetOriginalCharCount() const
130 return mCharCount;
133 const SkippedRange& LastRange() const
135 // this is only valid if mRanges is non-empty; no assertion here
136 // because nsTArray will already assert if we abuse it
137 return mRanges[mRanges.Length() - 1];
140 friend class gfxSkipCharsIterator;
142 private:
143 nsTArray<SkippedRange> mRanges;
144 uint32_t mCharCount;
148 * A gfxSkipCharsIterator represents a position in the original string. It lets you
149 * map efficiently to and from positions in the string after skipped characters
150 * have been removed. You can also specify an offset that is added to all
151 * incoming original string offsets and subtracted from all outgoing original
152 * string offsets --- useful when the gfxSkipChars corresponds to something
153 * offset from the original DOM coordinates, which it often does for gfxTextRuns.
155 * The current positions (in both the original and skipped strings) are
156 * always constrained to be >= 0 and <= the string length. When the position
157 * is equal to the string length, it is at the end of the string. The current
158 * positions do not include any aOriginalStringToSkipCharsOffset.
160 * When the position in the original string corresponds to a skipped character,
161 * the skipped-characters offset is the offset of the next unskipped character,
162 * or the skipped-characters string length if there is no next unskipped character.
164 class gfxSkipCharsIterator
166 public:
168 * @param aOriginalStringToSkipCharsOffset add this to all incoming and
169 * outgoing original string offsets
171 gfxSkipCharsIterator(const gfxSkipChars& aSkipChars,
172 int32_t aOriginalStringToSkipCharsOffset,
173 int32_t aOriginalStringOffset)
174 : mSkipChars(&aSkipChars),
175 mOriginalStringOffset(0),
176 mSkippedStringOffset(0),
177 mCurrentRangeIndex(-1),
178 mOriginalStringToSkipCharsOffset(aOriginalStringToSkipCharsOffset)
180 SetOriginalOffset(aOriginalStringOffset);
183 explicit gfxSkipCharsIterator(const gfxSkipChars& aSkipChars,
184 int32_t aOriginalStringToSkipCharsOffset = 0)
185 : mSkipChars(&aSkipChars),
186 mOriginalStringOffset(0),
187 mSkippedStringOffset(0),
188 mCurrentRangeIndex(-1),
189 mOriginalStringToSkipCharsOffset(aOriginalStringToSkipCharsOffset)
192 gfxSkipCharsIterator(const gfxSkipCharsIterator& aIterator)
193 : mSkipChars(aIterator.mSkipChars),
194 mOriginalStringOffset(aIterator.mOriginalStringOffset),
195 mSkippedStringOffset(aIterator.mSkippedStringOffset),
196 mCurrentRangeIndex(aIterator.mCurrentRangeIndex),
197 mOriginalStringToSkipCharsOffset(aIterator.mOriginalStringToSkipCharsOffset)
201 * The empty constructor creates an object that is useless until it is assigned.
203 gfxSkipCharsIterator()
204 : mSkipChars(nullptr)
208 * Return true if this iterator is properly initialized and usable.
210 bool IsInitialized()
212 return mSkipChars != nullptr;
216 * Set the iterator to aOriginalStringOffset in the original string.
217 * This can efficiently move forward or backward from the current position.
218 * aOriginalStringOffset is clamped to [0,originalStringLength].
220 void SetOriginalOffset(int32_t aOriginalStringOffset);
223 * Set the iterator to aSkippedStringOffset in the skipped string.
224 * This can efficiently move forward or backward from the current position.
225 * aSkippedStringOffset is clamped to [0,skippedStringLength].
227 void SetSkippedOffset(uint32_t aSkippedStringOffset);
229 uint32_t ConvertOriginalToSkipped(int32_t aOriginalStringOffset)
231 SetOriginalOffset(aOriginalStringOffset);
232 return GetSkippedOffset();
235 uint32_t ConvertSkippedToOriginal(int32_t aSkippedStringOffset)
237 SetSkippedOffset(aSkippedStringOffset);
238 return GetOriginalOffset();
242 * Test if the character at the current position in the original string
243 * is skipped or not. If aRunLength is non-null, then *aRunLength is set
244 * to a number of characters all of which are either skipped or not, starting
245 * at this character. When the current position is at the end of the original
246 * string, we return true and *aRunLength is set to zero.
248 bool IsOriginalCharSkipped(int32_t* aRunLength = nullptr) const;
250 void AdvanceOriginal(int32_t aDelta)
252 SetOriginalOffset(GetOriginalOffset() + aDelta);
255 void AdvanceSkipped(int32_t aDelta)
257 SetSkippedOffset(GetSkippedOffset() + aDelta);
261 * @return the offset within the original string
263 int32_t GetOriginalOffset() const
265 return mOriginalStringOffset - mOriginalStringToSkipCharsOffset;
269 * @return the offset within the skipped string corresponding to the
270 * current position in the original string. If the current position
271 * in the original string is a character that is skipped, then we return
272 * the position corresponding to the first non-skipped character in the
273 * original string after the current position, or the length of the skipped
274 * string if there is no such character.
276 uint32_t GetSkippedOffset() const
278 return mSkippedStringOffset;
281 int32_t GetOriginalEnd() const
283 return mSkipChars->GetOriginalCharCount() -
284 mOriginalStringToSkipCharsOffset;
287 private:
288 const gfxSkipChars* mSkipChars;
290 // Current position
291 int32_t mOriginalStringOffset;
292 uint32_t mSkippedStringOffset;
294 // Index of the last skippedRange that precedes or contains the current
295 // position in the original string.
296 // If index == -1 then we are before the first skipped char.
297 int32_t mCurrentRangeIndex;
299 // This offset is added to map from "skipped+unskipped characters in
300 // the original DOM string" character space to "skipped+unskipped
301 // characters in the textrun's gfxSkipChars" character space
302 int32_t mOriginalStringToSkipCharsOffset;
305 #endif /*GFX_SKIP_CHARS_H*/