Loading angle and flip options.
[tbo.git] / src / comic-load.c
1 #include <glib.h>
2 #include <glib/gi18n.h>
3 #include <gtk/gtk.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include "comic-load.h"
8 #include "tbo-types.h"
9 #include "comic.h"
10 #include "page.h"
11 #include "frame.h"
12 #include "tbo-object.h"
13 #include "svgimage.h"
14 #include "textobj.h"
15 #include "piximage.h"
16 #include "tbo-utils.h"
17
18 char *TITLE;
19
20 Comic *COMIC = NULL;
21 Page *CURRENT_PAGE;
22 Frame *CURRENT_FRAME;
23 TextObj *CURRENT_TEXT = NULL;
24
25 struct attr {
26     char *name;
27     char *format;
28     void *pointer;
29 };
30
31 void
32 parse_attrs (struct attr attrs[],
33              int attrs_size,
34              const gchar **attribute_names,
35              const gchar **attribute_values)
36 {
37     int i;
38     const gchar **name_cursor = attribute_names;
39     const gchar **value_cursor = attribute_values;
40
41     while (*name_cursor) {
42         for (i=0; i<attrs_size; i++)
43         {
44             if (strcmp (*name_cursor, attrs[i].name) == 0)
45             {
46                 if (strcmp (attrs[i].format, "%s") == 0)
47                 {
48                     sprintf(attrs[i].pointer, "%s", *value_cursor);
49                 }
50                 else
51                     sscanf (*value_cursor, attrs[i].format, attrs[i].pointer);
52             }
53         }
54         name_cursor++;
55         value_cursor++;
56     }
57 }
58
59 void
60 create_tbo_comic (const gchar **attribute_names, const gchar **attribute_values)
61 {
62     int width = 0;
63     int height = 0;
64
65     struct attr attrs[] = {
66         {"width", "%d", &width},
67         {"height", "%d", &height},
68     };
69
70     parse_attrs (attrs, G_N_ELEMENTS (attrs), attribute_names, attribute_values);
71
72     COMIC = tbo_comic_new (TITLE, width, height);
73     tbo_comic_del_page (COMIC, 0);
74 }
75
76 void
77 create_tbo_frame (const gchar **attribute_names, const gchar **attribute_values)
78 {
79     int x=0, y=0;
80     int width=0, height=0;
81     int border=1;
82     float r=0.0, g=0.0, b=0.0;
83
84     struct attr attrs[] = {
85         {"x", "%d", &x},
86         {"y", "%d", &y},
87         {"width", "%d", &width},
88         {"height", "%d", &height},
89         {"border", "%d", &border},
90         {"r", "%f", &r},
91         {"g", "%f", &g},
92         {"b", "%f", &b},
93     };
94
95     parse_attrs (attrs, G_N_ELEMENTS (attrs), attribute_names, attribute_values);
96
97     CURRENT_FRAME = tbo_page_new_frame (CURRENT_PAGE, x, y, width, height);
98     CURRENT_FRAME->border = border;
99     CURRENT_FRAME->color->r = r;
100     CURRENT_FRAME->color->g = g;
101     CURRENT_FRAME->color->b = b;
102 }
103
104 void
105 create_tbo_piximage (const gchar **attribute_names, const gchar **attribute_values)
106 {
107     PIXImage *pix;
108     int x=0, y=0;
109     int width=0, height=0;
110     float angle=0.0;
111     int flipv=0, fliph=0;
112     char path[255];
113
114     struct attr attrs[] = {
115         {"x", "%d", &x},
116         {"y", "%d", &y},
117         {"width", "%d", &width},
118         {"height", "%d", &height},
119         {"flipv", "%d", &flipv},
120         {"fliph", "%d", &fliph},
121         {"angle", "%f", &angle},
122         {"path", "%s", path},
123     };
124
125     parse_attrs (attrs, G_N_ELEMENTS (attrs), attribute_names, attribute_values);
126
127     pix = tbo_piximage_new_width_params (x, y, width, height, path);
128     pix->angle = angle;
129     pix->flipv = flipv;
130     pix->fliph = fliph;
131     tbo_frame_add_obj (CURRENT_FRAME, pix);
132 }
133
134 void
135 create_tbo_svgimage (const gchar **attribute_names, const gchar **attribute_values)
136 {
137     SVGImage *svg;
138     int x=0, y=0;
139     int width=0, height=0;
140     float angle=0.0;
141     int flipv=0, fliph=0;
142     char path[255];
143
144     struct attr attrs[] = {
145         {"x", "%d", &x},
146         {"y", "%d", &y},
147         {"width", "%d", &width},
148         {"height", "%d", &height},
149         {"flipv", "%d", &flipv},
150         {"fliph", "%d", &fliph},
151         {"angle", "%f", &angle},
152         {"path", "%s", path},
153     };
154
155     parse_attrs (attrs, G_N_ELEMENTS (attrs), attribute_names, attribute_values);
156
157     svg = tbo_svgimage_new_width_params (x, y, width, height, path);
158     svg->angle = angle;
159     svg->flipv = flipv;
160     svg->fliph = fliph;
161     tbo_frame_add_obj (CURRENT_FRAME, svg);
162 }
163
164 void
165 create_tbo_text (const gchar **attribute_names, const gchar **attribute_values)
166 {
167     TextObj *textobj;
168     int x=0, y=0;
169     int width=0, height=0;
170     float angle=0.0;
171     int flipv=0, fliph=0;
172     char font[255];
173     float r=0.0, g=0.0, b=0.0;
174
175     struct attr attrs[] = {
176         {"x", "%d", &x},
177         {"y", "%d", &y},
178         {"width", "%d", &width},
179         {"height", "%d", &height},
180         {"flipv", "%d", &flipv},
181         {"fliph", "%d", &fliph},
182         {"angle", "%f", &angle},
183         {"font", "%s", font},
184         {"r", "%f", &r},
185         {"g", "%f", &g},
186         {"b", "%f", &b},
187     };
188
189     parse_attrs (attrs, G_N_ELEMENTS (attrs), attribute_names, attribute_values);
190     textobj = tbo_text_new_width_params (x, y, width, height, "text", font, r, g, b);
191     textobj->angle = angle;
192     textobj->flipv = flipv;
193     textobj->fliph = fliph;
194     CURRENT_TEXT = textobj;
195     tbo_frame_add_obj (CURRENT_FRAME, textobj);
196
197 }
198
199 /* The handler functions. */
200
201 void
202 start_element (GMarkupParseContext *context,
203         const gchar         *element_name,
204         const gchar        **attribute_names,
205         const gchar        **attribute_values,
206         gpointer             user_data,
207         GError             **error) {
208
209     if (strcmp (element_name, "tbo") == 0)
210     {
211         create_tbo_comic (attribute_names, attribute_values);
212     }
213     else if (strcmp (element_name, "page") == 0)
214     {
215         CURRENT_PAGE = tbo_page_new (COMIC);
216         COMIC->pages = g_list_append (COMIC->pages, CURRENT_PAGE);
217     }
218     else if (strcmp (element_name, "frame") == 0)
219     {
220         create_tbo_frame (attribute_names, attribute_values);
221     }
222     else if (strcmp (element_name, "svgimage") == 0)
223     {
224         create_tbo_svgimage (attribute_names, attribute_values);
225     }
226     else if (strcmp (element_name, "piximage") == 0)
227     {
228         create_tbo_piximage (attribute_names, attribute_values);
229     }
230     else if (strcmp (element_name, "text") == 0)
231     {
232         create_tbo_text (attribute_names, attribute_values);
233     }
234 }
235
236 void
237 text (GMarkupParseContext *context,
238         const gchar       *text,
239         gsize              text_len,
240         gpointer           user_data,
241         GError            **error)
242 {
243     if (CURRENT_TEXT)
244     {
245         char *text2 = g_strndup (text, text_len);
246         tbo_text_set_text (CURRENT_TEXT, g_strstrip (text2));
247         g_free (text2);
248     }
249 }
250
251 void
252 end_element (GMarkupParseContext *context,
253         const gchar              *element_name,
254         gpointer                 user_data,
255         GError                   **error)
256 {
257     if (strcmp (element_name, "tbo") == 0)
258     {
259         g_free (TITLE);
260     }
261     else if (strcmp (element_name, "text") == 0)
262     {
263         CURRENT_TEXT = NULL;
264     }
265 }
266
267 static GMarkupParser parser = {
268     start_element,
269     end_element,
270     text,
271     NULL,
272     NULL
273 };
274
275 Comic *
276 tbo_comic_load (char *filename)
277 {
278     char *text;
279     gsize length;
280     GMarkupParseContext *context = g_markup_parse_context_new (
281             &parser,
282             0,
283             NULL,
284             NULL);
285
286     char base_name[255];
287     get_base_name (filename, base_name, 255);
288     TITLE = g_strdup(base_name);
289
290     if (g_file_get_contents (filename, &text, &length, NULL) == FALSE) {
291         GtkWidget *dialog = gtk_message_dialog_new (NULL,
292                 GTK_DIALOG_MODAL,
293                 GTK_MESSAGE_ERROR,
294                 GTK_BUTTONS_CLOSE,
295                 _("Couldn't load file"));
296         return NULL;
297     }
298
299     if (g_markup_parse_context_parse (context, text, length, NULL) == FALSE) {
300         GtkWidget *dialog = gtk_message_dialog_new (NULL,
301                 GTK_DIALOG_MODAL,
302                 GTK_MESSAGE_ERROR,
303                 GTK_BUTTONS_CLOSE,
304                 _("Couldn't parse file"));
305         return NULL;
306     }
307
308     g_free(text);
309     g_markup_parse_context_free (context);
310     return COMIC;
311 }