gfx/thebes/gfxSkipChars.h

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

michael@0 1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
michael@0 2 * This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #ifndef GFX_SKIP_CHARS_H
michael@0 7 #define GFX_SKIP_CHARS_H
michael@0 8
michael@0 9 #include "nsTArray.h"
michael@0 10
michael@0 11 /*
michael@0 12 * gfxSkipChars is a data structure representing a list of characters that
michael@0 13 * have been skipped. The initial string is called the "original string"
michael@0 14 * and after skipping some characters, the result is called the "skipped string".
michael@0 15 * gfxSkipChars provides efficient ways to translate between offsets in the
michael@0 16 * original string and the skipped string. It is used by textrun code to keep
michael@0 17 * track of offsets before and after text transformations such as whitespace
michael@0 18 * compression and control code deletion.
michael@0 19 */
michael@0 20
michael@0 21 /**
michael@0 22 * The gfxSkipChars is represented as a sorted array of skipped ranges.
michael@0 23 *
michael@0 24 * A freshly-created gfxSkipChars means "all chars kept".
michael@0 25 */
michael@0 26 class gfxSkipChars
michael@0 27 {
michael@0 28 private:
michael@0 29 class SkippedRange
michael@0 30 {
michael@0 31 public:
michael@0 32 SkippedRange(uint32_t aOffset, uint32_t aLength, uint32_t aDelta)
michael@0 33 : mOffset(aOffset), mLength(aLength), mDelta(aDelta)
michael@0 34 { }
michael@0 35
michael@0 36 uint32_t Start() const
michael@0 37 {
michael@0 38 return mOffset;
michael@0 39 }
michael@0 40
michael@0 41 uint32_t End() const
michael@0 42 {
michael@0 43 return mOffset + mLength;
michael@0 44 }
michael@0 45
michael@0 46 uint32_t Length() const
michael@0 47 {
michael@0 48 return mLength;
michael@0 49 }
michael@0 50
michael@0 51 uint32_t SkippedOffset() const
michael@0 52 {
michael@0 53 return mOffset - mDelta;
michael@0 54 }
michael@0 55
michael@0 56 uint32_t Delta() const
michael@0 57 {
michael@0 58 return mDelta;
michael@0 59 }
michael@0 60
michael@0 61 uint32_t NextDelta() const
michael@0 62 {
michael@0 63 return mDelta + mLength;
michael@0 64 }
michael@0 65
michael@0 66 void Extend(uint32_t aChars)
michael@0 67 {
michael@0 68 mLength += aChars;
michael@0 69 }
michael@0 70
michael@0 71 private:
michael@0 72 uint32_t mOffset; // original-string offset at which we want to skip
michael@0 73 uint32_t mLength; // number of skipped chars at this offset
michael@0 74 uint32_t mDelta; // sum of lengths of preceding skipped-ranges
michael@0 75 };
michael@0 76
michael@0 77 public:
michael@0 78 gfxSkipChars()
michael@0 79 : mCharCount(0)
michael@0 80 { }
michael@0 81
michael@0 82 void SkipChars(uint32_t aChars)
michael@0 83 {
michael@0 84 NS_ASSERTION(mCharCount + aChars > mCharCount,
michael@0 85 "Character count overflow");
michael@0 86 uint32_t rangeCount = mRanges.Length();
michael@0 87 uint32_t delta = 0;
michael@0 88 if (rangeCount > 0) {
michael@0 89 SkippedRange& lastRange = mRanges[rangeCount - 1];
michael@0 90 if (lastRange.End() == mCharCount) {
michael@0 91 lastRange.Extend(aChars);
michael@0 92 mCharCount += aChars;
michael@0 93 return;
michael@0 94 }
michael@0 95 delta = lastRange.NextDelta();
michael@0 96 }
michael@0 97 mRanges.AppendElement(SkippedRange(mCharCount, aChars, delta));
michael@0 98 mCharCount += aChars;
michael@0 99 }
michael@0 100
michael@0 101 void KeepChars(uint32_t aChars)
michael@0 102 {
michael@0 103 NS_ASSERTION(mCharCount + aChars > mCharCount,
michael@0 104 "Character count overflow");
michael@0 105 mCharCount += aChars;
michael@0 106 }
michael@0 107
michael@0 108 void SkipChar()
michael@0 109 {
michael@0 110 SkipChars(1);
michael@0 111 }
michael@0 112
michael@0 113 void KeepChar()
michael@0 114 {
michael@0 115 KeepChars(1);
michael@0 116 }
michael@0 117
michael@0 118 void TakeFrom(gfxSkipChars* aSkipChars)
michael@0 119 {
michael@0 120 mRanges.SwapElements(aSkipChars->mRanges);
michael@0 121 mCharCount = aSkipChars->mCharCount;
michael@0 122 aSkipChars->mCharCount = 0;
michael@0 123 }
michael@0 124
michael@0 125 int32_t GetOriginalCharCount() const
michael@0 126 {
michael@0 127 return mCharCount;
michael@0 128 }
michael@0 129
michael@0 130 const SkippedRange& LastRange() const
michael@0 131 {
michael@0 132 // this is only valid if mRanges is non-empty; no assertion here
michael@0 133 // because nsTArray will already assert if we abuse it
michael@0 134 return mRanges[mRanges.Length() - 1];
michael@0 135 }
michael@0 136
michael@0 137 friend class gfxSkipCharsIterator;
michael@0 138
michael@0 139 private:
michael@0 140 nsTArray<SkippedRange> mRanges;
michael@0 141 uint32_t mCharCount;
michael@0 142 };
michael@0 143
michael@0 144 /**
michael@0 145 * A gfxSkipCharsIterator represents a position in the original string. It lets you
michael@0 146 * map efficiently to and from positions in the string after skipped characters
michael@0 147 * have been removed. You can also specify an offset that is added to all
michael@0 148 * incoming original string offsets and subtracted from all outgoing original
michael@0 149 * string offsets --- useful when the gfxSkipChars corresponds to something
michael@0 150 * offset from the original DOM coordinates, which it often does for gfxTextRuns.
michael@0 151 *
michael@0 152 * The current positions (in both the original and skipped strings) are
michael@0 153 * always constrained to be >= 0 and <= the string length. When the position
michael@0 154 * is equal to the string length, it is at the end of the string. The current
michael@0 155 * positions do not include any aOriginalStringToSkipCharsOffset.
michael@0 156 *
michael@0 157 * When the position in the original string corresponds to a skipped character,
michael@0 158 * the skipped-characters offset is the offset of the next unskipped character,
michael@0 159 * or the skipped-characters string length if there is no next unskipped character.
michael@0 160 */
michael@0 161 class gfxSkipCharsIterator
michael@0 162 {
michael@0 163 public:
michael@0 164 /**
michael@0 165 * @param aOriginalStringToSkipCharsOffset add this to all incoming and
michael@0 166 * outgoing original string offsets
michael@0 167 */
michael@0 168 gfxSkipCharsIterator(const gfxSkipChars& aSkipChars,
michael@0 169 int32_t aOriginalStringToSkipCharsOffset,
michael@0 170 int32_t aOriginalStringOffset)
michael@0 171 : mSkipChars(&aSkipChars),
michael@0 172 mOriginalStringOffset(0),
michael@0 173 mSkippedStringOffset(0),
michael@0 174 mCurrentRangeIndex(-1),
michael@0 175 mOriginalStringToSkipCharsOffset(aOriginalStringToSkipCharsOffset)
michael@0 176 {
michael@0 177 SetOriginalOffset(aOriginalStringOffset);
michael@0 178 }
michael@0 179
michael@0 180 gfxSkipCharsIterator(const gfxSkipChars& aSkipChars,
michael@0 181 int32_t aOriginalStringToSkipCharsOffset = 0)
michael@0 182 : mSkipChars(&aSkipChars),
michael@0 183 mOriginalStringOffset(0),
michael@0 184 mSkippedStringOffset(0),
michael@0 185 mCurrentRangeIndex(-1),
michael@0 186 mOriginalStringToSkipCharsOffset(aOriginalStringToSkipCharsOffset)
michael@0 187 { }
michael@0 188
michael@0 189 gfxSkipCharsIterator(const gfxSkipCharsIterator& aIterator)
michael@0 190 : mSkipChars(aIterator.mSkipChars),
michael@0 191 mOriginalStringOffset(aIterator.mOriginalStringOffset),
michael@0 192 mSkippedStringOffset(aIterator.mSkippedStringOffset),
michael@0 193 mCurrentRangeIndex(aIterator.mCurrentRangeIndex),
michael@0 194 mOriginalStringToSkipCharsOffset(aIterator.mOriginalStringToSkipCharsOffset)
michael@0 195 { }
michael@0 196
michael@0 197 /**
michael@0 198 * The empty constructor creates an object that is useless until it is assigned.
michael@0 199 */
michael@0 200 gfxSkipCharsIterator()
michael@0 201 : mSkipChars(nullptr)
michael@0 202 { }
michael@0 203
michael@0 204 /**
michael@0 205 * Return true if this iterator is properly initialized and usable.
michael@0 206 */
michael@0 207 bool IsInitialized()
michael@0 208 {
michael@0 209 return mSkipChars != nullptr;
michael@0 210 }
michael@0 211
michael@0 212 /**
michael@0 213 * Set the iterator to aOriginalStringOffset in the original string.
michael@0 214 * This can efficiently move forward or backward from the current position.
michael@0 215 * aOriginalStringOffset is clamped to [0,originalStringLength].
michael@0 216 */
michael@0 217 void SetOriginalOffset(int32_t aOriginalStringOffset);
michael@0 218
michael@0 219 /**
michael@0 220 * Set the iterator to aSkippedStringOffset in the skipped string.
michael@0 221 * This can efficiently move forward or backward from the current position.
michael@0 222 * aSkippedStringOffset is clamped to [0,skippedStringLength].
michael@0 223 */
michael@0 224 void SetSkippedOffset(uint32_t aSkippedStringOffset);
michael@0 225
michael@0 226 uint32_t ConvertOriginalToSkipped(int32_t aOriginalStringOffset)
michael@0 227 {
michael@0 228 SetOriginalOffset(aOriginalStringOffset);
michael@0 229 return GetSkippedOffset();
michael@0 230 }
michael@0 231
michael@0 232 uint32_t ConvertSkippedToOriginal(int32_t aSkippedStringOffset)
michael@0 233 {
michael@0 234 SetSkippedOffset(aSkippedStringOffset);
michael@0 235 return GetOriginalOffset();
michael@0 236 }
michael@0 237
michael@0 238 /**
michael@0 239 * Test if the character at the current position in the original string
michael@0 240 * is skipped or not. If aRunLength is non-null, then *aRunLength is set
michael@0 241 * to a number of characters all of which are either skipped or not, starting
michael@0 242 * at this character. When the current position is at the end of the original
michael@0 243 * string, we return true and *aRunLength is set to zero.
michael@0 244 */
michael@0 245 bool IsOriginalCharSkipped(int32_t* aRunLength = nullptr) const;
michael@0 246
michael@0 247 void AdvanceOriginal(int32_t aDelta)
michael@0 248 {
michael@0 249 SetOriginalOffset(GetOriginalOffset() + aDelta);
michael@0 250 }
michael@0 251
michael@0 252 void AdvanceSkipped(int32_t aDelta)
michael@0 253 {
michael@0 254 SetSkippedOffset(GetSkippedOffset() + aDelta);
michael@0 255 }
michael@0 256
michael@0 257 /**
michael@0 258 * @return the offset within the original string
michael@0 259 */
michael@0 260 int32_t GetOriginalOffset() const
michael@0 261 {
michael@0 262 return mOriginalStringOffset - mOriginalStringToSkipCharsOffset;
michael@0 263 }
michael@0 264
michael@0 265 /**
michael@0 266 * @return the offset within the skipped string corresponding to the
michael@0 267 * current position in the original string. If the current position
michael@0 268 * in the original string is a character that is skipped, then we return
michael@0 269 * the position corresponding to the first non-skipped character in the
michael@0 270 * original string after the current position, or the length of the skipped
michael@0 271 * string if there is no such character.
michael@0 272 */
michael@0 273 uint32_t GetSkippedOffset() const
michael@0 274 {
michael@0 275 return mSkippedStringOffset;
michael@0 276 }
michael@0 277
michael@0 278 int32_t GetOriginalEnd() const
michael@0 279 {
michael@0 280 return mSkipChars->GetOriginalCharCount() -
michael@0 281 mOriginalStringToSkipCharsOffset;
michael@0 282 }
michael@0 283
michael@0 284 private:
michael@0 285 const gfxSkipChars* mSkipChars;
michael@0 286
michael@0 287 // Current position
michael@0 288 int32_t mOriginalStringOffset;
michael@0 289 uint32_t mSkippedStringOffset;
michael@0 290
michael@0 291 // Index of the last skippedRange that precedes or contains the current
michael@0 292 // position in the original string.
michael@0 293 // If index == -1 then we are before the first skipped char.
michael@0 294 int32_t mCurrentRangeIndex;
michael@0 295
michael@0 296 // This offset is added to map from "skipped+unskipped characters in
michael@0 297 // the original DOM string" character space to "skipped+unskipped
michael@0 298 // characters in the textrun's gfxSkipChars" character space
michael@0 299 int32_t mOriginalStringToSkipCharsOffset;
michael@0 300 };
michael@0 301
michael@0 302 #endif /*GFX_SKIP_CHARS_H*/

mercurial