~ubuntu-branches/ubuntu/quantal/librsvg/quantal-security

« back to all changes in this revision

Viewing changes to rsvg-filter.c

  • Committer: Package Import Robot
  • Author(s): Robert Roth
  • Date: 2012-01-18 23:37:53 UTC
  • mfrom: (1.1.29)
  • Revision ID: package-import@ubuntu.com-20120118233753-9jtotetl073dh34f
Tags: 2.35.0-0ubuntu1
* New upstream release (lp: #918016).
* debian/patches/10_rsvg-gz.patch: updated to apply.
* debian/watch: updated to also watch unstable xz tarballs.
* debian/control.in: updated dependencies.
* debian/librsvg2-2.symbols: added new symbol.

Show diffs side-by-side

added added

removed removed

Lines of Context:
59
59
    GdkPixbuf *source;
60
60
    GdkPixbuf *bg;
61
61
    RsvgFilterPrimitiveOutput lastresult;
62
 
    double affine[6];
63
 
    double paffine[6];
 
62
    cairo_matrix_t affine;
 
63
    cairo_matrix_t paffine;
64
64
    int channelmap[4];
65
65
    RsvgDrawingCtx *ctx;
66
66
};
89
89
rsvg_filter_primitive_get_bounds (RsvgFilterPrimitive * self, RsvgFilterContext * ctx)
90
90
{
91
91
    RsvgBbox box, otherbox;
92
 
    double affine[6];
 
92
    cairo_matrix_t affine;
93
93
 
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);
106
106
 
110
110
        if (self->x.factor != 'n' || self->y.factor != 'n' ||
111
111
            self->width.factor != 'n' || self->height.factor != 'n') {
112
112
 
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');
119
119
            else
120
 
                otherbox.x = 0;
 
120
                otherbox.rect.x = 0;
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');
123
123
            else
124
 
                otherbox.y = 0;
 
124
                otherbox.rect.y = 0;
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');
127
127
            else
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');
131
131
            else
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);
136
136
        }
137
137
 
138
 
    rsvg_bbox_init (&otherbox, affine);
 
138
    rsvg_bbox_init (&otherbox, &affine);
139
139
    otherbox.virgin = 0;
140
 
    otherbox.x = 0;
141
 
    otherbox.y = 0;
142
 
    otherbox.w = ctx->width;
143
 
    otherbox.h = ctx->height;
 
140
    otherbox.rect.x = 0;
 
141
    otherbox.rect.y = 0;
 
142
    otherbox.rect.width = ctx->width;
 
143
    otherbox.rect.height = ctx->height;
144
144
    rsvg_bbox_clip (&box, &otherbox);
145
145
    {
146
 
        RsvgIRect output = { box.x, box.y,
147
 
            box.x + box.w,
148
 
            box.y + box.h
 
146
        RsvgIRect output = { box.rect.x, box.rect.y,
 
147
            box.rect.x + box.rect.width,
 
148
            box.rect.y + box.rect.height
149
149
        };
150
150
        return output;
151
151
    }
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;
175
176
 
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);
183
184
 
184
 
    if (floor (ox) <= boundarys.x0 || floor (ox) >= boundarys.x1 ||
185
 
        floor (oy) <= boundarys.y0 || floor (oy) >= boundarys.y1)
 
185
    fox = floor (ox);
 
186
    foy = floor (oy);
 
187
    cox = ceil (ox);
 
188
    coy = ceil (oy);
 
189
 
 
190
    if (fox <= boundarys.x0 || fox >= boundarys.x1 ||
 
191
        foy <= boundarys.y0 || foy >= boundarys.y1)
186
192
        c1 = 0;
187
193
    else
188
 
        c1 = src[(guint) floor (oy) * rowstride + (guint) floor (ox) * 4 + ch];
 
194
        c1 = src[(guint) foy * rowstride + (guint) fox * 4 + ch];
189
195
 
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)
192
198
        c2 = 0;
193
199
    else
194
 
        c2 = src[(guint) floor (oy) * rowstride + (guint) ceil (ox) * 4 + ch];
 
200
        c2 = src[(guint) foy * rowstride + (guint) cox * 4 + ch];
195
201
 
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)
198
204
        c3 = 0;
199
205
    else
200
 
        c3 = src[(guint) ceil (oy) * rowstride + (guint) ceil (ox) * 4 + ch];
 
206
        c3 = src[(guint) coy * rowstride + (guint) cox * 4 + ch];
201
207
 
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)
204
210
        c4 = 0;
205
211
    else
