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