Blame synfig-core/src/modules/lyr_std/shade.cpp

Carlos Lopez a09598
/* === S Y N F I G ========================================================= */
Carlos Lopez a09598
/*!	\file shade.cpp
Carlos Lopez a09598
**	\brief Implementation of the "Shade" layer
Carlos Lopez a09598
**
Carlos Lopez a09598
**	$Id$
Carlos Lopez a09598
**
Carlos Lopez a09598
**	\legal
Carlos Lopez a09598
**	Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
Carlos Lopez a09598
**	Copyright (c) 2008 Chris Moore
Carlos Lopez e83454
**	Copyright (c) 2012-2013 Carlos Lรณpez
Carlos Lopez a09598
**
Carlos Lopez a09598
**	This package is free software; you can redistribute it and/or
Carlos Lopez a09598
**	modify it under the terms of the GNU General Public License as
Carlos Lopez a09598
**	published by the Free Software Foundation; either version 2 of
Carlos Lopez a09598
**	the License, or (at your option) any later version.
Carlos Lopez a09598
**
Carlos Lopez a09598
**	This package is distributed in the hope that it will be useful,
Carlos Lopez a09598
**	but WITHOUT ANY WARRANTY; without even the implied warranty of
Carlos Lopez a09598
**	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Carlos Lopez a09598
**	General Public License for more details.
Carlos Lopez a09598
**	\endlegal
Carlos Lopez a09598
*/
Carlos Lopez a09598
/* ========================================================================= */
Carlos Lopez a09598
Carlos Lopez a09598
/* === H E A D E R S ======================================================= */
Carlos Lopez a09598
Carlos Lopez a09598
#ifdef USING_PCH
Carlos Lopez a09598
#	include "pch.h"
Carlos Lopez a09598
#else
Carlos Lopez a09598
#ifdef HAVE_CONFIG_H
Carlos Lopez a09598
#	include <config.h></config.h>
Carlos Lopez a09598
#endif
Carlos Lopez a09598
13de48
#include <cstring></cstring>
13de48
13de48
#include <etl misc=""></etl>
13de48
Carlos Lopez a09598
#include "shade.h"
Carlos Lopez a09598
bw 94d8a6
#include <synfig localization.h=""></synfig>
bw 94d8a6
#include <synfig general.h=""></synfig>
bw 94d8a6
Carlos Lopez a09598
#include <synfig string.h=""></synfig>
Carlos Lopez a09598
#include <synfig time.h=""></synfig>
Carlos Lopez a09598
#include <synfig context.h=""></synfig>
Carlos Lopez a09598
#include <synfig paramdesc.h=""></synfig>
Carlos Lopez a09598
#include <synfig renddesc.h=""></synfig>
Carlos Lopez a09598
#include <synfig surface.h=""></synfig>
Carlos Lopez a09598
#include <synfig value.h=""></synfig>
Carlos Lopez a09598
#include <synfig valuenode.h=""></synfig>
Carlos Lopez a09598
#include <synfig segment.h=""></synfig>
Carlos Lopez 22afa5
#include <synfig cairo_renddesc.h=""></synfig>
Carlos Lopez a09598
da4398
#include <synfig primitive="" rendering="" transformationaffine.h=""></synfig>
13de48
13de48
#include <synfig common="" rendering="" task="" taskblur.h=""></synfig>
13de48
#include <synfig common="" rendering="" task="" tasktransformation.h=""></synfig>
5e2754
#include <synfig common="" rendering="" task="" taskpixelprocessor.h=""></synfig>
Carlos Lopez a09598
Carlos Lopez a09598
#endif
Carlos Lopez a09598
Carlos Lopez a09598
using namespace std;
9f3c68
using namespace etl;
9f3c68
using namespace synfig;
144d3f
using namespace modules;
9f3c68
using namespace lyr_std;
Carlos Lopez a09598
Carlos Lopez a09598
/*#define TYPE_BOX			0
Carlos Lopez a09598
#define TYPE_FASTGUASSIAN	1
Carlos Lopez a09598
#define TYPE_CROSS			2
Carlos Lopez a09598
#define TYPE_GAUSSIAN		3
Carlos Lopez a09598
#define TYPE_DISC			4
Carlos Lopez a09598
*/
Carlos Lopez a09598
Carlos Lopez a09598
/* -- G L O B A L S --------------------------------------------------------- */
Carlos Lopez a09598
Carlos Lopez a09598
SYNFIG_LAYER_INIT(Layer_Shade);
Carlos Lopez a09598
SYNFIG_LAYER_SET_NAME(Layer_Shade,"shade");
Carlos Lopez a09598
SYNFIG_LAYER_SET_LOCAL_NAME(Layer_Shade,N_("Shade"));
Carlos Lopez a09598
SYNFIG_LAYER_SET_CATEGORY(Layer_Shade,N_("Stylize"));
Carlos Lopez a09598
SYNFIG_LAYER_SET_VERSION(Layer_Shade,"0.2");
Carlos Lopez a09598
SYNFIG_LAYER_SET_CVS_ID(Layer_Shade,"$Id$");
Carlos Lopez a09598
Carlos Lopez a09598
/* -- F U N C T I O N S ----------------------------------------------------- */
Carlos Lopez a09598
eed519
static inline void clamp_size(Vector &v)
Carlos Lopez a09598
{
Carlos Lopez a09598
	if(v[0]<0.0)v[0]=0.0;
Carlos Lopez a09598
	if(v[1]<0.0)v[1]=0.0;
Carlos Lopez a09598
}
Carlos Lopez a09598
Carlos Lopez a09598
Layer_Shade::Layer_Shade():
e222d9
	Layer_CompositeFork(0.75,Color::BLEND_BEHIND),
