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

📄 gameswf_styles.cpp

📁 一个开源的Flash 播放器,可以在Windows/Linux 上运行
💻 CPP
字号:
// gameswf_styles.cpp	-- Thatcher Ulrich <tu@tulrich.com> 2003// This source code has been donated to the Public Domain.  Do// whatever you want with it.// Fill and line style types.#include "gameswf_styles.h"#include "gameswf_impl.h"#include "gameswf_log.h"#include "gameswf_render.h"#include "gameswf_stream.h"namespace gameswf{	//	// gradient_record	//	gradient_record::gradient_record()		:		m_ratio(0)	{	}	void	gradient_record::read(stream* in, int tag_type)	{		m_ratio = in->read_u8();		m_color.read(in, tag_type);	}	//	// fill_style	//	fill_style::fill_style()		:		m_type(0),		m_gradient_bitmap_info(0),		m_bitmap_character(0)	{		assert(m_gradients.size() == 0);	}	fill_style::~fill_style()	{	}	void	fill_style::read(stream* in, int tag_type, movie_definition_sub* md)	{		m_type = in->read_u8();		IF_VERBOSE_PARSE(log_msg("  fill_style read type = 0x%X\n", m_type));		if (m_type == 0x00)		{			// 0x00: solid fill			if (tag_type <= 22) {				m_color.read_rgb(in);			} else {				m_color.read_rgba(in);			}			IF_VERBOSE_PARSE(log_msg("  color: ");					 m_color.print());		}		else if (m_type == 0x10 || m_type == 0x12)		{			// 0x10: linear gradient fill			// 0x12: radial gradient fill			matrix	input_matrix;			input_matrix.read(in);			if (m_type == 0x10)			{				m_gradient_matrix.set_identity();				m_gradient_matrix.concatenate_translation(128.f, 0.f);				m_gradient_matrix.concatenate_scale(1.0f / 128.0f);			}			else 			{				m_gradient_matrix.set_identity();				m_gradient_matrix.concatenate_translation(32.f, 32.f);				m_gradient_matrix.concatenate_scale(1.0f / 512.0f);			}			matrix	m;			m.set_inverse(input_matrix);			m_gradient_matrix.concatenate(m);							// GRADIENT			int	num_gradients = in->read_u8();			assert(num_gradients >= 1 && num_gradients <= 8);			m_gradients.resize(num_gradients);			for (int i = 0; i < num_gradients; i++)			{				m_gradients[i].read(in, tag_type);			}			IF_VERBOSE_PARSE(log_msg("  gradients: num_gradients = %d\n", num_gradients));			// @@ hack.			if (num_gradients > 0)			{				m_color = m_gradients[0].m_color;			}			if (md->get_create_bitmaps() == DO_LOAD_BITMAPS)			{				m_gradient_bitmap_info = create_gradient_bitmap();			}			else			{				m_gradient_bitmap_info = render::create_bitmap_info_empty();			}			// Make sure our movie_def_impl knows about this bitmap.			md->add_bitmap_info(m_gradient_bitmap_info.get_ptr());		}		else if (m_type == 0x40 || m_type == 0x41)		{			// 0x40: tiled bitmap fill			// 0x41: clipped bitmap fill			int	bitmap_char_id = in->read_u16();			IF_VERBOSE_PARSE(log_msg("  bitmap_char = %d\n", bitmap_char_id));			// Look up the bitmap character.			m_bitmap_character = md->get_bitmap_character(bitmap_char_id);			matrix	m;			m.read(in);			// For some reason, it looks like they store the inverse of the			// TWIPS-to-texcoords matrix.			m_bitmap_matrix.set_inverse(m);			IF_VERBOSE_PARSE(m_bitmap_matrix.print());		}	}	rgba	fill_style::sample_gradient(int ratio) const	// Return the color at the specified ratio into our gradient.	// Ratio is in [0, 255].	{		assert(ratio >= 0 && ratio <= 255);		assert(m_type == 0x10 || m_type == 0x12);		assert(m_gradients.size() > 0);		if (ratio < m_gradients[0].m_ratio)			return m_gradients[0].m_color;						for (int i = 1; i < m_gradients.size(); i++)		{			if (m_gradients[i].m_ratio >= ratio)			{				const gradient_record& gr0 = m_gradients[i - 1];				const gradient_record& gr1 = m_gradients[i];				float	f = 0.0f;				if (gr0.m_ratio != gr1.m_ratio)				{					f = (ratio - gr0.m_ratio) / float(gr1.m_ratio - gr0.m_ratio);				}				rgba	result;				result.set_lerp(m_gradients[i - 1].m_color, m_gradients[i].m_color, f);				return result;			}		}		return m_gradients.back().m_color;	}	gameswf::bitmap_info*	fill_style::create_gradient_bitmap() const	// Make a bitmap_info* corresponding to our gradient.	// We can use this to set the gradient fill style.	{		assert(m_type == 0x10 || m_type == 0x12);		image::rgba*	im = NULL;		if (m_type == 0x10)		{			// Linear gradient.			im = image::create_rgba(256, 1);			for (int i = 0; i < im->m_width; i++)			{				rgba	sample = sample_gradient(i);				im->set_pixel(i, 0, sample.m_r, sample.m_g, sample.m_b, sample.m_a);			}		}		else if (m_type == 0x12)		{			// Radial gradient.			im = image::create_rgba(64, 64);			for (int j = 0; j < im->m_height; j++)			{				for (int i = 0; i < im->m_width; i++)				{					float	radius = (im->m_height - 1) / 2.0f;					float	y = (j - radius) / radius;					float	x = (i - radius) / radius;					int	ratio = (int) floorf(255.5f * sqrt(x * x + y * y));					if (ratio > 255)					{						ratio = 255;					}					rgba	sample = sample_gradient( ratio );					im->set_pixel(i, j, sample.m_r, sample.m_g, sample.m_b, sample.m_a);				}			}		}		gameswf::bitmap_info*	bi = gameswf::render::create_bitmap_info_rgba(im);		delete im;		return bi;	}	void	fill_style::apply(int fill_side, float ratio) const	// Push our style parameters into the renderer.	{		UNUSED(ratio);		if (m_type == 0x00)		{			// 0x00: solid fill			gameswf::render::fill_style_color(fill_side, m_color);		}		else if (m_type == 0x10 || m_type == 0x12)		{			// 0x10: linear gradient fill			// 0x12: radial gradient fill			if (m_gradient_bitmap_info == NULL)			{				// This can happen when morphing gradient styles.				// assert(morphing???);				// log an error?				fill_style*	this_non_const = const_cast<fill_style*>(this);				this_non_const->m_gradient_bitmap_info = create_gradient_bitmap();			}			if (m_gradient_bitmap_info != NULL)			{				gameswf::render::fill_style_bitmap(					fill_side,					m_gradient_bitmap_info.get_ptr(),					m_gradient_matrix,					gameswf::render_handler::WRAP_CLAMP);			}		}		else if (m_type == 0x40				 || m_type == 0x41)		{			// bitmap fill (either tiled or clipped)			gameswf::bitmap_info*	bi = NULL;			if (m_bitmap_character != NULL)			{				bi = m_bitmap_character->get_bitmap_info();				if (bi != NULL)				{					gameswf::render_handler::bitmap_wrap_mode	wmode = gameswf::render_handler::WRAP_REPEAT;					if (m_type == 0x41)					{						wmode = gameswf::render_handler::WRAP_CLAMP;					}					gameswf::render::fill_style_bitmap(						fill_side,						bi,						m_bitmap_matrix,						wmode);				}			}		}	}	void	fill_style::set_lerp(const fill_style& a, const fill_style& b, float t)	// Sets this style to a blend of a and b.  t = [0,1]	{		assert(t >= 0 && t <= 1);		// fill style type		m_type = a.get_type();		assert(m_type == b.get_type());		// fill style color		m_color.set_lerp(a.get_color(), b.get_color(), t);		// fill style gradient matrix		//		// @@ TODO morphed gradients don't come out exactly		// right; they shift around some.  Not sure where the		// problem is.		m_gradient_matrix.set_lerp(a.m_gradient_matrix, b.m_gradient_matrix, t);		// fill style gradients		assert(m_gradients.size() == a.m_gradients.size());		assert(m_gradients.size() == b.m_gradients.size());		for (int j=0; j < m_gradients.size(); j++)		{			m_gradients[j].m_ratio =				(Uint8) frnd(					flerp(a.m_gradients[j].m_ratio, b.m_gradients[j].m_ratio, t)					);			m_gradients[j].m_color.set_lerp(a.m_gradients[j].m_color, b.m_gradients[j].m_color, t);		}		m_gradient_bitmap_info = NULL;		// fill style bitmap ID		m_bitmap_character = a.m_bitmap_character;		assert(m_bitmap_character == b.m_bitmap_character);		// fill style bitmap matrix		m_bitmap_matrix.set_lerp(a.m_bitmap_matrix, b.m_bitmap_matrix, t);	}	//	// line_style	//		line_style::line_style()		:		m_width(0)	{	}	void	line_style::read(stream* in, int tag_type)	{		m_width = in->read_u16();		m_color.read(in, tag_type);	}	void	line_style::apply(float ratio) const	{		UNUSED(ratio);		gameswf::render::line_style_color(m_color);		gameswf::render::line_style_width(m_width);	}}// Local Variables:// mode: C++// c-basic-offset: 8 // tab-width: 8// indent-tabs-mode: t// End:

⌨️ 快捷键说明

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