/*
* Experimenta lMai Renderer -- MapCSS Lexer
*
- * (c) 2014 Martin Mares <mj@ucw.cz>
+ * (c) 2014--2015 Martin Mares <mj@ucw.cz>
*/
#include <ucw/lib.h>
#include "css-parse.h"
static struct fastbuf *fb;
+static struct fastbuf fbbuf;
static int lino;
void css_error(char *err, ...)
bclose(fb);
}
+void css_lex_string(const char *str)
+{
+ fbbuf_init_read(&fbbuf, (char *) str, strlen(str), 0);
+ fb = &fbbuf;
+}
+
int css_lex(void)
{
struct mempool *mp = css_this->pool;
char *p;
- int c, next, len;
+ int c, next, len, tok;
+
+ if (tok = css_this->pushed_token)
+ {
+ css_this->pushed_token = 0;
+ return tok;
+ }
for (;;)
{
}
%token LE GE NE CC
+%token SINGLE_PROP
%token <s> NUMBER IDENT QUOTED RGB
%type <s> ident_or_quoted
%%
input:
+ input_css
+ | prop_single
+ ;
+
+input_css:
/* empty */
- | input rule { clist_add_tail(&css_this->rules, &$2->n); }
+ | input_css rule { clist_add_tail(&css_this->rules, &$2->n); }
;
rule_start:
}
;
+prop_single:
+ SINGLE_PROP prop_value
+ {
+ struct style_prop *p = css_alloc(sizeof(*p));
+ css_this->parsed_prop = p;
+ *p = $2;
+ }
+ ;
+
ident_or_quoted: IDENT | QUOTED ;
%%
css_this = NULL;
return ss;
}
+
+struct style_prop *css_parse_prop(struct mempool *mp, char *objname, const char *key_str, const char *value_str)
+{
+ struct css_sheet ss = {
+ .pool = mp,
+ .filename = objname,
+ .pushed_token = SINGLE_PROP,
+ };
+ clist_init(&ss.rules);
+
+ css_this = &ss;
+ css_lex_string(value_str);
+ css_parse();
+
+ struct style_prop *p = ss.parsed_prop;
+ p->key = style_prop_encode(key_str);
+
+ css_this = NULL;
+ return p;
+}
/*
* Hic Est Leo -- MapCSS Stylesheets
*
- * (c) 2014 Martin Mares <mj@ucw.cz>
+ * (c) 2014--2015 Martin Mares <mj@ucw.cz>
*/
#ifndef _LEO_CSS_H
struct mempool *pool;
clist rules;
char *filename;
+
+ /* For parsing for single properties by css_parse_prop */
+ int pushed_token;
+ struct style_prop *parsed_prop;
};
struct css_rule {
extern struct css_sheet *css_this;
struct css_sheet *css_load(char *filename);
+struct style_prop *css_parse_prop(struct mempool *mp, char *objname, const char *key_str, const char *value_str);
/* css-lex.c */
int css_lex(void);
void css_lex_open(void);
void css_lex_close(void);
+void css_lex_string(const char *str);
color_t css_rgb_to_color(const char *rgb);
CF_STRING("File", P(file)),
CF_LOOKUP("Format", P(format), map_formats),
CF_LIST("StyleSheet", P(styles), &map_style_cf),
+ CF_INT("InlineStyles", P(inline_styles)),
CF_END
}
#undef P
map_load_source(ds);
}
+static void map_apply_inline_styles(struct osm_object *o, struct style_results *r)
+{
+ char *name = NULL;
+
+ CLIST_FOR_EACH(struct osm_tag *, t, o->tags)
+ {
+ const char *key = osm_key_decode(t->key);
+ if (!strncmp(key, "style:", 6))
+ {
+ key += 6;
+ layer_t layer = STYLE_LAYER_DEFAULT;
+ char *sep = strstr(key, "::");
+ if (sep)
+ {
+ if (sep[2])
+ {
+ // XXX: Only layers defined in the main stylesheet can be modified
+ layer = style_layer_encode_if_exists(sep+2);
+ if (!layer)
+ goto skip;
+ }
+ int keylen = sep - key;
+ char *t = mp_alloc(r->pool, keylen+1);
+ memcpy(t, key, keylen);
+ t[keylen] = 0;
+ key = t;
+ }
+
+ if (!name)
+ name = mp_printf(r->pool, "Inline style in object #%ju", (uintmax_t) o->id);
+ struct style_prop *p= css_parse_prop(r->pool, name, key, osm_val_decode(t->val));
+ style_set_by_layer(r, layer, p);
+skip: ;
+ }
+ }
+}
+
void map_apply_styles(struct svg *svg)
{
struct style_results r;
style_begin(&r, o);
CLIST_FOR_EACH(struct data_source_style *, ss, ds->styles)
css_apply(ss->css, &r);
+ if (ds->inline_styles)
+ map_apply_inline_styles(o, &r);
if (debug_dump_styling)
style_dump(&r);
sym_from_style(o, &r, svg);
# MapCSS stylesheet to apply (multiple style-sheets are allowed)
StyleSheet poskole.css
+
+ # Enable inline style properties (tags "style:<property>" or "style:<property>::<layer>")
+ InlineStyles 1
}
Source {
Format fixed
StyleSheet poskole.css
+ InlineStyles 1
}
# Projection of our map
Object {
X 374
Y 25
- Tag legend logo
+ Tag style:icon-image '"icons/logo.svg"'
+ Tag style:icon-width 36
+ Tag style:z-index 99
}
}
/*
* Hic Est Leo -- Global Map Operations
*
- * (c) 2014 Martin Mares <mj@ucw.cz>
+ * (c) 2014--2015 Martin Mares <mj@ucw.cz>
*/
#ifndef _LEO_MAP_H
char *file;
int format;
clist styles; // of data_source_style
+ int inline_styles;
// Runtime
struct osm *osm;
};
way[hack=raisetext] {
text-offset: 3;
}
-
-node[legend=logo] {
- icon-image: "icons/logo.svg";
- icon-width: 36;
- z-index: 99;
-}