1 /* === S Y N F I G ========================================================= */
3 ** \brief Template File
5 ** $Id: time.cpp,v 1.1.1.1 2005/01/04 01:23:15 darco Exp $
8 ** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
10 ** This package is free software; you can redistribute it and/or
11 ** modify it under the terms of the GNU General Public License as
12 ** published by the Free Software Foundation; either version 2 of
13 ** the License, or (at your option) any later version.
15 ** This package is distributed in the hope that it will be useful,
16 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 ** General Public License for more details.
21 /* ========================================================================= */
23 /* === H E A D E R S ======================================================= */
33 #include <ETL/stringf>
45 extern "C" { int _isnan(double x); }
50 // For some reason isnan() isn't working on macosx any more.
51 // This is a quick fix.
52 #if defined(__APPLE__) && !defined(SYNFIG_ISNAN_FIX)
56 inline bool isnan(double x) { return x != x; }
57 inline bool isnan(float x) { return x != x; }
58 #define SYNFIG_ISNAN_FIX 1
64 /* === U S I N G =========================================================== */
68 using namespace synfig;
70 #define tolower ::tolower
72 /* === M A C R O S ========================================================= */
74 /* === G L O B A L S ======================================================= */
76 /* === M E T H O D S ======================================================= */
78 Time::Time(const String &str_, float fps):
82 std::transform(str.begin(),str.end(),str.begin(),&tolower);
84 // Start/Begin Of Time
85 if(str=="sot" || str=="bot")
102 // Now try to read it in the letter-abreviated format
103 while(pos<str.size() && sscanf(String(str,pos).c_str(),"%f%n",&amount,&read))
106 if(pos>=str.size() || read==0)
108 // Throw up a warning if there are no units
109 // and the amount isn't zero. There is no need
110 // to warn about units if the value is zero
111 // it is the only case where units are irrelevant.
113 synfig::warning("Time(): No unit provided in time code, assuming SECONDS (\"%s\")",str.c_str());
136 synfig::warning("Time(): Individual frames referenced, but frame rate is unknown");
139 // try to read it in as a traditional time format
141 int hour,minute,second;
143 if(fps && sscanf(str.c_str(),"%d:%d:%d.%f",&hour,&minute,&second,&frame)==4)
145 value_=frame/fps+(hour*3600+minute*60+second);
149 if(sscanf(str.c_str(),"%d:%d:%d",&hour,&minute,&second)==3)
151 value_=hour*3600+minute*60+second;
155 synfig::warning("Time(): Bad time format");
160 synfig::warning("Time(): Unexpected character '%c' when parsing time string \"%s\"",str[pos],str.c_str());
169 Time::get_string(float fps, Time::Format format)const
174 return "SOT"; // Start Of Time
176 return "EOT"; // End Of Time
180 if(ceil(time.value_)-time.value_<epsilon_())
181 time.value_=ceil(time.value_);
185 hour=time/3600;time-=hour*3600;
186 minute=time/60;time-=minute*60;
188 if(format<=FORMAT_VIDEO)
191 second=time;time-=second;
196 frame=round_to_int(time*fps);
198 return strprintf("%02d:%02d:%02d.%02d",hour,minute,second,frame);
201 return strprintf("%02d:%02d:%02d",hour,minute,second);
206 if(format<=FORMAT_FULL || hour)
207 ret+=strprintf(format<=FORMAT_NOSPACES?"%dh":"%dh ",hour);
209 if(format<=FORMAT_FULL || hour || minute)
210 ret+=strprintf(format<=FORMAT_NOSPACES?"%dm":"%dm ",minute);
216 second=time;time-=second;
218 if(format<=FORMAT_FULL || second)
219 ret+=strprintf(format<=FORMAT_NOSPACES?"%ds":"%ds ",(int)second);
221 if(abs(frame-floor(frame)>=epsilon_()))
222 ret+=strprintf("%0.3ff",frame);
224 ret+=strprintf("%0.0ff",frame);
230 if(abs(second-floor(second))>=epsilon_())
231 ret+=strprintf("%0.8fs",second);
233 ret+=strprintf("%0.0fs",second);
240 Time::round(float fps)const
244 value_type time(*this);
248 if(abs(time-floor(time))<0.5)
249 return floor(time)/fps;
251 return ceil(time)/fps;
256 Time::is_valid()const
258 return !isnan(value_);