]> mj.ucw.cz Git - leo.git/commitdiff
Inline styles can be specified in object tags
authorMartin Mares <mj@ucw.cz>
Sun, 7 Jun 2015 15:39:28 +0000 (17:39 +0200)
committerMartin Mares <mj@ucw.cz>
Sun, 7 Jun 2015 15:39:28 +0000 (17:39 +0200)
css-lex.c
css-parse.y
css.h
map.c
map.cf
map.h
poskole.css

index 754c52674849200f444ed380a6b41536ef44ca3a..ae6727168b5315161f8df805c770bb544e63059c 100644 (file)
--- a/css-lex.c
+++ b/css-lex.c
@@ -1,7 +1,7 @@
 /*
  *     Experimenta lMai Renderer -- MapCSS Lexer
  *
- *     (c) 2014 Martin Mares <mj@ucw.cz>
+ *     (c) 2014--2015 Martin Mares <mj@ucw.cz>
  */
 
 #include <ucw/lib.h>
@@ -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 (;;)
     {
index d5a775781472577f4867a620166e00ca8585f5a5..33293217ddad9f66feffc3f0cf64000a06f2310c 100644 (file)
@@ -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 <s> NUMBER IDENT QUOTED RGB
 
 %type <s> 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 9344a639ed168d31a2c82bf99fd621b6d7d6ac1f..8ec18963de4a94ec5b7a8c8bf5215158b0e5f83b 100644 (file)
--- a/css.h
+++ b/css.h
@@ -1,7 +1,7 @@
 /*
  *     Hic Est Leo -- MapCSS Stylesheets
  *
- *     (c) 2014 Martin Mares <mj@ucw.cz>
+ *     (c) 2014--2015 Martin Mares <mj@ucw.cz>
  */
 
 #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 d15b835c2761b3c4aee6b2665de0127ba3c28b53..3dbf7194b3b79468088bf8bb12eeaeb729999fa6 100644 (file)
--- 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 3998e02ef5325c25e86b6af6229f03837c80808a..f1a33d3b2c16f61470c635d38261a28d8c54ec80 100644 (file)
--- 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:<property>" or "style:<property>::<layer>")
+               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 9dd80a795bea79538b51b186ef7f7ad3278959bf..8478af133c8244faae014e2bda4a3ef09a96a485 100644 (file)
--- a/map.h
+++ b/map.h
@@ -1,7 +1,7 @@
 /*
  *     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
@@ -32,6 +32,7 @@ struct data_source {
   char *file;
   int format;
   clist styles;                // of data_source_style
+  int inline_styles;
   // Runtime
   struct osm *osm;
 };
index a60f5633ffc87945b524dd3f30e523c4f51a460c..30631f5ae39eff668a51fbc5984c1bc4e9d1a105 100644 (file)
@@ -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;
-}