timespan.cpp

Go to the documentation of this file.
00001 // $Id: timespan.cpp 751 2006-03-31 15:43:49Z alex $
00002 /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE
00003 ================================XARAHEADERSTART===========================
00004  
00005                Xara LX, a vector drawing and manipulation program.
00006                     Copyright (C) 1993-2006 Xara Group Ltd.
00007        Copyright on certain contributions may be held in joint with their
00008               respective authors. See AUTHORS file for details.
00009 
00010 LICENSE TO USE AND MODIFY SOFTWARE
00011 ----------------------------------
00012 
00013 This file is part of Xara LX.
00014 
00015 Xara LX is free software; you can redistribute it and/or modify it
00016 under the terms of the GNU General Public License version 2 as published
00017 by the Free Software Foundation.
00018 
00019 Xara LX and its component source files are distributed in the hope
00020 that it will be useful, but WITHOUT ANY WARRANTY; without even the
00021 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00022 See the GNU General Public License for more details.
00023 
00024 You should have received a copy of the GNU General Public License along
00025 with Xara LX (see the file GPL in the root directory of the
00026 distribution); if not, write to the Free Software Foundation, Inc., 51
00027 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
00028 
00029 
00030 ADDITIONAL RIGHTS
00031 -----------------
00032 
00033 Conditional upon your continuing compliance with the GNU General Public
00034 License described above, Xara Group Ltd grants to you certain additional
00035 rights. 
00036 
00037 The additional rights are to use, modify, and distribute the software
00038 together with the wxWidgets library, the wxXtra library, and the "CDraw"
00039 library and any other such library that any version of Xara LX relased
00040 by Xara Group Ltd requires in order to compile and execute, including
00041 the static linking of that library to XaraLX. In the case of the
00042 "CDraw" library, you may satisfy obligation under the GNU General Public
00043 License to provide source code by providing a binary copy of the library
00044 concerned and a copy of the license accompanying it.
00045 
00046 Nothing in this section restricts any of the rights you have under
00047 the GNU General Public License.
00048 
00049 
00050 SCOPE OF LICENSE
00051 ----------------
00052 
00053 This license applies to this program (XaraLX) and its constituent source
00054 files only, and does not necessarily apply to other Xara products which may
00055 in part share the same code base, and are subject to their own licensing
00056 terms.
00057 
00058 This license does not apply to files in the wxXtra directory, which
00059 are built into a separate library, and are subject to the wxWindows
00060 license contained within that directory in the file "WXXTRA-LICENSE".
00061 
00062 This license does not apply to the binary libraries (if any) within
00063 the "libs" directory, which are subject to a separate license contained
00064 within that directory in the file "LIBS-LICENSE".
00065 
00066 
00067 ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS
00068 ----------------------------------------------
00069 
00070 Subject to the terms of the GNU Public License (see above), you are
00071 free to do whatever you like with your modifications. However, you may
00072 (at your option) wish contribute them to Xara's source tree. You can
00073 find details of how to do this at:
00074   http://www.xaraxtreme.org/developers/
00075 
00076 Prior to contributing your modifications, you will need to complete our
00077 contributor agreement. This can be found at:
00078   http://www.xaraxtreme.org/developers/contribute/
00079 
00080 Please note that Xara will not accept modifications which modify any of
00081 the text between the start and end of this header (marked
00082 XARAHEADERSTART and XARAHEADEREND).
00083 
00084 
00085 MARKS
00086 -----
00087 
00088 Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara
00089 designs are registered or unregistered trademarks, design-marks, and/or
00090 service marks of Xara Group Ltd. All rights in these marks are reserved.
00091 
00092 
00093       Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK.
00094                         http://www.xara.com/
00095 
00096 =================================XARAHEADEREND============================
00097  */
00098 
00099 #include "camtypes.h"
00100 #include "timespan.h"
00101 
00102 CC_IMPLEMENT_DYNAMIC(TimeSpan, CCObject)
00103 
00104 // We want better memory tracking
00105 #define new CAM_DEBUG_NEW
00106 
00107 /********************************************************************************************
00108 
00109 >   TimeSpan::TimeSpan()
00110 
00111     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
00112     Created:    17/03/97
00113     Purpose:    Constructs an empty TimeSpan object.
00114 
00115 ********************************************************************************************/
00116 
00117 TimeSpan::TimeSpan()
00118 {
00119     LO=HI=0;
00120 }
00121 
00122 
00123 /********************************************************************************************
00124 
00125 >   TimeSpan::TimeSpan(TimeSlice lower, TimeSlice upper)
00126 
00127     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
00128     Created:    17/03/97
00129     Inputs:     lower = a lower bound time to inherit
00130                 upper = an upper bound time to inherit
00131     Purpose:    Constructs an bounded TimeSpan object.
00132 
00133 ********************************************************************************************/
00134 
00135 TimeSpan::TimeSpan(TimeSlice lower, TimeSlice upper)
00136 {
00137     if (!SetBounds(lower,upper))
00138     {
00139         ERROR3("TimeSpan() constructor called with invalid bounds")
00140     }
00141 }
00142 
00143 
00144 /********************************************************************************************
00145 
00146 >   TimeSpan::TimeSpan(const TimeSpan &other)
00147 
00148     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
00149     Created:    17/03/97
00150     Inputs:     other = a reference to another time span
00151     Purpose:    Copy contructor for the TimeSpan object
00152 
00153 ********************************************************************************************/
00154 
00155 TimeSpan::TimeSpan(const TimeSpan &other)
00156 {
00157     (*this)=other;
00158 }
00159 
00160 
00161 /********************************************************************************************
00162 
00163 >   BOOL TimeSpan::SetBounds(TimeSlice lower, TimeSlice upper)
00164 
00165     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
00166     Created:    17/03/97
00167     Inputs:     lower = a lower bound time to inherit
00168                 upper = an upper bound time to inherit
00169     Returns:    TRUE if the bounds we valid, FALSE if not.
00170                 (invalid bounds means lower>=upper indicating an empty span)
00171     Purpose:    Set the bounds of this time span object. The bounds are always set in
00172                 the object even if they are invalid. 
00173 
00174 ********************************************************************************************/
00175 
00176 BOOL TimeSpan::SetBounds(TimeSlice lower, TimeSlice upper)
00177 {
00178     LO = lower;
00179     HI = upper;
00180     return (lower<upper);
00181 }
00182 
00183 
00184 /********************************************************************************************
00185 
00186 >   inline TimeSlice TimeSpan::GetLowerBound() const
00187 >   inline TimeSlice TimeSpan::Lo() const
00188 
00189     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
00190     Created:    17/03/97
00191     Inputs:     -
00192     Returns:    The lower bound of this TimeSpan object
00193     Purpose:    Dig out the lower bound of this TimeSpan object
00194     Errors:     Generates an error3 if this object is empty
00195 
00196 ********************************************************************************************/
00197 
00198 inline TimeSlice TimeSpan::GetLowerBound() const
00199 { 
00200     ERROR3IF(IsEmpty(), "TimeSpan::GetLowerBound() called on an empty TimeSpan");
00201     return LO;
00202 }
00203 
00204 inline TimeSlice TimeSpan::Lo() const
00205 { 
00206     ERROR3IF(IsEmpty(), "TimeSpan::Lo() called on an empty TimeSpan");
00207     return LO;
00208 }
00209 
00210 /********************************************************************************************
00211 
00212 >   inline TimeSlice TimeSpan::GetUpperBound() const 
00213     inline TimeSlice TimeSpan::Hi() const 
00214 
00215     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
00216     Created:    17/03/97
00217     Inputs:     -
00218     Returns:    The upper bound of this TimeSpan object
00219     Purpose:    Dig out the upper bound of this TimeSpan object. It should always be
00220                 greater than or equal to the lower bound, otherwise this span is invalid
00221     Errors:     Generates an error3 if this object is invalid
00222 
00223 ********************************************************************************************/
00224 
00225 inline TimeSlice TimeSpan::GetUpperBound() const 
00226 {
00227     ERROR3IF(IsEmpty(), "TimeSpan::GetUpperBound() called on an empty TimeSpan");
00228     return HI; 
00229 }
00230 
00231 inline TimeSlice TimeSpan::Hi() const 
00232 {
00233     ERROR3IF(IsEmpty(), "TimeSpan::Hi() called on an empty TimeSpan");
00234     return HI; 
00235 }
00236 
00237 
00238 /********************************************************************************************
00239 
00240 >   void TimeSpan::SetCreationTimeFrame(const DocView *pView, const Document *pDoc)
00241 
00242     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
00243     Created:    17/03/97
00244     Inputs:     pView = a view pointer
00245                 pDoc = a document pointer
00246     Purpose:    Set the lower and upper time span bounds to the view's now and the
00247                 documents max time.
00248 
00249 ********************************************************************************************/
00250 /*
00251 void TimeSpan::SetCreationTimeFrame(const DocView *pView, const Document *pDoc)
00252 {
00253     ERROR3IF(pView==NULL,"NULL view pointer passed to SetCreationTimeFrame");
00254     ERROR3IF(pDoc ==NULL,"NULL doc pointer passed to SetCreationTimeFrame");
00255     
00256     LO = pView->GetCurrentTime();
00257     HI = pDoc->GetUpperTimeBound();
00258     valid=(LO<=HI);
00259     
00260     ERROR3IF(!valid, "TimeSpan::SetCreationTimeFrame() has failed to set a valid time frame!");
00261 }
00262 */
00263 
00264 /********************************************************************************************
00265 
00266 >   void TimeSpan::MakeInvalid()
00267 
00268     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
00269     Created:    17/03/97
00270     Inputs:     -
00271     Purpose:    Make this time span invalid.
00272 
00273 ********************************************************************************************/
00274 
00275 void TimeSpan::MakeInvalid()
00276 {
00277     LO=HI;
00278 }
00279 
00280 
00281 /********************************************************************************************
00282 
00283 >   BOOL TimeSpan::IsEmpty() const
00284 
00285     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
00286     Created:    17/03/97
00287     Inputs:     -
00288     Returns:    TRUE if this time span object is empty, i.e. it contains a lower and
00289                 upper time such that lower>=upper.
00290                 FALSE if these conditions are not met.
00291     Purpose:    Check whether this time span object contains a non empty time frame. A time
00292                 span becomes empty as a result of trying to perform boolean operations
00293                 on time spans resulting in empty spans.
00294 
00295 ********************************************************************************************/
00296 
00297 inline BOOL TimeSpan::IsEmpty() const
00298 {
00299     return (LO>=HI);
00300 }
00301 
00302 
00303 
00304 /********************************************************************************************
00305 
00306 >   BOOL TimeSpan::IsSameAs(const TimeSpan &other) const
00307 
00308     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
00309     Created:    17/03/97
00310     Inputs:     other = a reference to another TimeSpan object
00311     Returns:    TRUE if other contains the same time span as this and they are both none empty
00312                 TRUE if other and this object are both empty
00313                 FALSE if neither of these conditions hold
00314     Purpose:    Check whether two TimeSpan objects are the same.
00315 
00316 ********************************************************************************************/
00317 
00318 BOOL TimeSpan::IsSameAs(const TimeSpan &other) const
00319 {
00320     BOOL same = (IsEmpty() == other.IsEmpty());
00321     if (!IsEmpty() && same)
00322     {   
00323         same = same && (LO == other.GetLowerBound());
00324         same = same && (HI == other.GetUpperBound());
00325     }
00326     return same;
00327 }
00328 
00329 
00330 /********************************************************************************************
00331 
00332 >   TimeSpan TimeSpan::Union(const TimeSpan &other) const
00333 
00334     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
00335     Created:    17/03/97
00336     Inputs:     other = a reference to another TimeSpan object
00337     Returns:    the union of the two time spans
00338     Purpose:    Find the union of this span with the other span. This union will always
00339                 be valid if either or both spans are non empty
00340 
00341 ********************************************************************************************/
00342 
00343 TimeSpan TimeSpan::Union(const TimeSpan &other) const
00344 {
00345     return (*this)+other;
00346 }
00347 
00348 /********************************************************************************************
00349 
00350 >   TimeSpan TimeSpan::Intersection(const TimeSpan &other) const
00351 
00352     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
00353     Created:    17/03/97
00354     Inputs:     other = a reference to another TimeSpan object
00355     Returns:    the intersection of the two time spans
00356     Purpose:    Find the intersection of this span with 'other' span. If the intersection
00357                 does not exist, either because one of the spans is empty or both spans
00358                 are valid but they don't intersect then an empty timespan object is
00359                 returned. Otherwise the intersection is returned
00360 
00361 ********************************************************************************************/
00362 
00363 TimeSpan TimeSpan::Intersection(const TimeSpan &other) const
00364 {
00365     return (*this)-other;
00366 }
00367 
00368 /********************************************************************************************
00369 
00370 >   BOOL TimeSpan::IsIntersectedWith(const TimeSpan &other) const
00371 
00372     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
00373     Created:    17/03/97
00374     Inputs:     other = a reference to another TimeSpan
00375     Returns:    TRUE if this time span does intersect with the 'other' time span
00376     Purpose:    Determine if this time span is intersected with the time span supplied
00377     SeeAlso:    TimeSpan::Intersection()
00378 
00379 ********************************************************************************************/
00380 
00381 BOOL TimeSpan::IsIntersectedWith(const TimeSpan &other) const
00382 {
00383     // both bounds must be valid for an intersection
00384     if (IsEmpty() || other.IsEmpty())
00385         return FALSE;
00386 
00387     // check for none intersection case
00388     TimeSlice lower = other.GetLowerBound();
00389     TimeSlice upper = other.GetUpperBound();
00390     return !(upper<LO || lower>HI);
00391 }
00392 
00393 
00394 /********************************************************************************************
00395 
00396 >   BOOL TimeSpan::InBounds(TimeSlice current) const
00397 
00398     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
00399     Created:    17/03/97
00400     Inputs:     A time slice
00401     Returns:    TRUE then current is within the bounds of this time span
00402     Purpose:    Checks whether the given time slice is within the bounds of this span
00403                 
00404 ********************************************************************************************/
00405 
00406 BOOL TimeSpan::InBounds(TimeSlice current) const
00407 {
00408     // Although Lo>Hi will return false always, lo==hi==current will return true
00409     // on an empty time span so check this.
00410     if (IsEmpty())
00411         return FALSE;
00412 
00413     return (LO<=current && current<=HI);
00414 }
00415 
00416 /********************************************************************************************
00417 
00418 >   BOOL TimeSpan::Contains(const TimeSpan& other) const
00419 
00420     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
00421     Created:    17/03/97
00422     Inputs:     A reference to another timespan
00423     Returns:    TRUE then other is contained entirely within this time span
00424                 FALSE if not. Other may still intersect this time span.
00425     Purpose:    Check wether the time span expressed by 'other' is contained entirely within
00426                 this time span
00427                 
00428 ********************************************************************************************/
00429 
00430 BOOL TimeSpan::Contains(const TimeSpan& other) const
00431 {
00432     // A.Contains(Empty(B))?  Empty(A).Contains(B)?
00433     if (IsEmpty() || other.IsEmpty())
00434         return FALSE;
00435 
00436     return (LO<=other.GetLowerBound() && HI>=other.GetUpperBound());
00437 }
00438 
00439 
00440 /********************************************************************************************
00441 
00442 >   void TimeSpan::Inflate(TimeSlice inflate)
00443 
00444     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
00445     Created:    17/03/97
00446     Inputs:     A reference to the inflation value
00447     Returns:    -
00448     Purpose:    Inflates the bounds of this object by 'inflate'
00449                 
00450 ********************************************************************************************/
00451 
00452 void TimeSpan::Inflate(TimeSlice inflate)
00453 {
00454     ERROR3IF(IsEmpty(),"TimeSpan::Inflate() called on an empty span");
00455     LO-=inflate;
00456     HI+=inflate;
00457 }
00458 
00459 /********************************************************************************************
00460 
00461 >   double TimeSpan::GetRelativeTime(TimeSlice current) const
00462 
00463     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
00464     Created:    17/03/97
00465     Inputs:     A current time to make relative
00466     Returns:    A relative time
00467     Purpose:    Convert the absolute time 'current' into a relative value. If the current
00468                 value is within this time span then the double result will lie
00469                 between 0 and 1, otherwise it will lie somewhere on the real line.
00470                 
00471 ********************************************************************************************/
00472 
00473 inline double TimeSpan::GetRelativeTime(TimeSlice current) const
00474 {
00475     ERROR3IF(IsEmpty(),"TimeSpan::GetRelativeTime() called on an empty span");
00476     return ((double)(LO-current)) / ((double)(HI-LO));
00477 }
00478 
00479 /********************************************************************************************
00480 
00481 >   inline TimeSlice TimeSpan::GetAbsoluteTime(double current) const
00482 
00483     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
00484     Created:    17/03/97
00485     Inputs:     A relative time to make absolute
00486     Returns:    An absolute time
00487     Purpose:    Convert the relative time 'current' into an absolute value. Performs
00488                 a linear interpolation on this timespans start and end times. Hence if
00489                 0<=current<=1 then the returned time will be somewhere within this time
00490                 span.
00491                 
00492 ********************************************************************************************/
00493 
00494 inline TimeSlice TimeSpan::GetAbsoluteTime(double current) const
00495 {
00496     ERROR3IF(IsEmpty(),"TimeSpan::GetAbsoluteTime() called on an empty span");
00497     return (LO + (TimeSlice)(0.5+current*((double)(HI-LO))));
00498 }
00499 
00500 
00501 
00502 /********************************************************************************************
00503 
00504 >   TimeSpan TimeSpan::operator+(TimeSlice value) const
00505 
00506     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
00507     Created:    17/03/97
00508     Inputs:     A reference to the TimeSlice value to add to both lower and upper bounds
00509     Returns:    The new shifted time span
00510     Purpose:    Returns TimeSpanA = TimeSpanB + TimeSlice
00511                 
00512 ********************************************************************************************/
00513 
00514 TimeSpan TimeSpan::operator+(TimeSlice value) const
00515 {
00516     return TimeSpan(LO+value, HI+value);
00517 }
00518 
00519 
00520 /********************************************************************************************
00521 
00522 >   TimeSpan TimeSpan::operator+(const TimeSpan& other) const
00523 
00524     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
00525     Created:    17/03/97
00526     Inputs:     A reference to a rhs TimeSpan value to add to this time span
00527     Returns:    A new time span holding the result of the addition ( a union )
00528     Purpose:    Overload operator+ to perform a union opertion.
00529                 
00530 ********************************************************************************************/
00531 
00532 TimeSpan TimeSpan::operator+(const TimeSpan& other) const
00533 {
00534     // is this empty?
00535     if (IsEmpty())
00536         return other;
00537 
00538     if (other.IsEmpty())
00539         return (*this);
00540 
00541     // make a union out of the bounds
00542     TimeSlice lower = other.GetLowerBound();
00543     TimeSlice upper = other.GetUpperBound();
00544     if (LO<lower) lower=LO;
00545     if (HI>upper) upper=HI;
00546     
00547     return TimeSpan(lower,upper);
00548 }
00549 
00550 
00551 
00552 
00553 
00554 /********************************************************************************************
00555 
00556 >   TimeSpan TimeSpan::operator-(TimeSlice value) const
00557 
00558     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
00559     Created:    17/03/97
00560     Inputs:     A reference to the TimeSlice value to add to both lower and upper bounds
00561     Returns:    A resulting time span
00562     Purpose:    Subtracts 'value' from the bounds of this timespan and returns the result
00563                 as a new time span.
00564                 
00565 ********************************************************************************************/
00566 
00567 TimeSpan TimeSpan::operator-(TimeSlice value) const
00568 {
00569     return TimeSpan(LO-value, HI-value);
00570 }
00571 
00572 
00573 /********************************************************************************************
00574 
00575 >   TimeSpan TimeSpan::operator-(const TimeSpan &other) const
00576 
00577     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
00578     Created:    17/03/97
00579     Inputs:     A reference to a rhs TimeSpan value to subtract from this time span
00580     Returns:    The result of subtracting other from this
00581     Purpose:    Overload the operator- function to perform an intersection of two time spans
00582                 returning the result in a new timespan.
00583                 
00584 ********************************************************************************************/
00585 
00586 TimeSpan TimeSpan::operator-(const TimeSpan &other) const
00587 {
00588     // both bounds must be valid for an intersection
00589     if (IsEmpty() || other.IsEmpty())
00590         return (*this);
00591 
00592     // check for none intersection case
00593     TimeSlice lower = other.GetLowerBound();
00594     TimeSlice upper = other.GetUpperBound();
00595     if (upper<LO || lower>HI)
00596         return (*this);
00597 
00598     // make an intersection now we know the two actually do intersect
00599     if (HI<upper) upper=HI;
00600     if (LO>lower) lower=LO;
00601     
00602     return TimeSpan(lower,upper);
00603 }
00604 
00605 
00606 
00607 /********************************************************************************************
00608 
00609 >   TimeSpan& TimeSpan::operator=(const TimeSpan &other)
00610 
00611     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
00612     Created:    17/03/97
00613     Inputs:     A reference to another time span
00614     Returns:    A reference to this time span
00615     Purpose:    Assignment operator overload, assigns this time span with that of
00616                 'other' and returns a reference for further assignment
00617                 
00618 ********************************************************************************************/
00619 
00620 TimeSpan& TimeSpan::operator=(const TimeSpan &other)
00621 {
00622     LO = other.GetLowerBound();
00623     HI = other.GetUpperBound();
00624     return (*this);
00625 }

Generated on Sat Nov 10 03:47:09 2007 for Camelot by  doxygen 1.4.4