206
 
        c4 = src[(guint) ceil (oy) * rowstride + (guint) floor (ox) * 4 + ch];
 
212
        c4 = src[(guint) coy * rowstride + (guint) fox * 4 + ch];
207
213
 
208
214
    c = (c1 * dist1 + c2 * dist2 + c3 * dist3 + c4 * dist4) / (dist1 + dist2 + dist3 + dist4);
209
215
 
211
217
}
212
218
 
213
219
static void
214
 
rsvg_filter_fix_coordinate_system (RsvgFilterContext * ctx, RsvgState * state, RsvgBbox bbox)
 
220
rsvg_filter_fix_coordinate_system (RsvgFilterContext * ctx, RsvgState * state, RsvgBbox *bbox)
215
221
{
216
222
    int x, y, height, width;
217
 
    int i;
218
223
 
219
 
    x = bbox.x;
220
 
    y = bbox.y;
221
 
    width = bbox.w;
222
 
    height = bbox.h;
 
224
    x = bbox->rect.x;
 
225
    y = bbox->rect.y;
 
226
    width = bbox->rect.width;
 
227
    height = bbox->rect.height;
223
228
 
224
229
    ctx->width = gdk_pixbuf_get_width (ctx->source);
225
230
    ctx->height = gdk_pixbuf_get_height (ctx->source);
226
231
 
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);
232
237
    }
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);
238
243
    }
239
244
}
240
245
 
339
344
 
340
345
void
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)
343
348
{
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;
347
350
    gint intstride;
348
351
    gint basestride;
349
352
    gint basex, basey;
371
374
    intpix = gdk_pixbuf_get_pixels (intermediate);
372
375
    basebpp = has_alpha ? 4 : 3;
373
376
 
374
 
    _rsvg_affine_invert (raw_inv_affine, affine);
375
 
 
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);
381
 
 
382
 
    _rsvg_affine_invert (inv_affine, tmp_affine);
383
 
 
 
377
    raw_inv_affine = *affine;
 
378
    if (cairo_matrix_invert (&raw_inv_affine) != CAIRO_STATUS_SUCCESS)
 
379
      return;
 
380
 
 
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)
 
384
      return;
384
385
 
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++)
481
482
 
482
483
    g_object_ref (source);
483
484
 
484
 
    rsvg_filter_fix_coordinate_system (ctx, rsvg_current_state (context), *bounds);
 
485
    rsvg_filter_fix_coordinate_system (ctx, rsvg_current_state (context), bounds);
485
486
 
486
487
    ctx->lastresult.result = source;
487
488
    ctx->lastresult.Rused = 1;
579
580
static GdkPixbuf *
580
581
rsvg_compile_bg (RsvgDrawingCtx * ctx)
581
582
{
582
 
    RsvgCairoRender *render = (RsvgCairoRender *) ctx->render;
 
583
    RsvgCairoRender *render = RSVG_CAIRO_RENDER (ctx->render);
583
584
    cairo_t *cr;
584
585
    cairo_surface_t *surface;
585
586
    GList *i;
670
671
        return output;
671
672
    }
672
673
 
673
 
    g_warning (_("%s not found\n"), name->str);
 
674
    /* g_warning (_("%s not found\n"), name->str); */
674
675
 
675
676
    output = ctx->lastresult;
676
677
    g_object_ref (ctx->lastresult.result);
1041
1042
    height = gdk_pixbuf_get_height (in);
1042
1043
    width = gdk_pixbuf_get_width (in);
1043
1044
 
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;
1046
1047
 
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;
1050
1051
    } else
1051
1052
        dx = dy = 1;
1052
1053
 
1265
1266
{
1266
1267
    gint ch;
1267
1268
    gint x, y;
1268
 
    gint rowstride, height, width;
1269
 
 
 
1269
    gint rowstride;
1270
1270
    guchar *in_pixels;
1271
1271
    guchar *output_pixels;
1272
 
 
1273
1272
    gint sum;
1274
1273
 
1275
 
 
1276
 
    height = gdk_pixbuf_get_height (in);
1277
 
    width = gdk_pixbuf_get_width (in);
1278
 
 
1279
1274
    in_pixels = gdk_pixbuf_get_pixels (in);
1280
1275
    output_pixels = gdk_pixbuf_get_pixels (output);
1281
1276
 
1414
1409
                                       gdk_pixbuf_get_width (in), gdk_pixbuf_get_height (in));
1415
1410
 
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;
1419
1414
 
1420
1415
    fast_blur (in, output, sdx, sdy, boundarys, op);
