~centralelyon2010/inkscape/imagelinks2

« back to all changes in this revision

Viewing changes to src/sp-feblend.cpp

  • Committer: Ted Gould
  • Date: 2008-11-21 05:24:08 UTC
  • Revision ID: ted@canonical.com-20081121052408-tilucis2pjrrpzxx
MergeĀ fromĀ fe-moved

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#define __SP_FEBLEND_CPP__
2
 
 
3
 
/** \file
4
 
 * SVG <feBlend> implementation.
5
 
 *
6
 
 */
7
 
/*
8
 
 * Authors:
9
 
 *   Hugo Rodrigues <haa.rodrigues@gmail.com>
10
 
 *   Niko Kiirala <niko@kiirala.com>
11
 
 *
12
 
 * Copyright (C) 2006,2007 authors
13
 
 *
14
 
 * Released under GNU GPL, read the file 'COPYING' for more information
15
 
 */
16
 
 
17
 
#ifdef HAVE_CONFIG_H
18
 
# include "config.h"
19
 
#endif
20
 
 
21
 
#include <string.h>
22
 
 
23
 
#include "attributes.h"
24
 
#include "svg/svg.h"
25
 
#include "sp-feblend.h"
26
 
#include "xml/repr.h"
27
 
 
28
 
#include "display/nr-filter.h"
29
 
#include "display/nr-filter-primitive.h"
30
 
#include "display/nr-filter-blend.h"
31
 
#include "display/nr-filter-types.h"
32
 
 
33
 
/* FeBlend base class */
34
 
 
35
 
static void sp_feBlend_class_init(SPFeBlendClass *klass);
36
 
static void sp_feBlend_init(SPFeBlend *feBlend);
37
 
 
38
 
static void sp_feBlend_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr);
39
 
static void sp_feBlend_release(SPObject *object);
40
 
static void sp_feBlend_set(SPObject *object, unsigned int key, gchar const *value);
41
 
static void sp_feBlend_update(SPObject *object, SPCtx *ctx, guint flags);
42
 
static Inkscape::XML::Node *sp_feBlend_write(SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags);
43
 
static void sp_feBlend_build_renderer(SPFilterPrimitive *sp_prim, NR::Filter *filter);
44
 
 
45
 
static SPFilterPrimitiveClass *feBlend_parent_class;
46
 
 
47
 
GType
48
 
sp_feBlend_get_type()
49
 
{
50
 
    static GType feBlend_type = 0;
51
 
 
52
 
    if (!feBlend_type) {
53
 
        GTypeInfo feBlend_info = {
54
 
            sizeof(SPFeBlendClass),
55
 
            NULL, NULL,
56
 
            (GClassInitFunc) sp_feBlend_class_init,
57
 
            NULL, NULL,
58
 
            sizeof(SPFeBlend),
59
 
            16,
60
 
            (GInstanceInitFunc) sp_feBlend_init,
61
 
            NULL,    /* value_table */
62
 
        };
63
 
        feBlend_type = g_type_register_static(SP_TYPE_FILTER_PRIMITIVE, "SPFeBlend", &feBlend_info, (GTypeFlags)0);
64
 
    }
65
 
    return feBlend_type;
66
 
}
67
 
 
68
 
static void
69
 
sp_feBlend_class_init(SPFeBlendClass *klass)
70
 
{
71
 
    SPObjectClass *sp_object_class = (SPObjectClass *)klass;
72
 
    SPFilterPrimitiveClass *sp_primitive_class = (SPFilterPrimitiveClass *)klass;
73
 
 
74
 
    feBlend_parent_class = (SPFilterPrimitiveClass*)g_type_class_peek_parent(klass);
75
 
 
76
 
    sp_object_class->build = sp_feBlend_build;
77
 
    sp_object_class->release = sp_feBlend_release;
78
 
    sp_object_class->write = sp_feBlend_write;
79
 
    sp_object_class->set = sp_feBlend_set;
80
 
    sp_object_class->update = sp_feBlend_update;
81
 
 
82
 
    sp_primitive_class->build_renderer = sp_feBlend_build_renderer;
83
 
}
84
 
 
85
 
static void
86
 
sp_feBlend_init(SPFeBlend *feBlend)
87
 
{
88
 
    feBlend->in2 = NR::NR_FILTER_SLOT_NOT_SET;
89
 
}
90
 
 
91
 
/**
92
 
 * Reads the Inkscape::XML::Node, and initializes SPFeBlend variables.  For this to get called,
93
 
 * our name must be associated with a repr via "sp_object_type_register".  Best done through
94
 
 * sp-object-repr.cpp's repr_name_entries array.
95
 
 */
96
 
static void
97
 
sp_feBlend_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr)
98
 
{
99
 
    if (((SPObjectClass *) feBlend_parent_class)->build) {
100
 
        ((SPObjectClass *) feBlend_parent_class)->build(object, document, repr);
101
 
    }
102
 
 
103
 
    /*LOAD ATTRIBUTES FROM REPR HERE*/
104
 
    sp_object_read_attr(object, "mode");
105
 
    sp_object_read_attr(object, "in2");
106
 
}
107
 
 
108
 
/**
109
 
 * Drops any allocated memory.
110
 
 */
111
 
static void
112
 
sp_feBlend_release(SPObject *object)
113
 
{
114
 
    if (((SPObjectClass *) feBlend_parent_class)->release)
115
 
        ((SPObjectClass *) feBlend_parent_class)->release(object);
116
 
}
117
 
 
118
 
