⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 animate_n.cpp

📁 彩信浏览器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// 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_n.cpp,v 1.21 2007/02/12 14:15:14 jackjansen Exp $  */#include "ambulant/smil2/animate_n.h"#include "ambulant/smil2/animate_f.h"#include "ambulant/lib/document.h"#include "ambulant/common/region_info.h"#include "ambulant/lib/colors.h"#include "ambulant/common/region_dim.h"#include "ambulant/lib/logger.h"//#define AM_DBG if(1)#ifndef AM_DBG#define AM_DBG if(0)#endif#define IGNORE_ATTR_COMP trueusing namespace ambulant;using namespace smil2;////////////////////////////////////// animate_node//// An animate_node is the base class for all animation node flavorsanimate_node::animate_node(context_type *ctx, const node *n, animate_attrs *aattrs):	time_node(ctx, n, tc_none, false), 	m_aattrs(aattrs) {}animate_node::~animate_node() {	delete m_aattrs;}void animate_node::prepare_interval() {}void animate_node::read_dom_value(common::animation_destination *dst, animate_registers& regs) const {}bool animate_node::set_animated_value(common::animation_destination *dst, animate_registers& regs) const {	return false;}void animate_node::apply_self_effect(animate_registers& regs) const {}////////////////////////////////////// linear_values animation// A linear_values_animation is applicable for linear-attributes// linear-attributes define: addition, subtraction and scaling// A linear_values_animation may be continuous or discrete // The interpolation mode (calcMode) of a continuous linear_values animation may be linear, paced or spline// F: the simple function// T: the type of the attribute// The type T must define addition, subtraction and scalingtemplate <class F, class T>class linear_values_animation : public animate_node {  public:	linear_values_animation(context_type *ctx, const node *n, animate_attrs *aattrs);	~linear_values_animation();		void prepare_interval();	  protected:	bool verify_key_times(std::vector<double>& keyTimes);		F m_simple_f;	animate_f<F> *m_animate_f;	std::vector<T> m_values;	};template <class F, class T>linear_values_animation<F, T>::linear_values_animation(context_type *ctx, const node *n, animate_attrs *aattrs):	animate_node(ctx, n, aattrs), m_animate_f(0)  {	m_aattrs->get_values(m_values);}template <class F, class T>linear_values_animation<F, T>::~linear_values_animation() {	delete m_animate_f;}template <class F, class T>void linear_values_animation<F, T>::prepare_interval() {	time_type dur = calc_dur();	time_type sfdur = dur;	const time_attrs* ta = get_time_attrs();	if(dur.is_definite() && ta->auto_reverse()) sfdur /= 2;	if(m_aattrs->get_calc_mode() == "paced") {		// ignore key times		m_simple_f.paced_init(sfdur(), m_values);	} else {		// use key times when valid and when not ignorable		std::vector<double> keyTimes;		m_aattrs->get_key_times(keyTimes);//gcc2.95 Internal compiler error in `assign_stack_temp_for_type `//		bool keyTimesValid = keyTimes.empty() || verify_key_times(keyTimes);		bool keyTimesValid = false;		if(keyTimes.empty() || verify_key_times(keyTimes))	        	keyTimesValid = true;		if(!keyTimes.empty() && keyTimesValid && 			(dur.is_definite() || m_aattrs->get_calc_mode() == "discrete")) {			m_simple_f.init(sfdur(), m_values, keyTimes);		} else				m_simple_f.init(sfdur(), m_values);	}	m_simple_f.set_auto_reverse(ta->auto_reverse());	m_simple_f.set_accelerate(ta->get_accelerate(), ta->get_decelerate());		time_type ad = m_interval.end - m_interval.begin;	m_animate_f = new animate_f<F>(m_simple_f, dur(), ad(), m_aattrs->is_accumulative());}template <class F, class T>bool linear_values_animation<F, T>::verify_key_times(std::vector<double>& keyTimes) {	bool keyTimesValid = true;	if(keyTimes.empty()) return true;	if(keyTimes.front() != 0.0 || keyTimes.size() != m_values.size())		keyTimesValid = false;	if(m_aattrs->get_calc_mode() != "discrete" && keyTimes.back() != 1.0)		keyTimesValid = false;	for(size_t i=1;i<keyTimes.size() && keyTimesValid ;i++) 			keyTimesValid = (keyTimes[i]>keyTimes[i-1]);	if(!keyTimesValid)		m_logger->trace("<%s id=\"%s\">: invalid key times", m_attrs.get_tag().c_str(), m_attrs.get_id().c_str());	AM_DBG {		if(!keyTimes.empty() && keyTimesValid) {			std::string str;			for(size_t i=0;i<keyTimes.size();i++) {//gcc2.95 Internal compiler err.char sz[32];				char sz[64];				sprintf(sz,"%.3f;", keyTimes[i]);str += sz;			}			m_logger->debug("%s[%s] keyTimes: %s", 				m_attrs.get_tag().c_str(), m_attrs.get_id().c_str(), str.c_str());		}	}	return keyTimesValid;}////////////////////////////////////// underlying_to_animation// A underlying_to_animation is applicable for linear-attributes// linear-attributes define: addition, subtraction and scaling// F: the simple function// T: the type of the attribute// The type T must define addition, subtraction and scalingtemplate <class T>class underlying_to_animation : public animate_node {  public:	underlying_to_animation(context_type *ctx, const node *n, animate_attrs *aattrs);	~underlying_to_animation();		void prepare_interval();		  protected:	typedef underlying_to_f<T> F;	F m_simple_f;	animate_f<F> *m_animate_f;	T m_value;};template <class T>underlying_to_animation<T>::underlying_to_animation(context_type *ctx, const node *n, animate_attrs *aattrs):	animate_node(ctx, n, aattrs), m_animate_f(0)  {	std::vector<T> v;	m_aattrs->get_values(v);	m_value = v[0];}template <class T>underlying_to_animation<T>::~underlying_to_animation() {	delete m_animate_f;}template <class T>void underlying_to_animation<T>::prepare_interval() {	time_type dur = calc_dur();	time_type sfdur = dur;	const time_attrs* ta = get_time_attrs();	if(dur.is_definite() && ta->auto_reverse()) sfdur /= 2;	m_simple_f.init(sfdur(), m_value);	m_simple_f.set_auto_reverse(ta->auto_reverse());	m_simple_f.set_accelerate(ta->get_accelerate(), ta->get_decelerate());	time_type ad = m_interval.end - m_interval.begin;	m_animate_f = new animate_f<F>(m_simple_f, dur(), ad(), m_aattrs->is_accumulative());}////////////////////////////////////// regdim_animation//// A regdim_animation may be used for all region dim animations except for "to" animations// // Animateable region/subregion attributes: "left", "top", "width", "height", "right", "bottom"template <class F>class regdim_animation : public linear_values_animation<F, common::region_dim> {  public:	  regdim_animation(time_node_context *ctx, const node *n, animate_attrs *aattrs)	:	linear_values_animation<F, common::region_dim>(ctx, n, aattrs) {}		void read_dom_value(common::animation_destination *dst, animate_registers& regs) const {		regs.rd = dst->get_region_dim(this->m_aattrs->get_target_attr(), true);	}	bool set_animated_value(common::animation_destination *dst, animate_registers& regs) const {		common::region_dim rd = dst->get_region_dim(this->m_aattrs->get_target_attr(), false);		if(rd != regs.rd || IGNORE_ATTR_COMP) {			AM_DBG {				lib::timer::time_type t = this->m_timer->elapsed();				lib::logger::get_logger()->debug("%s(%ld) -> %s", 					this->m_aattrs->get_target_attr().c_str(), t, ::repr(regs.rd).c_str());			}			dst->set_region_dim(this->m_aattrs->get_target_attr(), regs.rd);			return true;		}		return false;	}	void apply_self_effect(animate_registers& regs) const {		if(!this->m_animate_f) return;		lib::timer::time_type t = this->m_timer->elapsed();		common::region_dim rd = this->m_animate_f->at(t);		if(this->m_aattrs->is_additive())			regs.rd += rd; // add					else			regs.rd = rd; // override	}};class underlying_to_regdim_animation : public underlying_to_animation<common::region_dim> {  public:	underlying_to_regdim_animation(context_type *ctx, const node *n, animate_attrs *aattrs)	:	underlying_to_animation<common::region_dim>(ctx, n, aattrs) {}		void read_dom_value(common::animation_destination *dst, animate_registers& regs) const {		regs.rd = dst->get_region_dim(m_aattrs->get_target_attr(), true);	}	bool set_animated_value(common::animation_destination *dst, animate_registers& regs) const {		common::region_dim rd = dst->get_region_dim(m_aattrs->get_target_attr(), false);		if(rd != regs.rd || IGNORE_ATTR_COMP) {			AM_DBG {				lib::timer::time_type t = m_timer->elapsed();				lib::logger::get_logger()->debug("%s(%ld) -> %s", 					m_aattrs->get_target_attr().c_str(), t, ::repr(regs.rd).c_str());			}					dst->set_region_dim(m_aattrs->get_target_attr(), regs.rd);			return true;		}		return false;	}	void apply_self_effect(animate_registers& regs) const {		if(!m_animate_f) return;		lib::timer::time_type t = m_timer->elapsed();		common::region_dim rd = m_animate_f->at(t, regs.rd);		regs.rd = rd; // override	}};////////////////////////////////////// color_animation//// A color_animation may be used for all backgroundColor/color animations except for "to" animations// // Animateable region/subregion attributes: "backgroundColor", "color"template <class F>class color_animation : public linear_values_animation<F, lib::color_t> {  public:	color_animation(time_node_context *ctx, const node *n, animate_attrs *aattrs)	:	linear_values_animation<F, lib::color_t>(ctx, n, aattrs) {}		void read_dom_value(common::animation_destination *dst, animate_registers& regs) const {		regs.cl = dst->get_region_color(this->m_aattrs->get_target_attr(), true);	}	bool set_animated_value(common::animation_destination *dst, animate_registers& regs) const {		lib::color_t cl = dst->get_region_color(this->m_aattrs->get_target_attr(), false);		if(cl != regs.cl || IGNORE_ATTR_COMP) {			AM_DBG {				lib::timer::time_type t = this->m_timer->elapsed();				lib::logger::get_logger()->debug("%s(%ld) -> 0x%x", 					this->m_aattrs->get_target_attr().c_str(), t, regs.cl);			}							dst->set_region_color(this->m_aattrs->get_target_attr(), regs.cl);			return true;		}		return false;	}		void apply_self_effect(animate_registers& regs) const {		if(!this->m_animate_f) return;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -