efl

Форк
0
278 строк · 6.1 Кб
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

21
static RsvgHandle *rsvg = NULL;
22
static int width = 0;
23
static int height = 0;
24
static RsvgDimensionData dim;
25

26
static inline Eina_Bool
27
evas_image_load_file_is_svg(const char *file)
28
{
29
   int i, len = strlen(file);
30
   Eina_Bool is_gz = EINA_FALSE;
31

32
   for (i = len - 1; i > 0; i--)
33
     {
34
	if (file[i] == '.')
35
	  {
36
	     if (is_gz)
37
	       break;
38
	     else if (strcasecmp(file + i + 1, "gz") == 0)
39
	       is_gz = EINA_TRUE;
40
	     else
41
	       break;
42
	  }
43
     }
44

45
   if (i < 1) return EINA_FALSE;
46
   i++;
47
   if (i >= len) return EINA_FALSE;
48
   if (strncasecmp(file + i, "svg", 3) != 0) return EINA_FALSE;
49
   i += 3;
50
   if (is_gz)
51
     {
52
	if (file[i] == '.') return EINA_TRUE;
53
	else return EINA_FALSE;
54
     }
55
   else
56
     {
57
	if (file[i] == '\0') return EINA_TRUE;
58
	else if (((file[i] == 'z') || (file[i] == 'Z')) && (!file[i + 1])) return EINA_TRUE;
59
	else return EINA_FALSE;
60
     }
61
}
62

63
static int
64
_svg_init(const char *file)
65
{
66
#ifdef HAVE_SVG_2_36
67
# if !defined(GLIB_VERSION_2_36)
68
   g_type_init();
69
# endif
70
#else
71
   rsvg_init();
72
#endif
73

74
   if (!evas_image_load_file_is_svg(file)) return 0;
75

76
   rsvg = rsvg_handle_new_from_file(file, NULL);
77
   if (!rsvg) return 0;
78

79
   return 1;
80
}
81

82
static void
83
_svg_shutdown(void)
84
{
85
   if (rsvg)
86
     {
87
// we don't really need this it seems and it's deprecated in 2.46
88
//        rsvg_handle_close(rsvg, NULL);
89
        g_object_unref(rsvg);
90
     }
91
   // Maybe it's not crashing anymore, let's try it.
92
#ifndef HAVE_SVG_2_36
93
   rsvg_term();
94
#endif
95
}
96

97
static int
98
read_svg_header(int scale_down, double dpi, int size_w, int size_h)
99
{
100
   rsvg_handle_set_dpi(rsvg, 75.0);
101

102
#ifdef HAVE_SVG_2_51
103
   double owidth, oheight;
104

105
   rsvg_handle_get_intrinsic_size_in_pixels(rsvg, &owidth, &oheight);
106
   width = ceil(owidth);
107
   height = ceil(oheight);
108
   if ((width == 0) || (height == 0))
109
     {
110
        RsvgLength l1, l2;
111
        gboolean has_l1, has_l2, has_vb;
112
        RsvgRectangle vb;
113

114
        rsvg_handle_get_intrinsic_dimensions(rsvg, &has_l1, &l1, &has_l2, &l2, &has_vb, &vb);
115
        width = ceil(vb.width);
116
        height = ceil(vb.height);
117
     }
118
#else
119
   rsvg_handle_get_dimensions(rsvg, &dim);
120
   width = dim.width;
121
   height = dim.height;
122
#endif
123

124
   if ((width < 1) || (height < 1)) return 0;
125

126
   if (scale_down > 1)
127
     {
128
        width /= scale_down;
129
        height /= scale_down;
130
     }
131
   else if (dpi > 0.0)
132
     {
133
        width = (width * dpi) / 75;
134
        height = (height * dpi) / 75;
135
     }
136
   else if (size_w > 0 && size_h > 0)
137
     {
138
        int w, h;
139

140
        w = size_w;
141
        h = (size_w * height) / width;
142
        if (h > size_h)
143
          {
144
             h = size_h;
145
             w = (size_h * width) / height;
146
          }
147
        width = w;
148
        height = h;
149
     }
150
   if (width < 1) width = 1;
151
   if (height < 1) height = 1;
152

153
   return 1;
154
}
155

