Add:Core:Support for FRA FRA NLS Setting
[navit-package] / navit / layout.c
index e4f5571..332a9f5 100644 (file)
@@ -1,6 +1,6 @@
 /**
  * Navit, a modular navigation system.
- * Copyright (C) 2005-2008 Navit Team
+ * Copyright (C) 2005-2009 Navit Team
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
 #include <glib.h>
 #include <string.h>
 #include "item.h"
+#include "attr.h"
 #include "layout.h"
+#include "coord.h"
+#include "debug.h"
+
 
 struct layout * layout_new(struct attr *parent, struct attr **attrs)
 {
        struct layout *l;
        struct color def_color = {0xffff, 0xefef, 0xb7b7, 0xffff};
-       struct attr *name_attr,*color_attr,*order_delta_attr,*font_attr;
+       struct attr *name_attr,*color_attr,*order_delta_attr,*font_attr,*day_attr,*night_attr;
 
        if (! (name_attr=attr_search(attrs, NULL, attr_name)))
                return NULL;
@@ -35,6 +39,12 @@ struct layout * layout_new(struct attr *parent, struct attr **attrs)
        if ((font_attr=attr_search(attrs, NULL, attr_font))) {
                l->font = g_strdup(font_attr->u.str);
        }
+       if ((day_attr=attr_search(attrs, NULL, attr_daylayout))) {
+               l->dayname = g_strdup(day_attr->u.str);
+       }
+       if ((night_attr=attr_search(attrs, NULL, attr_nightlayout))) {
+               l->nightname = g_strdup(night_attr->u.str);
+       }
        if ((color_attr=attr_search(attrs, NULL, attr_color)))
                l->color = *color_attr->u.color;
        else
@@ -44,127 +54,386 @@ struct layout * layout_new(struct attr *parent, struct attr **attrs)
        return l;
 }
 
+int
+layout_add_attr(struct layout *layout, struct attr *attr)
+{
+       switch (attr->type) {
+       case attr_cursor:
+               layout->cursors = g_list_append(layout->cursors, attr->u.cursor);
+               return 1;
+       case attr_layer:
+               layout->layers = g_list_append(layout->layers, attr->u.layer);
+               return 1;
+       default:
+               return 0;
+       }
+}
 
-struct layer * layer_new(const char *name, int details)
+/**
+ * Searchs the layout for a cursor with the given name.
+ *
+ * @param layout The layout
+ * @param name The name
+ * @returns A pointer to cursor with the given name or the name default or NULL.
+ * @author Ralph Sennhauser (10/2009)
+*/
+struct cursor *
+layout_get_cursor(struct layout *this_, char *name)
+{
+       GList *c;
+       struct cursor *d=NULL;
+
+       c=g_list_first(this_->cursors);
+       while (c) {
+               if (! strcmp(((struct cursor *)c->data)->name, name))
+                       return c->data;
+               if (! strcmp(((struct cursor *)c->data)->name, "default"))
+                       d=c->data;
+               c=g_list_next(c);
+       }
+       return d;
+}
+
+
+
+struct cursor *
+cursor_new(struct attr *parent, struct attr **attrs)
+{
+       struct attr *w, *h, *name, *interval, *sequence_range;
+
+       w=attr_search(attrs, NULL, attr_w);
+       h=attr_search(attrs, NULL, attr_h);
+       if (! w || ! h)
+               return NULL;
+
+       struct cursor *this=g_new0(struct cursor,1);
+       this->w=w->u.num;
+       this->h=h->u.num;
+       name=attr_search(attrs, NULL, attr_name);
+       if (name)
+               this->name=g_strdup(name->u.str);
+       else
+               this->name=g_strdup("default");
+       interval=attr_search(attrs, NULL, attr_interval);
+       if (interval)
+               this->interval=interval->u.num;
+       sequence_range=attr_search(attrs, NULL, attr_sequence_range);
+       if (sequence_range) {
+               struct range *r=g_new0(struct range,1);
+               r->min=sequence_range->u.range.min;
+               r->max=sequence_range->u.range.max;
+               this->sequence_range=r;
+       }
+       else {
+               this->sequence_range=NULL;
+       }
+       dbg(2,"ret=%p\n", this);
+       return this;
+}
+
+void
+cursor_destroy(struct cursor *this_)
+{
+       if (this_->sequence_range)
+               g_free(this_->sequence_range);
+       if (this_->name) {
+               g_free(this_->name);
+       }
+       g_free(this_);
+}
+
+int
+cursor_add_attr(struct cursor *this_, struct attr *attr)
+{
+       switch (attr->type) {
+       case attr_itemgra:
+               this_->attrs=attr_generic_add_attr(this_->attrs, attr);
+               return 1;
+       default:
+               break;
+       }
+       return 0;
+}
+
+
+
+struct layer * layer_new(struct attr *parent, struct attr **attrs)
 {
        struct layer *l;
 
+       struct attr *name, *details;
        l = g_new0(struct layer, 1);
-       l->name = g_strdup(name);
-       l->details = details;
+       name=attr_search(attrs, NULL, attr_name);
+       if (name)
+               l->name = g_strdup(name->u.str);
+       details=attr_search(attrs, NULL, attr_details);
+       if (details)
+               l->details = details->u.num;
        return l;
 }
 
