51 enum Lean { kLeanForward = 0, kLeanForth = kLeanForward, kLeanBack = 1, kLeanBackward = kLeanBack};
52 enum {kDontConsiderLean = 0, kIgnoreLean = kDontConsiderLean, kConsiderLean = 1};
66 TextIndex Start(Lean* lean)
const {
if(lean) *lean = fLean;
return fStart;}
67 TextIndex End()
const {
return fEnd;}
68 int32 Length()
const {
return fEnd - fStart;}
71 int32 OverlapWith(
const RangeData& other)
const;
72 bool16 StartsBefore(
const RangeData& other, bool16 consideringLean = kIgnoreLean)
const;
73 bool16 EndsAfter(
const RangeData& other, bool16 consideringLean = kIgnoreLean)
const;
74 bool16 Precedes(
const RangeData& other)
const;
75 bool16 Leads(
const RangeData& other)
const;
76 bool16 Succeeds(
const RangeData& other)
const;
77 bool16 Follows(
const RangeData& other)
const;
78 bool16 CompletelyPrecedes(
const RangeData& other)
const {
return fEnd <= other.fStart;}
79 bool16 Contains(
const RangeData& other, bool16 consideringLean = kIgnoreLean)
const;
80 bool16 Contains(TextIndex index)
const;
81 bool16 Matches(
const RangeData& other, bool16 consideringLean = kConsiderLean)
const;
82 bool16 Begins(
const RangeData& other)
const;
83 bool16 Ends(
const RangeData& other)
const;
84 bool16 Anchors(
const RangeData& other)
const;
92 enum {kLeanTowardOriginal = 0, kLeanIntoClip = 1};
95 ASSERT_MSG( 0 <= fStart && fStart <= fEnd && (fLean == kLeanForward || fEnd > 0),
96 FORMAT_ARGS(
"Bad RangeData(%d,%d,%s) constructed", fStart, fEnd, fLean == kLeanForward ?
"kLeanForward" :
"kLeanBack"));
98 if( fStart < 0) fStart = 0;
99 if( fEnd < fStart) fEnd = fStart;
100 if( fLean == kLeanBackward && fEnd == 0) fLean = kLeanForward;
102 void ClipTo(
const RangeData* clip, bool16 leanInside){
if( clip) ClipTo_( *clip, leanInside);
else Check();}
103 void ClipTo_(
const RangeData& clip, bool16 leanInside);
128 : fStart(r.fStart), fEnd(r.fEnd), fLean(r.fLean)
130 ClipTo(clip, kLeanIntoClip);
147 inline RangeData::RangeData( TextIndex start, TextIndex end,
const RangeData* clip)
148 : fStart(start), fEnd(end), fLean(kLeanForward)
152 ASSERT( fStart < fEnd);
153 ClipTo( clip, kLeanIntoClip);
156 inline RangeData::RangeData( TextIndex caret, Lean lean,
const RangeData* clip)
157 : fStart(caret), fEnd(caret), fLean(lean)
159 ClipTo( clip, kLeanIntoClip);
176 inline RangeData::RangeData( TextIndex start, TextIndex end, Lean lean,
const RangeData* clip)
177 : fStart(start), fEnd(end), fLean(start == end ? lean : kLeanForward)
179 ClipTo( clip, kLeanIntoClip);
184 inline int32 RangeData::OverlapWith(
const RangeData& other)
const 188 return other.Length() + Length() - Join(other,*
this).Length();
191 inline bool16 RangeData::StartsBefore(
const RangeData& other, bool16 consideringLean)
const 193 return fStart < other.fStart
194 || (consideringLean && fStart == other.fStart && fLean == kLeanBack && other.fLean == kLeanForward);
197 inline bool16 RangeData::EndsAfter(
const RangeData& other, bool16 consideringLean )
const 199 return fEnd > other.fEnd
200 || (consideringLean && fStart == other.fEnd && fLean == kLeanForward
201 && (other.fLean == kLeanBack || other.fStart < other.fEnd));
204 inline bool16 RangeData::Precedes(
const RangeData& other)
const 206 RangeData::Lean myLean, otherLean;
207 int32 myEnd = EndLocation(*this).Start( &myLean);
208 int32 otherStart = StartLocation(other).Start( &otherLean);
210 if( myEnd < otherStart)
212 else if( myEnd > otherStart)
215 return myLean == RangeData::kLeanBack && otherLean == RangeData::kLeanForward;
218 inline bool16 RangeData::Leads(
const RangeData& other)
const 220 return Precedes( other);
223 inline bool16 RangeData::Succeeds(
const RangeData& other)
const 225 return EndLocation( other).Precedes( StartLocation( *
this));
228 inline bool16 RangeData::Follows(
const RangeData& other)
const 230 return Succeeds( other);
234 inline bool16 RangeData::Matches(
const RangeData& other, bool16 consideringLean)
const 236 return fStart == other.fStart && fEnd == other.fEnd && (!consideringLean || fLean == other.fLean);
239 inline bool16 RangeData::Begins(
const RangeData& other)
const 241 return fStart == other.fStart && fEnd <= other.fEnd;
244 inline bool16 RangeData::Ends(
const RangeData& other)
const 246 return fEnd == other.fEnd && fStart >= other.fStart;
249 inline bool16 RangeData::Anchors(
const RangeData& other)
const 251 return Begins(other) || Ends(other);
254 inline bool16 RangeData::Contains(
const RangeData& other, bool16 consideringLean)
const 256 if( consideringLean){
258 return *
this == other;
259 if( other.fStart == other.fEnd){
260 if( other.fStart == fStart)
261 return other.fLean == kLeanForward;
262 else if( other.fEnd == fEnd)
263 return other.fLean == kLeanBack;
267 return fStart <= other.fStart && other.fEnd <= fEnd;
270 inline bool16 RangeData::Contains(TextIndex index)
const 272 return RangeData::Contains(
RangeData(index, index + 1), kDontConsiderLean);
283 std::min(x.fStart, y.fStart),
284 std::max(x.fEnd, y.fEnd),
285 x.fLean || y.fLean ? RangeData::kLeanBack : RangeData::kLeanForward,
291 TextIndex end = x.End() + y;
292 TextIndex start = x.Start(nil);
293 return RangeData( std::min( start, end), std::max( start, end), x.fLean, clip);
298 TextIndex end = x.End();
299 TextIndex start = x.Start(nil) - y;
300 return RangeData( std::min( start, end), std::max( start, end), x.fLean, clip);
305 return RangeData( x.fStart + y, x.fEnd + y, x.fLean, clip);
317 return x.Start(nil) < y.Start(nil) || (x.Start(nil) == y.Start(nil) && x.End() < y.End());
327 return SlideForward( x, -y, clip);
332 return SlideForward( x, y);
337 return SlideBackward( x, y);
342 return x.Length() == 0 ? x :
RangeData( x.End(), RangeData::kLeanBack);
347 return x.Length() == 0 ? x :
RangeData( x.Start(nil), RangeData::kLeanForward);
352 return AdvanceEnd(x, end-x.End(), clip);
357 return RecedeStart(x, x.Start(nil)-start, clip);
362 return AdvanceEnd( x, -y, clip);
367 return AdvanceEnd( x, y);
372 return x.Length() == 0 ? x :
RangeData( (x.Start(nil) + x.End())/2, RangeData::kLeanForward);
377 return RecedeStart( x, -y, clip);
382 return RecedeStart( x, y);
392 return lhs.Matches(rhs, RangeData::kConsiderLean);
397 return !(lhs == rhs);
402 return RangeData( r.Start(nil), r.End(), lean);
407 RangeData::Lean lean;
408 (void)copyLean.Start(&lean);
409 return NewLean( r, lean);
414 return NewLean( r, RangeData::kLeanForward);
419 return NewLean( r, RangeData::kLeanBack);
433 StoryRange( TextIndex start, TextIndex end, Lean lean = kLeanForward) :
RangeData(start, end, lean) {}
436 TextIndex GetEnd()
const {
return End();}
437 TextIndex GetStart( RangeData::Lean* lean = nil)
const {
return Start(lean);}
471 TextIndex GetEnd()
const {
return range.End();}
473 TextIndex GetStart( RangeData::Lean* lean = nil)
const {
return range.Start(lean);}