Code

the SP_IS_GAUSSIANBLUR fix is not only for shapes. fixme: this boilerplate definitely...
[inkscape.git] / src / display / inkscape-cairo.cpp
1 /*
2  * Helper functions to use cairo with inkscape
3  *
4  * Copyright (C) 2007 bulia byak
5  *
6  * Released under GNU GPL
7  *
8  */
10 #include <cairo.h>
12 #ifdef HAVE_CONFIG_H
13 # include <config.h>
14 #endif
15 #include <libnr/n-art-bpath.h>
16 #include <libnr/nr-matrix-ops.h>
17 #include <libnr/nr-matrix-fns.h>
18 #include <libnr/nr-pixblock.h>
19 #include "../style.h"
20 #include "nr-arena.h"
23 /** Creates a cairo context to render to the given pixblock on the given area */
24 cairo_t *
25 nr_create_cairo_context (NRRectL *area, NRPixBlock *pb)
26 {
27     if (!nr_rect_l_test_intersect (&pb->area, area)) 
28         return NULL;
30     NRRectL clip;
31     nr_rect_l_intersect (&clip, &pb->area, area);
32     unsigned char *dpx = NR_PIXBLOCK_PX (pb) + (clip.y0 - pb->area.y0) * pb->rs + NR_PIXBLOCK_BPP (pb) * (clip.x0 - pb->area.x0);
33     int width = area->x1 - area->x0;
34     int height = area->y1 - area->y0;
35     // even though cairo cannot draw in nonpremul mode, select ARGB32 for R8G8B8A8N as the closest; later eliminate R8G8B8A8N everywhere
36     cairo_surface_t* cst = cairo_image_surface_create_for_data
37         (dpx,
38          ((pb->mode == NR_PIXBLOCK_MODE_R8G8B8A8P || pb->mode == NR_PIXBLOCK_MODE_R8G8B8A8N) ? CAIRO_FORMAT_ARGB32 : (pb->mode == NR_PIXBLOCK_MODE_R8G8B8? CAIRO_FORMAT_RGB24 : CAIRO_FORMAT_A8)),
39          width,
40          height,
41          pb->rs);
42     cairo_t *ct = cairo_create (cst);
44     return ct;
45 }
47 /** Feeds path-creating calls to the cairo context translating them from the SPCurve, with the given transform and shift */
48 void
49 feed_curve_to_cairo (cairo_t *ct, NArtBpath *bpath, NR::Matrix trans, NR::Point shift)
50 {
51     NR::Point lastX(0,0);
52     bool  closed = false;
53     for (int i = 0; bpath[i].code != NR_END; i++) {
54         switch (bpath[i].code) {
55             case NR_MOVETO_OPEN:
56             case NR_MOVETO:
57                 if (closed) cairo_close_path(ct);
58                 closed = (bpath[i].code == NR_MOVETO);
59                 lastX[NR::X] = bpath[i].x3;
60                 lastX[NR::Y] = bpath[i].y3;
61                 lastX *= trans;
62                 lastX -= shift;
63                 cairo_move_to(ct, lastX[NR::X], lastX[NR::Y]);
64                 break;
66             case NR_LINETO:
67                 lastX[NR::X] = bpath[i].x3;
68                 lastX[NR::Y] = bpath[i].y3;
69                 lastX *= trans;
70                 lastX -= shift;
71                 cairo_line_to(ct, lastX[NR::X], lastX[NR::Y]);
72                 break;
74             case NR_CURVETO: {
75                 NR::Point  tm1, tm2, tm3;
76                 tm1[0]=bpath[i].x1;
77                 tm1[1]=bpath[i].y1;
78                 tm2[0]=bpath[i].x2;
79                 tm2[1]=bpath[i].y2;
80                 tm3[0]=bpath[i].x3;
81                 tm3[1]=bpath[i].y3;
82                 tm1 *= trans;
83                 tm2 *= trans;
84                 tm3 *= trans;
85                 tm1 -= shift;
86                 tm2 -= shift;
87                 tm3 -= shift;
88                 cairo_curve_to (ct, tm1[NR::X], tm1[NR::Y], tm2[NR::X], tm2[NR::Y], tm3[NR::X], tm3[NR::Y]);
89                 break;
90             }
92             default:
93                 break;
94         }
95     }
96 }
99 /*
100   Local Variables:
101   mode:c++
102   c-file-style:"stroustrup"
103   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
104   indent-tabs-mode:nil
105   fill-column:99
106   End:
107 */
108 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :