index 0fca4509547b918bd93ec117f37e1fdc435bc9f3..7443039f66d551bfb7eb0a3fba18563c303b63ac 100644 (file)
#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"
-namespace NR {
+namespace Inkscape {
+namespace Filters {
FilterDiffuseLighting::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, FilterUnits const &units) {
- NRPixBlock *in = filter_get_alpha(slot.get(_input));
+ NRPixBlock *in = slot.get(_input);
if (!in) {
g_warning("Missing source image for feDiffuseLighting (in=%d)", _input);
return 1;
int dx = 1; //TODO setup
int dy = 1; //TODO setup
//surface scale
- Matrix trans = units.get_matrix_primitiveunits2pb();
+ Geom::Matrix trans = units.get_matrix_primitiveunits2pb();
gdouble ss = surfaceScale * trans[0];
gdouble kd = diffuseConstant; //diffuse lighting constant
- Fvector L, N, LC;
+ NR::Fvector L, N, LC;
gdouble inter;
nr_pixblock_setup_fast(out, in->mode,
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);
+ NR::compute_surface_normal(N, ss, in, i / w, i % w, dx, dy);
+ inter = kd * NR::scalar_product(N, L);
- data_o[j++] = CLAMP_D_TO_U8(inter * LC[LIGHT_RED]);
+ data_o[j++] = CLAMP_D_TO_U8(inter * LC[LIGHT_RED]); // CLAMP includes rounding!
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;
@@ -113,12 +106,12 @@ int FilterDiffuseLighting::render(FilterSlot &slot, FilterUnits const &units) {
// pixblock coordinates
//finish the work
for (i = 0, j = 0; i < w*h; i++) {
- compute_surface_normal(N, ss, in, i / w, i % w, dx, dy);
+ NR::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);
+ inter = kd * NR::scalar_product(N, L);
data_o[j++] = CLAMP_D_TO_U8(inter * LC[LIGHT_RED]);
data_o[j++] = CLAMP_D_TO_U8(inter * LC[LIGHT_GREEN]);
@@ -138,13 +131,13 @@ int FilterDiffuseLighting::render(FilterSlot &slot, FilterUnits const &units) {
// pixblock coordinates
//finish the work
for (i = 0, j = 0; i < w*h; i++) {
- compute_surface_normal(N, ss, in, i / w, i % w, dx, dy);
+ NR::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);
+ inter = kd * NR::scalar_product(N, L);
data_o[j++] = CLAMP_D_TO_U8(inter * LC[LIGHT_RED]);
data_o[j++] = CLAMP_D_TO_U8(inter * LC[LIGHT_GREEN]);
@@ -170,16 +163,30 @@ int FilterDiffuseLighting::render(FilterSlot &slot, FilterUnits const &units) {
//finishing
slot.set(_output, out);
- nr_pixblock_release(in);
- delete in;
+ //nr_pixblock_release(in);
+ //delete in;
return 0;
}
+void FilterDiffuseLighting::area_enlarge(NRRectL &area, Geom::Matrix const &trans)
+{
+ // TODO: support kernelUnitLength
+ double scalex = std::fabs(trans[0]) + std::fabs(trans[1]);
+ double scaley = std::fabs(trans[2]) + std::fabs(trans[3]);
+
+ //FIXME: no +2 should be there!... (noticable only for big scales at big zoom factor)
+ area.x0 -= (int)(scalex) + 2;
+ area.x1 += (int)(scalex) + 2;
+ area.y0 -= (int)(scaley) + 2;
+ area.y1 += (int)(scaley) + 2;
+}
+
FilterTraits FilterDiffuseLighting::get_input_traits() {
return TRAIT_PARALLER;
}
-} /* namespace NR */
+} /* namespace Filters */
+} /* namespace Inkscape */
/*
Local Variables:
fill-column:99
End:
*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :