X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=synfig-core%2Fsrc%2Fsynfig%2Fdistance.cpp;fp=synfig-core%2Fsrc%2Fsynfig%2Fdistance.cpp;h=efac8e93b47f48dfd89d7d7457d3c52864f35f46;hb=a095981e18cc37a8ecc7cd237cc22b9c10329264;hp=0000000000000000000000000000000000000000;hpb=9459638ad6797b8139f1e9f0715c96076dbf0890;p=synfig.git diff --git a/synfig-core/src/synfig/distance.cpp b/synfig-core/src/synfig/distance.cpp new file mode 100644 index 0000000..efac8e9 --- /dev/null +++ b/synfig-core/src/synfig/distance.cpp @@ -0,0 +1,257 @@ +/* === S Y N F I G ========================================================= */ +/*! \file distance.cpp +** \brief Template File +** +** $Id$ +** +** \legal +** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley +** Copyright (c) 2008 Chris Moore +** +** 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. +** +** 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 +*/ +/* ========================================================================= */ + +/* === H E A D E R S ======================================================= */ + +#ifdef USING_PCH +# include "pch.h" +#else +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "distance.h" +#include "renddesc.h" +#include "general.h" +#include +#endif + +/* === U S I N G =========================================================== */ + +using namespace std; +using namespace etl; +using namespace synfig; + +/* === M A C R O S ========================================================= */ + +#define POINTS_PER_INCH (72.0) +#define INCHES_PER_METER (39.3700787402) +#define POINTS_PER_METER (POINTS_PER_INCH*INCHES_PER_METER) +#define CENTIMETERS_PER_METER (100.0) +#define MILLIMETERS_PER_METER (1000.0) + +#define METERS_PER_UNIT (rend_desc.get_physical_w()/abs(rend_desc.get_tl()[0]-rend_desc.get_br()[0])) + +/* === G L O B A L S ======================================================= */ + +/* === P R O C E D U R E S ================================================= */ + +/* === M E T H O D S ======================================================= */ + +Distance::Distance(const synfig::String& str) +{ + (*this)=str; +/* int i(0); + float val; + int ret(strscanf(str,"%f%n",&val,&i)); + synfig::info("Distance::Distance(): ret=%d, val=%f",ret,val); + + if(ret<=0) + { + // Error + synfig::error("Distance::Distance(): Bad value \"%s\"",str.c_str()); + value_=0; + } + else + value_=val; + + synfig::info("Distance::Distance(): system=\"%s\"",String(str.begin()+i,str.end()).c_str()); + system_=ident_system(String(str.begin()+i,str.end())); +*/ +} + +Distance& +Distance::operator=(const synfig::String& str) +{ + int i(0); + float val; + int ret(strscanf(str,"%f%n",&val,&i)); + // synfig::info("Distance::Distance(): ret=%d, val=%f",ret,val); + + if(ret<=0) + { + // Error + synfig::error("Distance::Distance(): Bad value \"%s\"",str.c_str()); + return *this; + } + else + value_=val; + + synfig::String sys(str.begin()+i,str.end()); + + if(sys.size()) + system_=ident_system(sys); + return *this; +} + +synfig::String +Distance::get_string(int digits)const +{ + digits=min(9,max(0,digits)); + String fmt(strprintf("%%.%01df%%s",digits)); + return strprintf(fmt.c_str(),value_,system_name(system_).c_str()); +} + +void +Distance::convert(Distance::System target, const RendDesc& rend_desc) +{ + value_=get(target,rend_desc); + system_=target; +} + +Real +Distance::get(Distance::System target, const RendDesc& rend_desc)const +{ + if(target==SYSTEM_UNITS) + return units(rend_desc); + if(target==SYSTEM_PIXELS) + return units(rend_desc)*METERS_PER_UNIT*rend_desc.get_x_res(); + + return meters_to_system(meters(rend_desc),target); +} + +Real +Distance::meters()const +{ + switch(system_) + { + case SYSTEM_INCHES: return value_/INCHES_PER_METER; + case SYSTEM_POINTS: return value_/POINTS_PER_METER; + case SYSTEM_METERS: return value_; + case SYSTEM_CENTIMETERS: return value_/CENTIMETERS_PER_METER; + case SYSTEM_MILLIMETERS: return value_/MILLIMETERS_PER_METER; + default: throw BadSystem(); + } +} + +Real +Distance::meters(const RendDesc& rend_desc)const +{ + if(system_>SYSTEM_PIXELS) + return meters(); + if(system_==SYSTEM_UNITS) + return value_*METERS_PER_UNIT; + if(system_==SYSTEM_PIXELS) + return value_/rend_desc.get_x_res(); + + throw BadSystem(); +} + +Real +Distance::units(const RendDesc& rend_desc)const +{ + if(system_==SYSTEM_UNITS) + return value_; + + Real ret; + + if(system_>SYSTEM_PIXELS) + ret=meters(); + else + ret=value_/rend_desc.get_x_res(); + + return ret/METERS_PER_UNIT; +} + + +Real // (static) +Distance::meters_to_system(Real x,System target_system) +{ + switch(target_system) + { + case SYSTEM_INCHES: return x*INCHES_PER_METER; + case SYSTEM_POINTS: return x*POINTS_PER_METER; + case SYSTEM_METERS: return x; + case SYSTEM_CENTIMETERS: return x*CENTIMETERS_PER_METER; + case SYSTEM_MILLIMETERS: return x*MILLIMETERS_PER_METER; + default: throw BadSystem(); + } +} + +Distance::System // (static) +Distance::ident_system(const synfig::String& x) +{ + synfig::String str; + + // Make it all upper case, and remove white space + for(unsigned int i=0;i