156
static int
157
read_svg_data(void)
158
{
159
   cairo_surface_t *surface;
160
   cairo_t *cr;
161

162
   shm_alloc(width * height * (sizeof(DATA32)));
163
   if (!shm_addr) return 0;
164

165
   memset(shm_addr, 0, width * height * sizeof (DATA32));
166
   surface = cairo_image_surface_create_for_data((unsigned char *)shm_addr,
167
                                                 CAIRO_FORMAT_ARGB32,
168
                                                 width, height,
169
                                                 width * sizeof(DATA32));;
170
   if (!surface) return 0;
171

172
   cr = cairo_create(surface);
173
   if (!cr) return 0;
174

175
   if ((dim.em > 0.0) && (dim.ex > 0.0))
176
     cairo_scale(cr, (double) width / dim.em, (double) height / dim.ex);
177
   else
178
     cairo_scale(cr, (double)1, (double)1);
179

180
#ifdef HAVE_SVG_2_51
181
   RsvgRectangle vp =
182
     {
183
        .x = 0,
184
        .y = 0,
185
        .width = width,
186
        .height = height,
187
     };
188
   rsvg_handle_render_document(rsvg, cr, &vp, NULL);
189
#else
190
   rsvg_handle_render_cairo(rsvg, cr);
191
#endif
192

193
   cairo_surface_destroy(surface);
194
   cairo_destroy(cr);
195

196
   return 1;
197
}
198

199
int
200
main(int argc, char **argv)
201
{
202
   char *file;
203
   int i;
204
   int head_only = 0;
205
   int scale_down = 0;
206
   double dpi = 0.0;
207
   int size_w = 0, size_h = 0;
208

209
   if (argc < 2) return -1;
210
   file = argv[1];
211

212
   for (i = 2; i < argc; ++i)
213
     {
214
        if (!strcmp(argv[i], "-head"))
215
          head_only = 1;
216
        else if (!strcmp(argv[i], "-key"))
217
          { // not used by svg loader
218
             i++;
219
             // const char *key = argv[i];
220
          }
221
        else if (!strcmp(argv[i], "-opt-scale-down-by"))
222
          {
223
             i++;
224
             scale_down = atoi(argv[i]);
225
          }
226
        else if (!strcmp(argv[i], "-opt-dpi"))
227
          {
228
             i++;
229
             dpi = ((double)atoi(argv[i])) / 1000.0;
230
          }
231
        else if (!strcmp(argv[i], "-opt-size"))
232
          {
233
             i++;
234
             size_w = atoi(argv[i]);
235
             i++;
236
             size_h = atoi(argv[i]);
237
          }
238
     }
239

240
   timeout_init(5);
241

242
   if (!_svg_init(file)) return -1;
243
   if (!read_svg_header(scale_down, dpi, size_w, size_h)) return -1;
244

245
   if (head_only != 0)
246
     {
247
        printf("size %d %d\n", width, height);
248
        printf("alpha 1\n");
249
        printf("done\n");
250
     }
251
   else
252
     {
253
        if (read_svg_data())
254
          {
255
             printf("size %d %d\n", width, height);
256
             printf("alpha 1\n");
257
#ifdef _WIN32
258
             if (shm_fd) printf("shmfile %s\n", shmfile);
259
#else
260
             if (shm_fd >= 0) printf("shmfile %s\n", shmfile);
261
#endif
262
             else
263
               {
264
                  printf("data\n");
265
                  if (fwrite(shm_addr, width * height * sizeof(DATA32), 1, stdout) != 1)
266
                    {
267
                       // nothing much to do, the receiver will simply ignore the
268
                       // data as it's too short
269
                       //D("fwrite failed (%d bytes): %m\n", width * height * sizeof(DATA32));
270
                    }
271
               }
272
             shm_free();
273
          }
274
     }
275
   _svg_shutdown();
276
   fflush(stdout);
277
   return 0;
278
}
279

280

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.