]> mj.ucw.cz Git - leo.git/blob - sym-point.c
Symbols: Cloning, so far only for sym_line
[leo.git] / sym-point.c
1 /*
2  *      Hic Est Leo -- Point and Icon Symbolizer
3  *
4  *      (c) 2014 Martin Mares <mj@ucw.cz>
5  */
6
7 #include "leo.h"
8
9 #include <stdio.h>
10
11 #include "osm.h"
12 #include "sym.h"
13 #include "svg.h"
14
15 static void sym_point_draw(struct symbol *sym, struct svg *svg)
16 {
17   struct sym_point *p = (struct sym_point *) sym;
18   struct osm_object *o = sym->o;
19   struct osm_node *n = (struct osm_node *) o;
20
21   if (o->type != OSM_TYPE_NODE)
22     {
23       msg(L_ERROR, "Point symbolizer works only on nodes. It's a bug, isn't it?");
24       return;
25     }
26
27   switch (p->shape)
28     {
29     case VALUE_CIRCLE:
30       svg_push_element(svg, "circle");
31       svg_set_attr_dimen(svg, "cx", n->x);
32       svg_set_attr_dimen(svg, "cy", n->y);
33       svg_set_attr_dimen(svg, "r", p->size / 2);
34       break;
35     // FIXME: Other shapes
36     default:
37       osm_obj_warn(o, "Unknown symbol-shape %s", osm_val_decode(p->shape));
38       return;
39     }
40
41   // FIMXE: Use COLOR_NONE instead of do_stroke and do_fill
42   if (p->do_stroke)
43     {
44       svg_set_attr_color(svg, "stroke", p->stroke_color);
45       svg_set_attr_dimen(svg, "stroke-width", p->stroke_width);
46       if (p->stroke_opacity != 1)
47         svg_set_attr_float(svg, "stroke-opacity", p->stroke_opacity);
48     }
49   if (p->do_fill)
50     {
51       svg_set_attr_color(svg, "fill", p->fill_color);
52       if (p->fill_opacity != 1)
53         svg_set_attr_float(svg, "fill-opacity", p->fill_opacity);
54     }
55   else
56     svg_set_attr(svg, "fill", "none");
57   svg_pop(svg);
58 }
59
60 static void sym_point_gen(struct osm_object *o, struct style_info *si, struct svg *svg UNUSED)
61 {
62   if (o->type != OSM_TYPE_NODE)
63     return;
64
65   osm_val_t shape = style_get_ident(si, PROP_SYMBOL_SHAPE);
66   if (!shape)
67     return;
68
69   struct sym_point *sp = sym_point_new(o);
70   sp->shape = shape;
71
72   sp->size = 1;
73   style_get_number(si, PROP_SYMBOL_SIZE, &sp->size);
74
75   sp->stroke_width = 0.1;
76   sp->stroke_color = 0xffc800;
77   sp->stroke_opacity = 1;
78   if (style_get_color(si, PROP_SYMBOL_STROKE_COLOR, &sp->stroke_color) |
79       style_get_number(si, PROP_SYMBOL_STROKE_WIDTH, &sp->stroke_width))
80     {
81       sp->do_stroke = 1;
82       style_get_number(si, PROP_SYMBOL_STROKE_OPACITY, &sp->stroke_opacity);
83     }
84
85   sp->fill_color = 0x0000ff;
86   sp->fill_opacity = 1;
87   if (style_get_color(si, PROP_SYMBOL_FILL_COLOR, &sp->fill_color) || !sp->do_stroke)
88     {
89       sp->do_fill = 1;
90       style_get_number(si, PROP_SYMBOL_FILL_OPACITY, &sp->fill_opacity);
91     }
92
93   sym_plan(&sp->s, sym_zindex(o, si, 4));
94 }
95
96 struct symbolizer symbolizer_point = {
97   .name = "point",
98   .draw = sym_point_draw,
99   .gen = sym_point_gen,
100 };
101
102 struct sym_point *sym_point_new(struct osm_object *o)
103 {
104   return sym_new(SYMBOLIZER_POINT, o, sizeof(struct sym_point));
105 }
106
107 /*** Icons ***/
108
109 static void sym_icon_draw(struct symbol *sym, struct svg *svg)
110 {
111   struct sym_icon *i = (struct sym_icon *) sym;
112   svg_icon_put(svg, &i->sir);
113 }
114
115 static void sym_icon_gen(struct osm_object *o, struct style_info *si, struct svg *svg)
116 {
117   if (o->type != OSM_TYPE_NODE && o->type != OSM_TYPE_WAY && o->type != OSM_TYPE_MULTIPOLYGON)
118     return;
119
120   osm_val_t image = style_get_string(si, PROP_ICON_IMAGE);
121   if (!image)
122     return;
123
124   struct sym_icon *sic = sym_icon_new(o);
125   struct svg_icon *icon = svg_icon_load(svg, osm_val_decode(image));
126   struct svg_icon_request *sir = &sic->sir;
127   sir->icon = icon;
128
129   if (!osm_obj_center(o, &sir->x, &sir->y))
130     return;
131
132   sir->width = icon->width;
133   sir->height = icon->height;
134   style_scale(si, &sir->width, &sir->height, PROP_ICON_WIDTH, PROP_ICON_HEIGHT);
135
136   // FIXME
137   // sir->opacity = 1;
138   // style_get_number(si, PROP_ICON_OPACITY, &sir->opacity);
139
140   sym_plan(&sic->s, sym_zindex(o, si, 4));
141 }
142
143 struct symbolizer symbolizer_icon = {
144   .name = "icon",
145   .draw = sym_icon_draw,
146   .gen = sym_icon_gen,
147 };
148
149 struct sym_icon *sym_icon_new(struct osm_object *o)
150 {
151   return sym_new(SYMBOLIZER_ICON, o, sizeof(struct sym_icon));
152 }