From: Martin Mares Date: Sun, 7 Jun 2015 15:39:28 +0000 (+0200) Subject: Inline styles can be specified in object tags X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=d4c92f4212c4ddfe6fa73a9abd6b728011303604;p=leo.git Inline styles can be specified in object tags --- diff --git a/css-lex.c b/css-lex.c index 754c526..ae67271 100644 --- a/css-lex.c +++ b/css-lex.c @@ -1,7 +1,7 @@ /* * Experimenta lMai Renderer -- MapCSS Lexer * - * (c) 2014 Martin Mares + * (c) 2014--2015 Martin Mares */ #include @@ -17,6 +17,7 @@ #include "css-parse.h" static struct fastbuf *fb; +static struct fastbuf fbbuf; static int lino; void css_error(char *err, ...) @@ -38,11 +39,23 @@ void css_lex_close(void) 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 (;;) { diff --git a/css-parse.y b/css-parse.y index d5a7757..3329321 100644 --- a/css-parse.y +++ b/css-parse.y @@ -48,6 +48,7 @@ static void css_add_to_val_list(struct style_prop *list, struct style_prop *elt) } %token LE GE NE CC +%token SINGLE_PROP %token NUMBER IDENT QUOTED RGB %type ident_or_quoted @@ -62,8 +63,13 @@ static void css_add_to_val_list(struct style_prop *list, struct style_prop *elt) %% 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: @@ -280,6 +286,15 @@ prop_value_list: } ; +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 ; %% @@ -302,3 +317,23 @@ struct css_sheet *css_load(char *filename) 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; +} diff --git a/css.h b/css.h index 9344a63..8ec1896 100644 --- a/css.h +++ b/css.h @@ -1,7 +1,7 @@ /* * Hic Est Leo -- MapCSS Stylesheets * - * (c) 2014 Martin Mares + * (c) 2014--2015 Martin Mares */ #ifndef _LEO_CSS_H @@ -14,6 +14,10 @@ struct css_sheet { 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 { @@ -79,6 +83,7 @@ struct css_action { 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 */ @@ -86,6 +91,7 @@ void css_error(char *err, ...); 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); diff --git a/map.c b/map.c index d15b835..3dbf719 100644 --- a/map.c +++ b/map.c @@ -55,6 +55,7 @@ static struct cf_section map_source_cf = { 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 @@ -280,6 +281,43 @@ void map_load_sources(void) 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; @@ -305,6 +343,8 @@ void map_apply_styles(struct svg *svg) 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); diff --git a/map.cf b/map.cf index 3998e02..f1a33d3 100644 --- a/map.cf +++ b/map.cf @@ -12,11 +12,15 @@ Map { # MapCSS stylesheet to apply (multiple style-sheets are allowed) StyleSheet poskole.css + + # Enable inline style properties (tags "style:" or "style:::") + InlineStyles 1 } Source { Format fixed StyleSheet poskole.css + InlineStyles 1 } # Projection of our map @@ -55,7 +59,9 @@ FixedObjects { 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 } } diff --git a/map.h b/map.h index 9dd80a7..8478af1 100644 --- a/map.h +++ b/map.h @@ -1,7 +1,7 @@ /* * Hic Est Leo -- Global Map Operations * - * (c) 2014 Martin Mares + * (c) 2014--2015 Martin Mares */ #ifndef _LEO_MAP_H @@ -32,6 +32,7 @@ struct data_source { char *file; int format; clist styles; // of data_source_style + int inline_styles; // Runtime struct osm *osm; }; diff --git a/poskole.css b/poskole.css index a60f563..30631f5 100644 --- a/poskole.css +++ b/poskole.css @@ -705,9 +705,3 @@ node[hack=raisetext], way[hack=raisetext] { text-offset: 3; } - -node[legend=logo] { - icon-image: "icons/logo.svg"; - icon-width: 36; - z-index: 99; -}