-void layout_add_layer(struct layout *layout, struct layer *layer)
+int
+layer_add_attr(struct layer *layer, struct attr *attr)
 {
-       layout->layers = g_list_append(layout->layers, layer);
+       switch (attr->type) {
+       case attr_itemgra:
+               layer->itemgras = g_list_append(layer->itemgras, attr->u.itemgra);
+               return 1;
+       default:
+               return 0;
+       }
 }
 
-struct itemtype * itemtype_new(int order_min, int order_max)
-{
-       struct itemtype *itm;
 
-       itm = g_new0(struct itemtype, 1);
-       itm->order_min=order_min;
-       itm->order_max=order_max;
+struct itemgra * itemgra_new(struct attr *parent, struct attr **attrs)
+{
+       struct itemgra *itm;
+       struct attr *order, *item_types, *speed_range, *angle_range, *sequence_range;
+       enum item_type *type;
+       struct range defrange;
+       
+       itm = g_new0(struct itemgra, 1);
+       order=attr_search(attrs, NULL, attr_order);
+       item_types=attr_search(attrs, NULL, attr_item_types);
+       speed_range=attr_search(attrs, NULL, attr_speed_range);
+       angle_range=attr_search(attrs, NULL, attr_angle_range);
+       sequence_range=attr_search(attrs, NULL, attr_sequence_range);
+       defrange.min=0;
+       defrange.max=32767;
+       if (order) 
+               itm->order=order->u.range;
+       else 
+               itm->order=defrange;
+       if (speed_range) 
+               itm->speed_range=speed_range->u.range;
+       else 
+               itm->speed_range=defrange;
+       if (angle_range) 
+               itm->angle_range=angle_range->u.range;
+       else 
+               itm->angle_range=defrange;
+       if (sequence_range) 
+               itm->sequence_range=sequence_range->u.range;
+       else 
+               itm->sequence_range=defrange;
+       if (item_types) {
+               type=item_types->u.item_types;
+               while (type && *type != type_none) {
+                       itm->type=g_list_append(itm->type, GINT_TO_POINTER(*type));
+                       type++;
+               }
+       }
        return itm;
 }
+int
+itemgra_add_attr(struct itemgra *itemgra, struct attr *attr)
+{
+       switch (attr->type) {
+       case attr_polygon:
+       case attr_polyline:
+       case attr_circle:
+       case attr_text:
+       case attr_icon:
+       case attr_image:
+       case attr_arrows:
+               itemgra->elements = g_list_append(itemgra->elements, attr->u.element);
+               return 1;
+       default:
+               dbg(0,"unknown: %s\n", attr_to_name(attr->type));
+               return 0;
+       }
+}
+
+static void
+element_set_color(struct element *e, struct attr **attrs)
+{
+       struct attr *color;
+       color=attr_search(attrs, NULL, attr_color);
+       if (color)
+               e->color=*color->u.color;
+}
+
+static void
+element_set_text_size(struct element *e, struct attr **attrs)
+{
+       struct attr *text_size;
+       text_size=attr_search(attrs, NULL, attr_text_size);
+       if (text_size)
+               e->text_size=text_size->u.num;
+}
+
+static void
+element_set_polyline_width(struct element *e, struct attr **attrs)
+{
+       struct attr *width;
+       width=attr_search(attrs, NULL, attr_width);
+       if (width)
+               e->u.polyline.width=width->u.num;
+}
 
-void itemtype_add_type(struct itemtype *this, enum item_type type)
+static void
+element_set_polyline_directed(struct element *e, struct attr **attrs)
 {
-       this->type = g_list_append(this->type, GINT_TO_POINTER(type));
+       struct attr *directed;
+       directed=attr_search(attrs, NULL, attr_directed);
+       if (directed)
+               e->u.polyline.directed=directed->u.num;
 }
 
+static void
+element_set_polyline_dash(struct element *e, struct attr **attrs)
+{
+       struct attr *dash;
+       int i;
+
+       dash=attr_search(attrs, NULL, attr_dash);
+       if (dash) {
+               for (i=0; i<4; i++) {
+                       if (!dash->u.dash[i])
+                               break;
+                       e->u.polyline.dash_table[i] = dash->u.dash[i];
+               }
+               e->u.polyline.dash_num=i;
+       }
+}
 
-void layer_add_itemtype(struct layer *layer, struct itemtype * itemtype)
+static void
+element_set_polyline_offset(struct element *e, struct attr **attrs)
 {
-       layer->itemtypes = g_list_append(layer->itemtypes, itemtype);
+       struct attr *offset;
+       offset=attr_search(attrs, NULL, attr_offset);
+       if (offset)
+               e->u.polyline.offset=offset->u.num;
+}
 
+static void
+element_set_circle_width(struct element *e, struct attr **attrs)
+{
+       struct attr *width;
+       width=attr_search(attrs, NULL, attr_width);
+       if (width)
+               e->u.circle.width=width->u.num;
 }
 
-void itemtype_add_element(struct itemtype *itemtype, struct element *element)
+static void
+element_set_circle_radius(struct element *e, struct attr **attrs)
 {
-       itemtype->elements = g_list_append(itemtype->elements, element);
+       struct attr *radius;
+       radius=attr_search(attrs, NULL, attr_radius);
+       if (radius)
+               e->u.circle.radius=radius->u.num;
 }
 
-struct element *
-polygon_new(struct color *color)
+struct polygon *
+polygon_new(struct attr *parent, struct attr **attrs)
 {
        struct element *e;
        e = g_new0(struct element, 1);
        e->type=element_polygon;
-       e->color=*color;
+       element_set_color(e, attrs);
 
-       return e;
+       return (struct polygon *)e;
 }
 
-struct element *
-polyline_new(struct color *color, int width, int directed,
-             int *dash_table, int dash_num)
+struct polyline *
+polyline_new(struct attr *parent, struct attr **attrs)
 {
        struct element *e;
-       int i;
        
        e = g_new0(struct element, 1);
        e->type=element_polyline;
-       e->color=*color;
-       e->u.polyline.width=width;
-       e->u.polyline.directed=directed;
-       e->u.polyline.dash_num=dash_num;
-       for (i=0; i<dash_num; i++)
-               e->u.polyline.dash_table[i] = dash_table[i];
-
-       return e;
+       element_set_color(e, attrs);
+       element_set_polyline_width(e, attrs);
+       element_set_polyline_directed(e, attrs);
+       element_set_polyline_dash(e, attrs);
+       element_set_polyline_offset(e, attrs);
+       return (struct polyline *)e;
 }
 
-struct element *
-circle_new(struct color *color, int radius, int width, int label_size)
+struct circle *
+circle_new(struct attr *parent, struct attr **attrs)
 {
        struct element *e;
-       
+
        e = g_new0(struct element, 1);
        e->type=element_circle;
-       e->color=*color;
-       e->label_size=label_size;
-       e->u.circle.width=width;
-       e->u.circle.radius=radius;
+       element_set_color(e, attrs);
+       element_set_text_size(e, attrs);
+       element_set_circle_width(e, attrs);
+       element_set_circle_radius(e, attrs);
 
-       return e;
+       return (struct circle *)e;
 }
 
-struct element *
-label_new(int label_size)
+struct text *
+text_new(struct attr *parent, struct attr **attrs)
 {
        struct element *e;
        
        e = g_new0(struct element, 1);
-       e->type=element_label;
-       e->label_size=label_size;
+       e->type=element_text;
+       element_set_text_size(e, attrs);
 
-       return e;
+       return (struct text *)e;
 }
 
-struct element *
-icon_new(const char *src)
+struct icon *
+icon_new(struct attr *parent, struct attr **attrs)
 {
        struct element *e;
+       struct attr *src,*w,*h,*rotation;
+       src=attr_search(attrs, NULL, attr_src);
+       if (! src)
+               return NULL;
 
-       e = g_malloc0(sizeof(*e)+strlen(src)+1);
+       e = g_malloc0(sizeof(*e)+strlen(src->u.str)+1);
        e->type=element_icon;
        e->u.icon.src=(char *)(e+1);
-       strcpy(e->u.icon.src,src);
+       if ((w=attr_search(attrs, NULL, attr_w)))
+               e->u.icon.width=w->u.num;
+       else
+               e->u.icon.width=-1;
+       if ((h=attr_search(attrs, NULL, attr_h)))
+               e->u.icon.height=h->u.num;
+       else
+               e->u.icon.height=-1;
+       if ((rotation=attr_search(attrs, NULL, attr_rotation)))
+               e->u.icon.rotation=rotation->u.num;
+       strcpy(e->u.icon.src,src->u.str);
 
-       return e;       
+       return (struct icon *)e;        
 }
 
-struct element *
-image_new(void)
+struct image *
+image_new(struct attr *parent, struct attr **attrs)
 {
        struct element *e;
 
        e = g_malloc0(sizeof(*e));
        e->type=element_image;
 
-       return e;       
+       return (struct image *)e;       
 }
 
+struct arrows *
+arrows_new(struct attr *parent, struct attr **attrs)
+{
+       struct element *e;
+       e = g_malloc0(sizeof(*e));
+       e->type=element_arrows;
+       element_set_color(e, attrs);
+       return (struct arrows *)e;      
+}
+
+int
+element_add_attr(struct element *e, struct attr *attr)
+{
+       switch (attr->type) {
+       case attr_coord:
+               e->coord=g_realloc(e->coord,(e->coord_count+1)*sizeof(struct coord));
+               e->coord[e->coord_count++]=*attr->u.coord;
+               return 1;
+       default:
+               return 0;
+       }
+}