1421
1416
 
1533
1528
    dx = _rsvg_css_normalize_length (&upself->dx, ctx->ctx, 'w');
1534
1529
    dy = _rsvg_css_normalize_length (&upself->dy, ctx->ctx, 'v');
1535
1530
 
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;
1538
1533
 
1539
1534
    for (y = boundarys.y0; y < boundarys.y1; y++)
1540
1535
        for (x = boundarys.x0; x < boundarys.x1; x++) {
2098
2093
    gint achan = ctx->channelmap[3];
2099
2094
    guchar *in_pixels;
2100
2095
    guchar *output_pixels;
2101
 
 
2102
 
    RsvgFilterPrimitiveComponentTransfer *upself;
2103
 
 
2104
2096
    GdkPixbuf *output;
2105
2097
    GdkPixbuf *in;
2106
 
    upself = (RsvgFilterPrimitiveComponentTransfer *) self;
 
2098
 
2107
2099
    boundarys = rsvg_filter_primitive_get_bounds (self, ctx);
2108
2100
 
2109
2101
    for (c = 0; c < 4; c++) {
2329
2321
    rowstride = gdk_pixbuf_get_rowstride (in);
2330
2322
 
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;
2334
2326
 
2335
2327
    output = _rsvg_pixbuf_new_cleared (GDK_COLORSPACE_RGB, 1, 8, width, height);
2336
2328
 
2849
2841
    for (y = boundarys.y0; y < boundarys.y1; y++)
2850
2842
        for (x = boundarys.x0; x < boundarys.x1; x++) {
2851
2843
            if (xch != 4)
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);
2854
2846
            else
2855
2847
                ox = x;
2856
2848
 
2857
2849
            if (ych != 4)
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);
2860
2852
            else
2861
2853
                oy = y;
3186
3178
    RsvgIRect boundarys;
3187
3179
    guchar *output_pixels;
3188
3180
    GdkPixbuf *output;
3189
 
    gdouble affine[6];
 
3181
    cairo_matrix_t affine;
3190
3182
    GdkPixbuf *in;
3191
3183
 
 
3184
    affine = ctx->paffine;
 
3185
    if (cairo_matrix_invert (&affine) != CAIRO_STATUS_SUCCESS)
 
3186
      return;
 
3187
 
3192
3188
    in = rsvg_filter_get_in (self->in, ctx);
3193
3189
    height = gdk_pixbuf_get_height (in);
3194
3190
    width = gdk_pixbuf_get_width (in);
3203
3199
    output = _rsvg_pixbuf_new_cleared (GDK_COLORSPACE_RGB, 1, 8, width, height);
3204
3200
    output_pixels = gdk_pixbuf_get_pixels (output);
3205
3201
 
3206
 
    _rsvg_affine_invert (affine, ctx->paffine);
3207
 
 
3208
3202
    for (y = 0; y < tileHeight; y++) {
3209
3203
        for (x = 0; x < tileWidth; x++) {
3210
3204
            gint i;
3211
3205
            double point[2];
3212
3206
            guchar *pixel;
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;
3215
3209
 
3216
3210
            pixel = output_pixels + 4 * (x + boundarys.x0) + (y + boundarys.y0) * rowstride;
3217
3211
 
3331
3325
{
3332
3326
    RsvgDrawingCtx *ctx;
3333
3327
    RsvgFilterPrimitiveImage *upself;
3334
 
    int i;
3335
3328
    RsvgNode *drawable;
3336
3329
 
3337
3330
    ctx = context->ctx;
3345
3338
    if (!drawable)
3346
3339
        return NULL;
3347
3340
 
3348
 
    for (i = 0; i < 6; i++)
3349
 
        rsvg_current_state (ctx)->affine[i] = context->paffine[i];
 
3341
    rsvg_current_state (ctx)->affine = context->paffine;
3350
3342
 
3351
3343
    return rsvg_get_image_of_node (ctx, drawable, context->width, context->height);
3352
3344
}
3386
3378
 
3387
3379
 
3388
3380
    rsvg_art_affine_image (img, intermediate,
3389
 
                           ctx->paffine,
3390
 
                           (boundarys.x1 - boundarys.x0) / ctx->paffine[0],
3391
 
                           (boundarys.y1 - boundarys.y0) / ctx->paffine[3]);
 
3381
                           &ctx->paffine,
 
3382
                           (gdouble) width / ctx->paffine.xx,
 
3383
                           (gdouble) height / ctx->paffine.yy);
3392
3384
 
3393
3385
    if (!intermediate) {
3394
3386
        g_object_unref (img);
3526
3518
    filter->super.render = &rsvg_filter_primitive_image_render;
3527
3519
    filter->super.super.free = &rsvg_filter_primitive_image_free;
3528
3520
    filter->super.super.set_atts = rsvg_filter_primitive_image_set_atts;
 
3521
    filter->href = NULL;
3529
3522
    return (RsvgNode *) filter;
3530
3523
}
3531
3524
 
3801
3794
 
3802
3795
static vector3
3803
3796
get_light_direction (RsvgNodeLightSource * source, gdouble x1, gdouble y1, gdouble z,
3804
 
                     gdouble * affine, RsvgDrawingCtx * ctx)
 
3797
                     cairo_matrix_t *affine, RsvgDrawingCtx * ctx)
3805
3798
{
3806
3799
    vector3 output;
3807
3800
 
3814
3807
    default:
3815
3808
        {
3816
3809
            double x, y;
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;
3828
3821
 
3829
3822
static vector3
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)
3832
3825
{
3833
3826
    double base, angle, x, y;
3834
3827
    vector3 s;
3846
3839
    spy = _rsvg_css_normalize_length (&source->pointsAtY, ctx, 'v');
3847
3840
    spz = _rsvg_css_normalize_length (&source->pointsAtZ, ctx, 'o');
3848
3841
 
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;
3851
3844
 
3852
3845
    L.x = sx - x;
3853
3846
    L.y = sy - y;
3953
3946
    gdouble factor, surfaceScale;
3954
3947
    vector3 lightcolour, L, N;
3955
3948
    vector3 colour;
3956
 
    gdouble iaffine[6];
 
3949
    cairo_matrix_t iaffine;
3957
3950
    RsvgNodeLightSource *source = NULL;
3958
3951
    RsvgIRect boundarys;
3959
3952
 
3977
3970
    if (source == NULL)
3978
3971
        return;
3979
3972
 
 
3973
    iaffine = ctx->paffine;
 
3974
    if (cairo_matrix_invert (&iaffine) != CAIRO_STATUS_SUCCESS)
 
3975
      return;
 
3976
 
3980
3977
    upself = (RsvgFilterPrimitiveDiffuseLighting *) self;
3981
3978
    boundarys = rsvg_filter_primitive_get_bounds (self, ctx);
3982
3979
 
4004
4001
        rawdx = 1;
4005
4002
        rawdy = 1;
4006
4003
    } else {
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;
4011
4008
    }
4012
4009
 
4013
 
    _rsvg_affine_invert (iaffine, ctx->paffine);
4014
 
 
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);
4024
4019
 
4025
4020
            output_pixels[y * rowstride + x * 4 + ctx->channelmap[0]] =
4127
4122
    gdouble factor, max, base;
4128
4123
    vector3 lightcolour, colour;
4129
4124
    vector3 L;
4130
 
    gdouble iaffine[6];
 
4125
    cairo_matrix_t iaffine;
4131
4126
    RsvgIRect boundarys;
4132
4127
    RsvgNodeLightSource *source = NULL;
4133
4128
 
4151
4146
    if (source == NULL)
4152
4147
        return;
4153
4148
 
 
4149
    iaffine = ctx->paffine;
 
4150
    if (cairo_matrix_invert (&iaffine) != CAIRO_STATUS_SUCCESS)
 
4151
      return;
 
4152
 
4154
4153
    upself = (RsvgFilterPrimitiveSpecularLighting *) self;
4155
4154
    boundarys = rsvg_filter_primitive_get_bounds (self, ctx);
4156
4155
 
4172
4171
 
4173
4172
    surfaceScale = upself->surfaceScale / 255.0;
4174
4173
 
4175
 
    _rsvg_affine_invert (iaffine, ctx->paffine);
4176
 
 
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);
4181
4178
            L.z += 1;
4182
4179
            L = normalise (L);
4183
4180
 
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);
4189
4186
 
4190
4187
            factor = upself->specularConstant * pow (base, upself->specularExponent) * 255;
4316
4313
    GdkPixbuf *output;
4317
4314
    GdkPixbuf *in;
4318
4315
 
4319
 
    RsvgFilterPrimitiveTile *upself;
4320
 
 
4321
 
    upself = (RsvgFilterPrimitiveTile *) self;
4322
4316
    oboundarys = rsvg_filter_primitive_get_bounds (self, ctx);
4323
4317
 
4324
4318
    input = rsvg_filter_get_result (self->in, ctx);