Fix:maptool:Another name for faroe islands
[navit-package] / navit / layout.c
1 /**
2  * Navit, a modular navigation system.
3  * Copyright (C) 2005-2009 Navit Team
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * version 2 as published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the
16  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA  02110-1301, USA.
18  */
19
20 #include <glib.h>
21 #include <string.h>
22 #include "item.h"
23 #include "attr.h"
24 #include "layout.h"
25 #include "coord.h"
26 #include "debug.h"
27
28
29 struct layout * layout_new(struct attr *parent, struct attr **attrs)
30 {
31         struct layout *l;
32         struct color def_color = {0xffff, 0xefef, 0xb7b7, 0xffff};
33         struct attr *name_attr,*color_attr,*order_delta_attr,*font_attr,*day_attr,*night_attr;
34
35         if (! (name_attr=attr_search(attrs, NULL, attr_name)))
36                 return NULL;
37         l = g_new0(struct layout, 1);
38         l->name = g_strdup(name_attr->u.str);
39         if ((font_attr=attr_search(attrs, NULL, attr_font))) {
40                 l->font = g_strdup(font_attr->u.str);
41         }
42         if ((day_attr=attr_search(attrs, NULL, attr_daylayout))) {
43                 l->dayname = g_strdup(day_attr->u.str);
44         }
45         if ((night_attr=attr_search(attrs, NULL, attr_nightlayout))) {
46                 l->nightname = g_strdup(night_attr->u.str);
47         }
48         if ((color_attr=attr_search(attrs, NULL, attr_color)))
49                 l->color = *color_attr->u.color;
50         else
51                 l->color = def_color;
52         if ((order_delta_attr=attr_search(attrs, NULL, attr_order_delta)))
53                 l->order_delta=order_delta_attr->u.num;
54         return l;
55 }
56
57 int
58 layout_add_attr(struct layout *layout, struct attr *attr)
59 {
60         switch (attr->type) {
61         case attr_cursor:
62                 layout->cursors = g_list_append(layout->cursors, attr->u.cursor);
63                 return 1;
64         case attr_layer:
65                 layout->layers = g_list_append(layout->layers, attr->u.layer);
66                 return 1;
67         default:
68                 return 0;
69         }
70 }
71
72 /**
73  * Searchs the layout for a cursor with the given name.
74  *
75  * @param layout The layout
76  * @param name The name
77  * @returns A pointer to cursor with the given name or the name default or NULL.
78  * @author Ralph Sennhauser (10/2009)
79 */
80 struct cursor *
81 layout_get_cursor(struct layout *this_, char *name)
82 {
83         GList *c;
84         struct cursor *d=NULL;
85
86         c=g_list_first(this_->cursors);
87         while (c) {
88                 if (! strcmp(((struct cursor *)c->data)->name, name))
89                         return c->data;
90                 if (! strcmp(((struct cursor *)c->data)->name, "default"))
91                         d=c->data;
92                 c=g_list_next(c);
93         }
94         return d;
95 }
96
97
98
99 struct cursor *
100 cursor_new(struct attr *parent, struct attr **attrs)
101 {
102         struct attr *w, *h, *name, *interval, *sequence_range;
103
104         w=attr_search(attrs, NULL, attr_w);
105         h=attr_search(attrs, NULL, attr_h);
106         if (! w || ! h)
107                 return NULL;
108
109         struct cursor *this=g_new0(struct cursor,1);
110         this->w=w->u.num;
111         this->h=h->u.num;
112         name=attr_search(attrs, NULL, attr_name);
113         if (name)
114                 this->name=g_strdup(name->u.str);
115         else
116                 this->name=g_strdup("default");
117         interval=attr_search(attrs, NULL, attr_interval);
118         if (interval)
119                 this->interval=interval->u.num;
120         sequence_range=attr_search(attrs, NULL, attr_sequence_range);
121         if (sequence_range) {
122                 struct range *r=g_new0(struct range,1);
123                 r->min=sequence_range->u.range.min;
124                 r->max=sequence_range->u.range.max;
125                 this->sequence_range=r;
126         }
127         else {
128                 this->sequence_range=NULL;
129         }
130         dbg(2,"ret=%p\n", this);
131         return this;
132 }
133
134 void
135 cursor_destroy(struct cursor *this_)
136 {
137         if (this_->sequence_range)
138                 g_free(this_->sequence_range);
139         if (this_->name) {
140                 g_free(this_->name);
141         }
142         g_free(this_);
143 }
144
145 int
146 cursor_add_attr(struct cursor *this_, struct attr *attr)
147 {
148         switch (attr->type) {
149         case attr_itemgra:
150                 this_->attrs=attr_generic_add_attr(this_->attrs, attr);
151                 return 1;
152         default:
153                 break;
154         }
155         return 0;
156 }
157
158
159
160 struct layer * layer_new(struct attr *parent, struct attr **attrs)
161 {
162         struct layer *l;
163
164         struct attr *name, *details;
165         l = g_new0(struct layer, 1);
166         name=attr_search(attrs, NULL, attr_name);
167         if (name)
168                 l->name = g_strdup(name->u.str);
169         details=attr_search(attrs, NULL, attr_details);
170         if (details)
171                 l->details = details->u.num;
172         return l;
173 }
174
175 int
176 layer_add_attr(struct layer *layer, struct attr *attr)
177 {
178         switch (attr->type) {
179         case attr_itemgra:
180                 layer->itemgras = g_list_append(layer->itemgras, attr->u.itemgra);
181                 return 1;
182         default:
183                 return 0;
184         }
185 }
186
187
188 struct itemgra * itemgra_new(struct attr *parent, struct attr **attrs)
189 {
190         struct itemgra *itm;
191         struct attr *order, *item_types, *speed_range, *angle_range, *sequence_range;
192         enum item_type *type;
193         struct range defrange;
194         
195         itm = g_new0(struct itemgra, 1);
196         order=attr_search(attrs, NULL, attr_order);
197         item_types=attr_search(attrs, NULL, attr_item_types);
198         speed_range=attr_search(attrs, NULL, attr_speed_range);
199         angle_range=attr_search(attrs, NULL, attr_angle_range);
200         sequence_range=attr_search(attrs, NULL, attr_sequence_range);
201         defrange.min=0;
202         defrange.max=32767;
203         if (order) 
204                 itm->order=order->u.range;
205         else 
206                 itm->order=defrange;
207         if (speed_range) 
208                 itm->speed_range=speed_range->u.range;
209         else 
210                 itm->speed_range=defrange;
211         if (angle_range) 
212                 itm->angle_range=angle_range->u.range;
213         else 
214                 itm->angle_range=defrange;
215         if (sequence_range) 
216                 itm->sequence_range=sequence_range->u.range;
217         else 
218                 itm->sequence_range=defrange;
219         if (item_types) {
220                 type=item_types->u.item_types;
221                 while (type && *type != type_none) {
222                         itm->type=g_list_append(itm->type, GINT_TO_POINTER(*type));
223                         type++;
224                 }
225         }
226         return itm;
227 }
228 int
229 itemgra_add_attr(struct itemgra *itemgra, struct attr *attr)
230 {
231         switch (attr->type) {
232         case attr_polygon:
233         case attr_polyline:
234         case attr_circle:
235         case attr_text:
236         case attr_icon:
237         case attr_image:
238         case attr_arrows:
239                 itemgra->elements = g_list_append(itemgra->elements, attr->u.element);
240                 return 1;
241         default:
242                 dbg(0,"unknown: %s\n", attr_to_name(attr->type));
243                 return 0;
244         }
245 }
246
247 static void
248 element_set_color(struct element *e, struct attr **attrs)
249 {
250         struct attr *color;
251         color=attr_search(attrs, NULL, attr_color);
252         if (color)
253                 e->color=*color->u.color;
254 }
255
256 static void
257 element_set_text_size(struct element *e, struct attr **attrs)
258 {
259         struct attr *text_size;
260         text_size=attr_search(attrs, NULL, attr_text_size);
261         if (text_size)
262                 e->text_size=text_size->u.num;
263 }
264
265 static void
266 element_set_polyline_width(struct element *e, struct attr **attrs)
267 {
268         struct attr *width;
269         width=attr_search(attrs, NULL, attr_width);
270         if (width)
271                 e->u.polyline.width=width->u.num;
272 }
273
274 static void
275 element_set_polyline_directed(struct element *e, struct attr **attrs)
276 {
277         struct attr *directed;
278         directed=attr_search(attrs, NULL, attr_directed);
279         if (directed)
280                 e->u.polyline.directed=directed->u.num;
281 }
282
283 static void
284 element_set_polyline_dash(struct element *e, struct attr **attrs)
285 {
286         struct attr *dash;
287         int i;
288
289         dash=attr_search(attrs, NULL, attr_dash);
290         if (dash) {
291                 for (i=0; i<4; i++) {
292                         if (!dash->u.dash[i])
293                                 break;
294                         e->u.polyline.dash_table[i] = dash->u.dash[i];
295                 }
296                 e->u.polyline.dash_num=i;
297         }
298 }
299
300 static void
301 element_set_polyline_offset(struct element *e, struct attr **attrs)
302 {
303         struct attr *offset;
304         offset=attr_search(attrs, NULL, attr_offset);
305         if (offset)
306                 e->u.polyline.offset=offset->u.num;
307 }
308
309 static void
310 element_set_circle_width(struct element *e, struct attr **attrs)
311 {
312         struct attr *width;
313         width=attr_search(attrs, NULL, attr_width);
314         if (width)
315                 e->u.circle.width=width->u.num;
316 }
317
318 static void
319 element_set_circle_radius(struct element *e, struct attr **attrs)
320 {
321         struct attr *radius;
322         radius=attr_search(attrs, NULL, attr_radius);
323         if (radius)
324                 e->u.circle.radius=radius->u.num;
325 }
326
327 struct polygon *
328 polygon_new(struct attr *parent, struct attr **attrs)
329 {
330         struct element *e;
331         e = g_new0(struct element, 1);
332         e->type=element_polygon;
333         element_set_color(e, attrs);
334
335         return (struct polygon *)e;
336 }
337
338 struct polyline *
339 polyline_new(struct attr *parent, struct attr **attrs)
340 {
341         struct element *e;
342         
343         e = g_new0(struct element, 1);
344         e->type=element_polyline;
345         element_set_color(e, attrs);
346         element_set_polyline_width(e, attrs);
347         element_set_polyline_directed(e, attrs);
348         element_set_polyline_dash(e, attrs);
349         element_set_polyline_offset(e, attrs);
350         return (struct polyline *)e;
351 }
352
353 struct circle *
354 circle_new(struct attr *parent, struct attr **attrs)
355 {
356         struct element *e;
357
358         e = g_new0(struct element, 1);
359         e->type=element_circle;
360         element_set_color(e, attrs);
361         element_set_text_size(e, attrs);
362         element_set_circle_width(e, attrs);
363         element_set_circle_radius(e, attrs);
364
365         return (struct circle *)e;
366 }
367
368 struct text *
369 text_new(struct attr *parent, struct attr **attrs)
370 {
371         struct element *e;
372         
373         e = g_new0(struct element, 1);
374         e->type=element_text;
375         element_set_text_size(e, attrs);
376
377         return (struct text *)e;
378 }
379
380 struct icon *
381 icon_new(struct attr *parent, struct attr **attrs)
382 {
383         struct element *e;
384         struct attr *src,*w,*h,*rotation;
385         src=attr_search(attrs, NULL, attr_src);
386         if (! src)
387                 return NULL;
388
389         e = g_malloc0(sizeof(*e)+strlen(src->u.str)+1);
390         e->type=element_icon;
391         e->u.icon.src=(char *)(e+1);
392         if ((w=attr_search(attrs, NULL, attr_w)))
393                 e->u.icon.width=w->u.num;
394         else
395                 e->u.icon.width=-1;
396         if ((h=attr_search(attrs, NULL, attr_h)))
397                 e->u.icon.height=h->u.num;
398         else
399                 e->u.icon.height=-1;
400         if ((rotation=attr_search(attrs, NULL, attr_rotation)))
401                 e->u.icon.rotation=rotation->u.num;
402         strcpy(e->u.icon.src,src->u.str);
403
404         return (struct icon *)e;        
405 }
406
407 struct image *
408 image_new(struct attr *parent, struct attr **attrs)
409 {
410         struct element *e;
411
412         e = g_malloc0(sizeof(*e));
413         e->type=element_image;
414
415         return (struct image *)e;       
416 }
417
418 struct arrows *
419 arrows_new(struct attr *parent, struct attr **attrs)
420 {
421         struct element *e;
422         e = g_malloc0(sizeof(*e));
423         e->type=element_arrows;
424         element_set_color(e, attrs);
425         return (struct arrows *)e;      
426 }
427
428 int
429 element_add_attr(struct element *e, struct attr *attr)
430 {
431         switch (attr->type) {
432         case attr_coord:
433                 e->coord=g_realloc(e->coord,(e->coord_count+1)*sizeof(struct coord));
434                 e->coord[e->coord_count++]=*attr->u.coord;
435                 return 1;
436         default:
437                 return 0;
438         }
439 }