summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorNiko Kiirala <niko@kiirala.com>2007-07-23 08:12:06 +0000
committerkiirala <kiirala@users.sourceforge.net>2007-07-23 08:12:06 +0000
commitfc74301e2b3a60d25e11feae835ccea71d06c587 (patch)
treee6060b6ac0012224c0693a2cd09017b50e765054 /src
parentremoving kerns also trims multi-value x attribute; allow it to work on tspans... (diff)
downloadinkscape-fc74301e2b3a60d25e11feae835ccea71d06c587.tar.gz
inkscape-fc74301e2b3a60d25e11feae835ccea71d06c587.zip
Patch by Jean-René Reinhard: better SVG compliance for lighting effects
(bzr r3281)
Diffstat (limited to 'src')
-rw-r--r--src/display/Makefile_insert2
-rw-r--r--src/display/nr-filter-composite.cpp15
-rw-r--r--src/display/nr-filter-diffuselighting.cpp21
-rw-r--r--src/display/nr-filter-specularlighting.cpp26
-rw-r--r--src/display/nr-filter-utils.cpp11
-rw-r--r--src/display/nr-filter-utils.h45
6 files changed, 88 insertions, 32 deletions
diff --git a/src/display/Makefile_insert b/src/display/Makefile_insert
index eaa2f584f..a72175b3f 100644
--- a/src/display/Makefile_insert
+++ b/src/display/Makefile_insert
@@ -89,6 +89,8 @@ display_libspdisplay_a_SOURCES = \
display/nr-filter-getalpha.h \
display/nr-filter-pixops.h \
display/nr-filter-types.h \
+ display/nr-filter-utils.h \
+ display/nr-filter-utils.cpp \
display/pixblock-scaler.cpp \
display/pixblock-scaler.h \
display/pixblock-transform.cpp \
diff --git a/src/display/nr-filter-composite.cpp b/src/display/nr-filter-composite.cpp
index 43580191e..a5b1d5297 100644
--- a/src/display/nr-filter-composite.cpp
+++ b/src/display/nr-filter-composite.cpp
@@ -16,6 +16,7 @@
#include "display/nr-filter-composite.h"
#include "display/nr-filter-pixops.h"
#include "display/nr-filter-slot.h"
+#include "display/nr-filter-utils.h"
#include "libnr/nr-blit.h"
#include "libnr/nr-pixblock.h"
#include "libnr/nr-pixops.h"
@@ -66,25 +67,19 @@ composite_xor(unsigned char *r, unsigned char const *a, unsigned char const *b)
r[3] = NR_NORMALIZE_21(a[3] * (255 - b[3]) + b[3] * (255 - a[3]));
}
-static int clamp(int val) {
- if (val < 0) return 0;
- if (val > 255) return 255;
- return val;
-}
-
// BUGBUG / TODO
// This makes arithmetic compositing non re-entrant and non thread safe.
static int arith_k1, arith_k2, arith_k3, arith_k4;
inline void
composite_arithmetic(unsigned char *r, unsigned char const *a, unsigned char const *b)
{
- r[0] = clamp(NR_NORMALIZE_31(arith_k1 * a[0] * b[0]
+ r[0] = NR::clamp(NR_NORMALIZE_31(arith_k1 * a[0] * b[0]
+ arith_k2 * a[0] + arith_k3 * b[0] + arith_k4));
- r[1] = clamp(NR_NORMALIZE_31(arith_k1 * a[1] * b[1]
+ r[1] = NR::clamp(NR_NORMALIZE_31(arith_k1 * a[1] * b[1]
+ arith_k2 * a[1] + arith_k3 * b[1] + arith_k4));
- r[2] = clamp(NR_NORMALIZE_31(arith_k1 * a[2] * b[2]
+ r[2] = NR::clamp(NR_NORMALIZE_31(arith_k1 * a[2] * b[2]
+ arith_k2 * a[2] + arith_k3 * b[2] + arith_k4));
- r[3] = clamp(NR_NORMALIZE_31(arith_k1 * a[3] * b[3]
+ r[3] = NR::clamp(NR_NORMALIZE_31(arith_k1 * a[3] * b[3]
+ arith_k2 * a[3] + arith_k3 * b[3] + arith_k4));
}
diff --git a/src/display/nr-filter-diffuselighting.cpp b/src/display/nr-filter-diffuselighting.cpp
index 736055f32..96a2e9ca6 100644
--- a/src/display/nr-filter-diffuselighting.cpp
+++ b/src/display/nr-filter-diffuselighting.cpp
@@ -17,13 +17,13 @@
#include "display/nr-filter-diffuselighting.h"
#include "display/nr-filter-getalpha.h"
#include "display/nr-filter-slot.h"
+#include "display/nr-filter-utils.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 {
@@ -48,6 +48,7 @@ do {\
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;
@@ -87,9 +88,9 @@ int FilterDiffuseLighting::render(FilterSlot &slot, Matrix const &trans) {
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++] = CLAMP_D_TO_U8(inter * LC[LIGHT_RED]);
+ data_o[j++] = CLAMP_D_TO_U8(inter * LC[LIGHT_GREEN]);
+ data_o[j++] = CLAMP_D_TO_U8(inter * LC[LIGHT_BLUE]);
data_o[j++] = 255;
}
out->empty = FALSE;
@@ -113,9 +114,9 @@ int FilterDiffuseLighting::render(FilterSlot &slot, Matrix const &trans) {
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++] = CLAMP_D_TO_U8(inter * LC[LIGHT_RED]);
+ data_o[j++] = CLAMP_D_TO_U8(inter * LC[LIGHT_GREEN]);
+ data_o[j++] = CLAMP_D_TO_U8(inter * LC[LIGHT_BLUE]);
data_o[j++] = 255;
}
out->empty = FALSE;
@@ -139,9 +140,9 @@ int FilterDiffuseLighting::render(FilterSlot &slot, Matrix const &trans) {
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++] = CLAMP_D_TO_U8(inter * LC[LIGHT_RED]);
+ data_o[j++] = CLAMP_D_TO_U8(inter * LC[LIGHT_GREEN]);
+ data_o[j++] = CLAMP_D_TO_U8(inter * LC[LIGHT_BLUE]);
data_o[j++] = 255;
}
out->empty = FALSE;
diff --git a/src/display/nr-filter-specularlighting.cpp b/src/display/nr-filter-specularlighting.cpp
index 117df28f7..9957f4d59 100644
--- a/src/display/nr-filter-specularlighting.cpp
+++ b/src/display/nr-filter-specularlighting.cpp
@@ -18,13 +18,13 @@
#include "display/nr-filter-specularlighting.h"
#include "display/nr-filter-getalpha.h"
#include "display/nr-filter-slot.h"
+#include "display/nr-filter-utils.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 {
@@ -46,10 +46,12 @@ FilterSpecularLighting::~FilterSpecularLighting()
//Investigating Phong Lighting model we should not take N.H but
//R.E which equals to 2*N.H^2 - 1
+//replace the second line by
+//gdouble scal = scalar_product((N), (H)); scal = 2 * scal * scal - 1;\
+//to get the expected formula
#define COMPUTE_INTER(inter, H, N, ks, speculaExponent) \
do {\
- gdouble scal = scalar_product((N), (H));\
- scal = 2 * scal * scal - 1;\
+ gdouble scal = scalar_product((N), (H)); \
if (scal <= 0)\
(inter) = 0;\
else\
@@ -97,9 +99,9 @@ int FilterSpecularLighting::render(FilterSlot &slot, Matrix const &trans) {
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++] = CLAMP_D_TO_U8(inter * LC[LIGHT_RED]);
+ data_o[j++] = CLAMP_D_TO_U8(inter * LC[LIGHT_GREEN]);
+ data_o[j++] = CLAMP_D_TO_U8(inter * LC[LIGHT_BLUE]);
data_o[j++] = MAX(MAX(data_o[j-3], data_o[j-2]), data_o[j-1]);
}
out->empty = FALSE;
@@ -124,9 +126,9 @@ int FilterSpecularLighting::render(FilterSlot &slot, Matrix const &trans) {
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++] = CLAMP_D_TO_U8(inter * LC[LIGHT_RED]);
+ data_o[j++] = CLAMP_D_TO_U8(inter * LC[LIGHT_GREEN]);
+ data_o[j++] = CLAMP_D_TO_U8(inter * LC[LIGHT_BLUE]);
data_o[j++] = MAX(MAX(data_o[j-3], data_o[j-2]), data_o[j-1]);
}
out->empty = FALSE;
@@ -151,9 +153,9 @@ int FilterSpecularLighting::render(FilterSlot &slot, Matrix const &trans) {
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++] = CLAMP_D_TO_U8(inter * LC[LIGHT_RED]);
+ data_o[j++] = CLAMP_D_TO_U8(inter * LC[LIGHT_GREEN]);
+ data_o[j++] = CLAMP_D_TO_U8(inter * LC[LIGHT_BLUE]);
data_o[j++] = MAX(MAX(data_o[j-3], data_o[j-2]), data_o[j-1]);
}
out->empty = FALSE;
diff --git a/src/display/nr-filter-utils.cpp b/src/display/nr-filter-utils.cpp
new file mode 100644
index 000000000..85faadebc
--- /dev/null
+++ b/src/display/nr-filter-utils.cpp
@@ -0,0 +1,11 @@
+#include "nr-filter-utils.h"
+
+namespace NR {
+
+int clamp(int val) {
+ if (val < 0) return 0;
+ if (val > 255) return 255;
+ return val;
+}
+
+} //namespace NR
diff --git a/src/display/nr-filter-utils.h b/src/display/nr-filter-utils.h
new file mode 100644
index 000000000..b591b37cb
--- /dev/null
+++ b/src/display/nr-filter-utils.h
@@ -0,0 +1,45 @@
+#ifndef __NR_FILTER_UTILS_H__
+#define __NR_FILTER_UTILS_H__
+
+/** \file
+ * filter utils. Definition of functions needed by several filters.
+ *
+ * Authors:
+ * Jean-Rene Reinhard <jr@komite.net>
+ *
+ * Copyright (C) 2007 authors
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include "round.h"
+
+namespace NR {
+
+/**
+ * Clamps an integer value to a value between 0 and 255. Needed by filters where
+ * rendering computations can lead to component values out of bound.
+ *
+ * \return 0 if the value is smaller than 0, 255 if it is greater 255, else v
+ * \param v the value to clamp
+ */
+int clamp(int val);
+
+/**
+ * Macro to use the clamp function with double inputs and unsigned char output
+ */
+#define CLAMP_D_TO_U8(v) (unsigned char) clamp((int)round((v)))
+
+} /* namespace NR */
+
+#endif /* __NR_FILTER_UTILS_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 :