summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: c2f83fd)
raw | patch | inline | side by side (parent: c2f83fd)
author | kiirala <kiirala@users.sourceforge.net> | |
Fri, 20 Jul 2007 19:50:41 +0000 (19:50 +0000) | ||
committer | kiirala <kiirala@users.sourceforge.net> | |
Fri, 20 Jul 2007 19:50:41 +0000 (19:50 +0000) |
feSpecularLighting filter primitives
25 files changed:
diff --git a/src/Makefile_insert b/src/Makefile_insert
index 1371039c15bf472251d1a2f6c311d541edd446c8..548a4933491ffcfcd19c7eab85e3fbc9e9ddcbe1 100644 (file)
--- a/src/Makefile_insert
+++ b/src/Makefile_insert
sp-fediffuselighting-fns.h \
sp-fedisplacementmap.cpp sp-fedisplacementmap.h \
sp-fedisplacementmap-fns.h \
+ sp-fedistantlight.cpp sp-fedistantlight.h \
sp-feflood.cpp sp-feflood.h \
sp-feflood-fns.h \
sp-feimage.cpp sp-feimage.h \
sp-femorphology-fns.h \
sp-feoffset.cpp sp-feoffset.h \
sp-feoffset-fns.h \
+ sp-fepointlight.cpp sp-fepointlight.h \
sp-fespecularlighting.cpp sp-fespecularlighting.h \
sp-fespecularlighting-fns.h \
+ sp-fespotlight.cpp sp-fespotlight.h \
sp-fetile.cpp sp-fetile.h \
sp-fetile-fns.h \
sp-feturbulence.cpp sp-feturbulence.h \
diff --git a/src/attributes.cpp b/src/attributes.cpp
index 968e3863373a74a5f2f7772cff593f76aabc3b10..025f1991bf78bef9bf6a6a9b9d41c4d56474fca3 100644 (file)
--- a/src/attributes.cpp
+++ b/src/attributes.cpp
{SP_ATTR_XCHANNELSELECTOR, "xChannelSelector"},
{SP_ATTR_YCHANNELSELECTOR, "yChannelSelector"},
//{SP_ATTR_IN2, "in2"},
+ /*feDistantLight*/
+ {SP_ATTR_AZIMUTH, "azimuth"},
+ {SP_ATTR_ELEVATION, "elevation"},
+ /*fePointLight*/
+ {SP_ATTR_Z, "z"},
+ /*feSpotLight*/
+ {SP_ATTR_POINTSATX, "pointsAtX"},
+ {SP_ATTR_POINTSATY, "pointsAtY"},
+ {SP_ATTR_POINTSATZ, "pointsAtZ"},
+ {SP_ATTR_LIMITINGCONEANGLE, "limitingConeAngle"},
/*feFlood*/
{SP_ATTR_FLOODCOLOR, "flood-color"},
{SP_ATTR_FLOODOPACITY, "flood-opacity"},
diff --git a/src/attributes.h b/src/attributes.h
index 9e658f562d4b2bfd6a0a0682898d659601a0a13b..c7f1fb71edce1d8ad0156885a425fa861f414e52 100644 (file)
--- a/src/attributes.h
+++ b/src/attributes.h
SP_ATTR_XCHANNELSELECTOR,
SP_ATTR_YCHANNELSELECTOR,
//SP_ATTR_IN2,
+ /*feDistantLight*/
+ SP_ATTR_AZIMUTH,
+ SP_ATTR_ELEVATION,
+ /*fePointLight*/
+ SP_ATTR_Z,
+ /*feSpotLight*/
+ SP_ATTR_POINTSATX,
+ SP_ATTR_POINTSATY,
+ SP_ATTR_POINTSATZ,
+ SP_ATTR_LIMITINGCONEANGLE,
/*feFlood*/
SP_ATTR_FLOODCOLOR,
SP_ATTR_FLOODOPACITY,
index 1a4c01011af4648086e5c68d2363f8d87baa42e4..bc6fb33369744069c54cc5abd89e63dd2db0b1f2 100644 (file)
display/sp-canvas.$(OBJEXT): helper/sp-marshal.h
display_libspdisplay_a_SOURCES = \
+ display/nr-3dutils.h \
+ display/nr-3dutils.cpp \
display/nr-arena-forward.h \
display/nr-arena.cpp \
display/nr-arena.h \
display/nr-filter-gaussian.h \
display/nr-filter-blend.cpp \
display/nr-filter-blend.h \
+ display/nr-filter-diffuselighting.cpp \
+ display/nr-filter-diffuselighting.h \
display/nr-filter-offset.cpp \
display/nr-filter-offset.h \
+ display/nr-filter-specularlighting.cpp \
+ display/nr-filter-specularlighting.h \
display/nr-filter-composite.h \
display/nr-filter-composite.cpp \
display/nr-filter-slot.cpp \
display/pixblock-transform.cpp \
display/pixblock-transform.h \
display/inkscape-cairo.cpp \
- display/inkscape-cairo.h
+ display/inkscape-cairo.h \
+ display/nr-light.h \
+ display/nr-light.cpp \
+ display/nr-light-types.h
display_bezier_utils_test_SOURCES = display/bezier-utils-test.cpp
display_bezier_utils_test_LDADD = libnr/libnr.a -lglib-2.0
diff --git a/src/display/nr-3dutils.cpp b/src/display/nr-3dutils.cpp
--- /dev/null
@@ -0,0 +1,185 @@
+/*
+ * 3D utils.
+ *
+ * Authors:
+ * Jean-Rene Reinhard <jr@komite.net>
+ *
+ * Copyright (C) 2007 authors
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include <glib/gmessages.h>
+
+#include "libnr/nr-pixblock.h"
+#include "libnr/nr-matrix.h"
+#include "display/nr-3dutils.h"
+#include <cmath>
+
+namespace NR {
+
+#define BEGIN 0 // TOP or LEFT
+#define MIDDLE 1
+#define END 2 // BOTTOM or RIGHT
+
+#define START(v) ((v)==BEGIN? 1 : 0)
+#define FINISH(v) ((v)==END? 1 : 2)
+
+signed char K_X[3][3][3][3] = {
+ //K_X[TOP]
+ {
+ //K_X[TOP][LEFT]
+ {
+ { 0, 0, 0},
+ { 0, -2, 2},
+ { 0, -1, 1}
+ },
+ {
+ { 0, 0, 0},
+ {-2, 0, 2},
+ {-1, 0, 1}
+ },
+ {
+ { 0, 0, 0},
+ {-2, 2, 0},
+ {-1, 1, 0}
+ }
+ },
+ //K_X[MIDDLE]
+ {
+ //K_X[MIDDLE][LEFT]
+ {
+ { 0, -1, 1},
+ { 0, -2, 2},
+ { 0, -1, 1}
+ },
+ {
+ {-1, 0, 1},
+ {-2, 0, 2},
+ {-1, 0, 1}
+ },
+ {
+ {-1, 1, 0},
+ {-2, 2, 0},
+ {-1, 1, 0}
+ }
+ },
+ //K_X[BOTTOM]
+ {
+ //K_X[BOTTOM][LEFT]
+ {
+ { 0, -1, 1},
+ { 0, -2, 2},
+ { 0, 0, 0}
+ },
+ {
+ {-1, 0, 1},
+ {-2, 0, 2},
+ { 0, 0, 0}
+ },
+ {
+ {-1, 1, 0},
+ {-2, 2, 0},
+ { 0, 0, 0}
+ }
+ }
+};
+
+//K_Y is obtained by transposing K_X globally and each of its components
+
+gdouble FACTOR_X[3][3] = {
+ {2./3, 1./3, 2./3},
+ {1./2, 1./4, 1./2},
+ {2./3, 1./3, 2./3}
+};
+
+//FACTOR_Y is obtained by transposing FACTOR_X
+
+inline
+int get_carac(int i, int len, int delta) {
+ if (i < delta)
+ return BEGIN;
+ else if (i > len - 1 - delta)
+ return END;
+ else
+ return MIDDLE;
+}
+
+//assumes in is RGBA
+//should be made more resistant
+void compute_surface_normal(Fvector &N, gdouble ss, NRPixBlock *in, int i, int j, int dx, int dy) {
+ int w = in->area.x1 - in->area.x0;
+ int h = in->area.y1 - in->area.y0;
+ int k, l, alpha_idx, alpha_idx_y;
+ int x_carac, y_carac;
+ gdouble alpha;
+ gdouble accu_x;
+ gdouble accu_y;
+ unsigned char *data = NR_PIXBLOCK_PX (in);
+ g_assert(in->mode == NR_PIXBLOCK_MODE_R8G8B8A8P);
+ x_carac = get_carac(j, w, dx); //LEFT, MIDDLE or RIGHT
+ y_carac = get_carac(i, h, dy); //TOP, MIDDLE or BOTTOM
+ alpha_idx = 4*(i*w + j);
+ accu_x = 0;
+ accu_y = 0;
+ for (k = START(y_carac); k <= FINISH(y_carac); k++) {
+ alpha_idx_y = alpha_idx + 4*(k-1)*dy*w;
+ for (l = START(x_carac); l <= FINISH(x_carac); l++) {
+ alpha = (data + alpha_idx_y + 4*dx*(l-1))[3];
+ accu_x += K_X[y_carac][x_carac][k][l] * alpha / 255;
+ accu_y += K_X[x_carac][y_carac][l][k] * alpha / 255;
+ }
+ }
+ N[X_3D] = -1 * ss * FACTOR_X[y_carac][x_carac] * accu_x / dx;
+ N[Y_3D] = -1 * ss * FACTOR_X[x_carac][y_carac] * accu_y / dy;
+ N[Z_3D] = 1;
+ normalize_vector(N);
+ //std::cout << "(" << N[X_3D] << ", " << N[Y_3D] << ", " << N[Z_3D] << ")" << std::endl;
+}
+
+void convert_coord(gdouble &x, gdouble &y, gdouble &z, Matrix const &trans) {
+ Point p = Point(x, y);
+ p *= trans;
+ x = p[X];
+ y = p[Y];
+ z *= trans[0];
+}
+
+gdouble norm(const Fvector &v) {
+ return sqrt(v[X_3D]*v[X_3D] + v[Y_3D]*v[Y_3D] + v[Z_3D]*v[Z_3D]);
+}
+
+void normalize_vector(Fvector &v) {
+ int i, j;
+ gdouble nv = norm(v);
+ //TODO test nv == 0
+ for (j = 0; j < 3; j++) {
+ v[j] /= nv;
+ }
+}
+
+gdouble scalar_product(const Fvector &a, const Fvector &b) {
+ return a[X_3D] * b[X_3D] +
+ a[Y_3D] * b[Y_3D] +
+ a[Z_3D] * b[Z_3D];
+}
+
+void normalized_sum(Fvector &r, const Fvector &a, const Fvector &b) {
+ r[X_3D] = a[X_3D] + b[X_3D];
+ r[Y_3D] = a[Y_3D] + b[Y_3D];
+ r[Z_3D] = a[Z_3D] + b[Z_3D];
+ normalize_vector(r);
+}
+
+}/* namespace NR */
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
diff --git a/src/display/nr-3dutils.h b/src/display/nr-3dutils.h
--- /dev/null
+++ b/src/display/nr-3dutils.h
@@ -0,0 +1,111 @@
+#ifndef __NR_3DUTILS_H__
+#define __NR_3DUTILS_H__
+
+/*
+ * 3D utils. Definition of gdouble vectors of dimension 3 and of some basic
+ * functions.
+ *
+ * Authors:
+ * Jean-Rene Reinhard <jr@komite.net>
+ *
+ * Copyright (C) 2007 authors
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include <gdk/gdktypes.h>
+
+struct NRPixBlock;
+
+namespace NR {
+
+struct Matrix;
+
+#define X_3D 0
+#define Y_3D 1
+#define Z_3D 2
+
+/**
+ * a type of 3 gdouble components vectors
+ */
+typedef gdouble Fvector[3];
+
+/**
+ * The eye vector
+ */
+const static Fvector EYE_VECTOR = {0, 0, 1};
+
+/**
+ * returns the euclidian norm of the vector v
+ *
+ * \param v a reference to a vector with double components
+ * \return the euclidian norm of v
+ */
+gdouble norm(const Fvector &v);
+
+/**
+ * Normalizes a vector
+ *
+ * \param v a reference to a vector to normalize
+ */
+void normalize_vector(Fvector &v);
+
+/**
+ * Computes the scalar product between two Fvectors
+ *
+ * \param a a Fvector reference
+ * \param b a Fvector reference
+ * \return the scalar product of a and b
+ */
+gdouble scalar_product(const Fvector &a, const Fvector &b);
+
+/**
+ * Computes the normalized sum of two Fvectors
+ *
+ * \param r a Fvector reference where we store the result
+ * \param a a Fvector reference
+ * \param b a Fvector reference
+ */
+void normalized_sum(Fvector &r, const Fvector &a, const Fvector &b);
+
+/**
+ * Computes the unit suface normal vector of surface given by "in" at (i, j)
+ * and store it into N. "in" is a (NRPixBlock *) in mode RGBA but only the alpha
+ * channel is considered as a bump map. ss is the altitude when for the alpha
+ * value 255. dx and dy are the deltas used to compute in our discrete setting
+ *
+ * \param N a reference to a Fvector in which we store the unit surface normal
+ * \param ss the surface scale
+ * \param in a NRPixBlock * whose alpha channel codes the surface
+ * \param i the x coordinate of the point at which we compute the normal
+ * \param j the y coordinate of the point at which we compute the normal
+ * \param dx the delta used in the x coordinate
+ * \param dy the delta used in the y coordinate
+ */
+void compute_surface_normal(Fvector &N, gdouble ss, NRPixBlock *in, int i, int j, int dx, int dy);
+
+/**
+ * Applies the transformation matrix to (x, y, z). This function assumes that
+ * trans[0] = trans[3]. x and y are transformed according to trans, z is
+ * multiplied by trans[0].
+ *
+ * \param x a reference to a x coordinate
+ * \param y a reference to a y coordinate
+ * \param z a reference to a z coordinate
+ * \param z a reference to a transformation matrix
+ */
+void convert_coord(gdouble &x, gdouble &y, gdouble &z, Matrix const &trans);
+
+} /* namespace NR */
+
+#endif /* __NR_3DUTILS_H__ */
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
diff --git a/src/display/nr-filter-diffuselighting.cpp b/src/display/nr-filter-diffuselighting.cpp
--- /dev/null
@@ -0,0 +1,181 @@
+/*
+ * feDiffuseLighting renderer
+ *
+ * Authors:
+ * Niko Kiirala <niko@kiirala.com>
+ * Jean-Rene Reinhard <jr@komite.net>
+ *
+ * Copyright (C) 2007 authors
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include <glib/gmessages.h>
+
+#include "display/nr-3dutils.h"
+#include "display/nr-arena-item.h"
+#include "display/nr-filter-diffuselighting.h"
+#include "display/nr-filter-getalpha.h"
+#include "display/nr-filter-slot.h"
+#include "display/nr-light.h"
+#include "libnr/nr-blit.h"
+#include "libnr/nr-pixblock.h"
+#include "libnr/nr-matrix.h"
+#include "libnr/nr-rect-l.h"
+#include "color.h"
+#include "round.h"
+
+namespace NR {
+
+FilterDiffuseLighting::FilterDiffuseLighting()
+{
+ light_type = NO_LIGHT;
+ diffuseConstant = 1;
+ surfaceScale = 1;
+ lighting_color = 0xffffffff;
+}
+
+FilterPrimitive * FilterDiffuseLighting::create() {
+ return new FilterDiffuseLighting();
+}
+
+FilterDiffuseLighting::~FilterDiffuseLighting()
+{}
+
+#define COMPUTE_INTER(inter, N, L, kd) \
+do {\
+ (inter) = (kd) * scalar_product((N), (L)); \
+ if ((inter) < 0) (inter) = 0; \
+}while(0)
+
+int FilterDiffuseLighting::render(FilterSlot &slot, Matrix const &trans) {
+ NRPixBlock *in = filter_get_alpha(slot.get(_input));
+ NRPixBlock *out = new NRPixBlock;
+
+ int w = in->area.x1 - in->area.x0;
+ int h = in->area.y1 - in->area.y0;
+ int x0 = in->area.x0;
+ int y0 = in->area.y0;
+ int i, j;
+ //As long as FilterRes and kernel unit is not supported we hardcode the
+ //default value
+ int dx = 1; //TODO setup
+ int dy = 1; //TODO setup
+ //surface scale
+ //TODO for the time being, assumes userSpaceOnUse
+ gdouble ss = surfaceScale * trans[0];
+ gdouble kd = diffuseConstant; //diffuse lighting constant
+
+ Fvector L, N, LC;
+ gdouble inter;
+
+ nr_pixblock_setup_fast(out, in->mode,
+ in->area.x0, in->area.y0, in->area.x1, in->area.y1,
+ true);
+ unsigned char *data_i = NR_PIXBLOCK_PX (in);
+ unsigned char *data_o = NR_PIXBLOCK_PX (out);
+ //No light, nothing to do
+ switch (light_type) {
+ case DISTANT_LIGHT:
+ //the light vector is constant
+ {
+ DistantLight *dl = new DistantLight(light.distant, lighting_color);
+ dl->light_vector(L);
+ dl->light_components(LC);
+ //finish the work
+ for (i = 0, j = 0; i < w*h; i++) {
+ compute_surface_normal(N, ss, in, i / w, i % w, dx, dy);
+ COMPUTE_INTER(inter, N, L, kd);
+
+ data_o[j++] = (unsigned char) round(inter * LC[LIGHT_RED]);
+ data_o[j++] = (unsigned char) round(inter * LC[LIGHT_GREEN]);
+ data_o[j++] = (unsigned char) round(inter * LC[LIGHT_BLUE]);
+ data_o[j++] = 255;
+ }
+ out->empty = FALSE;
+ delete dl;
+ }
+ break;
+ case POINT_LIGHT:
+ {
+ PointLight *pl = new PointLight(light.point, lighting_color, trans);
+ pl->light_components(LC);
+ //TODO we need a reference to the filter to determine primitiveUnits
+ //slot._arena_item->filter seems to be ok on simple examples
+ //for now assume userSpaceOnUse
+ //if objectBoundingBox is used, use a different matrix for light_vector
+ //finish the work
+ for (i = 0, j = 0; i < w*h; i++) {
+ compute_surface_normal(N, ss, in, i / w, i % w, dx, dy);
+ pl->light_vector(L,
+ i % w + x0,
+ i / w + y0,
+ ss * (double) data_i[4*i+3]/ 255);
+ COMPUTE_INTER(inter, N, L, kd);
+
+ data_o[j++] = (unsigned char) round(inter * LC[LIGHT_RED]);
+ data_o[j++] = (unsigned char) round(inter * LC[LIGHT_GREEN]);
+ data_o[j++] = (unsigned char) round(inter * LC[LIGHT_BLUE]);
+ data_o[j++] = 255;
+ }
+ out->empty = FALSE;
+ delete pl;
+ }
+ break;
+ case SPOT_LIGHT:
+ {
+ SpotLight *sl = new SpotLight(light.spot, lighting_color, trans);
+ //TODO we need a reference to the filter to determine primitiveUnits
+ //slot._arena_item->filter seems to be ok on simple examples
+ //for now assume userSpaceOnUse
+ //if objectBoundingBox is used, use a different matrix for light_vector
+ //finish the work
+ for (i = 0, j = 0; i < w*h; i++) {
+ compute_surface_normal(N, ss, in, i / w, i % w, dx, dy);
+ sl->light_vector(L,
+ i % w + x0,
+ i / w + y0,
+ ss * (double) data_i[4*i+3]/ 255);
+ sl->light_components(LC, L);
+ COMPUTE_INTER(inter, N, L, kd);
+
+ data_o[j++] = (unsigned char) round(inter * LC[LIGHT_RED]);
+ data_o[j++] = (unsigned char) round(inter * LC[LIGHT_GREEN]);
+ data_o[j++] = (unsigned char) round(inter * LC[LIGHT_BLUE]);
+ data_o[j++] = 255;
+ }
+ out->empty = FALSE;
+ delete sl;
+ }
+ break;
+ //else unknown light source, doing nothing
+ case NO_LIGHT:
+ default:
+ {
+ if (light_type != NO_LIGHT)
+ g_warning("unknown light source %d", light_type);
+ for (i = 0; i < w*h; i++) {
+ data_o[4*i+3] = 255;
+ }
+ out->empty = false;
+ }
+ }
+
+ //finishing
+ slot.set(_output, out);
+ delete in;
+ return 0;
+}
+
+} /* namespace NR */
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
diff --git a/src/display/nr-filter-diffuselighting.h b/src/display/nr-filter-diffuselighting.h
--- /dev/null
@@ -0,0 +1,60 @@
+#ifndef __NR_FILTER_DIFFUSELIGHTING_H__
+#define __NR_FILTER_DIFFUSELIGHTING_H__
+
+/*
+ * feDiffuseLighting renderer
+ *
+ * Authors:
+ * Niko Kiirala <niko@kiirala.com>
+ * Jean-Rene Reinhard <jr@komite.net>
+ *
+ * Copyright (C) 2007 authors
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include <gdk/gdktypes.h>
+#include "display/nr-light-types.h"
+#include "display/nr-filter-primitive.h"
+#include "display/nr-filter-slot.h"
+#include "libnr/nr-matrix.h"
+#include "sp-fedistantlight.h"
+#include "sp-fepointlight.h"
+#include "sp-fespotlight.h"
+#include "color.h"
+
+namespace NR {
+
+class FilterDiffuseLighting : public FilterPrimitive {
+public:
+ union {
+ SPFeDistantLight *distant;
+ SPFePointLight *point;
+ SPFeSpotLight *spot;
+ } light;
+ LightType light_type;
+ gdouble diffuseConstant;
+ gdouble surfaceScale;
+ guint32 lighting_color;
+
+ FilterDiffuseLighting();
+ static FilterPrimitive *create();
+ virtual ~FilterDiffuseLighting();
+ virtual int render(FilterSlot &slot, Matrix const &trans);
+
+private:
+};
+
+} /* namespace NR */
+
+#endif /* __NR_FILTER_DIFFUSELIGHTING_H__ */
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
diff --git a/src/display/nr-filter-specularlighting.cpp b/src/display/nr-filter-specularlighting.cpp
--- /dev/null
@@ -0,0 +1,190 @@
+/*
+ * feSpecularLighting renderer
+ *
+ * Authors:
+ * Niko Kiirala <niko@kiirala.com>
+ * Jean-Rene Reinhard <jr@komite.net>
+ *
+ * Copyright (C) 2007 authors
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include <glib/gmessages.h>
+#include <cmath>
+
+#include "display/nr-3dutils.h"
+#include "display/nr-arena-item.h"
+#include "display/nr-filter-specularlighting.h"
+#include "display/nr-filter-getalpha.h"
+#include "display/nr-filter-slot.h"
+#include "display/nr-light.h"
+#include "libnr/nr-blit.h"
+#include "libnr/nr-pixblock.h"
+#include "libnr/nr-matrix.h"
+#include "libnr/nr-rect-l.h"
+#include "color.h"
+#include "round.h"
+
+namespace NR {
+
+FilterSpecularLighting::FilterSpecularLighting()
+{
+ light_type = NO_LIGHT;
+ specularConstant = 1;
+ specularExponent = 1;
+ surfaceScale = 1;
+ lighting_color = 0xffffffff;
+}
+
+FilterPrimitive * FilterSpecularLighting::create() {
+ return new FilterSpecularLighting();
+}
+
+FilterSpecularLighting::~FilterSpecularLighting()
+{}
+
+//Investigating Phong Lighting model we should not take N.H but
+//R.E which equals to 2*N.H^2 - 1
+#define COMPUTE_INTER(inter, H, N, ks, speculaExponent) \
+do {\
+ gdouble scal = scalar_product((N), (H));\
+ scal = 2 * scal * scal - 1;\
+ if (scal <= 0)\
+ (inter) = 0;\
+ else\
+ (inter) = (ks) * std::pow(scal, (specularExponent));\
+}while(0)
+
+int FilterSpecularLighting::render(FilterSlot &slot, Matrix const &trans) {
+ NRPixBlock *in = filter_get_alpha(slot.get(_input));
+ NRPixBlock *out = new NRPixBlock;
+
+ //Fvector *L = NULL; //vector to the light
+
+ int w = in->area.x1 - in->area.x0;
+ int h = in->area.y1 - in->area.y0;
+ int x0 = in->area.x0;
+ int y0 = in->area.y0;
+ int i, j;
+ //As long as FilterRes and kernel unit is not supported we hardcode the
+ //default value
+ int dx = 1; //TODO setup
+ int dy = 1; //TODO setup
+ //surface scale
+ //TODO for the time being, assumes userSpaceOnUse
+ gdouble ss = surfaceScale * trans[0];
+ gdouble ks = specularConstant; //diffuse lighting constant
+ Fvector L, N, LC, H;
+ gdouble inter;
+
+ nr_pixblock_setup_fast(out, in->mode,
+ in->area.x0, in->area.y0, in->area.x1, in->area.y1,
+ true);
+ unsigned char *data_i = NR_PIXBLOCK_PX (in);
+ unsigned char *data_o = NR_PIXBLOCK_PX (out);
+ //No light, nothing to do
+ switch (light_type) {
+ case DISTANT_LIGHT:
+ //the light vector is constant
+ {
+ DistantLight *dl = new DistantLight(light.distant, lighting_color);
+ dl->light_vector(L);
+ dl->light_components(LC);
+ normalized_sum(H, L, EYE_VECTOR);
+ //finish the work
+ for (i = 0, j = 0; i < w*h; i++) {
+ compute_surface_normal(N, ss, in, i / w, i % w, dx, dy);
+ COMPUTE_INTER(inter, N, H, ks, specularExponent);
+
+ data_o[j++] = (unsigned char) round(inter * LC[LIGHT_RED]);
+ data_o[j++] = (unsigned char) round(inter * LC[LIGHT_GREEN]);
+ data_o[j++] = (unsigned char) round(inter * LC[LIGHT_BLUE]);
+ data_o[j++] = MAX(MAX(data_o[j-3], data_o[j-2]), data_o[j-1]);
+ }
+ out->empty = FALSE;
+ delete dl;
+ }
+ break;
+ case POINT_LIGHT:
+ {
+ PointLight *pl = new PointLight(light.point, lighting_color, trans);
+ pl->light_components(LC);
+ //TODO we need a reference to the filter to determine primitiveUnits
+ //slot._arena_item->filter seems to be ok on simple examples
+ //for now assume userSpaceOnUse
+ //if objectBoundingBox is used, use a different matrix for light_vector
+ //finish the work
+ for (i = 0, j = 0; i < w*h; i++) {
+ compute_surface_normal(N, ss, in, i / w, i % w, dx, dy);
+ pl->light_vector(L,
+ i % w + x0,
+ i / w + y0,
+ ss * (double) data_i[4*i+3]/ 255);
+ normalized_sum(H, L, EYE_VECTOR);
+ COMPUTE_INTER(inter, N, H, ks, specularExponent);
+
+ data_o[j++] = (unsigned char) round(inter * LC[LIGHT_RED]);
+ data_o[j++] = (unsigned char) round(inter * LC[LIGHT_GREEN]);
+ data_o[j++] = (unsigned char) round(inter * LC[LIGHT_BLUE]);
+ data_o[j++] = MAX(MAX(data_o[j-3], data_o[j-2]), data_o[j-1]);
+ }
+ out->empty = FALSE;
+ delete pl;
+ }
+ break;
+ case SPOT_LIGHT:
+ {
+ SpotLight *sl = new SpotLight(light.spot, lighting_color, trans);
+ //TODO we need a reference to the filter to determine primitiveUnits
+ //slot._arena_item->filter seems to be ok on simple examples
+ //for now assume userSpaceOnUse
+ //if objectBoundingBox is used, use a different matrix for light_vector
+ //finish the work
+ for (i = 0, j = 0; i < w*h; i++) {
+ compute_surface_normal(N, ss, in, i / w, i % w, dx, dy);
+ sl->light_vector(L,
+ i % w + x0,
+ i / w + y0,
+ ss * (double) data_i[4*i+3]/ 255);
+ sl->light_components(LC, L);
+ normalized_sum(H, L, EYE_VECTOR);
+ COMPUTE_INTER(inter, N, H, ks, specularExponent);
+
+ data_o[j++] = (unsigned char) round(inter * LC[LIGHT_RED]);
+ data_o[j++] = (unsigned char) round(inter * LC[LIGHT_GREEN]);
+ data_o[j++] = (unsigned char) round(inter * LC[LIGHT_BLUE]);
+ data_o[j++] = MAX(MAX(data_o[j-3], data_o[j-2]), data_o[j-1]);
+ }
+ out->empty = FALSE;
+ delete sl;
+ }
+ break;
+ //else unknown light source, doing nothing
+ case NO_LIGHT:
+ default:
+ {
+ if (light_type != NO_LIGHT)
+ g_warning("unknown light source %d", light_type);
+ out->empty = false;
+ }
+ }
+
+ //finishing
+ slot.set(_output, out);
+ delete in;
+ return 0;
+}
+
+} /* namespace NR */
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
diff --git a/src/display/nr-filter-specularlighting.h b/src/display/nr-filter-specularlighting.h
--- /dev/null
@@ -0,0 +1,61 @@
+#ifndef __NR_FILTER_SPECULARLIGHTING_H__
+#define __NR_FILTER_SPECULARLIGHTING_H__
+
+/*
+ * feSpecularLighting renderer
+ *
+ * Authors:
+ * Niko Kiirala <niko@kiirala.com>
+ * Jean-Rene Reinhard <jr@komite.net>
+ *
+ * Copyright (C) 2007 authors
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include <gdk/gdktypes.h>
+#include "display/nr-light-types.h"
+#include "display/nr-filter-primitive.h"
+#include "display/nr-filter-slot.h"
+#include "libnr/nr-matrix.h"
+#include "sp-fedistantlight.h"
+#include "sp-fepointlight.h"
+#include "sp-fespotlight.h"
+#include "color.h"
+
+namespace NR {
+
+class FilterSpecularLighting : public FilterPrimitive {
+public:
+ union {
+ SPFeDistantLight *distant;
+ SPFePointLight *point;
+ SPFeSpotLight *spot;
+ } light;
+ LightType light_type;
+ gdouble surfaceScale;
+ gdouble specularConstant;
+ gdouble specularExponent;
+ guint32 lighting_color;
+
+ FilterSpecularLighting();
+ static FilterPrimitive *create();
+ virtual ~FilterSpecularLighting();
+ virtual int render(FilterSlot &slot, Matrix const &trans);
+
+private:
+};
+
+} /* namespace NR */
+
+#endif /* __NR_FILTER_SPECULARLIGHTING_H__ */
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
index 61571f43bde80a5321bc764be81c6f532b253b45..8a22778a130566eaa57233496c5b2e7429f27fc1 100644 (file)
#include "display/nr-filter-blend.h"
#include "display/nr-filter-offset.h"
#include "display/nr-filter-composite.h"
+#include "display/nr-filter-diffuselighting.h"
+#include "display/nr-filter-specularlighting.h"
#include "display/nr-arena-item.h"
#include "libnr/nr-pixblock.h"
_constructor[NR_FILTER_COMPONENTTRANSFER] = NULL;
_constructor[NR_FILTER_COMPOSITE] = &FilterComposite::create;
_constructor[NR_FILTER_CONVOLVEMATRIX] = NULL;
- _constructor[NR_FILTER_DIFFUSELIGHTING] = NULL;
+ _constructor[NR_FILTER_DIFFUSELIGHTING] = &FilterDiffuseLighting::create;
_constructor[NR_FILTER_DISPLACEMENTMAP] = NULL;
_constructor[NR_FILTER_FLOOD] = NULL;
_constructor[NR_FILTER_GAUSSIANBLUR] = &FilterGaussian::create;
_constructor[NR_FILTER_MERGE] = NULL;
_constructor[NR_FILTER_MORPHOLOGY] = NULL;
_constructor[NR_FILTER_OFFSET] = &FilterOffset::create;
- _constructor[NR_FILTER_SPECULARLIGHTING] = NULL;
+ _constructor[NR_FILTER_SPECULARLIGHTING] = &FilterSpecularLighting::create;
_constructor[NR_FILTER_TILE] = NULL;
_constructor[NR_FILTER_TURBULENCE] = NULL;
created = true;
diff --git a/src/display/nr-light-types.h b/src/display/nr-light-types.h
--- /dev/null
@@ -0,0 +1,25 @@
+#ifndef __NR_LIGHT_TYPES_H__
+#define __NR_LIGHT_TYPES_H__
+
+namespace NR {
+
+enum LightType{
+ NO_LIGHT = 0,
+ DISTANT_LIGHT,
+ POINT_LIGHT,
+ SPOT_LIGHT
+};
+
+} /* namespace NR */
+
+#endif // __NR_LIGHT_TYPES_H__
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
diff --git a/src/display/nr-light.cpp b/src/display/nr-light.cpp
--- /dev/null
+++ b/src/display/nr-light.cpp
@@ -0,0 +1,119 @@
+#define __NR_LIGHT_CPP__
+
+/*
+ * Light rendering helpers
+ *
+ * Author:
+ * Jean-Rene Reinhard <jr@komite.net>
+ *
+ * Copyright (C) 2006 Jean-Rene Reinhard
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include <cmath>
+
+#include "libnr/nr-pixops.h"
+#include "display/nr-light.h"
+#include "display/nr-3dutils.h"
+#include "sp-fedistantlight.h"
+#include "sp-fepointlight.h"
+#include "sp-fespotlight.h"
+
+namespace NR {
+
+DistantLight::DistantLight(SPFeDistantLight *light, guint32 lighting_color) {
+ color = lighting_color;
+ azimuth = M_PI / 180 * light->azimuth;
+ elevation = M_PI / 180 * light->elevation;
+}
+
+DistantLight::~DistantLight() {}
+
+void DistantLight::light_vector(Fvector &v) {
+ v[X_3D] = std::cos(azimuth)*std::cos(elevation);
+ v[Y_3D] = std::sin(azimuth)*std::cos(elevation);
+ v[Z_3D] = std::sin(elevation);
+}
+
+void DistantLight::light_components(Fvector &lc) {
+ lc[LIGHT_RED] = NR_RGBA32_R(color);
+ lc[LIGHT_GREEN] = NR_RGBA32_G(color);
+ lc[LIGHT_BLUE] = NR_RGBA32_B(color);
+}
+
+PointLight::PointLight(SPFePointLight *light, guint32 lighting_color, const Matrix &trans) {
+ color = lighting_color;
+ l_x = light->x;
+ l_y = light->y;
+ l_z = light->z;
+ convert_coord(l_x, l_y, l_z, trans);
+}
+
+PointLight::~PointLight() {}
+
+void PointLight::light_vector(Fvector &v, gdouble x, gdouble y, gdouble z) {
+ v[X_3D] = l_x - x;
+ v[Y_3D] = l_y - y;
+ v[Z_3D] = l_z - z;
+ normalize_vector(v);
+}
+
+void PointLight::light_components(Fvector &lc) {
+ lc[LIGHT_RED] = NR_RGBA32_R(color);
+ lc[LIGHT_GREEN] = NR_RGBA32_G(color);
+ lc[LIGHT_BLUE] = NR_RGBA32_B(color);
+}
+
+SpotLight::SpotLight(SPFeSpotLight *light, guint32 lighting_color, const Matrix &trans) {
+ gdouble p_x, p_y, p_z;
+ color = lighting_color;
+ l_x = light->x;
+ l_y = light->y;
+ l_z = light->z;
+ p_x = light->pointsAtX;
+ p_y = light->pointsAtY;
+ p_z = light->pointsAtZ;
+ cos_lca = std::cos(M_PI / 180 * light->limitingConeAngle);
+ speExp = light->specularExponent;
+ convert_coord(l_x, l_y, l_z, trans);
+ convert_coord(p_x, p_y, p_z, trans);
+ S[X_3D] = p_x - l_x;
+ S[Y_3D] = p_y - l_y;
+ S[Z_3D] = p_z - l_z;
+ normalize_vector(S);
+
+}
+
+SpotLight::~SpotLight() {}
+
+void SpotLight::light_vector(Fvector &v, gdouble x, gdouble y, gdouble z) {
+ v[X_3D] = l_x - x;
+ v[Y_3D] = l_y - y;
+ v[Z_3D] = l_z - z;
+ normalize_vector(v);
+}
+
+void SpotLight::light_components(Fvector &lc, const Fvector &L) {
+ gdouble spmod = (-1) * scalar_product(L, S);
+ if (spmod <= cos_lca)
+ spmod = 0;
+ else
+ spmod = std::pow(spmod, speExp);
+ lc[LIGHT_RED] = spmod * NR_RGBA32_R(color);
+ lc[LIGHT_GREEN] = spmod * NR_RGBA32_G(color);
+ lc[LIGHT_BLUE] = spmod * NR_RGBA32_B(color);
+}
+
+} /* namespace NR */
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
diff --git a/src/display/nr-light.h b/src/display/nr-light.h
--- /dev/null
+++ b/src/display/nr-light.h
@@ -0,0 +1,160 @@
+#ifndef __NR_LIGHT_H__
+#define __NR_LIGHT_H__
+/** \file
+ * These classes provide tools to compute interesting objects relative to light
+ * sources. Each class provides a constructor converting information contained
+ * in a sp light object into information useful in the current setting, a
+ * method to get the light vector (at a given point) and a method to get the
+ * light color components (at a given point).
+ */
+
+#include <gdk/gdktypes.h>
+#include "display/nr-3dutils.h"
+#include "display/nr-light-types.h"
+
+struct SPFeDistantLight;
+struct SPFePointLight;
+struct SPFeSpotLight;
+
+namespace NR {
+
+struct Matrix;
+
+enum LightComponent {
+ LIGHT_RED = 0,
+ LIGHT_GREEN,
+ LIGHT_BLUE
+};
+
+class DistantLight {
+ public:
+ /**
+ * Constructor
+ *
+ * \param light the sp light object
+ * \param lighting_color the lighting_color used
+ */
+ DistantLight(SPFeDistantLight *light, guint32 lighting_color);
+ ~DistantLight();
+
+ /**
+ * Computes the light vector of the distant light
+ *
+ * \param v a Fvector referece where we store the result
+ */
+ void light_vector(Fvector &v);
+
+ /**
+ * Computes the light components of the distant light
+ *
+ * \param lc a Fvector referece where we store the result, X=R, Y=G, Z=B
+ */
+ void light_components(Fvector &lc);
+
+ private:
+ guint32 color;
+ gdouble azimuth; //azimuth in rad
+ gdouble elevation; //elevation in rad
+};
+
+class PointLight {
+ public:
+ /**
+ * Constructor
+ *
+ * \param light the sp light object
+ * \param lighting_color the lighting_color used
+ * \param trans the transformation between absolute coordinate (those
+ * employed in the sp light object) and current coordinate (those
+ * employed in the rendering)
+ */
+ PointLight(SPFePointLight *light, guint32 lighting_color, const Matrix &trans);
+ ~PointLight();
+ /**
+ * Computes the light vector of the distant light at point (x,y,z).
+ * x, y and z are given in the arena_item coordinate, they are used as
+ * is
+ *
+ * \param v a Fvector referece where we store the result
+ * \param x x coordinate of the current point
+ * \param y y coordinate of the current point
+ * \param z z coordinate of the current point
+ */
+ void light_vector(Fvector &v, gdouble x, gdouble y, gdouble z);
+
+ /**
+ * Computes the light components of the distant light
+ *
+ * \param lc a Fvector referece where we store the result, X=R, Y=G, Z=B
+ */
+ void light_components(Fvector &lc);
+
+ private:
+ guint32 color;
+ //light position coordinates in render setting
+ gdouble l_x;
+ gdouble l_y;
+ gdouble l_z;
+};
+
+class SpotLight {
+ public:
+ /**
+ * Constructor
+ *
+ * \param light the sp light object
+ * \param lighting_color the lighting_color used
+ * \param trans the transformation between absolute coordinate (those
+ * employed in the sp light object) and current coordinate (those
+ * employed in the rendering)
+ */
+ SpotLight(SPFeSpotLight *light, guint32 lighting_color, const Matrix &trans);
+ ~SpotLight();
+
+ /**
+ * Computes the light vector of the distant light at point (x,y,z).
+ * x, y and z are given in the arena_item coordinate, they are used as
+ * is
+ *
+ * \param v a Fvector referece where we store the result
+ * \param x x coordinate of the current point
+ * \param y y coordinate of the current point
+ * \param z z coordinate of the current point
+ */
+ void light_vector(Fvector &v, gdouble x, gdouble y, gdouble z);
+
+ /**
+ * Computes the light components of the distant light at the current
+ * point. We only need the light vector to compute theses
+ *
+ * \param lc a Fvector referece where we store the result, X=R, Y=G, Z=B
+ * \param L the light vector of the current point
+ */
+ void light_components(Fvector &lc, const Fvector &L);
+
+ private:
+ guint32 color;
+ //light position coordinates in render setting
+ gdouble l_x;
+ gdouble l_y;
+ gdouble l_z;
+ gdouble cos_lca; //cos of the limiting cone angle
+ gdouble speExp; //specular exponent;
+ Fvector S; //unit vector from light position in the direction
+ //the spot point at
+};
+
+
+} /* namespace NR */
+
+#endif // __NR_LIGHT_H__
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
index d48c02c96d0978014c42a7a8cd5a7101f24a9649..543c16e8b03834536dabee69118a449baaefad58 100644 (file)
/*
* Authors:
* hugo Rodrigues <haa.rodrigues@gmail.com>
+ * Jean-Rene Reinhard <jr@komite.net>
*
* Copyright (C) 2006 Hugo Rodrigues
+ * 2007 authors
*
* Released under GNU GPL, read the file 'COPYING' for more information
*/
#include "attributes.h"
#include "svg/svg.h"
+#include "sp-object.h"
+#include "svg/svg-color.h"
#include "sp-fediffuselighting.h"
#include "xml/repr.h"
-
+#include "display/nr-filter-diffuselighting.h"
/* FeDiffuseLighting base class */
static void sp_feDiffuseLighting_release(SPObject *object);
static void sp_feDiffuseLighting_set(SPObject *object, unsigned int key, gchar const *value);
static void sp_feDiffuseLighting_update(SPObject *object, SPCtx *ctx, guint flags);
+//we assume that svg:feDiffuseLighting can have any number of children
+//only the first one is considered as the light source of the filter
+//TODO is that right?
+//if not modify child_added and remove_child to raise errors
+static void sp_feDiffuseLighting_child_added(SPObject *object,
+ Inkscape::XML::Node *child,
+ Inkscape::XML::Node *ref);
+static void sp_feDiffuseLighting_remove_child(SPObject *object, Inkscape::XML::Node *child);
+static void sp_feDiffuseLighting_order_changed(SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *old_ref, Inkscape::XML::Node *new_ref);
static Inkscape::XML::Node *sp_feDiffuseLighting_write(SPObject *object, Inkscape::XML::Node *repr, guint flags);
+static void sp_feDiffuseLighting_build_renderer(SPFilterPrimitive *primitive, NR::Filter *filter);
+static void sp_feDiffuseLighting_children_modified(SPFeDiffuseLighting *sp_diffuselighting);
static SPFilterPrimitiveClass *feDiffuseLighting_parent_class;
sp_feDiffuseLighting_class_init(SPFeDiffuseLightingClass *klass)
{
SPObjectClass *sp_object_class = (SPObjectClass *)klass;
-
+ SPFilterPrimitiveClass *sp_primitive_class = (SPFilterPrimitiveClass *)klass;
feDiffuseLighting_parent_class = (SPFilterPrimitiveClass*)g_type_class_peek_parent(klass);
sp_object_class->build = sp_feDiffuseLighting_build;
sp_object_class->write = sp_feDiffuseLighting_write;
sp_object_class->set = sp_feDiffuseLighting_set;
sp_object_class->update = sp_feDiffuseLighting_update;
+ sp_object_class->child_added = sp_feDiffuseLighting_child_added;
+ sp_object_class->remove_child = sp_feDiffuseLighting_remove_child;
+ sp_object_class->order_changed = sp_feDiffuseLighting_order_changed;
+
+ sp_primitive_class->build_renderer = sp_feDiffuseLighting_build_renderer;
}
static void
sp_feDiffuseLighting_init(SPFeDiffuseLighting *feDiffuseLighting)
{
+ feDiffuseLighting->surfaceScale = 1;
+ feDiffuseLighting->diffuseConstant = 1;
+ feDiffuseLighting->lighting_color = 0xffffffff;
+ //TODO kernelUnit
+ feDiffuseLighting->renderer = NULL;
}
/**
@@ -89,6 +114,11 @@ sp_feDiffuseLighting_build(SPObject *object, SPDocument *document, Inkscape::XML
}
/*LOAD ATTRIBUTES FROM REPR HERE*/
+ sp_object_read_attr(object, "surfaceScale");
+ sp_object_read_attr(object, "diffuseConstant");
+ sp_object_read_attr(object, "kernelUnitLength");
+ sp_object_read_attr(object, "lighting-color");
+
}
/**
sp_feDiffuseLighting_set(SPObject *object, unsigned int key, gchar const *value)
{
SPFeDiffuseLighting *feDiffuseLighting = SP_FEDIFFUSELIGHTING(object);
- (void)feDiffuseLighting;
-
+
switch(key) {
/*DEAL WITH SETTING ATTRIBUTES HERE*/
+//TODO test forbidden values
+ case SP_ATTR_SURFACESCALE:
+ feDiffuseLighting->surfaceScale = g_ascii_strtod(value, NULL);
+ if (feDiffuseLighting->renderer) {
+ feDiffuseLighting->renderer->surfaceScale = feDiffuseLighting->surfaceScale;
+ }
+ object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ break;
+ case SP_ATTR_DIFFUSECONSTANT:
+ feDiffuseLighting->diffuseConstant = g_ascii_strtod(value, NULL);
+ if (feDiffuseLighting->renderer) {
+ feDiffuseLighting->renderer->diffuseConstant = feDiffuseLighting->diffuseConstant;
+ }
+ object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ break;
+ case SP_ATTR_KERNELUNITLENGTH:
+ //TODO kernelUnit
+ //feDiffuseLighting->kernelUnitLength.set(value);
+ /*TODOif (feDiffuseLighting->renderer) {
+ feDiffuseLighting->renderer->surfaceScale = feDiffuseLighting->renderer;
+ }
+ */
+ object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ break;
+ case SP_PROP_LIGHTING_COLOR:
+ feDiffuseLighting->lighting_color = sp_svg_read_color(value, 0xffffffff);
+ if (feDiffuseLighting->renderer) {
+ feDiffuseLighting->renderer->lighting_color = feDiffuseLighting->lighting_color;
+ }
+ object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ break;
default:
if (((SPObjectClass *) feDiffuseLighting_parent_class)->set)
((SPObjectClass *) feDiffuseLighting_parent_class)->set(object, key, value);
@@ -126,11 +186,11 @@ sp_feDiffuseLighting_set(SPObject *object, unsigned int key, gchar const *value)
static void
sp_feDiffuseLighting_update(SPObject *object, SPCtx *ctx, guint flags)
{
- if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG |
- SP_OBJECT_VIEWPORT_MODIFIED_FLAG)) {
-
- /* do something to trigger redisplay, updates? */
-
+ if (flags & (SP_OBJECT_MODIFIED_FLAG)) {
+ sp_object_read_attr(object, "surfaceScale");
+ sp_object_read_attr(object, "diffuseConstant");
+ sp_object_read_attr(object, "kernelUnit");
+ sp_object_read_attr(object, "lighting-color");
}
if (((SPObjectClass *) feDiffuseLighting_parent_class)->update) {
static Inkscape::XML::Node *
sp_feDiffuseLighting_write(SPObject *object, Inkscape::XML::Node *repr, guint flags)
{
+ SPFeDiffuseLighting *fediffuselighting = SP_FEDIFFUSELIGHTING(object);
+
// Inkscape-only object, not copied during an "plain SVG" dump:
if (flags & SP_OBJECT_WRITE_EXT) {
if (repr) {
// is this sane?
- repr->mergeFrom(SP_OBJECT_REPR(object), "id");
+ //repr->mergeFrom(SP_OBJECT_REPR(object), "id");
} else {
repr = SP_OBJECT_REPR(object)->duplicate(NULL); // FIXME
}
}
+ sp_repr_set_css_double(repr, "surfaceScale", fediffuselighting->surfaceScale);
+ sp_repr_set_css_double(repr, "diffuseConstant", fediffuselighting->diffuseConstant);
+ /*TODO kernelUnits */
+ gchar c[64];
+ sp_svg_write_color(c, 64, fediffuselighting->lighting_color);
+ repr->setAttribute("lighting-color", c);
if (((SPObjectClass *) feDiffuseLighting_parent_class)->write) {
((SPObjectClass *) feDiffuseLighting_parent_class)->write(object, repr, flags);
}
@@ -161,6 +229,103 @@ sp_feDiffuseLighting_write(SPObject *object, Inkscape::XML::Node *repr, guint fl
return repr;
}
+/**
+ * Callback for child_added event.
+ */
+static void
+sp_feDiffuseLighting_child_added(SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *ref)
+{
+ SPFeDiffuseLighting *f = SP_FEDIFFUSELIGHTING(object);
+
+ if (((SPObjectClass *) feDiffuseLighting_parent_class)->child_added)
+ (* ((SPObjectClass *) feDiffuseLighting_parent_class)->child_added)(object, child, ref);
+
+ sp_feDiffuseLighting_children_modified(f);
+ object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
+}
+
+
+/**
+ * Callback for remove_child event.
+ */
+static void
+sp_feDiffuseLighting_remove_child(SPObject *object, Inkscape::XML::Node *child)
+{
+ SPFeDiffuseLighting *f = SP_FEDIFFUSELIGHTING(object);
+
+ if (((SPObjectClass *) feDiffuseLighting_parent_class)->remove_child)
+ (* ((SPObjectClass *) feDiffuseLighting_parent_class)->remove_child)(object, child);
+
+ sp_feDiffuseLighting_children_modified(f);
+ object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
+}
+
+static void
+sp_feDiffuseLighting_order_changed (SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *old_ref, Inkscape::XML::Node *new_ref)
+{
+ SPFeDiffuseLighting *f = SP_FEDIFFUSELIGHTING(object);
+ if (((SPObjectClass *) (feDiffuseLighting_parent_class))->order_changed)
+ (* ((SPObjectClass *) (feDiffuseLighting_parent_class))->order_changed) (object, child, old_ref, new_ref);
+
+ sp_feDiffuseLighting_children_modified(f);
+ object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
+}
+
+static void sp_feDiffuseLighting_children_modified(SPFeDiffuseLighting *sp_diffuselighting)
+{
+ if (sp_diffuselighting->renderer) {
+ sp_diffuselighting->renderer->light_type = NR::NO_LIGHT;
+ if (SP_IS_FEDISTANTLIGHT(sp_diffuselighting->children)) {
+ sp_diffuselighting->renderer->light_type = NR::DISTANT_LIGHT;
+ sp_diffuselighting->renderer->light.distant = SP_FEDISTANTLIGHT(sp_diffuselighting->children);
+ }
+ if (SP_IS_FEPOINTLIGHT(sp_diffuselighting->children)) {
+ sp_diffuselighting->renderer->light_type = NR::POINT_LIGHT;
+ sp_diffuselighting->renderer->light.point = SP_FEPOINTLIGHT(sp_diffuselighting->children);
+ }
+ if (SP_IS_FESPOTLIGHT(sp_diffuselighting->children)) {
+ sp_diffuselighting->renderer->light_type = NR::SPOT_LIGHT;
+ sp_diffuselighting->renderer->light.spot = SP_FESPOTLIGHT(sp_diffuselighting->children);
+ }
+ }
+}
+
+static void sp_feDiffuseLighting_build_renderer(SPFilterPrimitive *primitive, NR::Filter *filter) {
+ g_assert(primitive != NULL);
+ g_assert(filter != NULL);
+
+ SPFeDiffuseLighting *sp_diffuselighting = SP_FEDIFFUSELIGHTING(primitive);
+
+ int primitive_n = filter->add_primitive(NR::NR_FILTER_DIFFUSELIGHTING);
+ NR::FilterPrimitive *nr_primitive = filter->get_primitive(primitive_n);
+ NR::FilterDiffuseLighting *nr_diffuselighting = dynamic_cast<NR::FilterDiffuseLighting*>(nr_primitive);
+ g_assert(nr_diffuselighting != NULL);
+
+ sp_diffuselighting->renderer = nr_diffuselighting;
+ sp_filter_primitive_renderer_common(primitive, nr_primitive);
+
+ nr_diffuselighting->diffuseConstant = sp_diffuselighting->diffuseConstant;
+ nr_diffuselighting->surfaceScale = sp_diffuselighting->surfaceScale;
+ nr_diffuselighting->lighting_color = sp_diffuselighting->lighting_color;
+ //We assume there is at most one child
+ nr_diffuselighting->light_type = NR::NO_LIGHT;
+ if (SP_IS_FEDISTANTLIGHT(primitive->children)) {
+ nr_diffuselighting->light_type = NR::DISTANT_LIGHT;
+ nr_diffuselighting->light.distant = SP_FEDISTANTLIGHT(primitive->children);
+ }
+ if (SP_IS_FEPOINTLIGHT(primitive->children)) {
+ nr_diffuselighting->light_type = NR::POINT_LIGHT;
+ nr_diffuselighting->light.point = SP_FEPOINTLIGHT(primitive->children);
+ }
+ if (SP_IS_FESPOTLIGHT(primitive->children)) {
+ nr_diffuselighting->light_type = NR::SPOT_LIGHT;
+ nr_diffuselighting->light.spot = SP_FESPOTLIGHT(primitive->children);
+ }
+
+ //nr_offset->set_dx(sp_offset->dx);
+ //nr_offset->set_dy(sp_offset->dy);
+}
+
/*
Local Variables:
index c937c2dd862c5f9a865dca42acbad78d1d25b697..15988b306663251bcf9d9fe2d87efe694de7dd32 100644 (file)
/*
* Authors:
* Hugo Rodrigues <haa.rodrigues@gmail.com>
+ * Jean-Rene Reinhard <jr@komite.net>
*
* Copyright (C) 2006 Hugo Rodrigues
+ * 2007 authors
*
* Released under GNU GPL, read the file 'COPYING' for more information
*/
#include "sp-filter.h"
#include "sp-fediffuselighting-fns.h"
+namespace NR {
+class FilterDiffuseLighting;
+}
+
/* FeDiffuseLighting base class */
class SPFeDiffuseLightingClass;
struct SPFeDiffuseLighting : public SPFilterPrimitive {
/** DIFFUSELIGHTING ATTRIBUTES HERE */
-
+ gfloat surfaceScale;
+ gfloat diffuseConstant;
+ NumberOptNumber kernelUnitLength;
+ guint32 lighting_color;
+
+ NR::FilterDiffuseLighting *renderer;
};
struct SPFeDiffuseLightingClass {
diff --git a/src/sp-fedistantlight.cpp b/src/sp-fedistantlight.cpp
--- /dev/null
@@ -0,0 +1,209 @@
+#define __SP_FEDISTANTLIGHT_CPP__
+
+/** \file
+ * SVG <fedistantlight> implementation.
+ */
+/*
+ * Authors:
+ * Hugo Rodrigues <haa.rodrigues@gmail.com>
+ * Niko Kiirala <niko@kiirala.com>
+ * Jean-Rene Reinhard <jr@komite.net>
+ *
+ * Copyright (C) 2006,2007 Authors
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <glib.h>
+
+#include "attributes.h"
+#include "document.h"
+#include "sp-fedistantlight.h"
+#include "sp-fediffuselighting-fns.h"
+#include "sp-fespecularlighting-fns.h"
+#include "xml/repr.h"
+
+#define SP_MACROS_SILENT
+#include "macros.h"
+
+/* FeDistantLight class */
+
+static void sp_fedistantlight_class_init(SPFeDistantLightClass *klass);
+static void sp_fedistantlight_init(SPFeDistantLight *fedistantlight);
+
+static void sp_fedistantlight_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr);
+static void sp_fedistantlight_release(SPObject *object);
+static void sp_fedistantlight_set(SPObject *object, unsigned int key, gchar const *value);
+static void sp_fedistantlight_update(SPObject *object, SPCtx *ctx, guint flags);
+static Inkscape::XML::Node *sp_fedistantlight_write(SPObject *object, Inkscape::XML::Node *repr, guint flags);
+
+static SPObjectClass *feDistantLight_parent_class;
+
+GType
+sp_fedistantlight_get_type()
+{
+ static GType fedistantlight_type = 0;
+
+ if (!fedistantlight_type) {
+ GTypeInfo fedistantlight_info = {
+ sizeof(SPFeDistantLightClass),
+ NULL, NULL,
+ (GClassInitFunc) sp_fedistantlight_class_init,
+ NULL, NULL,
+ sizeof(SPFeDistantLight),
+ 16,
+ (GInstanceInitFunc) sp_fedistantlight_init,
+ NULL, /* value_table */
+ };
+ fedistantlight_type = g_type_register_static(SP_TYPE_OBJECT, "SPFeDistantLight", &fedistantlight_info, (GTypeFlags)0);
+ }
+ return fedistantlight_type;
+}
+
+static void
+sp_fedistantlight_class_init(SPFeDistantLightClass *klass)
+{
+
+ SPObjectClass *sp_object_class = (SPObjectClass *)klass;
+
+ feDistantLight_parent_class = (SPObjectClass*)g_type_class_peek_parent(klass);
+
+ sp_object_class->build = sp_fedistantlight_build;
+ sp_object_class->release = sp_fedistantlight_release;
+ sp_object_class->write = sp_fedistantlight_write;
+ sp_object_class->set = sp_fedistantlight_set;
+ sp_object_class->update = sp_fedistantlight_update;
+}
+
+static void
+sp_fedistantlight_init(SPFeDistantLight *fedistantlight)
+{
+ fedistantlight->azimuth = 0;
+ fedistantlight->elevation = 0;
+}
+
+/**
+ * Reads the Inkscape::XML::Node, and initializes SPDistantLight variables. For this to get called,
+ * our name must be associated with a repr via "sp_object_type_register". Best done through
+ * sp-object-repr.cpp's repr_name_entries array.
+ */
+static void
+sp_fedistantlight_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr)
+{
+ if (((SPObjectClass *) feDistantLight_parent_class)->build) {
+ ((SPObjectClass *) feDistantLight_parent_class)->build(object, document, repr);
+ }
+
+ //Read values of key attributes from XML nodes into object.
+ sp_object_read_attr(object, "azimuth");
+ sp_object_read_attr(object, "elevation");
+
+//is this necessary?
+ sp_document_add_resource(document, "fedistantlight", object);
+}
+
+/**
+ * Drops any allocated memory.
+ */
+static void
+sp_fedistantlight_release(SPObject *object)
+{
+ //SPFeDistantLight *fedistantlight = SP_FEDISTANTLIGHT(object);
+
+ if (SP_OBJECT_DOCUMENT(object)) {
+ /* Unregister ourselves */
+ sp_document_remove_resource(SP_OBJECT_DOCUMENT(object), "fedistantlight", SP_OBJECT(object));
+ }
+
+//TODO: release resources here
+}
+
+/**
+ * Sets a specific value in the SPFeDistantLight.
+ */
+static void
+sp_fedistantlight_set(SPObject *object, unsigned int key, gchar const *value)
+{
+ SPFeDistantLight *fedistantlight = SP_FEDISTANTLIGHT(object);
+
+ switch (key) {
+ case SP_ATTR_AZIMUTH:
+ fedistantlight->azimuth = g_ascii_strtod(value, NULL);
+ if (object->parent &&
+ (SP_IS_FEDIFFUSELIGHTING(object->parent) ||
+ SP_IS_FESPECULARLIGHTING(object->parent))) {
+ object->parent->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ }
+ break;
+ case SP_ATTR_ELEVATION:
+ fedistantlight->elevation = g_ascii_strtod(value, NULL);
+ if (object->parent &&
+ (SP_IS_FEDIFFUSELIGHTING(object->parent) ||
+ SP_IS_FESPECULARLIGHTING(object->parent))) {
+ object->parent->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ }
+ break;
+ default:
+ // See if any parents need this value.
+ if (((SPObjectClass *) feDistantLight_parent_class)->set) {
+ ((SPObjectClass *) feDistantLight_parent_class)->set(object, key, value);
+ }
+ break;
+ }
+}
+
+/**
+ * * Receives update notifications.
+ * */
+static void
+sp_fedistantlight_update(SPObject *object, SPCtx *ctx, guint flags)
+{
+ SPFeDistantLight *feDistantLight = SP_FEDISTANTLIGHT(object);
+
+ if (flags & SP_OBJECT_MODIFIED_FLAG) {
+ /* do something to trigger redisplay, updates? */
+ sp_object_read_attr(object, "azimuth");
+ sp_object_read_attr(object, "elevation");
+ }
+
+ if (((SPObjectClass *) feDistantLight_parent_class)->update) {
+ ((SPObjectClass *) feDistantLight_parent_class)->update(object, ctx, flags);
+ }
+}
+
+/**
+ * Writes its settings to an incoming repr object, if any.
+ */
+static Inkscape::XML::Node *
+sp_fedistantlight_write(SPObject *object, Inkscape::XML::Node *repr, guint flags)
+{
+ SPFeDistantLight *fedistantlight = SP_FEDISTANTLIGHT(object);
+
+ if (!repr) {
+ repr = SP_OBJECT_REPR(object)->duplicate(NULL); // FIXME
+ }
+
+ sp_repr_set_css_double(repr, "azimuth", fedistantlight->azimuth);
+ sp_repr_set_css_double(repr, "elevation", fedistantlight->elevation);
+
+ if (((SPObjectClass *) feDistantLight_parent_class)->write) {
+ ((SPObjectClass *) feDistantLight_parent_class)->write(object, repr, flags);
+ }
+
+ return repr;
+}
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
diff --git a/src/sp-fedistantlight.h b/src/sp-fedistantlight.h
--- /dev/null
+++ b/src/sp-fedistantlight.h
@@ -0,0 +1,59 @@
+#ifndef SP_FEDISTANTLIGHT_H_SEEN
+#define SP_FEDISTANTLIGHT_H_SEEN
+
+/** \file
+ * SVG <filter> implementation, see sp-filter.cpp.
+ */
+/*
+ * Authors:
+ * Hugo Rodrigues <haa.rodrigues@gmail.com>
+ * Niko Kiirala <niko@kiirala.com>
+ * Jean-Rene Reinhard <jr@komite.net>
+ *
+ * Copyright (C) 2006,2007 Authors
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include "sp-object.h"
+
+#define SP_TYPE_FEDISTANTLIGHT (sp_fedistantlight_get_type())
+#define SP_FEDISTANTLIGHT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SP_TYPE_FEDISTANTLIGHT, SPFeDistantLight))
+#define SP_FEDISTANTLIGHT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), SP_TYPE_FEDISTANTLIGHT, SPFeDistantLightClass))
+#define SP_IS_FEDISTANTLIGHT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SP_TYPE_FEDISTANTLIGHT))
+#define SP_IS_FEDISTANTLIGHT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SP_TYPE_FEDISTANTLIGHT))
+
+/* Distant light class */
+
+
+class SPFeDistantLight;
+class SPFeDistantLightClass;
+
+struct SPFeDistantLight : public SPObject {
+
+ /** azimuth attribute */
+ gfloat azimuth;
+ /** elevation attribute */
+ gfloat elevation;
+
+ //other fields
+};
+
+struct SPFeDistantLightClass {
+ SPObjectClass parent_class;
+};
+
+GType
+sp_fedistantlight_get_type();
+#endif /* !SP_FEDISTANTLIGHT_H_SEEN */
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
diff --git a/src/sp-fepointlight.cpp b/src/sp-fepointlight.cpp
--- /dev/null
+++ b/src/sp-fepointlight.cpp
@@ -0,0 +1,221 @@
+#define __SP_FEPOINTLIGHT_CPP__
+
+/** \file
+ * SVG <fepointlight> implementation.
+ */
+/*
+ * Authors:
+ * Hugo Rodrigues <haa.rodrigues@gmail.com>
+ * Niko Kiirala <niko@kiirala.com>
+ * Jean-Rene Reinhard <jr@komite.net>
+ *
+ * Copyright (C) 2006,2007 Authors
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <glib.h>
+
+#include "attributes.h"
+#include "document.h"
+#include "sp-fepointlight.h"
+#include "sp-fediffuselighting-fns.h"
+#include "sp-fespecularlighting-fns.h"
+#include "xml/repr.h"
+
+#define SP_MACROS_SILENT
+#include "macros.h"
+
+/* FePointLight class */
+
+static void sp_fepointlight_class_init(SPFePointLightClass *klass);
+static void sp_fepointlight_init(SPFePointLight *fepointlight);
+
+static void sp_fepointlight_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr);
+static void sp_fepointlight_release(SPObject *object);
+static void sp_fepointlight_set(SPObject *object, unsigned int key, gchar const *value);
+static void sp_fepointlight_update(SPObject *object, SPCtx *ctx, guint flags);
+static Inkscape::XML::Node *sp_fepointlight_write(SPObject *object, Inkscape::XML::Node *repr, guint flags);
+
+static SPObjectClass *fePointLight_parent_class;
+
+GType
+sp_fepointlight_get_type()
+{
+ static GType fepointlight_type = 0;
+
+ if (!fepointlight_type) {
+ GTypeInfo fepointlight_info = {
+ sizeof(SPFePointLightClass),
+ NULL, NULL,
+ (GClassInitFunc) sp_fepointlight_class_init,
+ NULL, NULL,
+ sizeof(SPFePointLight),
+ 16,
+ (GInstanceInitFunc) sp_fepointlight_init,
+ NULL, /* value_table */
+ };
+ fepointlight_type = g_type_register_static(SP_TYPE_OBJECT, "SPFePointLight", &fepointlight_info, (GTypeFlags)0);
+ }
+ return fepointlight_type;
+}
+
+static void
+sp_fepointlight_class_init(SPFePointLightClass *klass)
+{
+
+ SPObjectClass *sp_object_class = (SPObjectClass *)klass;
+
+ fePointLight_parent_class = (SPObjectClass*)g_type_class_peek_parent(klass);
+
+ sp_object_class->build = sp_fepointlight_build;
+ sp_object_class->release = sp_fepointlight_release;
+ sp_object_class->write = sp_fepointlight_write;
+ sp_object_class->set = sp_fepointlight_set;
+ sp_object_class->update = sp_fepointlight_update;
+}
+
+static void
+sp_fepointlight_init(SPFePointLight *fepointlight)
+{
+ fepointlight->x = 0;
+ fepointlight->y = 0;
+ fepointlight->z = 0;
+}
+
+/**
+ * Reads the Inkscape::XML::Node, and initializes SPPointLight variables. For this to get called,
+ * our name must be associated with a repr via "sp_object_type_register". Best done through
+ * sp-object-repr.cpp's repr_name_entries array.
+ */
+static void
+sp_fepointlight_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr)
+{
+ if (((SPObjectClass *) fePointLight_parent_class)->build) {
+ ((SPObjectClass *) fePointLight_parent_class)->build(object, document, repr);
+ }
+
+ //Read values of key attributes from XML nodes into object.
+ sp_object_read_attr(object, "x");
+ sp_object_read_attr(object, "y");
+ sp_object_read_attr(object, "z");
+
+//is this necessary?
+ sp_document_add_resource(document, "fepointlight", object);
+}
+
+/**
+ * Drops any allocated memory.
+ */
+static void
+sp_fepointlight_release(SPObject *object)
+{
+ //SPFePointLight *fepointlight = SP_FEPOINTLIGHT(object);
+
+ if (SP_OBJECT_DOCUMENT(object)) {
+ /* Unregister ourselves */
+ sp_document_remove_resource(SP_OBJECT_DOCUMENT(object), "fepointlight", SP_OBJECT(object));
+ }
+
+//TODO: release resources here
+}
+
+/**
+ * Sets a specific value in the SPFePointLight.
+ */
+static void
+sp_fepointlight_set(SPObject *object, unsigned int key, gchar const *value)
+{
+ SPFePointLight *fepointlight = SP_FEPOINTLIGHT(object);
+
+ switch (key) {
+ case SP_ATTR_X:
+ fepointlight->x = g_ascii_strtod(value, NULL);
+ if (object->parent &&
+ (SP_IS_FEDIFFUSELIGHTING(object->parent) ||
+ SP_IS_FESPECULARLIGHTING(object->parent))) {
+ object->parent->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ }
+ break;
+ case SP_ATTR_Y:
+ fepointlight->y = g_ascii_strtod(value, NULL);
+ if (object->parent &&
+ (SP_IS_FEDIFFUSELIGHTING(object->parent) ||
+ SP_IS_FESPECULARLIGHTING(object->parent))) {
+ object->parent->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ }
+ break;
+ case SP_ATTR_Z:
+ fepointlight->z = g_ascii_strtod(value, NULL);
+ if (object->parent &&
+ (SP_IS_FEDIFFUSELIGHTING(object->parent) ||
+ SP_IS_FESPECULARLIGHTING(object->parent))) {
+ object->parent->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ }
+ break;
+ default:
+ // See if any parents need this value.
+ if (((SPObjectClass *) fePointLight_parent_class)->set) {
+ ((SPObjectClass *) fePointLight_parent_class)->set(object, key, value);
+ }
+ break;
+ }
+}
+
+/**
+ * * Receives update notifications.
+ * */
+static void
+sp_fepointlight_update(SPObject *object, SPCtx *ctx, guint flags)
+{
+ SPFePointLight *fePointLight = SP_FEPOINTLIGHT(object);
+
+ if (flags & SP_OBJECT_MODIFIED_FLAG) {
+ /* do something to trigger redisplay, updates? */
+ sp_object_read_attr(object, "x");
+ sp_object_read_attr(object, "y");
+ sp_object_read_attr(object, "z");
+ }
+
+ if (((SPObjectClass *) fePointLight_parent_class)->update) {
+ ((SPObjectClass *) fePointLight_parent_class)->update(object, ctx, flags);
+ }
+}
+
+/**
+ * Writes its settings to an incoming repr object, if any.
+ */
+static Inkscape::XML::Node *
+sp_fepointlight_write(SPObject *object, Inkscape::XML::Node *repr, guint flags)
+{
+ SPFePointLight *fepointlight = SP_FEPOINTLIGHT(object);
+
+ if (!repr) {
+ repr = SP_OBJECT_REPR(object)->duplicate(NULL); // FIXME
+ }
+
+ sp_repr_set_css_double(repr, "x", fepointlight->x);
+ sp_repr_set_css_double(repr, "y", fepointlight->y);
+ sp_repr_set_css_double(repr, "z", fepointlight->z);
+
+ if (((SPObjectClass *) fePointLight_parent_class)->write) {
+ ((SPObjectClass *) fePointLight_parent_class)->write(object, repr, flags);
+ }
+
+ return repr;
+}
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
diff --git a/src/sp-fepointlight.h b/src/sp-fepointlight.h
--- /dev/null
+++ b/src/sp-fepointlight.h
@@ -0,0 +1,61 @@
+#ifndef SP_FEPOINTLIGHT_H_SEEN
+#define SP_FEPOINTLIGHT_H_SEEN
+
+/** \file
+ * SVG <filter> implementation, see sp-filter.cpp.
+ */
+/*
+ * Authors:
+ * Hugo Rodrigues <haa.rodrigues@gmail.com>
+ * Niko Kiirala <niko@kiirala.com>
+ * Jean-Rene Reinhard <jr@komite.net>
+ *
+ * Copyright (C) 2006,2007 Authors
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include "sp-object.h"
+
+#define SP_TYPE_FEPOINTLIGHT (sp_fepointlight_get_type())
+#define SP_FEPOINTLIGHT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SP_TYPE_FEPOINTLIGHT, SPFePointLight))
+#define SP_FEPOINTLIGHT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), SP_TYPE_FEPOINTLIGHT, SPFePointLightClass))
+#define SP_IS_FEPOINTLIGHT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SP_TYPE_FEPOINTLIGHT))
+#define SP_IS_FEPOINTLIGHT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SP_TYPE_FEPOINTLIGHT))
+
+/* Distant light class */
+
+
+class SPFePointLight;
+class SPFePointLightClass;
+
+struct SPFePointLight : public SPObject {
+
+ /** x coordinate of the light source */
+ gfloat x;
+ /** y coordinate of the light source */
+ gfloat y;
+ /** z coordinate of the light source */
+ gfloat z;
+
+ //other fields
+};
+
+struct SPFePointLightClass {
+ SPObjectClass parent_class;
+};
+
+GType
+sp_fepointlight_get_type();
+#endif /* !SP_FEPOINTLIGHT_H_SEEN */
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
index cc9837041b0df00f353938cfc565a05b7803b0e7..85f2aa862a6fba9cc4238a13501641d1f8faa046 100644 (file)
/*
* Authors:
* hugo Rodrigues <haa.rodrigues@gmail.com>
+ * Jean-Rene Reinhard <jr@komite.net>
*
* Copyright (C) 2006 Hugo Rodrigues
+ * 2007 authors
*
* Released under GNU GPL, read the file 'COPYING' for more information
*/
#include "attributes.h"
#include "svg/svg.h"
+#include "sp-object.h"
+#include "svg/svg-color.h"
#include "sp-fespecularlighting.h"
#include "xml/repr.h"
-
+#include "display/nr-filter-specularlighting.h"
/* FeSpecularLighting base class */
static void sp_feSpecularLighting_release(SPObject *object);
static void sp_feSpecularLighting_set(SPObject *object, unsigned int key, gchar const *value);
static void sp_feSpecularLighting_update(SPObject *object, SPCtx *ctx, guint flags);
+//we assume that svg:feSpecularLighting can have any number of children
+//only the first one is considered as the light source of the filter
+//TODO is that right?
+//if not modify child_added and remove_child to raise errors
+static void sp_feSpecularLighting_child_added(SPObject *object,
+ Inkscape::XML::Node *child,
+ Inkscape::XML::Node *ref);
+static void sp_feSpecularLighting_remove_child(SPObject *object, Inkscape::XML::Node *child);
+static void sp_feSpecularLighting_order_changed(SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *old_ref, Inkscape::XML::Node *new_ref);
static Inkscape::XML::Node *sp_feSpecularLighting_write(SPObject *object, Inkscape::XML::Node *repr, guint flags);
+static void sp_feSpecularLighting_build_renderer(SPFilterPrimitive *primitive, NR::Filter *filter);
+static void sp_feSpecularLighting_children_modified(SPFeSpecularLighting *sp_specularlighting);
static SPFilterPrimitiveClass *feSpecularLighting_parent_class;
sp_feSpecularLighting_class_init(SPFeSpecularLightingClass *klass)
{
SPObjectClass *sp_object_class = (SPObjectClass *)klass;
-
+ SPFilterPrimitiveClass *sp_primitive_class = (SPFilterPrimitiveClass *)klass;
feSpecularLighting_parent_class = (SPFilterPrimitiveClass*)g_type_class_peek_parent(klass);
sp_object_class->build = sp_feSpecularLighting_build;
sp_object_class->write = sp_feSpecularLighting_write;
sp_object_class->set = sp_feSpecularLighting_set;
sp_object_class->update = sp_feSpecularLighting_update;
+ sp_object_class->child_added = sp_feSpecularLighting_child_added;
+ sp_object_class->remove_child = sp_feSpecularLighting_remove_child;
+ sp_object_class->order_changed = sp_feSpecularLighting_order_changed;
+
+ sp_primitive_class->build_renderer = sp_feSpecularLighting_build_renderer;
}
static void
sp_feSpecularLighting_init(SPFeSpecularLighting *feSpecularLighting)
{
+ feSpecularLighting->surfaceScale = 1;
+ feSpecularLighting->specularConstant = 1;
+ feSpecularLighting->specularExponent = 1;
+ feSpecularLighting->lighting_color = 0xffffffff;
+ //TODO kernelUnit
+ feSpecularLighting->renderer = NULL;
}
/**
@@ -89,6 +115,12 @@ sp_feSpecularLighting_build(SPObject *object, SPDocument *document, Inkscape::XM
}
/*LOAD ATTRIBUTES FROM REPR HERE*/
+ sp_object_read_attr(object, "surfaceScale");
+ sp_object_read_attr(object, "specularConstant");
+ sp_object_read_attr(object, "specularExponent");
+ sp_object_read_attr(object, "kernelUnitLength");
+ sp_object_read_attr(object, "lighting-color");
+
}
/**
sp_feSpecularLighting_set(SPObject *object, unsigned int key, gchar const *value)
{
SPFeSpecularLighting *feSpecularLighting = SP_FESPECULARLIGHTING(object);
- (void)feSpecularLighting;
-
+
switch(key) {
/*DEAL WITH SETTING ATTRIBUTES HERE*/
+//TODO test forbidden values
+ case SP_ATTR_SURFACESCALE:
+ feSpecularLighting->surfaceScale = g_ascii_strtod(value, NULL);
+ if (feSpecularLighting->renderer) {
+ feSpecularLighting->renderer->surfaceScale = feSpecularLighting->surfaceScale;
+ }
+ object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ break;
+ case SP_ATTR_SPECULARCONSTANT:
+ feSpecularLighting->specularConstant = g_ascii_strtod(value, NULL);
+ if (feSpecularLighting->renderer) {
+ feSpecularLighting->renderer->specularConstant = feSpecularLighting->specularConstant;
+ }
+ object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ break;
+ case SP_ATTR_SPECULAREXPONENT:
+ feSpecularLighting->specularExponent = g_ascii_strtod(value, NULL);
+ if (feSpecularLighting->renderer) {
+ feSpecularLighting->renderer->specularExponent = feSpecularLighting->specularExponent;
+ }
+ object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ break;
+ case SP_ATTR_KERNELUNITLENGTH:
+ //TODO kernelUnit
+ //feSpecularLighting->kernelUnitLength.set(value);
+ /*TODOif (feSpecularLighting->renderer) {
+ feSpecularLighting->renderer->surfaceScale = feSpecularLighting->renderer;
+ }
+ */
+ object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ break;
+ case SP_PROP_LIGHTING_COLOR:
+ feSpecularLighting->lighting_color = sp_svg_read_color(value, 0xffffffff);
+ if (feSpecularLighting->renderer) {
+ feSpecularLighting->renderer->lighting_color = feSpecularLighting->lighting_color;
+ }
+ object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ break;
default:
if (((SPObjectClass *) feSpecularLighting_parent_class)->set)
((SPObjectClass *) feSpecularLighting_parent_class)->set(object, key, value);
@@ -126,11 +195,12 @@ sp_feSpecularLighting_set(SPObject *object, unsigned int key, gchar const *value
static void
sp_feSpecularLighting_update(SPObject *object, SPCtx *ctx, guint flags)
{
- if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG |
- SP_OBJECT_VIEWPORT_MODIFIED_FLAG)) {
-
- /* do something to trigger redisplay, updates? */
-
+ if (flags & (SP_OBJECT_MODIFIED_FLAG)) {
+ sp_object_read_attr(object, "surfaceScale");
+ sp_object_read_attr(object, "specularConstant");
+ sp_object_read_attr(object, "specularExponent");
+ sp_object_read_attr(object, "kernelUnitLength");
+ sp_object_read_attr(object, "lighting-color");
}
if (((SPObjectClass *) feSpecularLighting_parent_class)->update) {
static Inkscape::XML::Node *
sp_feSpecularLighting_write(SPObject *object, Inkscape::XML::Node *repr, guint flags)
{
+ SPFeSpecularLighting *fespecularlighting = SP_FESPECULARLIGHTING(object);
+
// Inkscape-only object, not copied during an "plain SVG" dump:
if (flags & SP_OBJECT_WRITE_EXT) {
if (repr) {
// is this sane?
- repr->mergeFrom(SP_OBJECT_REPR(object), "id");
+ //repr->mergeFrom(SP_OBJECT_REPR(object), "id");
} else {
repr = SP_OBJECT_REPR(object)->duplicate(NULL); // FIXME
}
}
+ sp_repr_set_css_double(repr, "surfaceScale", fespecularlighting->surfaceScale);
+ sp_repr_set_css_double(repr, "specularConstant", fespecularlighting->specularConstant);
+ sp_repr_set_css_double(repr, "specularExponent", fespecularlighting->specularExponent);
+ /*TODO kernelUnits */
+ gchar c[64];
+ sp_svg_write_color(c, 64, fespecularlighting->lighting_color);
+ repr->setAttribute("lighting-color", c);
if (((SPObjectClass *) feSpecularLighting_parent_class)->write) {
((SPObjectClass *) feSpecularLighting_parent_class)->write(object, repr, flags);
}
@@ -161,6 +240,104 @@ sp_feSpecularLighting_write(SPObject *object, Inkscape::XML::Node *repr, guint f
return repr;
}
+/**
+ * Callback for child_added event.
+ */
+static void
+sp_feSpecularLighting_child_added(SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *ref)
+{
+ SPFeSpecularLighting *f = SP_FESPECULARLIGHTING(object);
+
+ if (((SPObjectClass *) feSpecularLighting_parent_class)->child_added)
+ (* ((SPObjectClass *) feSpecularLighting_parent_class)->child_added)(object, child, ref);
+
+ sp_feSpecularLighting_children_modified(f);
+ object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
+}
+
+
+/**
+ * Callback for remove_child event.
+ */
+static void
+sp_feSpecularLighting_remove_child(SPObject *object, Inkscape::XML::Node *child)
+{
+ SPFeSpecularLighting *f = SP_FESPECULARLIGHTING(object);
+
+ if (((SPObjectClass *) feSpecularLighting_parent_class)->remove_child)
+ (* ((SPObjectClass *) feSpecularLighting_parent_class)->remove_child)(object, child);
+
+ sp_feSpecularLighting_children_modified(f);
+ object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
+}
+
+static void
+sp_feSpecularLighting_order_changed (SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *old_ref, Inkscape::XML::Node *new_ref)
+{
+ SPFeSpecularLighting *f = SP_FESPECULARLIGHTING(object);
+ if (((SPObjectClass *) (feSpecularLighting_parent_class))->order_changed)
+ (* ((SPObjectClass *) (feSpecularLighting_parent_class))->order_changed) (object, child, old_ref, new_ref);
+
+ sp_feSpecularLighting_children_modified(f);
+ object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
+}
+
+static void sp_feSpecularLighting_children_modified(SPFeSpecularLighting *sp_specularlighting)
+{
+ if (sp_specularlighting->renderer) {
+ sp_specularlighting->renderer->light_type = NR::NO_LIGHT;
+ if (SP_IS_FEDISTANTLIGHT(sp_specularlighting->children)) {
+ sp_specularlighting->renderer->light_type = NR::DISTANT_LIGHT;
+ sp_specularlighting->renderer->light.distant = SP_FEDISTANTLIGHT(sp_specularlighting->children);
+ }
+ if (SP_IS_FEPOINTLIGHT(sp_specularlighting->children)) {
+ sp_specularlighting->renderer->light_type = NR::POINT_LIGHT;
+ sp_specularlighting->renderer->light.point = SP_FEPOINTLIGHT(sp_specularlighting->children);
+ }
+ if (SP_IS_FESPOTLIGHT(sp_specularlighting->children)) {
+ sp_specularlighting->renderer->light_type = NR::SPOT_LIGHT;
+ sp_specularlighting->renderer->light.spot = SP_FESPOTLIGHT(sp_specularlighting->children);
+ }
+ }
+}
+
+static void sp_feSpecularLighting_build_renderer(SPFilterPrimitive *primitive, NR::Filter *filter) {
+ g_assert(primitive != NULL);
+ g_assert(filter != NULL);
+
+ SPFeSpecularLighting *sp_specularlighting = SP_FESPECULARLIGHTING(primitive);
+
+ int primitive_n = filter->add_primitive(NR::NR_FILTER_SPECULARLIGHTING);
+ NR::FilterPrimitive *nr_primitive = filter->get_primitive(primitive_n);
+ NR::FilterSpecularLighting *nr_specularlighting = dynamic_cast<NR::FilterSpecularLighting*>(nr_primitive);
+ g_assert(nr_specularlighting != NULL);
+
+ sp_specularlighting->renderer = nr_specularlighting;
+ sp_filter_primitive_renderer_common(primitive, nr_primitive);
+
+ nr_specularlighting->specularConstant = sp_specularlighting->specularConstant;
+ nr_specularlighting->specularExponent = sp_specularlighting->specularExponent;
+ nr_specularlighting->surfaceScale = sp_specularlighting->surfaceScale;
+ nr_specularlighting->lighting_color = sp_specularlighting->lighting_color;
+ //We assume there is at most one child
+ nr_specularlighting->light_type = NR::NO_LIGHT;
+ if (SP_IS_FEDISTANTLIGHT(primitive->children)) {
+ nr_specularlighting->light_type = NR::DISTANT_LIGHT;
+ nr_specularlighting->light.distant = SP_FEDISTANTLIGHT(primitive->children);
+ }
+ if (SP_IS_FEPOINTLIGHT(primitive->children)) {
+ nr_specularlighting->light_type = NR::POINT_LIGHT;
+ nr_specularlighting->light.point = SP_FEPOINTLIGHT(primitive->children);
+ }
+ if (SP_IS_FESPOTLIGHT(primitive->children)) {
+ nr_specularlighting->light_type = NR::SPOT_LIGHT;
+ nr_specularlighting->light.spot = SP_FESPOTLIGHT(primitive->children);
+ }
+
+ //nr_offset->set_dx(sp_offset->dx);
+ //nr_offset->set_dy(sp_offset->dy);
+}
+
/*
Local Variables:
index 3c0887f157f46c829dccf675646b472bb1e79810..9aa38b53e807fcc07e11233b755fb43becfca9bc 100644 (file)
/*
* Authors:
* Hugo Rodrigues <haa.rodrigues@gmail.com>
+ * Jean-Rene Reinhard <jr@komite.net>
*
* Copyright (C) 2006 Hugo Rodrigues
+ * 2007 authors
*
* Released under GNU GPL, read the file 'COPYING' for more information
*/
#include "sp-filter.h"
#include "sp-fespecularlighting-fns.h"
+namespace NR {
+class FilterSpecularLighting;
+}
+
/* FeSpecularLighting base class */
class SPFeSpecularLightingClass;
struct SPFeSpecularLighting : public SPFilterPrimitive {
/** SPECULARLIGHTING ATTRIBUTES HERE */
-
+ gfloat surfaceScale;
+ gfloat specularConstant;
+ gfloat specularExponent;
+ NumberOptNumber kernelUnitLength;
+ guint32 lighting_color;
+
+ NR::FilterSpecularLighting *renderer;
};
struct SPFeSpecularLightingClass {
diff --git a/src/sp-fespotlight.cpp b/src/sp-fespotlight.cpp
--- /dev/null
+++ b/src/sp-fespotlight.cpp
@@ -0,0 +1,281 @@
+#define __SP_FESPOTLIGHT_CPP__
+
+/** \file
+ * SVG <fespotlight> implementation.
+ */
+/*
+ * Authors:
+ * Hugo Rodrigues <haa.rodrigues@gmail.com>
+ * Niko Kiirala <niko@kiirala.com>
+ * Jean-Rene Reinhard <jr@komite.net>
+ *
+ * Copyright (C) 2006,2007 Authors
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <glib.h>
+
+#include "attributes.h"
+#include "document.h"
+#include "sp-fespotlight.h"
+#include "sp-fediffuselighting-fns.h"
+#include "sp-fespecularlighting-fns.h"
+#include "xml/repr.h"
+
+#define SP_MACROS_SILENT
+#include "macros.h"
+
+/* FeSpotLight class */
+
+static void sp_fespotlight_class_init(SPFeSpotLightClass *klass);
+static void sp_fespotlight_init(SPFeSpotLight *fespotlight);
+
+static void sp_fespotlight_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr);
+static void sp_fespotlight_release(SPObject *object);
+static void sp_fespotlight_set(SPObject *object, unsigned int key, gchar const *value);
+static void sp_fespotlight_update(SPObject *object, SPCtx *ctx, guint flags);
+static Inkscape::XML::Node *sp_fespotlight_write(SPObject *object, Inkscape::XML::Node *repr, guint flags);
+
+static SPObjectClass *feSpotLight_parent_class;
+
+GType
+sp_fespotlight_get_type()
+{
+ static GType fespotlight_type = 0;
+
+ if (!fespotlight_type) {
+ GTypeInfo fespotlight_info = {
+ sizeof(SPFeSpotLightClass),
+ NULL, NULL,
+ (GClassInitFunc) sp_fespotlight_class_init,
+ NULL, NULL,
+ sizeof(SPFeSpotLight),
+ 16,
+ (GInstanceInitFunc) sp_fespotlight_init,
+ NULL, /* value_table */
+ };
+ fespotlight_type = g_type_register_static(SP_TYPE_OBJECT, "SPFeSpotLight", &fespotlight_info, (GTypeFlags)0);
+ }
+ return fespotlight_type;
+}
+
+static void
+sp_fespotlight_class_init(SPFeSpotLightClass *klass)
+{
+
+ SPObjectClass *sp_object_class = (SPObjectClass *)klass;
+
+ feSpotLight_parent_class = (SPObjectClass*)g_type_class_peek_parent(klass);
+
+ sp_object_class->build = sp_fespotlight_build;
+ sp_object_class->release = sp_fespotlight_release;
+ sp_object_class->write = sp_fespotlight_write;
+ sp_object_class->set = sp_fespotlight_set;
+ sp_object_class->update = sp_fespotlight_update;
+}
+
+static void
+sp_fespotlight_init(SPFeSpotLight *fespotlight)
+{
+ fespotlight->x = 0;
+ fespotlight->y = 0;
+ fespotlight->z = 0;
+ fespotlight->pointsAtX = 0;
+ fespotlight->pointsAtY = 0;
+ fespotlight->pointsAtZ = 0;
+ fespotlight->specularExponent = 1;
+ fespotlight->limitingConeAngle = 90;
+}
+
+/**
+ * Reads the Inkscape::XML::Node, and initializes SPPointLight variables. For this to get called,
+ * our name must be associated with a repr via "sp_object_type_register". Best done through
+ * sp-object-repr.cpp's repr_name_entries array.
+ */
+static void
+sp_fespotlight_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr)
+{
+ if (((SPObjectClass *) feSpotLight_parent_class)->build) {
+ ((SPObjectClass *) feSpotLight_parent_class)->build(object, document, repr);
+ }
+
+ //Read values of key attributes from XML nodes into object.
+ sp_object_read_attr(object, "x");
+ sp_object_read_attr(object, "y");
+ sp_object_read_attr(object, "z");
+ sp_object_read_attr(object, "pointsAtX");
+ sp_object_read_attr(object, "pointsAtY");
+ sp_object_read_attr(object, "pointsAtZ");
+ sp_object_read_attr(object, "specularExponent");
+ sp_object_read_attr(object, "limitingConeAngle");
+
+//is this necessary?
+ sp_document_add_resource(document, "fespotlight", object);
+}
+
+/**
+ * Drops any allocated memory.
+ */
+static void
+sp_fespotlight_release(SPObject *object)
+{
+ //SPFeSpotLight *fespotlight = SP_FESPOTLIGHT(object);
+
+ if (SP_OBJECT_DOCUMENT(object)) {
+ /* Unregister ourselves */
+ sp_document_remove_resource(SP_OBJECT_DOCUMENT(object), "fespotlight", SP_OBJECT(object));
+ }
+
+//TODO: release resources here
+}
+
+/**
+ * Sets a specific value in the SPFeSpotLight.
+ */
+static void
+sp_fespotlight_set(SPObject *object, unsigned int key, gchar const *value)
+{
+ SPFeSpotLight *fespotlight = SP_FESPOTLIGHT(object);
+
+ switch (key) {
+ case SP_ATTR_X:
+ fespotlight->x = g_ascii_strtod(value, NULL);
+ if (object->parent &&
+ (SP_IS_FEDIFFUSELIGHTING(object->parent) ||
+ SP_IS_FESPECULARLIGHTING(object->parent))) {
+ object->parent->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ }
+ break;
+ case SP_ATTR_Y:
+ fespotlight->y = g_ascii_strtod(value, NULL);
+ if (object->parent &&
+ (SP_IS_FEDIFFUSELIGHTING(object->parent) ||
+ SP_IS_FESPECULARLIGHTING(object->parent))) {
+ object->parent->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ }
+ break;
+ case SP_ATTR_Z:
+ fespotlight->z = g_ascii_strtod(value, NULL);
+ if (object->parent &&
+ (SP_IS_FEDIFFUSELIGHTING(object->parent) ||
+ SP_IS_FESPECULARLIGHTING(object->parent))) {
+ object->parent->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ }
+ break;
+ case SP_ATTR_POINTSATX:
+ fespotlight->pointsAtX = g_ascii_strtod(value, NULL);
+ if (object->parent &&
+ (SP_IS_FEDIFFUSELIGHTING(object->parent) ||
+ SP_IS_FESPECULARLIGHTING(object->parent))) {
+ object->parent->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ }
+ break;
+ case SP_ATTR_POINTSATY:
+ fespotlight->pointsAtY = g_ascii_strtod(value, NULL);
+ if (object->parent &&
+ (SP_IS_FEDIFFUSELIGHTING(object->parent) ||
+ SP_IS_FESPECULARLIGHTING(object->parent))) {
+ object->parent->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ }
+ break;
+ case SP_ATTR_POINTSATZ:
+ fespotlight->pointsAtZ = g_ascii_strtod(value, NULL);
+ if (object->parent &&
+ (SP_IS_FEDIFFUSELIGHTING(object->parent) ||
+ SP_IS_FESPECULARLIGHTING(object->parent))) {
+ object->parent->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ }
+ break;
+ case SP_ATTR_SPECULAREXPONENT:
+ fespotlight->specularExponent = g_ascii_strtod(value, NULL);
+ if (object->parent &&
+ (SP_IS_FEDIFFUSELIGHTING(object->parent) ||
+ SP_IS_FESPECULARLIGHTING(object->parent))) {
+ object->parent->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ }
+ break;
+ case SP_ATTR_LIMITINGCONEANGLE:
+ fespotlight->limitingConeAngle = g_ascii_strtod(value, NULL);
+ if (object->parent &&
+ (SP_IS_FEDIFFUSELIGHTING(object->parent) ||
+ SP_IS_FESPECULARLIGHTING(object->parent))) {
+ object->parent->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ }
+ break;
+ default:
+ // See if any parents need this value.
+ if (((SPObjectClass *) feSpotLight_parent_class)->set) {
+ ((SPObjectClass *) feSpotLight_parent_class)->set(object, key, value);
+ }
+ break;
+ }
+}
+
+/**
+ * * Receives update notifications.
+ * */
+static void
+sp_fespotlight_update(SPObject *object, SPCtx *ctx, guint flags)
+{
+ SPFeSpotLight *feSpotLight = SP_FESPOTLIGHT(object);
+
+ if (flags & SP_OBJECT_MODIFIED_FLAG) {
+ /* do something to trigger redisplay, updates? */
+ sp_object_read_attr(object, "x");
+ sp_object_read_attr(object, "y");
+ sp_object_read_attr(object, "z");
+ sp_object_read_attr(object, "pointsAtX");
+ sp_object_read_attr(object, "pointsAtY");
+ sp_object_read_attr(object, "pointsAtZ");
+ sp_object_read_attr(object, "specularExponent");
+ sp_object_read_attr(object, "limitingConeAngle");
+ }
+
+ if (((SPObjectClass *) feSpotLight_parent_class)->update) {
+ ((SPObjectClass *) feSpotLight_parent_class)->update(object, ctx, flags);
+ }
+}
+
+/**
+ * Writes its settings to an incoming repr object, if any.
+ */
+static Inkscape::XML::Node *
+sp_fespotlight_write(SPObject *object, Inkscape::XML::Node *repr, guint flags)
+{
+ SPFeSpotLight *fespotlight = SP_FESPOTLIGHT(object);
+
+ if (!repr) {
+ repr = SP_OBJECT_REPR(object)->duplicate(NULL); // FIXME
+ }
+
+ sp_repr_set_css_double(repr, "x", fespotlight->x);
+ sp_repr_set_css_double(repr, "y", fespotlight->y);
+ sp_repr_set_css_double(repr, "z", fespotlight->z);
+ sp_repr_set_css_double(repr, "pointsAtX", fespotlight->pointsAtX);
+ sp_repr_set_css_double(repr, "pointsAtY", fespotlight->pointsAtY);
+ sp_repr_set_css_double(repr, "pointsAtZ", fespotlight->pointsAtZ);
+ sp_repr_set_css_double(repr, "specularExponent", fespotlight->specularExponent);
+ sp_repr_set_css_double(repr, "limitingConeAngle", fespotlight->limitingConeAngle);
+
+ if (((SPObjectClass *) feSpotLight_parent_class)->write) {
+ ((SPObjectClass *) feSpotLight_parent_class)->write(object, repr, flags);
+ }
+
+ return repr;
+}
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
diff --git a/src/sp-fespotlight.h b/src/sp-fespotlight.h
--- /dev/null
+++ b/src/sp-fespotlight.h
@@ -0,0 +1,70 @@
+#ifndef SP_FESPOTLIGHT_H_SEEN
+#define SP_FESPOTLIGHT_H_SEEN
+
+/** \file
+ * SVG <filter> implementation, see sp-filter.cpp.
+ */
+/*
+ * Authors:
+ * Hugo Rodrigues <haa.rodrigues@gmail.com>
+ * Niko Kiirala <niko@kiirala.com>
+ * Jean-Rene Reinhard <jr@komite.net>
+ *
+ * Copyright (C) 2006,2007 Authors
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include "sp-object.h"
+
+#define SP_TYPE_FESPOTLIGHT (sp_fespotlight_get_type())
+#define SP_FESPOTLIGHT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SP_TYPE_FESPOTLIGHT, SPFeSpotLight))
+#define SP_FESPOTLIGHT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), SP_TYPE_FESPOTLIGHT, SPFeSpotLightClass))
+#define SP_IS_FESPOTLIGHT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SP_TYPE_FESPOTLIGHT))
+#define SP_IS_FESPOTLIGHT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SP_TYPE_FESPOTLIGHT))
+
+/* Distant light class */
+
+
+class SPFeSpotLight;
+class SPFeSpotLightClass;
+
+struct SPFeSpotLight : public SPObject {
+
+ /** x coordinate of the light source */
+ gfloat x;
+ /** y coordinate of the light source */
+ gfloat y;
+ /** z coordinate of the light source */
+ gfloat z;
+ /** x coordinate of the point the source is pointing at */
+ gfloat pointsAtX;
+ /** y coordinate of the point the source is pointing at */
+ gfloat pointsAtY;
+ /** z coordinate of the point the source is pointing at */
+ gfloat pointsAtZ;
+ /** specular exponent (focus of the light) */
+ gfloat specularExponent;
+ /** limiting cone angle */
+ gfloat limitingConeAngle;
+ //other fields
+};
+
+struct SPFeSpotLightClass {
+ SPObjectClass parent_class;
+};
+
+GType
+sp_fespotlight_get_type();
+#endif /* !SP_FESPOTLIGHT_H_SEEN */
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
diff --git a/src/sp-object-repr.cpp b/src/sp-object-repr.cpp
index a4b47ca220c13c017567334e3593246ccd76e9aa..4e417e29434a6902864276e64584dbe8987df9c0 100644 (file)
--- a/src/sp-object-repr.cpp
+++ b/src/sp-object-repr.cpp
#include "sp-fecomposite.h"
#include "sp-feconvolvematrix.h"
#include "sp-fediffuselighting.h"
+#include "sp-fedistantlight.h"
#include "sp-fedisplacementmap.h"
#include "sp-feflood.h"
#include "sp-feimage.h"
#include "sp-femerge.h"
#include "sp-femorphology.h"
#include "sp-feoffset.h"
+#include "sp-fepointlight.h"
#include "sp-fespecularlighting.h"
+#include "sp-fespotlight.h"
#include "sp-fetile.h"
#include "sp-feturbulence.h"
{ "svg:feComposite", SP_TYPE_FECOMPOSITE },
{ "svg:feConvolveMatrix", SP_TYPE_FECONVOLVEMATRIX },
{ "svg:feDiffuseLighting", SP_TYPE_FEDIFFUSELIGHTING },
+ { "svg:feDistantLight", SP_TYPE_FEDISTANTLIGHT },
{ "svg:feDisplacementMap", SP_TYPE_FEDISPLACEMENTMAP },
{ "svg:feFlood", SP_TYPE_FEFLOOD },
{ "svg:feGaussianBlur", SP_TYPE_GAUSSIANBLUR },
{ "svg:feMerge", SP_TYPE_FEMERGE },
{ "svg:feMorphology", SP_TYPE_FEMORPHOLOGY },
{ "svg:feOffset", SP_TYPE_FEOFFSET },
+ { "svg:fePointLight", SP_TYPE_FEPOINTLIGHT },
{ "svg:feSpecularLighting", SP_TYPE_FESPECULARLIGHTING },
+ { "svg:feSpotLight", SP_TYPE_FESPOTLIGHT },
{ "svg:feTile", SP_TYPE_FETILE },
{ "svg:feTurbulence", SP_TYPE_FETURBULENCE },
{ "svg:image", SP_TYPE_IMAGE },