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 :