Added copyright lines for files I've edited this year.
[synfig.git] / synfig-core / trunk / src / synfig / time.cpp
index ebaacdf..ea59b8e 100644 (file)
@@ -2,19 +2,21 @@
 /*!    \file time.cpp
 **     \brief Template File
 **
-**     $Id: time.cpp,v 1.1.1.1 2005/01/04 01:23:15 darco Exp $
+**     $Id$
 **
 **     \legal
-**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**     Copyright (c) 2007, 2008 Chris Moore
 **
-**     This software and associated documentation
-**     are CONFIDENTIAL and PROPRIETARY property of
-**     the above-mentioned copyright holder.
+**     This package is free software; you can redistribute it and/or
+**     modify it under the terms of the GNU General Public License as
+**     published by the Free Software Foundation; either version 2 of
+**     the License, or (at your option) any later version.
 **
-**     You may not copy, print, publish, or in any
-**     other way distribute this software without
-**     a prior written agreement with
-**     the copyright holder.
+**     This package is distributed in the hope that it will be useful,
+**     but WITHOUT ANY WARRANTY; without even the implied warranty of
+**     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+**     General Public License for more details.
 **     \endlegal
 */
 /* ========================================================================= */
 #include "general.h"
 #include <cmath>
 #include <cassert>
+#include <algorithm>
 #include <ctype.h>
 #include <math.h>
 
-#ifndef isnan
 
 #ifdef WIN32
 #include <float.h>
@@ -47,12 +49,18 @@ extern "C" { int _isnan(double x); }
 #endif
 #endif
 
-#ifdef __APPLE__
-#define isnan __isnan
+// For some reason isnan() isn't working on macosx any more.
+// This is a quick fix.
+#if defined(__APPLE__) && !defined(SYNFIG_ISNAN_FIX)
+#ifdef isnan
+#undef isnan
 #endif
-
+inline bool isnan(double x) { return x != x; }
+inline bool isnan(float x) { return x != x; }
+#define SYNFIG_ISNAN_FIX 1
 #endif
 
+
 #endif
 
 /* === U S I N G =========================================================== */
@@ -76,13 +84,13 @@ Time::Time(const String &str_, float fps):
        std::transform(str.begin(),str.end(),str.begin(),&tolower);
 
        // Start/Begin Of Time
-       if(str=="SOT" || str=="BOT")
+       if(str=="sot" || str=="bot")
        {
                operator=(begin());
                return;
        }
        // End Of Time
-       if(str=="EOT")
+       if(str=="eot")
        {
                operator=(end());
                return;
@@ -92,8 +100,8 @@ Time::Time(const String &str_, float fps):
        unsigned int pos=0;
        int read;
        float amount;
-       
-       // Now try to read it in the letter-abreviated format
+
+       // Now try to read it in the letter-abbreviated format
        while(pos<str.size() && sscanf(String(str,pos).c_str(),"%f%n",&amount,&read))
        {
                pos+=read;
@@ -139,7 +147,7 @@ Time::Time(const String &str_, float fps):
                                                        value_=frame/fps+(hour*3600+minute*60+second);
                                                        return;
                                        }
-                       
+
                                        if(sscanf(str.c_str(),"%d:%d:%d",&hour,&minute,&second)==3)
                                        {
                                                value_=hour*3600+minute*60+second;
@@ -163,28 +171,29 @@ String
 Time::get_string(float fps, Time::Format format)const
 {
        Time time(*this);
-       
+
        if(time<=begin())
                return "SOT";   // Start Of Time
        if(time>=end())
                return "EOT";   // End Of Time
-       
+
        if(fps<0)fps=0;
-       
+
        if(ceil(time.value_)-time.value_<epsilon_())
                time.value_=ceil(time.value_);
-       
+
        int hour,minute;
-       
+
        hour=time/3600;time-=hour*3600;
        minute=time/60;time-=minute*60;
-       
+
+       // <= is redefined, so this means "is the FORMAT_VIDEO bit set in the format?"
        if(format<=FORMAT_VIDEO)
        {
                int second;
                second=time;time-=second;
 
-               if(fps)
+               if(fps && fps>1)
                {
                        int frame;
                        frame=round_to_int(time*fps);
@@ -194,39 +203,81 @@ Time::get_string(float fps, Time::Format format)const
                else
                        return strprintf("%02d:%02d:%02d",hour,minute,second);
        }
-       
+
        String ret;
+       bool started = false;
 
        if(format<=FORMAT_FULL || hour)
-               ret+=strprintf(format<=FORMAT_NOSPACES?"%dh":"%dh ",hour);
-       
-       if(format<=FORMAT_FULL || hour || minute)
-               ret+=strprintf(format<=FORMAT_NOSPACES?"%dm":"%dm ",minute);
-       
-       if(fps)
+       {
+               ret+=strprintf("%dh",hour);
+               started = true;
+       }
+
+       if(format<=FORMAT_FULL || minute)
+       {
+               if (!(format<=FORMAT_NOSPACES) && started)
+                       ret += " ";
+
+               ret += strprintf("%dm", minute);
+               started = true;
+       }
+
+       if(fps && fps>1)
        {
                int second;
                float frame;
                second=time;time-=second;
                frame=time*fps;
+
                if(format<=FORMAT_FULL || second)
-                       ret+=strprintf(format<=FORMAT_NOSPACES?"%ds":"%ds ",(int)second);
-               
-               if(abs(frame-floor(frame)>=epsilon_()))
-                       ret+=strprintf("%0.3ff",frame);
-               else
-                       ret+=strprintf("%0.0ff",frame);
+               {
+                       if (!(format<=FORMAT_NOSPACES) && started)
+                               ret += " ";
+
+                       ret += strprintf("%ds", (int)second);
+                       started = true;
+               }
+
+               if(format<=FORMAT_FULL || frame || !started)
+               {
+                       if (!(format<=FORMAT_NOSPACES) && started)
+                               ret += " ";
+
+                       if(abs(frame-floor(frame) >= epsilon_()))
+                               ret += strprintf("%0.3ff", frame);
+                       else
+                               ret += strprintf("%0.0ff", frame);
+               }
        }
        else
        {
                float second;
                second=time;
-               if(abs(second-floor(second))>=epsilon_())
-                       ret+=strprintf("%0.8fs",second);
-               else
-                       ret+=strprintf("%0.0fs",second);
+               if(format<=FORMAT_FULL || second || !started)
+               {
+                       if (!(format<=FORMAT_NOSPACES) && started)
+                               ret += " ";
+
+                       if(abs(second-floor(second))>=epsilon_())
+                       {
+                               String seconds(strprintf("%0.8f",second));
+
+                               // skip trailing zeros
+                               int count = 0;
+                               String::reverse_iterator i = seconds.rbegin();
+                               for ( ; (*i) == '0'; i++)
+                                       count++;
+
+                               // if we removed too many, go back one place, leaving one zero
+                               if (*i < '0' || *i > '9') count--;
+
+                               ret += seconds.substr(0, seconds.size()-count) + "s";
+                       }
+                       else
+                               ret+=strprintf("%0.0fs",second);
+               }
        }
-       
+
        return ret;
 }
 
@@ -245,6 +296,14 @@ Time::round(float fps)const
                return ceil(time)/fps;
 }
 
+#ifdef _DEBUG
+const char *
+Time::c_str()const
+{
+       return get_string().c_str();
+}
+#endif
+
 //! \writeme
 bool
 Time::is_valid()const