Dev:Adding a Layer
Here's an example of how to add a simple layer to an existing module. For this example I picked something very easy: a layer which removes all colour from the layers beneath it. I will call this creation "Desaturate", and add it to the mod_filter module.
Contents
The Code
So first I need to create desaturate.h and desaturate.cpp in the synfig/src/modules/mod_filter/ folder:
desaturate.h:
/* === S Y N F I G ========================================================= */ /*! \file desaturate.h ** \brief Header file for implementation of the "Desaturate" layer ** ** \legal ** Copyright (c) 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 ** ========================================================================= */ /* === S T A R T =========================================================== */ #ifndef __SYNFIG_DESATURATE_H #define __SYNFIG_DESATURATE_H /* === H E A D E R S ======================================================= */ #include <synfig/layer.h> /* === C L A S S E S & S T R U C T S ======================================= */ class Desaturate : public synfig::Layer { SYNFIG_LAYER_MODULE_EXT public: virtual synfig::ValueBase get_param(const synfig::String&)const; virtual Vocab get_param_vocab()const; virtual synfig::Color get_color(synfig::Context, const synfig::Point&)const; virtual bool accelerated_render(synfig::Context,synfig::Surface*,int, const synfig::RendDesc &, synfig::ProgressCallback *)const; virtual bool reads_context()const { return true; } }; // END of class Desaturate #endif
desaturate.cpp:
/* === S Y N F I G ========================================================= */ /*! \file desaturate.cpp ** \brief Implementation of the "Desaturate" layer ** ** \legal ** Copyright (c) 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 <config.h> #endif #include "desaturate.h" #include <synfig/context.h> #include <synfig/paramdesc.h> #include <synfig/renddesc.h> #include <synfig/surface.h> #include <synfig/value.h> #endif using namespace synfig; /* === G L O B A L S ======================================================= */ SYNFIG_LAYER_INIT(Desaturate); SYNFIG_LAYER_SET_NAME(Desaturate,"desaturate"); SYNFIG_LAYER_SET_LOCAL_NAME(Desaturate,N_("Desaturate")); SYNFIG_LAYER_SET_CATEGORY(Desaturate,N_("Filters")); SYNFIG_LAYER_SET_VERSION(Desaturate,"0.1"); SYNFIG_LAYER_SET_CVS_ID(Desaturate,"$Id$"); /* === M E T H O D S ======================================================= */ ValueBase Desaturate::get_param(const String ¶m)const { EXPORT_NAME(); EXPORT_VERSION(); return ValueBase(); } Layer::Vocab Desaturate::get_param_vocab()const { return Layer::Vocab(); } Color Desaturate::get_color(Context context, const Point &getpos)const { Color tmp(context.get_color(getpos)); return tmp.set_s(0); } bool Desaturate::accelerated_render(Context context, Surface* surface, int quality, const RendDesc& renddesc, ProgressCallback* cb )const { SuperCallback supercb(cb,0,9500,10000); // render the context onto the given surface if(!context.accelerated_render(surface,quality,renddesc,&supercb)) return false; // set the saturation of each pixel to zero int x,y; Surface::pen pen(surface->begin()); for(y=0;y<renddesc.get_h();y++,pen.inc_y(),pen.dec_x(x)) for(x=0;x<renddesc.get_w();x++,pen.inc_x()) { Color tmp(pen.get_value()); pen.put_value(tmp.set_s(0)); } // mark our progress as finished if(cb && !cb->amount_complete(10000,10000)) return false; return true; }
Then I need to edit modules/mod_filter/Makefile.am and add these two files to the list of source files (maintain alphabetical order please):
libmod_filter_la_SOURCES = blur.cpp blur.h colorcorrect.cpp colorcorrect.h desaturate.cpp desaturate.h halftone2.cpp halftone2.h lumakey.cpp lumakey.h radialblur.cpp radialblur.h main.cpp halftone.cpp halftone.h halftone3.cpp halftone3.h
And finally we edit modules/mod_filter/main.cpp. Add this with the other #include lines:
#include "desaturate.h"
and add this with the other LAYER(...) lines:
LAYER(Desaturate)
then rebuild (including the autoreconf, ./configure, etc., to get the new files added to the Makefile) and we're done.
The Description
I'll break the header up into sections, describing each part:
The initial comment
This contains basic documentation and legal stuff. Just copy, paste, and edit from another file.
/* === S Y N F I G ========================================================= */ /*! \file desaturate.h ** \brief Header file for implementation of the "Desaturate" layer ** ** \legal ** Copyright (c) 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 ** ========================================================================= */ /* === S T A R T =========================================================== */
Protection against Multiple Inclusion
This #ifndef is a standard way to make sure the header is only compiled once, even if it happens to be included multiple times. Use a unique symbol, based on the file name.
#ifndef __SYNFIG_DESATURATE_H #define __SYNFIG_DESATURATE_H
Include files which are needed. We're not doing anything much, so all we need to include is layer.h, which defines the Layer class that all layers inherit from.
/* === H E A D E R S ======================================================= */ #include <synfig/layer.h>
Define the class which implements our layer. We inherit from the Layer class.
/* === C L A S S E S & S T R U C T S ======================================= */ class Desaturate : public synfig::Layer { SYNFIG_LAYER_MODULE_EXT public: virtual synfig::ValueBase get_param(const synfig::String&)const; virtual Vocab get_param_vocab()const; virtual synfig::Color get_color(synfig::Context, const synfig::Point&)const; virtual bool accelerated_render(synfig::Context,synfig::Surface*,int, const synfig::RendDesc &, synfig::ProgressCallback *)const; virtual bool reads_context()const { return true; } }; // END of class Desaturate #endif