c722e8c4382f7a3c164e5f779b2bec9c297b5599
[tbo.git] / src / svgimage.c
1 #include <stdlib.h>
2 #include <string.h>
3 #include <math.h>
4 #include <gtk/gtk.h>
5 #include <glib/gi18n.h>
6 #include <cairo.h>
7 #include <librsvg/rsvg.h>
8 #include <librsvg/rsvg-cairo.h>
9 #include "svgimage.h"
10 #include "tbo-types.h"
11
12 #define DOODLE_DIR DATA_DIR "/doodle/"
13
14
15 SVGImage *
16 tbo_svgimage_new ()
17 {
18     SVGImage *image;
19     image = malloc (sizeof(SVGImage));
20     image->data = malloc(sizeof(char)*255);
21     image->free = tbo_svg_image_free;
22     image->draw = tbo_svg_image_draw;
23     image->save = tbo_svg_image_save;
24     image->type = SVGOBJ;
25     image->flipv = FALSE;
26     image->fliph = FALSE;
27     return image;
28 }
29
30 SVGImage *
31 tbo_svgimage_new_width_params (int x,
32                                int y,
33                                int width,
34                                int height,
35                                const char *path)
36 {
37     SVGImage *image;
38     image = tbo_svgimage_new ();
39     image->x = x;
40     image->y = y;
41     image->width = width;
42     image->height = height;
43     snprintf (image->data, 255, "%s", path);
44     image->type = SVGOBJ;
45     image->flipv = FALSE;
46     image->fliph = FALSE;
47     return image;
48 }
49
50 void
51 tbo_svg_image_free (SVGImage *self)
52 {
53     free (self->data);
54     free (self);
55 }
56
57 void
58 tbo_svg_image_draw (SVGImage *self, Frame *frame, cairo_t *cr)
59 {
60     GError *error = NULL;
61     RsvgHandle *rsvg_handle = NULL;
62     RsvgDimensionData rsvg_dimension_data;
63     char path[255];
64     snprintf (path, 255, DOODLE_DIR "%s", self->data);
65     rsvg_handle = rsvg_handle_new_from_file (path, &error);
66     if (!rsvg_handle)
67     {
68         g_print (_("Couldn't load %s\n"), path);
69         return;
70     }
71     if (error != NULL)
72     {
73         g_print ("%s\n", error->message);
74         g_error_free (error);
75         return;
76     }
77     else
78     {
79         rsvg_handle_get_dimensions (rsvg_handle, &rsvg_dimension_data);
80         int w = rsvg_dimension_data.width;
81         int h = rsvg_dimension_data.height;
82         if (!self->width) self->width = w;
83         if (!self->height) self->height = h;
84
85         float factorw = (float)self->width / (float)w;
86         float factorh = (float)self->height / (float)h;
87
88         cairo_matrix_t mx = {1, 0, 0, 1, 0, 0};
89         tbo_object_get_flip_matrix (self, &mx);
90
91         cairo_rectangle(cr, frame->x+2, frame->y+2, frame->width-4, frame->height-4);
92         cairo_clip (cr);
93         cairo_translate (cr, frame->x+self->x, frame->y+self->y);
94         cairo_rotate (cr, self->angle);
95         cairo_transform (cr, &mx);
96         cairo_scale (cr, factorw, factorh);
97
98         rsvg_handle_render_cairo (rsvg_handle, cr);
99
100         cairo_scale (cr, 1/factorw, 1/factorh);
101         cairo_transform (cr, &mx);
102         cairo_rotate (cr, -self->angle);
103         cairo_translate (cr, -(frame->x+self->x), -(frame->y+self->y));
104         cairo_reset_clip (cr);
105
106         g_object_unref (rsvg_handle);
107     }
108 }
109
110 void
111 tbo_svg_image_save (SVGImage *self, FILE *file)
112 {
113     char buffer[1024];
114
115     snprintf (buffer, 1024, "   <svgimage x=\"%d\" y=\"%d\" "
116                            "width=\"%d\" height=\"%d\" "
117                            "angle=\"%f\" flipv=\"%d\" fliph=\"%d\" "
118                            "path=\"%s\">\n ",
119                            self->x, self->y, self->width, self->height,
120                            self->angle, self->flipv, self->fliph, (char*)self->data);
121     fwrite (buffer, sizeof (char), strlen (buffer), file);
122
123     snprintf (buffer, 1024, "   </svgimage>\n");
124     fwrite (buffer, sizeof (char), strlen (buffer), file);
125 }