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