nr-filter-turbulence.cpp revision 5bd488c81c6b0d67689527621b3b60799b708af0
/*
* feTurbulence filter primitive renderer
*
* Authors:
* World Wide Web Consortium <http://www.w3.org/>
* Felipe Corrêa da Silva Sanches <juca@members.fsf.org>
*
* This file has a considerable amount of code adapted from
* the W3C SVG filter specs, available at:
* http://www.w3.org/TR/SVG11/filters.html#feTurbulence
*
* W3C original code is licensed under the terms of
* the (GPL compatible) W3C® SOFTWARE NOTICE AND LICENSE:
*
* Copyright (C) 2007 authors
* Released under GNU GPL version 2 (or later), read the file 'COPYING' for more information
*/
#include "display/cairo-templates.h"
#include "display/cairo-utils.h"
#include "display/nr-filter.h"
#include "display/nr-filter-turbulence.h"
#include "display/nr-filter-units.h"
#include "display/nr-filter-utils.h"
#include "libnr/nr-rect-l.h"
#include <math.h>
namespace Inkscape {
namespace Filters{
class TurbulenceGenerator {
public:
: _wrapx(0)
, _wrapy(0)
, _wrapw(0)
, _wraph(0)
, _inited(false)
{}
bool fractalnoise, int octaves)
{
// setup random number generator
// set values
int i;
for (int k = 0; k < 4; ++k) {
for (i = 0; i < BSize; ++i) {
_latticeSelector[i] = i;
// normalize gradient
_gradient[i][k][0] /= s;
_gradient[i][k][1] /= s;
}
}
while (--i) {
// shuffle lattice selectors
}
// fill out the remaining part of the gradient
for (i = 0; i < BSize + 2; ++i)
{
for(int k = 0; k < 4; ++k) {
}
}
// When stitching tiled turbulence, the frequencies must be adjusted
// so that the tile borders will be continuous.
if (_stitchTiles) {
{
}
{
}
}
_inited = true;
}
double pixel[4];
double ratio = 1.0;
for (int k = 0; k < 4; ++k)
pixel[k] = 0.0;
{
double tx = x + PerlinOffset;
double ty = y + PerlinOffset;
if (_stitchTiles) {
}
int i = _latticeSelector[bx0];
int j = _latticeSelector[bx1];
double result[4];
// channel numbering: R=0, G=1, B=2, A=3
for (int k = 0; k < 4; ++k) {
}
if (_fractalnoise) {
for (int k = 0; k < 4; ++k)
} else {
for (int k = 0; k < 4; ++k)
}
x *= 2;
y *= 2;
ratio *= 2;
if(_stitchTiles)
{
// Update stitch values. Subtracting PerlinOffset before the multiplication and
// adding it afterward simplifies to subtracting it once.
wrapw *= 2;
wraph *= 2;
}
}
if (_fractalnoise) {
r = premul_alpha(r, a);
g = premul_alpha(g, a);
b = premul_alpha(b, a);
ASSEMBLE_ARGB32(pxout, a,r,g,b);
return pxout;
} else {
r = premul_alpha(r, a);
g = premul_alpha(g, a);
b = premul_alpha(b, a);
ASSEMBLE_ARGB32(pxout, a,r,g,b);
return pxout;
}
}
//G_GNUC_PURE
/*guint32 turbulencePixel(Geom::Point const &p) const {
if (!_fractalnoise) {
guint32 r = CLAMP_D_TO_U8(turbulence(0, p)*255.0);
guint32 g = CLAMP_D_TO_U8(turbulence(1, p)*255.0);
guint32 b = CLAMP_D_TO_U8(turbulence(2, p)*255.0);
guint32 a = CLAMP_D_TO_U8(turbulence(3, p)*255.0);
r = premul_alpha(r, a);
g = premul_alpha(g, a);
b = premul_alpha(b, a);
ASSEMBLE_ARGB32(pxout, a,r,g,b);
return pxout;
} else {
guint32 r = CLAMP_D_TO_U8((turbulence(0, p)*255.0 + 255.0) / 2);
guint32 g = CLAMP_D_TO_U8((turbulence(1, p)*255.0 + 255.0) / 2);
guint32 b = CLAMP_D_TO_U8((turbulence(2, p)*255.0 + 255.0) / 2);
guint32 a = CLAMP_D_TO_U8((turbulence(3, p)*255.0 + 255.0) / 2);
r = premul_alpha(r, a);
g = premul_alpha(g, a);
b = premul_alpha(b, a);
ASSEMBLE_ARGB32(pxout, a,r,g,b);
return pxout;
}
}*/
private:
void _setupSeed(long seed) {
}
long _random() {
/* Produces results in the range [1, 2**31 - 2].
* Algorithm is: r = (a * r) mod m
* where a = 16807 and m = 2**31 - 1 = 2147483647
* See [Park & Miller], CACM vol. 31 no. 10 p. 1195, Oct. 1988
* To test: the algorithm should produce the result 1043618065
* as the 10,000th generated number if the original seed is 1. */
return _seed;
}
static inline double _scurve(double t) {
return t * t * (3.0 - 2.0*t);
}
static inline double _lerp(double t, double a, double b) {
return a + t * (b-a);
}
// random number generator constants
static long const
// other constants
static int const
BSize = 0x100,
BMask = 0xff;
static double const
PerlinOffset = 4096.0;
long _seed;
int _octaves;
bool _stitchTiles;
bool _inited;
bool _fractalnoise;
};
: gen(new TurbulenceGenerator())
, XbaseFrequency(0)
, YbaseFrequency(0)
, numOctaves(1)
, seed(0)
, updated(false)
{
}
return new FilterTurbulence();
}
{
delete gen;
}
}
numOctaves = num;
}
void FilterTurbulence::set_seed(double s){
seed = s;
}
stitchTiles = st;
}
type = t;
}
void FilterTurbulence::set_updated(bool u){
}
struct Turbulence {
{}
guint32 operator()(int x, int y) {
}
private:
TurbulenceGenerator const &_gen;
};
{
}
}
} /* namespace Filters */
} /* namespace Inkscape */
/*
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:fileencoding=utf-8:textwidth=99 :