📄 animate_a.cpp
字号:
// This file is part of Ambulant Player, www.ambulantplayer.org.//// Copyright (C) 2003-2007 Stichting CWI, // Kruislaan 413, 1098 SJ Amsterdam, The Netherlands.//// Ambulant Player is free software; you can redistribute it and/or modify// it under the terms of the GNU Lesser General Public License as published by// the Free Software Foundation; either version 2.1 of the License, or// (at your option) any later version.//// Ambulant Player 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 Lesser General Public License for more details.//// You should have received a copy of the GNU Lesser General Public License// along with Ambulant Player; if not, write to the Free Software// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA/* * @$Id: animate_a.cpp,v 1.18 2007/02/12 14:15:14 jackjansen Exp $ */#include "ambulant/smil2/animate_a.h"#include "ambulant/lib/node.h"#include "ambulant/lib/document.h"#include "ambulant/lib/colors.h"#include "ambulant/common/region_dim.h"#include "ambulant/lib/logger.h"#include "ambulant/lib/parselets.h"#include "ambulant/lib/gpaths.h"//#define AM_DBG if(1)#ifndef AM_DBG#define AM_DBG if(0)#endifusing namespace ambulant;using namespace smil2;animate_attrs::animate_attrs(const lib::node *n, const lib::node* tparent): m_node(n), m_tparent(tparent), m_target(0) { m_logger = lib::logger::get_logger(); const char *pid = m_node->get_attribute("id"); m_id = (pid?pid:"no-id"); m_tag = m_node->get_local_name(); locate_target_element(); locate_target_attr(); m_animtype = find_anim_type(); read_enum_atttrs(); AM_DBG m_logger->debug("%s[%s].%s --> %s.%s", m_tag.c_str(), m_id.c_str(), m_animtype.c_str(), m_target_type.c_str(), m_attrname.c_str()); apply_constraints(); }animate_attrs::~animate_attrs() {}void animate_attrs::locate_target_element() { const char *p = m_node->get_attribute("targetElement"); if(p) { m_target = m_node->get_context()->get_node(p); if(!m_target) { m_logger->trace("<%s id=\"%s\" targetElement=\"%s\">: target not found", m_tag.c_str(), m_id.c_str(), p); m_logger->warn(gettext("Error in SMIL animation")); return; } } else { m_target = m_tparent; } if(m_target) { std::string ttag = m_target->get_local_name(); if(ttag == "region") m_target_type = "region"; else if(ttag == "area") m_target_type = "area"; else m_target_type = "subregion"; } else { m_logger->trace("<%s id=\"%s\">: failed to locate target node", m_tag.c_str(), m_id.c_str()); m_logger->warn(gettext("Error in SMIL animation")); }}void animate_attrs::locate_target_attr() { if(m_tag == "animateMotion") { m_attrname = "position"; m_attrtype = "point"; return; } const char *p = m_node->get_attribute("attributeName"); if(!p) { m_logger->trace("<%s id=\"%s\">: attributeName is missing", m_tag.c_str(), m_id.c_str()); m_logger->warn(gettext("Error in SMIL animation")); return; } m_attrname = p; static char *reg_dim_names[] = {"left", "top", "width", "height", "right", "bottom"}; static int n = sizeof(reg_dim_names)/sizeof(const char *); for(int i=0;i<n;i++) { if(m_attrname == reg_dim_names[i]) { m_attrtype = "reg_dim"; break; } } if(!m_attrtype.empty()) return; if(m_attrname == "backgroundColor") { m_attrtype = "color"; } else if(m_attrname == "z-index") { m_attrtype = "int"; } else if(m_attrname == "soundLevel") { m_attrtype = "double"; } else if(m_attrname == "coords") { m_attrtype = "int_tuple"; } else if(m_attrname == "color") { m_attrtype = "color"; } else if (m_attrname == "soundAlign") { m_attrtype = "soundAlign"; } else { m_logger->trace("<%s id=\"%s\" attributeName=\"%s\">: attribute cannot be animated", m_tag.c_str(), m_id.c_str(), m_attrname.c_str()); m_logger->warn(gettext("Error in SMIL animation")); }}// Return true when // a) calcMode is discrete// b) the attribute is not linear (emum or strings)// c) for set animationsbool animate_attrs::is_discrete() const { return m_calc_mode == "discrete" || m_tag == "set"; }// Returns one of: invalid, values, from-to, from-by, to, byconst char* animate_attrs::find_anim_type() { const char *ppath = m_node->get_attribute("path"); if(ppath) return "path"; const char *pvalues = m_node->get_attribute("values"); if(pvalues) return "values"; const char *pfrom = m_node->get_attribute("from"); const char *pto = m_node->get_attribute("to"); const char *pby = m_node->get_attribute("by"); if(!pto && !pby) return "invalid"; if(pfrom) { if(pto) return "from-to"; else if(pby) return "from-by"; } else { if(pto) return "to"; else if(pby) return "by"; } m_logger->error("<%s id=\"%s\">: the animation values are invalid", m_tag.c_str(), m_id.c_str()); m_logger->warn(gettext("Error in SMIL animation")); return "invalid";}void animate_attrs::read_enum_atttrs() { const char *p = m_node->get_attribute("additive"); if(p && strcmp(p, "sum") == 0 /* && attr additive */) m_additive = true; else if(p && strcmp(p, "replace") == 0) m_additive = false; else { m_additive = false; // default is 'replace' if(m_animtype == "by" /* && attr additive */) m_additive = true; } p = m_node->get_attribute("accumulate"); if(p && strcmp(p, "sum") == 0 /* && attr additive */) m_accumulate = true; else if(p && strcmp(p, "none") == 0) m_accumulate = false; else m_accumulate = false; // default is 'none' p = m_node->get_attribute("calcMode"); if(p) m_calc_mode = p; // verify in (linear, paced, spline, discrete) else { m_calc_mode = "linear"; if(m_tag == "animateMotion") m_calc_mode = "paced"; }}// Apply any constraints after reading attributes// Validate attributesvoid animate_attrs::apply_constraints() { if(m_tag == "set") m_calc_mode = "discrete"; // validate if(!m_target || m_attrtype.empty()) { m_animtype = "invalid"; } // Override additive for "by" animations if(m_animtype == "by" /* && attr additive */) m_additive = true; // XXX: check values // ...}void animate_attrs::get_key_times(std::vector<double>& v) { const char *p = m_node->get_attribute("keyTimes"); if(!p) return; std::list<std::string> c; lib::split_trim_list(p, c, ';'); lib::number_p parser; for(std::list<std::string>::iterator it=c.begin();it!=c.end();it++) { if(parser.matches(*it)) v.push_back(parser.get_result()); else { m_logger->error("<%s id=\"%s\" keyTimes=\"%s\">: invalid keyTime", m_tag.c_str(), m_id.c_str(), p); m_logger->warn(gettext("Error in SMIL animation")); } }}void animate_attrs::get_key_splines(std::vector<qtuple>& v) { const char *attr = m_node->get_attribute("keySplines"); if(!attr) return; std::list<std::string> c; lib::split_trim_list(attr, c, ';'); lib::number_p parser; for(std::list<std::string>::iterator it=c.begin();it!=c.end();it++) { std::list<std::string> sc; lib::split_trim_list(*it, sc, ' '); if(sc.size() != 4) { m_logger->error("<%s id=\"%s\" keySplines=\"%s\">: invalid keySplines", m_tag.c_str(), m_id.c_str(), attr); m_logger->warn(gettext("Error in SMIL animation")); } qtuple qt; double *p = qt.v; bool succeeded = true; for(std::list<std::string>::iterator it2=sc.begin();it2!=sc.end();it2++) { if(parser.matches(*it)) *p++ = parser.get_result(); else { m_logger->error("<%s id=\"%s\" keySplines=\"%s\">: invalid keySplines", m_tag.c_str(), m_id.c_str(), p); m_logger->warn(gettext("Error in SMIL animation")); succeeded = false; break; } } if(succeeded) v.push_back(qt); }}int animate_attrs::safeatoi(const char *p) { if(!p) return 0; return atoi(p);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -