1 /* -*- Mode: C++; tab-width: 20; 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/. */
6 #include "gfxSkipChars.h"
7 #include "mozilla/BinarySearch.h"
8 #include "mozilla/gfx/Logging.h"
10 struct SkippedRangeStartComparator
{
11 const uint32_t mOffset
;
12 explicit SkippedRangeStartComparator(const uint32_t aOffset
)
14 int operator()(const gfxSkipChars::SkippedRange
& aRange
) const {
15 return (mOffset
< aRange
.Start()) ? -1 : 1;
19 void gfxSkipCharsIterator::SetOriginalOffset(int32_t aOffset
) {
20 aOffset
+= mOriginalStringToSkipCharsOffset
;
21 if (MOZ_UNLIKELY(uint32_t(aOffset
) > mSkipChars
->mCharCount
)) {
22 gfxCriticalError() << "invalid offset " << aOffset
23 << " for gfxSkipChars length " << mSkipChars
->mCharCount
;
24 aOffset
= mSkipChars
->mCharCount
;
27 mOriginalStringOffset
= aOffset
;
29 const uint32_t rangeCount
= mSkipChars
->mRanges
.Length();
30 if (rangeCount
== 0) {
31 mSkippedStringOffset
= aOffset
;
35 // at start of string?
37 mSkippedStringOffset
= 0;
39 rangeCount
&& mSkipChars
->mRanges
[0].Start() == 0 ? 0 : -1;
43 // find the range that includes or precedes aOffset
44 const nsTArray
<gfxSkipChars::SkippedRange
>& ranges
= mSkipChars
->mRanges
;
46 mozilla::BinarySearchIf(ranges
, 0, rangeCount
,
47 SkippedRangeStartComparator(aOffset
), &idx
);
49 if (idx
== rangeCount
) {
50 mCurrentRangeIndex
= rangeCount
- 1;
51 } else if (uint32_t(aOffset
) < ranges
[idx
].Start()) {
52 mCurrentRangeIndex
= idx
- 1;
53 if (mCurrentRangeIndex
== -1) {
54 mSkippedStringOffset
= aOffset
;
58 mCurrentRangeIndex
= idx
;
61 const gfxSkipChars::SkippedRange
& r
= ranges
[mCurrentRangeIndex
];
62 if (uint32_t(aOffset
) < r
.End()) {
63 mSkippedStringOffset
= r
.SkippedOffset();
67 mSkippedStringOffset
= aOffset
- r
.NextDelta();
70 struct SkippedRangeOffsetComparator
{
71 const uint32_t mOffset
;
72 explicit SkippedRangeOffsetComparator(const uint32_t aOffset
)
74 int operator()(const gfxSkipChars::SkippedRange
& aRange
) const {
75 return (mOffset
< aRange
.SkippedOffset()) ? -1 : 1;
79 void gfxSkipCharsIterator::SetSkippedOffset(uint32_t aOffset
) {
81 (mSkipChars
->mRanges
.IsEmpty() && aOffset
<= mSkipChars
->mCharCount
) ||
82 (aOffset
<= mSkipChars
->LastRange().SkippedOffset() +
83 mSkipChars
->mCharCount
-
84 mSkipChars
->LastRange().End()),
85 "Invalid skipped offset");
86 mSkippedStringOffset
= aOffset
;
88 uint32_t rangeCount
= mSkipChars
->mRanges
.Length();
89 if (rangeCount
== 0) {
90 mOriginalStringOffset
= aOffset
;
94 const nsTArray
<gfxSkipChars::SkippedRange
>& ranges
= mSkipChars
->mRanges
;
96 mozilla::BinarySearchIf(ranges
, 0, rangeCount
,
97 SkippedRangeOffsetComparator(aOffset
), &idx
);
99 if (idx
== rangeCount
) {
100 mCurrentRangeIndex
= rangeCount
- 1;
101 } else if (aOffset
< ranges
[idx
].SkippedOffset()) {
102 mCurrentRangeIndex
= idx
- 1;
103 if (mCurrentRangeIndex
== -1) {
104 mOriginalStringOffset
= aOffset
;
108 mCurrentRangeIndex
= idx
;
111 const gfxSkipChars::SkippedRange
& r
= ranges
[mCurrentRangeIndex
];
112 mOriginalStringOffset
= r
.End() + aOffset
- r
.SkippedOffset();
115 bool gfxSkipCharsIterator::IsOriginalCharSkipped(int32_t* aRunLength
) const {
116 if (mCurrentRangeIndex
== -1) {
117 // we're before the first skipped range (if any)
119 uint32_t end
= mSkipChars
->mRanges
.IsEmpty()
120 ? mSkipChars
->mCharCount
121 : mSkipChars
->mRanges
[0].Start();
122 *aRunLength
= end
- mOriginalStringOffset
;
124 return mSkipChars
->mCharCount
== uint32_t(mOriginalStringOffset
);
127 const gfxSkipChars::SkippedRange
& range
=
128 mSkipChars
->mRanges
[mCurrentRangeIndex
];
130 if (uint32_t(mOriginalStringOffset
) < range
.End()) {
132 *aRunLength
= range
.End() - mOriginalStringOffset
;
139 uint32_t(mCurrentRangeIndex
) + 1 < mSkipChars
->mRanges
.Length()
140 ? mSkipChars
->mRanges
[mCurrentRangeIndex
+ 1].Start()
141 : mSkipChars
->mCharCount
;
142 *aRunLength
= end
- mOriginalStringOffset
;
145 return mSkipChars
->mCharCount
== uint32_t(mOriginalStringOffset
);