Source code

Revision control

Copy as Markdown

Other Tools

/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "gfxSkipChars.h"
#include "mozilla/BinarySearch.h"
#include "mozilla/gfx/Logging.h"
struct SkippedRangeStartComparator {
const uint32_t mOffset;
explicit SkippedRangeStartComparator(const uint32_t aOffset)
: mOffset(aOffset) {}
int operator()(const gfxSkipChars::SkippedRange& aRange) const {
return (mOffset < aRange.Start()) ? -1 : 1;
}
};
void gfxSkipCharsIterator::SetOriginalOffset(int32_t aOffset) {
aOffset += mOriginalStringToSkipCharsOffset;
if (MOZ_UNLIKELY(uint32_t(aOffset) > mSkipChars->mCharCount)) {
gfxCriticalError() << "invalid offset " << aOffset
<< " for gfxSkipChars length " << mSkipChars->mCharCount;
aOffset = mSkipChars->mCharCount;
}
mOriginalStringOffset = aOffset;
const uint32_t rangeCount = mSkipChars->mRanges.Length();
if (rangeCount == 0) {
mSkippedStringOffset = aOffset;
return;
}
// at start of string?
if (aOffset == 0) {
mSkippedStringOffset = 0;
mCurrentRangeIndex =
rangeCount && mSkipChars->mRanges[0].Start() == 0 ? 0 : -1;
return;
}
// find the range that includes or precedes aOffset
const nsTArray<gfxSkipChars::SkippedRange>& ranges = mSkipChars->mRanges;
size_t idx;
mozilla::BinarySearchIf(ranges, 0, rangeCount,
SkippedRangeStartComparator(aOffset), &idx);
if (idx == rangeCount) {
mCurrentRangeIndex = rangeCount - 1;
} else if (uint32_t(aOffset) < ranges[idx].Start()) {
mCurrentRangeIndex = idx - 1;
if (mCurrentRangeIndex == -1) {
mSkippedStringOffset = aOffset;
return;
}
} else {
mCurrentRangeIndex = idx;
}
const gfxSkipChars::SkippedRange& r = ranges[mCurrentRangeIndex];
if (uint32_t(aOffset) < r.End()) {
mSkippedStringOffset = r.SkippedOffset();
return;
}
mSkippedStringOffset = aOffset - r.NextDelta();
}
struct SkippedRangeOffsetComparator {
const uint32_t mOffset;
explicit SkippedRangeOffsetComparator(const uint32_t aOffset)
: mOffset(aOffset) {}
int operator()(const gfxSkipChars::SkippedRange& aRange) const {
return (mOffset < aRange.SkippedOffset()) ? -1 : 1;
}
};
void gfxSkipCharsIterator::SetSkippedOffset(uint32_t aOffset) {
NS_ASSERTION(
(mSkipChars->mRanges.IsEmpty() && aOffset <= mSkipChars->mCharCount) ||
(aOffset <= mSkipChars->LastRange().SkippedOffset() +
mSkipChars->mCharCount -
mSkipChars->LastRange().End()),
"Invalid skipped offset");
mSkippedStringOffset = aOffset;
uint32_t rangeCount = mSkipChars->mRanges.Length();
if (rangeCount == 0) {
mOriginalStringOffset = aOffset;
return;
}
const nsTArray<gfxSkipChars::SkippedRange>& ranges = mSkipChars->mRanges;
size_t idx;
mozilla::BinarySearchIf(ranges, 0, rangeCount,
SkippedRangeOffsetComparator(aOffset), &idx);
if (idx == rangeCount) {
mCurrentRangeIndex = rangeCount - 1;
} else if (aOffset < ranges[idx].SkippedOffset()) {
mCurrentRangeIndex = idx - 1;
if (mCurrentRangeIndex == -1) {
mOriginalStringOffset = aOffset;
return;
}
} else {
mCurrentRangeIndex = idx;
}
const gfxSkipChars::SkippedRange& r = ranges[mCurrentRangeIndex];
mOriginalStringOffset = r.End() + aOffset - r.SkippedOffset();
}
bool gfxSkipCharsIterator::IsOriginalCharSkipped(int32_t* aRunLength) const {
if (mCurrentRangeIndex == -1) {
// we're before the first skipped range (if any)
if (aRunLength) {
uint32_t end = mSkipChars->mRanges.IsEmpty()
? mSkipChars->mCharCount
: mSkipChars->mRanges[0].Start();
*aRunLength = end - mOriginalStringOffset;
}
return mSkipChars->mCharCount == uint32_t(mOriginalStringOffset);
}
const gfxSkipChars::SkippedRange& range =
mSkipChars->mRanges[mCurrentRangeIndex];
if (uint32_t(mOriginalStringOffset) < range.End()) {
if (aRunLength) {
*aRunLength = range.End() - mOriginalStringOffset;
}
return true;
}
if (aRunLength) {
uint32_t end =
uint32_t(mCurrentRangeIndex) + 1 < mSkipChars->mRanges.Length()
? mSkipChars->mRanges[mCurrentRangeIndex + 1].Start()
: mSkipChars->mCharCount;
*aRunLength = end - mOriginalStringOffset;
}
return mSkipChars->mCharCount == uint32_t(mOriginalStringOffset);
}