summaryrefslogtreecommitdiff
path: root/src/generic/evas/svg/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/generic/evas/svg/main.c')
-rw-r--r--src/generic/evas/svg/main.c230
1 files changed, 230 insertions, 0 deletions
diff --git a/src/generic/evas/svg/main.c b/src/generic/evas/svg/main.c
new file mode 100644
index 0000000..5fc7912
--- /dev/null
+++ b/src/generic/evas/svg/main.c
@@ -0,0 +1,230 @@
1#ifdef HAVE_CONFIG_H
2#include <config.h>
3#endif
4#include <stdio.h>
5#include "shmfile.h"
6#include "timeout.h"
7
8#include <Eina.h>
9
10#include <librsvg/rsvg.h>
11#ifndef LIBRSVG_CHECK_VERSION
12# include <librsvg/librsvg-features.h>
13#endif
14#if LIBRSVG_CHECK_VERSION(2,36,2)
15#else
16# include <librsvg/rsvg-cairo.h>
17#endif
18
19#define DATA32 unsigned int
20
21static RsvgHandle *rsvg = NULL;
22static int width = 0;
23static int height = 0;
24static RsvgDimensionData dim;
25
26static inline Eina_Bool evas_image_load_file_is_svg(const char *file)
27{
28 int i, len = strlen(file);
29 Eina_Bool is_gz = EINA_FALSE;
30
31 for (i = len - 1; i > 0; i--)
32 {
33 if (file[i] == '.')
34 {
35 if (is_gz)
36 break;
37 else if (strcasecmp(file + i + 1, "gz") == 0)
38 is_gz = EINA_TRUE;
39 else
40 break;
41 }
42 }
43
44 if (i < 1) return EINA_FALSE;
45 i++;
46 if (i >= len) return EINA_FALSE;
47 if (strncasecmp(file + i, "svg", 3) != 0) return EINA_FALSE;
48 i += 3;
49 if (is_gz)
50 {
51 if (file[i] == '.') return EINA_TRUE;
52 else return EINA_FALSE;
53 }
54 else
55 {
56 if (file[i] == '\0') return EINA_TRUE;
57 else if (((file[i] == 'z') || (file[i] == 'Z')) && (!file[i + 1])) return EINA_TRUE;
58 else return EINA_FALSE;
59 }
60}
61
62static int
63_svg_init(const char *file)
64{
65#ifdef HAVE_SVG_2_36
66# if !defined(GLIB_VERSION_2_36)
67 g_type_init();
68# endif
69#else
70 rsvg_init();
71#endif
72
73 if (!evas_image_load_file_is_svg(file)) return 0;
74
75 rsvg = rsvg_handle_new_from_file(file, NULL);
76
77 return 1;
78}
79
80static void
81_svg_shutdown(void)
82{
83 if (rsvg)
84 {
85 rsvg_handle_close(rsvg, NULL);
86 g_object_unref(rsvg);
87 }
88 // Maybe it's not crashing anymore, let's try it.
89#ifndef HAVE_SVG_2_36
90 rsvg_term();
91#endif
92}
93
94static int
95read_svg_header(int scale_down, double dpi, int size_w, int size_h)
96{
97 rsvg_handle_set_dpi(rsvg, 75.0);
98 rsvg_handle_get_dimensions(rsvg, &dim);
99 width = dim.width;
100 height = dim.height;
101
102 if ((width < 1) || (height < 1)) return 0;
103
104 if (scale_down > 1)
105 {
106 width /= scale_down;
107 height /= scale_down;
108 }
109 else if (dpi > 0.0)
110 {
111 width = (width * dpi) / 75;
112 height = (height * dpi) / 75;
113 }
114 else if (size_w > 0 && size_h > 0)
115 {
116 int w, h;
117
118 w = size_w;
119 h = (size_w * height) / width;
120 if (h > size_h)
121 {
122 h = size_h;
123 w = (size_h * width) / height;
124 }
125 width = w;
126 height = h;
127 }
128 if (width < 1) width = 1;
129 if (height < 1) height = 1;
130
131 return 1;
132}
133
134static int
135read_svg_data(void)
136{
137 cairo_surface_t *surface;
138 cairo_t *cr;
139
140 shm_alloc(width * height * (sizeof(DATA32)));
141 if (!shm_addr) return 0;
142
143 memset(shm_addr, 0, width * height * sizeof (DATA32));
144 surface = cairo_image_surface_create_for_data((unsigned char *)shm_addr, CAIRO_FORMAT_ARGB32,
145 width, height, width * sizeof(DATA32));;
146 if (!surface) return 0;
147
148 cr = cairo_create(surface);
149 if (!cr) return 0;
150
151 cairo_scale(cr, (double) width / dim.em, (double) height / dim.ex);
152 rsvg_handle_render_cairo(rsvg, cr);
153 cairo_surface_destroy(surface);
154 cairo_destroy(cr);
155
156 return 1;
157}
158
159int main(int argc, char **argv)
160{
161 char *file;
162 int i;
163 int head_only = 0;
164 int scale_down = 0;
165 double dpi = 0.0;
166 int size_w = 0, size_h = 0;
167
168 if (argc < 2) return -1;
169 file = argv[1];
170
171 for (i = 2; i < argc; ++i)
172 {
173 if (!strcmp(argv[i], "-head"))
174 head_only = 1;
175 else if (!strcmp(argv[i], "-key"))
176 { // not used by svg loader
177 i++;
178 // const char *key = argv[i];
179 }
180 else if (!strcmp(argv[i], "-opt-scale-down-by"))
181 {
182 i++;
183 scale_down = atoi(argv[i]);
184 }
185 else if (!strcmp(argv[i], "-opt-dpi"))
186 {
187 i++;
188 dpi = ((double)atoi(argv[i])) / 1000.0;
189 }
190 else if (!strcmp(argv[i], "-opt-size"))
191 {
192 i++;
193 size_w = atoi(argv[i]);
194 i++;
195 size_h = atoi(argv[i]);
196 }
197 }
198
199 timeout_init(5);
200
201 if (!_svg_init(file)) return -1;
202 if (!read_svg_header(scale_down, dpi, size_w, size_h)) return -1;
203
204 if (head_only != 0)
205 {
206 printf("size %d %d\n", width, height);
207 printf("alpha 1\n");
208 printf("done\n");
209 }
210 else
211 {
212 if (read_svg_data())
213 {
214 printf("size %d %d\n", width, height);
215 printf("alpha 1\n");
216 if (shm_fd >= 0) printf("shmfile %s\n", shmfile);
217 else
218 {
219 printf("data\n");
220 fwrite(shm_addr, width * height * sizeof(DATA32), 1, stdout);
221 }
222 shm_free();
223 }
224 }
225 _svg_shutdown();
226 fflush(stdout);
227 return 0;
228
229}
230