/* === S Y N F I G ========================================================= */ /*! \file value.cpp ** \brief Template Header ** ** $Id$ ** ** \legal ** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley ** Copyright (c) 2007, 2008 Chris Moore ** Copyright (c) 2011 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 ** 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 "value.h" #include "general.h" #include #include "canvas.h" #include "gradient.h" #include "vector.h" #include "time.h" #include "segment.h" #include "color.h" #endif using namespace synfig; using namespace std; using namespace etl; /* === M A C R O S ========================================================= */ /* === G L O B A L S ======================================================= */ /* === P R O C E D U R E S ================================================= */ /* === M E T H O D S ======================================================= */ ValueBase::ValueBase():type(TYPE_NIL),data(0),ref_count(0),loop_(0),static_(0) { } ValueBase::ValueBase(Type x): type(x), data(0), loop_(0), static_(0) { switch(type) { case TYPE_BOOL: data=static_cast(new bool()); break; case TYPE_INTEGER: data=static_cast(new int()); break; case TYPE_ANGLE: data=static_cast(new Angle()); break; case TYPE_VECTOR: data=static_cast(new Vector()); break; case TYPE_TIME: data=static_cast(new Time()); break; case TYPE_REAL: data=static_cast(new Real()); break; case TYPE_COLOR: data=static_cast(new Color()); break; case TYPE_SEGMENT: data=static_cast(new Segment()); break; case TYPE_BLINEPOINT: data=static_cast(new BLinePoint()); break; case TYPE_WIDTHPOINT: data=static_cast(new WidthPoint()); break; case TYPE_DASHITEM: data=static_cast(new DashItem()); break; case TYPE_LIST: data=static_cast(new list_type()); break; case TYPE_STRING: data=static_cast(new String()); break; case TYPE_GRADIENT: data=static_cast(new Gradient()); break; case TYPE_CANVAS: data=static_cast(new etl::handle()); break; default: break; } } ValueBase::~ValueBase() { clear(); } const char* ValueBase::get(const char*)const { return get(String()).c_str(); } #ifdef _DEBUG String ValueBase::get_string() const { switch(type) { case TYPE_NIL: return "Nil"; case TYPE_BOOL: return strprintf("Bool (%s)", get(bool()) ? "true" : "false"); case TYPE_INTEGER: return strprintf("Integer (%s)", get(int())); case TYPE_ANGLE: return strprintf("Angle (%.2f)", Angle::deg(get(Angle())).get()); // All types after this point are larger than 32 bits case TYPE_TIME: return strprintf("Time (%s)", get(Time()).get_string().c_str()); case TYPE_REAL: return strprintf("Real (%f)", get(Real())); // All types after this point are larger than 64 bits case TYPE_VECTOR: return strprintf("Vector (%f, %f)", get(Vector())[0], get(Vector())[1]); case TYPE_COLOR: return strprintf("Color (%s)", get(Color()).get_string().c_str()); case TYPE_SEGMENT: return strprintf("Segment ((%f, %f) to (%f, %f))", get(Segment()).p1[0], get(Segment()).p1[1], get(Segment()).p2[0], get(Segment()).p2[1]); case TYPE_BLINEPOINT: return strprintf("BLinePoint (%s)", get(BLinePoint()).get_vertex()[0], get(BLinePoint()).get_vertex()[1]); case TYPE_WIDTHPOINT: return strprintf("WidthPoint (%s)", get(WidthPoint()).get_position(), get(WidthPoint()).get_width()); case TYPE_DASHITEM: return strprintf("DashItem (%s)", get(DashItem()).get_offset(), get(DashItem()).get_length()); // All types after this point require construction/destruction case TYPE_LIST: return strprintf("List (%d elements)", get(list_type()).size()); case TYPE_CANVAS: return strprintf("Canvas (%s)", get(etl::loose_handle())->get_id().c_str()); case TYPE_STRING: return strprintf("String (%s)", get(String()).c_str()); case TYPE_GRADIENT: return strprintf("Gradient (%d cpoints)", get(Gradient()).size()); default: return "Invalid type"; } } #endif // _DEBUG void ValueBase::set(Canvas* x) { clear(); if(x && x->is_inline()) { _set(etl::handle(x)); } else { _set(etl::loose_handle(x)); } assert(get(x)==x); } void ValueBase::set(etl::loose_handle x) { clear(); if(x && x->is_inline()) _set(etl::handle(x)); else _set(etl::loose_handle(x)); assert(get(x)==x); } void ValueBase::set(etl::handle x) { clear(); if(x && x->is_inline()) _set(etl::handle(x)); else _set(etl::loose_handle(x)); assert(get(x)==x); } void ValueBase::set(const list_type &x) { _set(x); } void ValueBase::set(const char* x) { _set(String(x)); } void ValueBase::set(char* x) { _set(String(x)); } bool ValueBase::is_valid()const { return type>TYPE_NIL && type(data); break; case TYPE_INTEGER: delete static_cast(data); break; case TYPE_ANGLE: delete static_cast(data); break; case TYPE_TIME: delete static_cast(data); break; case TYPE_REAL: delete static_cast(data); break; case TYPE_VECTOR: delete static_cast(data); break; case TYPE_COLOR: delete static_cast(data); break; case TYPE_SEGMENT: delete static_cast(data); break; case TYPE_BLINEPOINT: delete static_cast(data); break; case TYPE_WIDTHPOINT: delete static_cast(data); break; case TYPE_DASHITEM: delete static_cast(data); break; case TYPE_LIST: delete static_cast(data); break; case TYPE_CANVAS: { etl::handle canvas(get(etl::loose_handle())); if(canvas && canvas->is_inline()) delete static_cast*>(data); else delete static_cast*>(data); break; } case TYPE_STRING: delete static_cast(data); break; case TYPE_GRADIENT: delete static_cast(data); break; default: break; } } ref_count.detach(); data=0; type=TYPE_NIL; } String ValueBase::type_name(Type id) { // don't internationalize these type names - they're using in .sif files switch(id) { /* TRANSLATORS: this is the name of a type -- see http://synfig.org/wiki/Dev:Types */ case TYPE_BOOL: return N_("bool"); /* TRANSLATORS: this is the name of a type -- see http://synfig.org/wiki/Dev:Types */ case TYPE_INTEGER: return N_("integer"); /* TRANSLATORS: this is the name of a type -- see http://synfig.org/wiki/Dev:Types */ case TYPE_ANGLE: return N_("angle"); /* TRANSLATORS: this is the name of a type -- see http://synfig.org/wiki/Dev:Types */ case TYPE_TIME: return N_("time"); /* TRANSLATORS: this is the name of a type -- see http://synfig.org/wiki/Dev:Types */ case TYPE_REAL: return N_("real"); /* TRANSLATORS: this is the name of a type -- see http://synfig.org/wiki/Dev:Types */ case TYPE_VECTOR: return N_("vector"); /* TRANSLATORS: this is the name of a type -- see http://synfig.org/wiki/Dev:Types */ case TYPE_COLOR: return N_("color"); /* TRANSLATORS: this is the name of a type -- see http://synfig.org/wiki/Dev:Types */ case TYPE_SEGMENT: return N_("segment"); /* TRANSLATORS: this is the name of a type -- see http://synfig.org/wiki/Dev:Types */ case TYPE_BLINEPOINT: return N_("bline_point"); /* TRANSLATORS: this is the name of a type -- see http://synfig.org/wiki/Dev:Types */ case TYPE_WIDTHPOINT: return N_("width_point"); /* TRANSLATORS: this is the name of a type -- see http://synfig.org/wiki/Dev:Types */ case TYPE_DASHITEM: return N_("dash_item"); /* TRANSLATORS: this is the name of a type -- see http://synfig.org/wiki/Dev:Types */ case TYPE_LIST: return N_("list"); /* TRANSLATORS: this is the name of a type -- see http://synfig.org/wiki/Dev:Types */ case TYPE_CANVAS: return N_("canvas"); /* TRANSLATORS: this is the name of a type -- see http://synfig.org/wiki/Dev:Types */ case TYPE_STRING: return N_("string"); /* TRANSLATORS: this is the name of a type -- see http://synfig.org/wiki/Dev:Types */ case TYPE_GRADIENT: return N_("gradient"); /* TRANSLATORS: this is the name of a type -- see http://synfig.org/wiki/Dev:Types */ case TYPE_NIL: return N_("nil"); default: break; } synfig::warning("Encountered unknown ValueBase with an Type of %d",id); // assert(0); return "UNKNOWN"; } String ValueBase::type_local_name(Type id) { return dgettext("synfig",type_name(id).c_str()); } ValueBase::Type ValueBase::ident_type(const String &str) { if(str=="nil" || str=="null") return TYPE_NIL; else if(str=="time" || str==_("time")) return TYPE_TIME; else if(str=="real" || str=="float" || str==_("real")) return TYPE_REAL; else if(str=="integer" || str=="int" || str==_("integer")) return TYPE_INTEGER; else if(str=="bool" || str==_("bool")) return TYPE_BOOL; else if(str=="angle" || str=="degrees" || str=="radians" || str=="rotations") return TYPE_ANGLE; else if(str=="vector" || str=="point") return TYPE_VECTOR; else if(str=="color") return TYPE_COLOR; else if(str=="string") return TYPE_STRING; else if(str=="canvas") return TYPE_CANVAS; else if(str=="list") return TYPE_LIST; else if(str=="segment") return TYPE_SEGMENT; else if(str=="gradient") return TYPE_GRADIENT; else if(str=="bline_point" || str=="blinepoint") return TYPE_BLINEPOINT; else if(str=="width_point" || str=="widthpoint") return TYPE_WIDTHPOINT; else if(str=="dash_item" || str=="dashitem") return TYPE_DASHITEM; return TYPE_NIL; } bool ValueBase::operator==(const ValueBase& rhs)const { if(get_type()!=rhs.get_type()) return false; if(data==rhs.data) return true; switch(get_type()) { case TYPE_TIME: return get(Time()).is_equal(rhs.get(Time())); case TYPE_REAL: return abs(get(Real())-rhs.get(Real()))<=0.00000000000001; case TYPE_INTEGER: return get(int())==rhs.get(int()); case TYPE_BOOL: return get(bool())==rhs.get(bool()); case TYPE_ANGLE: return get(Angle())==rhs.get(Angle()); case TYPE_VECTOR: return get(Vector()).is_equal_to(rhs.get(Vector())); case TYPE_COLOR: return get(Color())==rhs.get(Color()); case TYPE_STRING: return get(String())==rhs.get(String()); case TYPE_CANVAS: return get(Canvas::LooseHandle())==rhs.get(Canvas::LooseHandle()); case TYPE_LIST: return get_list()==rhs.get_list(); case TYPE_WIDTHPOINT: return get(WidthPoint())==rhs.get(WidthPoint()); case TYPE_DASHITEM: return get(DashItem())==rhs.get(DashItem()); case TYPE_SEGMENT: // return get(Segment())==rhs.get(Segment()); case TYPE_GRADIENT: // return get(Gradient())==rhs.get(Gradient()); case TYPE_BLINEPOINT: // return get(BLinePoint())==rhs.get(BLinePoint()); case TYPE_NIL: default: return false; } return false; }