Bug 1874684 - Part 28: Return DateDuration from DifferenceISODateTime. r=mgaudet
[gecko.git] / gfx / thebes / gfxSkipChars.cpp
blobcd230efe74cca368c93fac8d7c1da42cade81653
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)
13 : mOffset(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;
32 return;
35 // at start of string?
36 if (aOffset == 0) {
37 mSkippedStringOffset = 0;
38 mCurrentRangeIndex =
39 rangeCount && mSkipChars->mRanges[0].Start() == 0 ? 0 : -1;
40 return;
43 // find the range that includes or precedes aOffset
44 const nsTArray<gfxSkipChars::SkippedRange>& ranges = mSkipChars->mRanges;
45 size_t idx;
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;
55 return;
57 } else {
58 mCurrentRangeIndex = idx;
61 const gfxSkipChars::SkippedRange& r = ranges[mCurrentRangeIndex];
62 if (uint32_t(aOffset) < r.End()) {
63 mSkippedStringOffset = r.SkippedOffset();
64 return;
67 mSkippedStringOffset = aOffset - r.NextDelta();
70 struct SkippedRangeOffsetComparator {
71 const uint32_t mOffset;
72 explicit SkippedRangeOffsetComparator(const uint32_t aOffset)
73 : mOffset(aOffset) {}
74 int operator()(const gfxSkipChars::SkippedRange& aRange) const {
75 return (mOffset < aRange.SkippedOffset()) ? -1 : 1;
79 void gfxSkipCharsIterator::SetSkippedOffset(uint32_t aOffset) {
80 NS_ASSERTION(
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;
91 return;
94 const nsTArray<gfxSkipChars::SkippedRange>& ranges = mSkipChars->mRanges;
95 size_t idx;
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;
105 return;
107 } else {
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)
118 if (aRunLength) {
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()) {
131 if (aRunLength) {
132 *aRunLength = range.End() - mOriginalStringOffset;
134 return true;
137 if (aRunLength) {
138 uint32_t end =
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);