Now it's possible to add png images :D
[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     tbo_frame_add_obj (CURRENT_FRAME, pix);
129 }
130
131 void
132 create_tbo_svgimage (const gchar **attribute_names, const gchar **attribute_values)
133 {
134     SVGImage *svg;
135     int x=0, y=0;
136     int width=0, height=0;
137     float angle=0.0;
138     int flipv=0, fliph=0;
139     char path[255];
140
141     struct attr attrs[] = {
142         {"x", "%d", &x},
143         {"y", "%d", &y},
144         {"width", "%d", &width},
145         {"height", "%d", &height},
146         {"flipv", "%d", &flipv},
147         {"fliph", "%d", &fliph},
148         {"angle", "%f", &angle},
149         {"path", "%s", path},
150     };
151
152     parse_attrs (attrs, G_N_ELEMENTS (attrs), attribute_names, attribute_values);
153
154     svg = tbo_svgimage_new_width_params (x, y, width, height, path);
155     tbo_frame_add_obj (CURRENT_FRAME, svg);
156 }
157
158 void
159 create_tbo_text (const gchar **attribute_names, const gchar **attribute_values)
160 {
161     TextObj *textobj;
162     int x=0, y=0;
163     int width=0, height=0;
164     float angle=0.0;
165     int flipv=0, fliph=0;
166     char font[255];
167     float r=0.0, g=0.0, b=0.0;
168
169     struct attr attrs[] = {
170         {"x", "%d", &x},
171         {"y", "%d", &y},
172         {"width", "%d", &width},
173         {"height", "%d", &height},
174         {"flipv", "%d", &flipv},
175         {"fliph", "%d", &fliph},
176         {"angle", "%f", &angle},
177         {"font", "%s", font},
178         {"r", "%f", &r},
179         {"g", "%f", &g},
180         {"b", "%f", &b},
181     };
182
183     parse_attrs (attrs, G_N_ELEMENTS (attrs), attribute_names, attribute_values);
184     textobj = tbo_text_new_width_params (x, y, width, height, "text", font, r, g, b);
185     textobj->angle = angle;
186     CURRENT_TEXT = textobj;
187     tbo_frame_add_obj (CURRENT_FRAME, textobj);
188
189 }
190
191 /* The handler functions. */
192
193 void
194 start_element (GMarkupParseContext *context,
195         const gchar         *element_name,
196         const gchar        **attribute_names,
197         const gchar        **attribute_values,
198         gpointer             user_data,
199         GError             **error) {
200
201     if (strcmp (element_name, "tbo") == 0)
202     {
203         create_tbo_comic (attribute_names, attribute_values);
204     }
205     else if (strcmp (element_name, "page") == 0)
206     {
207         CURRENT_PAGE = tbo_page_new (COMIC);
208         COMIC->pages = g_list_append (COMIC->pages, CURRENT_PAGE);
209     }
210     else if (strcmp (element_name, "frame") == 0)
211     {
212         create_tbo_frame (attribute_names, attribute_values);
213     }
214     else if (strcmp (element_name, "svgimage") == 0)
215     {
216         create_tbo_svgimage (attribute_names, attribute_values);
217     }
218     else if (strcmp (element_name, "piximage") == 0)
219     {
220         create_tbo_piximage (attribute_names, attribute_values);
221     }
222     else if (strcmp (element_name, "text") == 0)
223     {
224         create_tbo_text (attribute_names, attribute_values);
225     }
226 }
227
228 void
229 text (GMarkupParseContext *context,
230         const gchar       *text,
231         gsize              text_len,
232         gpointer           user_data,
233         GError            **error)
234 {
235     if (CURRENT_TEXT)
236     {
237         char *text2 = g_strndup (text, text_len);
238         tbo_text_set_text (CURRENT_TEXT, g_strstrip (text2));
239         g_free (text2);
240     }
241 }
242
243 void
244 end_element (GMarkupParseContext *context,
245         const gchar              *element_name,
246         gpointer                 user_data,
247         GError                   **error)
248 {
249     if (strcmp (element_name, "tbo") == 0)
250     {
251         g_free (TITLE);
252     }
253     else if (strcmp (element_name, "text") == 0)
254     {
255         CURRENT_TEXT = NULL;
256     }
257 }
258
259 static GMarkupParser parser = {
260     start_element,
261     end_element,
262     text,
263     NULL,
264     NULL
265 };
266
267 Comic *
268 tbo_comic_load (char *filename)
269 {
270     char *text;
271     gsize length;
272     GMarkupParseContext *context = g_markup_parse_context_new (
273             &parser,
274             0,
275             NULL,
276             NULL);
277
278     char base_name[255];
279     get_base_name (filename, base_name, 255);
280     TITLE = g_strdup(base_name);
281
282     if (g_file_get_contents (filename, &text, &length, NULL) == FALSE) {
283         GtkWidget *dialog = gtk_message_dialog_new (NULL,
284                 GTK_DIALOG_MODAL,
285                 GTK_MESSAGE_ERROR,
286                 GTK_BUTTONS_CLOSE,
287                 _("Couldn't load file"));
288         return NULL;
289     }
290
291     if (g_markup_parse_context_parse (context, text, length, NULL) == FALSE) {
292         GtkWidget *dialog = gtk_message_dialog_new (NULL,
293                 GTK_DIALOG_MODAL,
294                 GTK_MESSAGE_ERROR,
295                 GTK_BUTTONS_CLOSE,
296                 _("Couldn't parse file"));
297         return NULL;
298     }
299
300     g_free(text);
301     g_markup_parse_context_free (context);
302     return COMIC;
303 }