Carlos Lopez 94540e
	param_size(ValueBase(Vector(0.1,0.1))),
Carlos Lopez 94540e
	param_type(ValueBase(int(Blur::FASTGAUSSIAN))),
Carlos Lopez 94540e
	param_color(ValueBase(Color::black())),
Carlos Lopez 94540e
	param_origin(ValueBase(Vector(0.2,-0.2))),
Carlos Lopez 94540e
	param_invert(ValueBase(false))
Carlos Lopez a09598
{
Carlos Lopez b3fcc2
	SET_INTERPOLATION_DEFAULTS();
Carlos Lopez b3fcc2
	SET_STATIC_DEFAULTS();
Carlos Lopez a09598
}
Carlos Lopez a09598
Carlos Lopez a09598
bool
Carlos Lopez a09598
Layer_Shade::set_param(const String ¶m, const ValueBase &value)
Carlos Lopez a09598
{
Carlos Lopez 94540e
	IMPORT_VALUE_PLUS(param_size,
Carlos Lopez 94540e
		{
9f3c68
			Vector size=param_size.get(Vector());
eed519
			clamp_size(size);
Carlos Lopez 94540e
			param_size.set(size);
Carlos Lopez 94540e
		}
Carlos Lopez 94540e
		);
Carlos Lopez 94540e
	IMPORT_VALUE(param_type);
Carlos Lopez 94540e
	IMPORT_VALUE_PLUS(param_color,
Carlos Lopez 94540e
		{
9f3c68
			Color color=param_color.get(Color());
Carlos Lopez 94540e
			if (color.get_a() == 0)
Carlos Lopez 94540e
			{
Carlos Lopez 94540e
				if (converted_blend_)
Carlos Lopez 94540e
				{
Carlos Lopez a09598
					set_blend_method(Color::BLEND_ALPHA_OVER);
Carlos Lopez 94540e
					color.set_a(1);
Carlos Lopez 94540e
					param_color.set(color);
Carlos Lopez 94540e
				}
Carlos Lopez 94540e
				else
Carlos Lopez 94540e
					transparent_color_ = true;
Carlos Lopez 94540e
			}
Carlos Lopez 94540e
		}
Carlos Lopez 94540e
		);
Carlos Lopez 94540e
	IMPORT_VALUE(param_origin);
Carlos Lopez 94540e
	IMPORT_VALUE(param_invert);
Carlos Lopez a09598
Carlos Lopez 94540e
	if(param=="offset")
Carlos Lopez 1c6c0b
		return set_param("origin", value);
Carlos Lopez a09598
Carlos Lopez a09598
	return Layer_Composite::set_param(param,value);
Carlos Lopez a09598
}
Carlos Lopez a09598
Carlos Lopez a09598
ValueBase
Carlos Lopez a09598
Layer_Shade::get_param(const String ¶m)const
Carlos Lopez a09598
{
Carlos Lopez 94540e
	EXPORT_VALUE(param_size);
Carlos Lopez 94540e
	EXPORT_VALUE(param_type);
Carlos Lopez 94540e
	EXPORT_VALUE(param_color);
Carlos Lopez 94540e
	EXPORT_VALUE(param_origin);
Carlos Lopez 94540e
	EXPORT_VALUE(param_invert);
Carlos Lopez a09598
Carlos Lopez a09598
	EXPORT_NAME();
Carlos Lopez a09598
	EXPORT_VERSION();
Carlos Lopez a09598
Carlos Lopez a09598
	return Layer_Composite::get_param(param);
Carlos Lopez a09598
}
Carlos Lopez a09598
Carlos Lopez a09598
Color
Carlos Lopez a09598
Layer_Shade::get_color(Context context, const Point &pos)const
Carlos Lopez a09598
{
9f3c68
	Vector size=param_size.get(Vector());
Carlos Lopez 94540e
	int type=param_type.get(int());
9f3c68
	Color color=param_color.get(Color());
9f3c68
	Vector origin=param_origin.get(Vector());
Carlos Lopez 94540e
	bool invert=param_invert.get(bool());
Carlos Lopez 94540e
	
Carlos Lopez a09598
	Point blurpos = Blur(size,type)(pos);
Carlos Lopez a09598
Carlos Lopez a09598
	if(get_amount()==0.0)
Carlos Lopez a09598
		return context.get_color(pos);
Carlos Lopez a09598
Carlos Lopez a09598
	Color shade(color);
Carlos Lopez a09598
Carlos Lopez a09598
	if(!invert)
Carlos Lopez a09598
		shade.set_a(context.get_color(blurpos-origin).get_a());
Carlos Lopez a09598
	else
Carlos Lopez a09598
		shade.set_a(1.0f-context.get_color(blurpos-origin).get_a());
Carlos Lopez a09598
Carlos Lopez a09598
	return Color::blend(shade,context.get_color(pos),get_amount(),get_blend_method());
Carlos Lopez a09598
}
Carlos Lopez a09598
Carlos Lopez a09598
Layer::Vocab
Carlos Lopez a09598
Layer_Shade::get_param_vocab(void)const
Carlos Lopez a09598
{
Carlos Lopez a09598
	Layer::Vocab ret(Layer_Composite::get_param_vocab());
Carlos Lopez a09598
Carlos Lopez a09598
	ret.push_back(ParamDesc("color")
Carlos Lopez a09598
		.set_local_name(_("Color"))
Carlos Lopez a09598
	);
Carlos Lopez a09598
	ret.push_back(ParamDesc("origin")
Carlos Lopez a09598
		.set_local_name(_("Origin"))
Carlos Lopez a09598
	);
Carlos Lopez a09598
	ret.push_back(ParamDesc("size")
Carlos Lopez a09598
		.set_local_name(_("Size"))
Carlos Lopez a09598
		.set_description(_("Size of Shade"))
Carlos Lopez a09598
		.set_is_distance()
Carlos Lopez a09598
		.set_origin("origin")
Carlos Lopez a09598
	);
Carlos Lopez a09598
	ret.push_back(ParamDesc("type")
Carlos Lopez a09598
		.set_local_name(_("Type"))
Carlos Lopez a09598
		.set_description(_("Type of blur to use"))
Carlos Lopez a09598
		.set_hint("enum")
Carlos Lopez a09598
		.add_enum_value(Blur::BOX,"box",_("Box Blur"))
Carlos Lopez a09598
		.add_enum_value(Blur::FASTGAUSSIAN,"fastgaussian",_("Fast Gaussian Blur"))
Carlos Lopez a09598
		.add_enum_value(Blur::CROSS,"cross",_("Cross-Hatch Blur"))
Carlos Lopez a09598
		.add_enum_value(Blur::GAUSSIAN,"gaussian",_("Gaussian Blur"))
Carlos Lopez a09598
		.add_enum_value(Blur::DISC,"disc",_("Disc Blur"))
Carlos Lopez a09598
	);
Carlos Lopez a09598
Carlos Lopez a09598
	ret.push_back(ParamDesc("invert")
Carlos Lopez a09598
		.set_local_name(_("Invert"))
Carlos Lopez a09598
	);
Carlos Lopez a09598
Carlos Lopez a09598
	return ret;
Carlos Lopez a09598
}
Carlos Lopez a09598
Carlos Lopez a09598
Rect
Carlos Lopez a09598
Layer_Shade::get_full_bounding_rect(Context context)const
Carlos Lopez a09598
{
9f3c68
	Vector size=param_size.get(Vector());
9f3c68
	Vector origin=param_origin.get(Vector());
Carlos Lopez 94540e
	bool invert=param_invert.get(bool());
Carlos Lopez 94540e
Carlos Lopez a09598
	if(is_disabled())
Carlos Lopez a09598
		return context.get_full_bounding_rect();
Carlos Lopez a09598
Carlos Lopez a09598
	if(invert)
Carlos Lopez a09598
		return Rect::full_plane();
Carlos Lopez a09598
Carlos Lopez a09598
	Rect under(context.get_full_bounding_rect());
Carlos Lopez a09598
Carlos Lopez a09598
	if(Color::is_onto(get_blend_method()))
Carlos Lopez a09598
		return under;
Carlos Lopez a09598
Carlos Lopez a09598
	Rect bounds((under+origin).expand_x(size[0]).expand_y(size[1]));
Carlos Lopez a09598
Carlos Lopez a09598
	if(is_solid_color())
Carlos Lopez a09598
		return bounds;
Carlos Lopez a09598
Carlos Lopez a09598
	return bounds|under;
Carlos Lopez a09598
}
e222d9
e222d9
rendering::Task::Handle
13de48
Layer_Shade::build_composite_fork_task_vfunc(ContextParams /* context_params */, rendering::Task::Handle sub_task)const
13de48
{
13de48
	Vector size = param_size.get(Vector());
13de48
	rendering::Blur::Type type = (rendering::Blur::Type)param_type.get(int());
13de48
	Color color = param_color.get(Color());
13de48
	Vector origin = param_origin.get(Vector());
13de48
	bool invert = param_invert.get(bool());
13de48
13de48
	rendering::TaskBlur::Handle task_blur(new rendering::TaskBlur());
13de48
	task_blur->blur.size = size;
13de48
	task_blur->blur.type = type;
13de48
	task_blur->sub_task() = sub_task->clone_recursive();
13de48
13de48
	ColorMatrix matrix;
13de48
	matrix *= ColorMatrix().set_replace_color(color);
13de48
	if (invert)
13de48
		matrix *= ColorMatrix().set_invert_alpha();
13de48
13de48
	rendering::TaskPixelColorMatrix::Handle task_colormatrix(new rendering::TaskPixelColorMatrix());
13de48
	task_colormatrix->matrix = matrix;
13de48
	task_colormatrix->sub_task() = task_blur;
13de48
5e2754
	rendering::TaskTransformationAffine::Handle task_transformation(new rendering::TaskTransformationAffine());
5e2754
	task_transformation->transformation->matrix.set_translate(origin);
13de48
	task_transformation->sub_task() = task_colormatrix;
13de48
13de48
	return task_transformation;
13de48
}