89
89
rsvg_filter_primitive_get_bounds (RsvgFilterPrimitive * self, RsvgFilterContext * ctx)
91
91
RsvgBbox box, otherbox;
92
cairo_matrix_t affine;
94
_rsvg_affine_identity (affine);
95
rsvg_bbox_init (&box, affine);
96
rsvg_bbox_init (&otherbox, ctx->affine);
94
cairo_matrix_init_identity (&affine);
95
rsvg_bbox_init (&box, &affine);
96
rsvg_bbox_init (&otherbox, &ctx->affine);
97
97
otherbox.virgin = 0;
98
98
if (ctx->filter->filterunits == objectBoundingBox)
99
99
_rsvg_push_view_box (ctx->ctx, 1., 1.);
100
otherbox.x = _rsvg_css_normalize_length (&ctx->filter->x, ctx->ctx, 'h');
101
otherbox.y = _rsvg_css_normalize_length (&ctx->filter->y, ctx->ctx, 'v');
102
otherbox.w = _rsvg_css_normalize_length (&ctx->filter->width, ctx->ctx, 'h');
103
otherbox.h = _rsvg_css_normalize_length (&ctx->filter->height, ctx->ctx, 'v');
100
otherbox.rect.x = _rsvg_css_normalize_length (&ctx->filter->x, ctx->ctx, 'h');
101
otherbox.rect.y = _rsvg_css_normalize_length (&ctx->filter->y, ctx->ctx, 'v');
102
otherbox.rect.width = _rsvg_css_normalize_length (&ctx->filter->width, ctx->ctx, 'h');
103
otherbox.rect.height = _rsvg_css_normalize_length (&ctx->filter->height, ctx->ctx, 'v');
104
104
if (ctx->filter->filterunits == objectBoundingBox)
105
105
_rsvg_pop_view_box (ctx->ctx);
110
110
if (self->x.factor != 'n' || self->y.factor != 'n' ||
111
111
self->width.factor != 'n' || self->height.factor != 'n') {
113
rsvg_bbox_init (&otherbox, ctx->paffine);
113
rsvg_bbox_init (&otherbox, &ctx->paffine);
114
114
otherbox.virgin = 0;
115
115
if (ctx->filter->primitiveunits == objectBoundingBox)
116
116
_rsvg_push_view_box (ctx->ctx, 1., 1.);
117
117
if (self->x.factor != 'n')
118
otherbox.x = _rsvg_css_normalize_length (&self->x, ctx->ctx, 'h');
118
otherbox.rect.x = _rsvg_css_normalize_length (&self->x, ctx->ctx, 'h');
121
121
if (self->y.factor != 'n')
122
otherbox.y = _rsvg_css_normalize_length (&self->y, ctx->ctx, 'v');
122
otherbox.rect.y = _rsvg_css_normalize_length (&self->y, ctx->ctx, 'v');
125
125
if (self->width.factor != 'n')
126
otherbox.w = _rsvg_css_normalize_length (&self->width, ctx->ctx, 'h');
126
otherbox.rect.width = _rsvg_css_normalize_length (&self->width, ctx->ctx, 'h');
128
otherbox.w = ctx->ctx->vb.w;
128
otherbox.rect.width = ctx->ctx->vb.rect.width;
129
129
if (self->height.factor != 'n')
130
otherbox.h = _rsvg_css_normalize_length (&self->height, ctx->ctx, 'v');
130
otherbox.rect.height = _rsvg_css_normalize_length (&self->height, ctx->ctx, 'v');
132
otherbox.h = ctx->ctx->vb.h;
132
otherbox.rect.height = ctx->ctx->vb.rect.height;
133
133
if (ctx->filter->primitiveunits == objectBoundingBox)
134
134
_rsvg_pop_view_box (ctx->ctx);
135
135
rsvg_bbox_clip (&box, &otherbox);
138
rsvg_bbox_init (&otherbox, affine);
138
rsvg_bbox_init (&otherbox, &affine);
139
139
otherbox.virgin = 0;
142
otherbox.w = ctx->width;
143
otherbox.h = ctx->height;
142
otherbox.rect.width = ctx->width;
143
otherbox.rect.height = ctx->height;
144
144
rsvg_bbox_clip (&box, &otherbox);
146
RsvgIRect output = { box.x, box.y,
146
RsvgIRect output = { box.rect.x, box.rect.y,
147
box.rect.x + box.rect.width,
148
box.rect.y + box.rect.height
172
172
double xmod, ymod;
173
173
double dist1, dist2, dist3, dist4;
174
174
double c, c1, c2, c3, c4;
175
double fox, foy, cox, coy;
176
177
xmod = fmod (ox, 1.0);
177
178
ymod = fmod (oy, 1.0);
181
182
dist3 = (xmod) * (ymod);
182
183
dist4 = (1 - xmod) * (ymod);
184
if (floor (ox) <= boundarys.x0 || floor (ox) >= boundarys.x1 ||
185
floor (oy) <= boundarys.y0 || floor (oy) >= boundarys.y1)
190
if (fox <= boundarys.x0 || fox >= boundarys.x1 ||
191
foy <= boundarys.y0 || foy >= boundarys.y1)
188
c1 = src[(guint) floor (oy) * rowstride + (guint) floor (ox) * 4 + ch];
194
c1 = src[(guint) foy * rowstride + (guint) fox * 4 + ch];
190
if (ceil (ox) <= boundarys.x0 || ceil (ox) >= boundarys.x1 ||
191
floor (oy) <= boundarys.y0 || floor (oy) >= boundarys.y1)
196
if (cox <= boundarys.x0 || cox >= boundarys.x1 ||
197
foy <= boundarys.y0 || foy >= boundarys.y1)
194
c2 = src[(guint) floor (oy) * rowstride + (guint) ceil (ox) * 4 + ch];
200
c2 = src[(guint) foy * rowstride + (guint) cox * 4 + ch];
196
if (ceil (ox) <= boundarys.x0 || ceil (ox) >= boundarys.x1 ||
197
ceil (oy) <= boundarys.y0 || ceil (oy) >= boundarys.y1)
202
if (cox <= boundarys.x0 || cox >= boundarys.x1 ||
203
coy <= boundarys.y0 || coy >= boundarys.y1)
200
c3 = src[(guint) ceil (oy) * rowstride + (guint) ceil (ox) * 4 + ch];
206
c3 = src[(guint) coy * rowstride + (guint) cox * 4 + ch];
202
if (floor (ox) <= boundarys.x0 || floor (ox) >= boundarys.x1 ||
203
ceil (oy) <= boundarys.y0 || ceil (oy) >= boundarys.y1)
208
if (fox <= boundarys.x0 || fox >= boundarys.x1 ||
209
coy <= boundarys.y0 || coy >= boundarys.y1)
206
c4 = src[(guint) ceil (oy) * rowstride + (guint) floor (ox) * 4 + ch];
212
c4 = src[(guint) coy * rowstride + (guint) fox * 4 + ch];
208
214
c = (c1 * dist1 + c2 * dist2 + c3 * dist3 + c4 * dist4) / (dist1 + dist2 + dist3 + dist4);
214
rsvg_filter_fix_coordinate_system (RsvgFilterContext * ctx, RsvgState * state, RsvgBbox bbox)
220
rsvg_filter_fix_coordinate_system (RsvgFilterContext * ctx, RsvgState * state, RsvgBbox *bbox)
216
222
int x, y, height, width;
226
width = bbox->rect.width;
227
height = bbox->rect.height;
224
229
ctx->width = gdk_pixbuf_get_width (ctx->source);
225
230
ctx->height = gdk_pixbuf_get_height (ctx->source);
227
for (i = 0; i < 6; i++)
228
ctx->affine[i] = state->affine[i];
232
ctx->affine = state->affine;
229
233
if (ctx->filter->filterunits == objectBoundingBox) {
230
double affine[6] = { width, 0, 0, height, x, y };
231
_rsvg_affine_multiply (ctx->affine, affine, ctx->affine);
234
cairo_matrix_t affine;
235
cairo_matrix_init (&affine, width, 0, 0, height, x, y);
236
cairo_matrix_multiply (&ctx->affine, &affine, &ctx->affine);
233
for (i = 0; i < 6; i++)
234
ctx->paffine[i] = state->affine[i];
238
ctx->paffine = state->affine;
235
239
if (ctx->filter->primitiveunits == objectBoundingBox) {
236
double affine[6] = { width, 0, 0, height, x, y };
237
_rsvg_affine_multiply (ctx->paffine, affine, ctx->paffine);
240
cairo_matrix_t affine;
241
cairo_matrix_init (&affine, width, 0, 0, height, x, y);
242
cairo_matrix_multiply (&ctx->paffine, &affine, &ctx->paffine);
341
346
rsvg_art_affine_image (const GdkPixbuf * img, GdkPixbuf * intermediate,
342
double *affine, double w, double h)
347
cairo_matrix_t *affine, double w, double h)
344
gdouble tmp_affine[6];
345
gdouble inv_affine[6];
346
gdouble raw_inv_affine[6];
349
cairo_matrix_t inv_affine, raw_inv_affine;
349
352
gint basex, basey;
371
374
intpix = gdk_pixbuf_get_pixels (intermediate);
372
375
basebpp = has_alpha ? 4 : 3;
374
_rsvg_affine_invert (raw_inv_affine, affine);
376
/*scale to w and h */
377
tmp_affine[0] = (double) w;
378
tmp_affine[3] = (double) h;
379
tmp_affine[1] = tmp_affine[2] = tmp_affine[4] = tmp_affine[5] = 0;
380
_rsvg_affine_multiply (tmp_affine, tmp_affine, affine);
382
_rsvg_affine_invert (inv_affine, tmp_affine);
377
raw_inv_affine = *affine;
378
if (cairo_matrix_invert (&raw_inv_affine) != CAIRO_STATUS_SUCCESS)
381
cairo_matrix_init_scale (&inv_affine, w, h);
382
cairo_matrix_multiply (&inv_affine, &inv_affine, affine);
383
if (cairo_matrix_invert (&inv_affine) != CAIRO_STATUS_SUCCESS)
385
386
/*apply the transformation */
386
387
for (i = 0; i < iwidth; i++)
387
388
for (j = 0; j < iheight; j++) {
388
fbasex = (inv_affine[0] * (double) i + inv_affine[2] * (double) j +
389
inv_affine[4]) * (double) width;
390
fbasey = (inv_affine[1] * (double) i + inv_affine[3] * (double) j +
391
inv_affine[5]) * (double) height;
389
fbasex = (inv_affine.xx * (double) i + inv_affine.xy * (double) j +
390
inv_affine.x0) * (double) width;
391
fbasey = (inv_affine.yx * (double) i + inv_affine.yy * (double) j +
392
inv_affine.y0) * (double) height;
392
393
basex = floor (fbasex);
393
394
basey = floor (fbasey);
394
rawx = raw_inv_affine[0] * i + raw_inv_affine[2] * j + raw_inv_affine[4];
395
rawy = raw_inv_affine[1] * i + raw_inv_affine[3] * j + raw_inv_affine[5];
395
rawx = raw_inv_affine.xx * i + raw_inv_affine.xy * j + raw_inv_affine.x0;
396
rawy = raw_inv_affine.yx * i + raw_inv_affine.yy * j + raw_inv_affine.y0;
396
397
if (rawx < 0 || rawy < 0 || rawx >= w ||
397
398
rawy >= h || basex < 0 || basey < 0 || basex >= width || basey >= height) {
398
399
for (k = 0; k < 4; k++)
1041
1042
height = gdk_pixbuf_get_height (in);
1042
1043
width = gdk_pixbuf_get_width (in);
1044
targetx = upself->targetx * ctx->paffine[0];
1045
targety = upself->targety * ctx->paffine[3];
1045
targetx = upself->targetx * ctx->paffine.xx;
1046
targety = upself->targety * ctx->paffine.yy;
1047
1048
if (upself->dx != 0 || upself->dy != 0) {
1048
dx = upself->dx * ctx->paffine[0];
1049
dy = upself->dy * ctx->paffine[3];
1049
dx = upself->dx * ctx->paffine.xx;
1050
dy = upself->dy * ctx->paffine.yy;
1414
1409
gdk_pixbuf_get_width (in), gdk_pixbuf_get_height (in));
1416
1411
/* scale the SD values */
1417
sdx = upself->sdx * ctx->paffine[0];
1418
sdy = upself->sdy * ctx->paffine[3];
1412
sdx = upself->sdx * ctx->paffine.xx;
1413
sdy = upself->sdy * ctx->paffine.yy;
1420
1415
fast_blur (in, output, sdx, sdy, boundarys, op);
1533
1528
dx = _rsvg_css_normalize_length (&upself->dx, ctx->ctx, 'w');
1534
1529
dy = _rsvg_css_normalize_length (&upself->dy, ctx->ctx, 'v');
1536
ox = ctx->paffine[0] * dx + ctx->paffine[2] * dy;
1537
oy = ctx->paffine[1] * dx + ctx->paffine[3] * dy;
1531
ox = ctx->paffine.xx * dx + ctx->paffine.xy * dy;
1532
oy = ctx->paffine.yx * dx + ctx->paffine.yy * dy;
1539
1534
for (y = boundarys.y0; y < boundarys.y1; y++)
1540
1535
for (x = boundarys.x0; x < boundarys.x1; x++) {
2329
2321
rowstride = gdk_pixbuf_get_rowstride (in);
2331
2323
/* scale the radius values */
2332
kx = upself->rx * ctx->paffine[0];
2333
ky = upself->ry * ctx->paffine[3];
2324
kx = upself->rx * ctx->paffine.xx;
2325
ky = upself->ry * ctx->paffine.yy;
2335
2327
output = _rsvg_pixbuf_new_cleared (GDK_COLORSPACE_RGB, 1, 8, width, height);
2849
2841
for (y = boundarys.y0; y < boundarys.y1; y++)
2850
2842
for (x = boundarys.x0; x < boundarys.x1; x++) {
2852
ox = x + upself->scale * ctx->paffine[0] *
2844
ox = x + upself->scale * ctx->paffine.xx *
2853
2845
((double) in2_pixels[y * rowstride + x * 4 + xch] / 255.0 - 0.5);
2858
oy = y + upself->scale * ctx->paffine[3] *
2850
oy = y + upself->scale * ctx->paffine.yy *
2859
2851
((double) in2_pixels[y * rowstride + x * 4 + ych] / 255.0 - 0.5);
3203
3199
output = _rsvg_pixbuf_new_cleared (GDK_COLORSPACE_RGB, 1, 8, width, height);
3204
3200
output_pixels = gdk_pixbuf_get_pixels (output);
3206
_rsvg_affine_invert (affine, ctx->paffine);
3208
3202
for (y = 0; y < tileHeight; y++) {
3209
3203
for (x = 0; x < tileWidth; x++) {
3211
3205
double point[2];
3213
point[0] = affine[0] * (x + boundarys.x0) + affine[2] * (y + boundarys.y0) + affine[4];
3214
point[1] = affine[1] * (x + boundarys.x0) + affine[3] * (y + boundarys.y0) + affine[5];
3207
point[0] = affine.xx * (x + boundarys.x0) + affine.xy * (y + boundarys.y0) + affine.x0;
3208
point[1] = affine.yx * (x + boundarys.x0) + affine.yy * (y + boundarys.y0) + affine.y0;
3216
3210
pixel = output_pixels + 4 * (x + boundarys.x0) + (y + boundarys.y0) * rowstride;
3388
3380
rsvg_art_affine_image (img, intermediate,
3390
(boundarys.x1 - boundarys.x0) / ctx->paffine[0],
3391
(boundarys.y1 - boundarys.y0) / ctx->paffine[3]);
3382
(gdouble) width / ctx->paffine.xx,
3383
(gdouble) height / ctx->paffine.yy);
3393
3385
if (!intermediate) {
3394
3386
g_object_unref (img);
3817
x = affine[0] * x1 + affine[2] * y1 + affine[4];
3818
y = affine[1] * x1 + affine[3] * y1 + affine[5];
3810
x = affine->xx * x1 + affine->xy * y1 + affine->x0;
3811
y = affine->yx * x1 + affine->yy * y1 + affine->y0;
3819
3812
output.x = _rsvg_css_normalize_length (&source->x, ctx, 'h') - x;
3820
3813
output.y = _rsvg_css_normalize_length (&source->y, ctx, 'v') - y;
3821
3814
output.z = _rsvg_css_normalize_length (&source->z, ctx, 'o') - z;
3830
3823
get_light_colour (RsvgNodeLightSource * source, vector3 colour,
3831
gdouble x1, gdouble y1, gdouble z, gdouble * affine, RsvgDrawingCtx * ctx)
3824
gdouble x1, gdouble y1, gdouble z, cairo_matrix_t *affine, RsvgDrawingCtx * ctx)
3833
3826
double base, angle, x, y;
3846
3839
spy = _rsvg_css_normalize_length (&source->pointsAtY, ctx, 'v');
3847
3840
spz = _rsvg_css_normalize_length (&source->pointsAtZ, ctx, 'o');
3849
x = affine[0] * x1 + affine[2] * y1 + affine[4];
3850
y = affine[1] * x1 + affine[3] * y1 + affine[5];
3842
x = affine->xx * x1 + affine->xy * y1 + affine->x0;
3843
y = affine->yx * x1 + affine->yy * y1 + affine->y0;
4007
dx = upself->dx * ctx->paffine[0];
4008
dy = upself->dy * ctx->paffine[3];
4004
dx = upself->dx * ctx->paffine.xx;
4005
dy = upself->dy * ctx->paffine.yy;
4009
4006
rawdx = upself->dx;
4010
4007
rawdy = upself->dy;
4013
_rsvg_affine_invert (iaffine, ctx->paffine);
4015
4010
for (y = boundarys.y0; y < boundarys.y1; y++)
4016
4011
for (x = boundarys.x0; x < boundarys.x1; x++) {
4017
4012
z = surfaceScale * (double) in_pixels[y * rowstride + x * 4 + ctx->channelmap[3]];
4018
L = get_light_direction (source, x, y, z, iaffine, ctx->ctx);
4013
L = get_light_direction (source, x, y, z, &iaffine, ctx->ctx);
4019
4014
N = get_surface_normal (in_pixels, boundarys, x, y,
4020
4015
dx, dy, rawdx, rawdy, upself->surfaceScale,
4021
4016
rowstride, ctx->channelmap[3]);
4022
lightcolour = get_light_colour (source, colour, x, y, z, iaffine, ctx->ctx);
4017
lightcolour = get_light_colour (source, colour, x, y, z, &iaffine, ctx->ctx);
4023
4018
factor = dotproduct (N, L);
4025
4020
output_pixels[y * rowstride + x * 4 + ctx->channelmap[0]] =
4173
4172
surfaceScale = upself->surfaceScale / 255.0;
4175
_rsvg_affine_invert (iaffine, ctx->paffine);
4177
4174
for (y = boundarys.y0; y < boundarys.y1; y++)
4178
4175
for (x = boundarys.x0; x < boundarys.x1; x++) {
4179
4176
z = in_pixels[y * rowstride + x * 4 + 3] * surfaceScale;
4180
L = get_light_direction (source, x, y, z, iaffine, ctx->ctx);
4177
L = get_light_direction (source, x, y, z, &iaffine, ctx->ctx);
4182
4179
L = normalise (L);
4184
lightcolour = get_light_colour (source, colour, x, y, z, iaffine, ctx->ctx);
4181
lightcolour = get_light_colour (source, colour, x, y, z, &iaffine, ctx->ctx);
4185
4182
base = dotproduct (get_surface_normal (in_pixels, boundarys, x, y,
4186
1, 1, 1.0 / ctx->paffine[0],
4187
1.0 / ctx->paffine[3], upself->surfaceScale,
4183
1, 1, 1.0 / ctx->paffine.xx,
4184
1.0 / ctx->paffine.yy, upself->surfaceScale,
4188
4185
rowstride, ctx->channelmap[3]), L);
4190
4187
factor = upself->specularConstant * pow (base, upself->specularExponent) * 255;