Dev:Adding a Layer

From Synfig Studio :: Documentation
Revision as of 11:25, 16 April 2008 by Dooglus (Talk | contribs) (work in progress)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

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.

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 &param)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