X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=synfig-core%2Fsrc%2Fmodules%2Fmod_filter%2Fhalftone3.cpp;fp=synfig-core%2Fsrc%2Fmodules%2Fmod_filter%2Fhalftone3.cpp;h=a2a4283d18669a607939c6f1dffaf05489b6d0e9;hb=a095981e18cc37a8ecc7cd237cc22b9c10329264;hp=0000000000000000000000000000000000000000;hpb=9459638ad6797b8139f1e9f0715c96076dbf0890;p=synfig.git diff --git a/synfig-core/src/modules/mod_filter/halftone3.cpp b/synfig-core/src/modules/mod_filter/halftone3.cpp new file mode 100644 index 0000000..a2a4283 --- /dev/null +++ b/synfig-core/src/modules/mod_filter/halftone3.cpp @@ -0,0 +1,408 @@ +/* === S Y N F I G ========================================================= */ +/*! \file halftone3.cpp +** \brief Implementation of the "Halftone 3" layer +** +** $Id$ +** +** \legal +** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley +** Copyright (c) 2007-2008 Chris Moore +** +** 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 "halftone3.h" +#include "halftone.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#endif + +/* === M A C R O S ========================================================= */ + +using namespace synfig; +using namespace std; +using namespace etl; + +/* === G L O B A L S ======================================================= */ + +SYNFIG_LAYER_INIT(Halftone3); +SYNFIG_LAYER_SET_NAME(Halftone3,"halftone3"); +SYNFIG_LAYER_SET_LOCAL_NAME(Halftone3,N_("Halftone 3")); +SYNFIG_LAYER_SET_CATEGORY(Halftone3,N_("Filters")); +SYNFIG_LAYER_SET_VERSION(Halftone3,"0.0"); +SYNFIG_LAYER_SET_CVS_ID(Halftone3,"$Id$"); + +/* === P R O C E D U R E S ================================================= */ + +#define HALFSQRT2 (0.7) +#define SQRT2 (1.414213562f) + +/* === M E T H O D S ======================================================= */ + +Halftone3::Halftone3() +{ + size=(synfig::Vector(0.25,0.25)); + type=TYPE_SYMMETRIC; + + for(int i=0;i<3;i++) + { + tone[i].size=size; + tone[i].type=type; + tone[i].origin=(synfig::Point(0,0)); + tone[i].angle=Angle::deg(30.0)*(float)i; + } + + subtractive=true; + + if(subtractive) + { + color[0]=Color::cyan(); + color[1]=Color::magenta(); + color[2]=Color::yellow(); + } + else + { + color[0]=Color::red(); + color[1]=Color::green(); + color[2]=Color::blue(); + } + + set_blend_method(Color::BLEND_STRAIGHT); + + for(int i=0;i<3;i++) + for(int j=0;j<3;j++) + inverse_matrix[i][j]=(j==i)?1.0f:0.0f; + + sync(); +} + +void +Halftone3::sync() +{ + for(int i=0;i<3;i++) + { + tone[i].size=size; + tone[i].type=type; + } + +#define matrix inverse_matrix + //float matrix[3][3]; + + if(subtractive) + { + for(int i=0;i<3;i++) + { + matrix[i][0]=1.0f-(color[i].get_r()); + matrix[i][1]=1.0f-(color[i].get_g()); + matrix[i][2]=1.0f-(color[i].get_b()); + float mult=sqrt(matrix[i][0]*matrix[i][0]+matrix[i][1]*matrix[i][1]+matrix[i][2]*matrix[i][2]); + if(mult) + { + matrix[i][0]/=mult; + matrix[i][1]/=mult; + matrix[i][2]/=mult; + matrix[i][0]/=mult; + matrix[i][1]/=mult; + matrix[i][2]/=mult; + } + } + } + else + { + for(int i=0;i<3;i++) + { + matrix[i][0]=color[i].get_r(); + matrix[i][1]=color[i].get_g(); + matrix[i][2]=color[i].get_b(); + float mult=sqrt(matrix[i][0]*matrix[i][0]+matrix[i][1]*matrix[i][1]+matrix[i][2]*matrix[i][2]); + if(mult) + { + matrix[i][0]/=mult; + matrix[i][1]/=mult; + matrix[i][2]/=mult; + matrix[i][0]/=mult; + matrix[i][1]/=mult; + matrix[i][2]/=mult; + } + } + } +#undef matrix + + + +#if 0 + // Insert guass-jordan elimination code here + int k=0,i=0,j=0,z_size=3; +#define A inverse_matrix + + for (k=0;k(this); +} + +bool +Halftone3::set_param(const String & param, const ValueBase &value) +{ + IMPORT_PLUS(size, {tone[0].size=size; tone[1].size=size; tone[2].size=size;}); + IMPORT_PLUS(type, {tone[0].type=type; tone[1].type=type; tone[2].type=type;}); + + IMPORT_PLUS(color[0],sync()); + IMPORT_PLUS(color[1],sync()); + IMPORT_PLUS(color[2],sync()); + + IMPORT_PLUS(subtractive,sync()); + + IMPORT(tone[0].angle); + IMPORT(tone[0].origin); + + IMPORT(tone[1].angle); + IMPORT(tone[1].origin); + + IMPORT(tone[2].angle); + IMPORT(tone[2].origin); + + IMPORT_AS(tone[0].origin,"tone[0].offset"); + IMPORT_AS(tone[1].origin,"tone[1].offset"); + IMPORT_AS(tone[2].origin,"tone[2].offset"); + + return Layer_Composite::set_param(param,value); +} + +ValueBase +Halftone3::get_param(const String & param)const +{ + EXPORT(size); + EXPORT(type); + + EXPORT(color[0]); + EXPORT(color[1]); + EXPORT(color[2]); + + EXPORT(subtractive); + + EXPORT(tone[0].angle); + EXPORT(tone[0].origin); + + EXPORT(tone[1].angle); + EXPORT(tone[1].origin); + + EXPORT(tone[2].angle); + EXPORT(tone[2].origin); + + EXPORT_NAME(); + EXPORT_VERSION(); + + return Layer_Composite::get_param(param); +} + +Layer::Vocab +Halftone3::get_param_vocab()const +{ + Layer::Vocab ret(Layer_Composite::get_param_vocab()); + + ret.push_back(ParamDesc("size") + .set_local_name(_("Mask Size")) + ); + ret.push_back(ParamDesc("type") + .set_local_name(_(" Type")) + .set_hint("enum") + .add_enum_value(TYPE_SYMMETRIC,"symmetric",_("Symmetric")) + .add_enum_value(TYPE_LIGHTONDARK,"lightondark",_("Light On Dark")) + //.add_enum_value(TYPE_DARKONLIGHT,"darkonlight",_("Dark on Light")) + .add_enum_value(TYPE_DIAMOND,"diamond",_("Diamond")) + .add_enum_value(TYPE_STRIPE,"stripe",_("Stripe")) + ); + ret.push_back(ParamDesc("subtractive") + .set_local_name(_("Subtractive Flag")) + ); + + for(int i=0;i<3;i++) + { + String chan_name(strprintf("Chan%d",i)); + + ret.push_back(ParamDesc(strprintf("color[%d]",i)) + .set_local_name(chan_name+_(" Color")) + ); + + ret.push_back(ParamDesc(strprintf("tone[%d].origin",i)) + .set_local_name(chan_name+_(" Mask Origin")) + .set_is_distance() + ); + ret.push_back(ParamDesc(strprintf("tone[%d].angle",i)) + .set_local_name(chan_name+_(" Mask Angle")) + .set_origin(strprintf("tone[%d].origin",i)) + ); + } + + return ret; +} + +Color +Halftone3::get_color(Context context, const Point &point)const +{ + const Color undercolor(context.get_color(point)); + const Color color(color_func(point,0,undercolor)); + + if(get_amount()==1.0 && get_blend_method()==Color::BLEND_STRAIGHT) + return color; + else + return Color::blend(color,undercolor,get_amount(),get_blend_method()); +} + +bool +Halftone3::accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const +{ + SuperCallback supercb(cb,0,9500,10000); + + if(!context.accelerated_render(surface,quality,renddesc,&supercb)) + return false; + if(get_amount()==0) + return true; + + const Real pw(renddesc.get_pw()),ph(renddesc.get_ph()); + const Point tl(renddesc.get_tl()); + const int w(surface->get_w()); + const int h(surface->get_h()); + const float supersample_size(abs(pw/(tone[0].size).mag())); + + Surface::pen pen(surface->begin()); + Point pos; + int x,y; + + if(is_solid_color()) + { + for(y=0,pos[1]=tl[1];yamount_complete(10000,10000)) + return false; + + return true; +}