Now it's abaliable to clone objects with ctrl+d
[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->clone = tbo_svg_image_clone;
25     image->type = SVGOBJ;
26     image->flipv = FALSE;
27     image->fliph = FALSE;
28     return image;
29 }
30
31 SVGImage *
32 tbo_svgimage_new_width_params (int x,
33                                int y,
34                                int width,
35                                int height,
36                                const char *path)
37 {
38     SVGImage *image;
39     image = tbo_svgimage_new ();
40     image->x = x;
41     image->y = y;
42     image->width = width;
43     image->height = height;
44     snprintf (image->data, 255, "%s", path);
45     image->type = SVGOBJ;
46     image->flipv = FALSE;
47     image->fliph = FALSE;
48     return image;
49 }
50
51 void
52 tbo_svg_image_free (SVGImage *self)
53 {
54     free (self->data);
55     free (self);
56 }
57
58 void
59 tbo_svg_image_draw (SVGImage *self, Frame *frame, cairo_t *cr)
60 {
61     GError *error = NULL;
62     RsvgHandle *rsvg_handle = NULL;
63     RsvgDimensionData rsvg_dimension_data;
64     char path[255];
65     snprintf (path, 255, DOODLE_DIR "%s", self->data);
66     rsvg_handle = rsvg_handle_new_from_file (path, &error);
67     if (!rsvg_handle)
68     {
69         g_print (_("Couldn't load %s\n"), path);
70         return;
71     }
72     if (error != NULL)
73     {
74         g_print ("%s\n", error->message);
75         g_error_free (error);
76         return;
77     }
78     else
79     {
80         rsvg_handle_get_dimensions (rsvg_handle, &rsvg_dimension_data);
81         int w = rsvg_dimension_data.width;
82         int h = rsvg_dimension_data.height;
83         if (!self->width) self->width = w;
84         if (!self->height) self->height = h;
85
86         float factorw = (float)self->width / (float)w;
87         float factorh = (float)self->height / (float)h;
88
89         cairo_matrix_t mx = {1, 0, 0, 1, 0, 0};
90         tbo_object_get_flip_matrix (self, &mx);
91
92         cairo_rectangle(cr, frame->x+2, frame->y+2, frame->width-4, frame->height-4);
93         cairo_clip (cr);
94         cairo_translate (cr, frame->x+self->x, frame->y+self->y);
95         cairo_rotate (cr, self->angle);
96         cairo_transform (cr, &mx);
97         cairo_scale (cr, factorw, factorh);
98
99         rsvg_handle_render_cairo (rsvg_handle, cr);
100
101         cairo_scale (cr, 1/factorw, 1/factorh);
102         cairo_transform (cr, &mx);
103         cairo_rotate (cr, -self->angle);
104         cairo_translate (cr, -(frame->x+self->x), -(frame->y+self->y));
105         cairo_reset_clip (cr);
106
107         g_object_unref (rsvg_handle);
108     }
109 }
110
111 void
112 tbo_svg_image_save (SVGImage *self, FILE *file)
113 {
114     char buffer[1024];
115
116     snprintf (buffer, 1024, "   <svgimage x=\"%d\" y=\"%d\" "
117                            "width=\"%d\" height=\"%d\" "
118                            "angle=\"%f\" flipv=\"%d\" fliph=\"%d\" "
119                            "path=\"%s\">\n ",
120                            self->x, self->y, self->width, self->height,
121                            self->angle, self->flipv, self->fliph, (char*)self->data);
122     fwrite (buffer, sizeof (char), strlen (buffer), file);
123
124     snprintf (buffer, 1024, "   </svgimage>\n");
125     fwrite (buffer, sizeof (char), strlen (buffer), file);
126 }
127
128 SVGImage *
129 tbo_svg_image_clone (SVGImage *self)
130 {
131     SVGImage *newimage;
132
133     newimage = tbo_svgimage_new_width_params (self->x,
134                                               self->y,
135                                               self->width,
136                                               self->height,
137                                               self->data);
138     newimage->angle = self->angle;
139     newimage->flipv = self->flipv;
140     newimage->fliph = self->fliph;
141
142     return newimage;
143 }