static NR::FilterBlendMode sp_feBlend_readmode(gchar const *value)
119
 
{
120
 
    if (!value) return NR::BLEND_NORMAL;
121
 
    switch (value[0]) {
122
 
        case 'n':
123
 
            if (strncmp(value, "normal", 6) == 0)
124
 
                return NR::BLEND_NORMAL;
125
 
            break;
126
 
        case 'm':
127
 
            if (strncmp(value, "multiply", 8) == 0)
128
 
                return NR::BLEND_MULTIPLY;
129
 
            break;
130
 
        case 's':
131
 
            if (strncmp(value, "screen", 6) == 0)
132
 
                return NR::BLEND_SCREEN;
133
 
            break;
134
 
        case 'd':
135
 
            if (strncmp(value, "darken", 6) == 0)
136
 
                return NR::BLEND_DARKEN;
137
 
            break;
138
 
        case 'l':
139
 
            if (strncmp(value, "lighten", 7) == 0)
140
 
                return NR::BLEND_LIGHTEN;
141
 
            break;
142
 
        default:
143
 
            // do nothing by default
144
 
            break;
145
 
    }
146
 
    return NR::BLEND_NORMAL;
147
 
}
148
 
 
149
 
/**
150
 
 * Sets a specific value in the SPFeBlend.
151
 
 */
152
 
static void
153
 
sp_feBlend_set(SPObject *object, unsigned int key, gchar const *value)
154
 
{
155
 
    SPFeBlend *feBlend = SP_FEBLEND(object);
156
 
    (void)feBlend;
157
 
 
158
 
    NR::FilterBlendMode mode;
159
 
    int input;
160
 
    switch(key) {
161
 
        /*DEAL WITH SETTING ATTRIBUTES HERE*/
162
 
        case SP_ATTR_MODE:
163
 
            mode = sp_feBlend_readmode(value);
164
 
            if (mode != feBlend->blend_mode) {
165
 
                feBlend->blend_mode = mode;
166
 
                object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
167
 
            }
168
 
            break;
169
 
        case SP_ATTR_IN2:
170
 
            input = sp_filter_primitive_read_in(feBlend, value);
171
 
            if (input != feBlend->in2) {
172
 
                feBlend->in2 = input;
173
 
                object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
174
 
            }
175
 
            break;
176
 
        default:
177
 
            if (((SPObjectClass *) feBlend_parent_class)->set)
178
 
                ((SPObjectClass *) feBlend_parent_class)->set(object, key, value);
179
 
            break;
180
 
    }
181
 
 
182
 
}
183
 
 
184
 
/**
185
 
 * Receives update notifications.
186
 
 */
187
 
static void
188
 
sp_feBlend_update(SPObject *object, SPCtx *ctx, guint flags)
189
 
{
190
 
    if (flags & SP_OBJECT_MODIFIED_FLAG) {
191
 
        sp_object_read_attr(object, "mode");
192
 
        sp_object_read_attr(object, "in2");
193
 
    }
194
 
 
195
 
    if (((SPObjectClass *) feBlend_parent_class)->update) {
196
 
        ((SPObjectClass *) feBlend_parent_class)->update(object, ctx, flags);
197
 
    }
198
 
}
199
 
 
200
 
/**
201
 
 * Writes its settings to an incoming repr object, if any.
202
 
 */
203
 
static Inkscape::XML::Node *
204
 
sp_feBlend_write(SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags)
205
 
{
206
 
    // Inkscape-only object, not copied during an "plain SVG" dump:
207
 
    if (flags & SP_OBJECT_WRITE_EXT) {
208
 
        if (repr) {
209
 
            // is this sane?
210
 
            // repr->mergeFrom(SP_OBJECT_REPR(object), "id");
211
 
        } else {
212
 
            repr = SP_OBJECT_REPR(object)->duplicate(doc);
213
 
        }
214
 
    }
215
 
 
216
 
    if (((SPObjectClass *) feBlend_parent_class)->write) {
217
 
        ((SPObjectClass *) feBlend_parent_class)->write(object, doc, repr, flags);
218
 
    }
219
 
 
220
 
    return repr;
221
 
}
222
 
 
223
 
static void sp_feBlend_build_renderer(SPFilterPrimitive *primitive, NR::Filter *filter) {
224
 
    g_assert(primitive != NULL);
225
 
    g_assert(filter != NULL);
226
 
 
227
 
    SPFeBlend *sp_blend = SP_FEBLEND(primitive);
228
 
 
229
 
    int primitive_n = filter->add_primitive(NR::NR_FILTER_BLEND);
230
 
    NR::FilterPrimitive *nr_primitive = filter->get_primitive(primitive_n);
231
 
    NR::FilterBlend *nr_blend = dynamic_cast<NR::FilterBlend*>(nr_primitive);
232
 
    g_assert(nr_blend != NULL);
233
 
 
234
 
    sp_filter_primitive_renderer_common(primitive, nr_primitive);
235
 
 
236
 
    nr_blend->set_mode(sp_blend->blend_mode);
237
 
    nr_blend->set_input(1, sp_blend->in2);
238
 
}
239
 
 
240
 
/*
241
 
  Local Variables:
242
 
  mode:c++
243
 
  c-file-style:"stroustrup"
244
 
  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
245
 
  indent-tabs-mode:nil
246
 
  fill-column:99
247
 
  End:
248
 
*/
249
 
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :