/*! \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-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007, 2008 Chris Moore
+** Copyright (c) 2008 Gerco Ballintijn
+** Copyright (c) 2008 Carlos López
**
** This package is free software; you can redistribute it and/or
** modify it under the terms of the GNU General Public License as
#include "general.h"
#include <cmath>
#include <cassert>
+#include <algorithm>
#include <ctype.h>
#include <math.h>
-#ifndef isnan
#ifdef WIN32
#include <float.h>
#endif
#endif
-#ifdef __APPLE__
-#define isnan __isnanf
+// 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 =========================================================== */
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;
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;
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;
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;
-
+
+ int hour = 0, minute = 0;
+ if(!(format<=FORMAT_FRAMES))
+ {
+ 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);
else
return strprintf("%02d:%02d:%02d",hour,minute,second);
}
-
+
+ if (format <= FORMAT_FRAMES)
+ {
+ if (fps && fps>0)
+ return strprintf("%df", round_to_int(time * fps));
+ else
+ return strprintf("%ds", round_to_int(time * 1));
+ }
+
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 || abs(frame) > epsilon_() || !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;
}
return ceil(time)/fps;
}
+#ifdef _DEBUG
+const char *
+Time::c_str()const
+{
+ return get_string().c_str();
+}
+#endif
+
//! \writeme
bool
Time::is_valid()const