]> mj.ucw.cz Git - leo.git/commitdiff
Symbols: Comparison, disabling, and iterating
authorMartin Mares <mj@ucw.cz>
Sun, 27 Mar 2022 20:24:54 +0000 (22:24 +0200)
committerMartin Mares <mj@ucw.cz>
Sun, 27 Mar 2022 20:25:32 +0000 (22:25 +0200)
sym-line.c
sym.c
sym.h

index 09dcee4d73c7f8e7fc6c811d1b46a0ad913dfac3..74d6d56df8678ec4faac11dab9c2e5d7df7ea551 100644 (file)
@@ -184,10 +184,42 @@ static void sym_line_gen(struct osm_object *o, struct style_info *si, struct svg
     }
 }
 
+static bool sym_line_same_p(struct symbol *xx, struct symbol *yy)
+{
+  struct sym_line *x = (struct sym_line *) xx;
+  struct sym_line *y = (struct sym_line *) yy;
+
+  if (!(x->width == y->width &&
+        x->color == y->color &&
+       x->opacity == y->opacity &&
+       x->line_cap == y->line_cap &&
+       x->line_join == y->line_join &&
+       x->miter_limit == y->miter_limit &&
+       x->dash_offset == y->dash_offset))
+    return 0;
+
+  if (x->dash_pattern || y->dash_pattern)
+    {
+      if (!x->dash_pattern || !y->dash_pattern)
+       return 0;
+
+      if (GARY_SIZE(x->dash_pattern) != GARY_SIZE(y->dash_pattern))
+       return 0;
+
+      uint dashes = GARY_SIZE(x->dash_pattern);
+      for (uint i=0; i < dashes; i++)
+       if (x->dash_pattern[i] != y->dash_pattern[i])
+         return 0;
+    }
+
+  return 1;
+}
+
 struct symbolizer symbolizer_line = {
   .name = "line",
   .draw = sym_line_draw,
   .gen = sym_line_gen,
+  .same_p = sym_line_same_p,
 };
 
 struct sym_line *sym_line_new(struct osm_object *o)
diff --git a/sym.c b/sym.c
index 8f28f078aaae5ab039b8cc166925827deac94d41..67a718d9ea7b8bac5a56bd798d376d8a5a3d7ebb 100644 (file)
--- a/sym.c
+++ b/sym.c
 #undef CLAMP           // FIXME: Fix in libucw?
 #define CLAMP(x,min,max) ({ typeof(x) _t=x; (_t < min) ? min : (_t > max) ? max : _t; })       /** Clip a number @x to interval [@min,@max] **/
 
+static struct symbolizer symbolizer_disabled = {
+  .name = "disabled",
+};
+
 static struct symbolizer *symbolizers[] = {
   [SYMBOLIZER_INVALID] = NULL,
   [SYMBOLIZER_POINT] = &symbolizer_point,
@@ -27,6 +31,7 @@ static struct symbolizer *symbolizers[] = {
   [SYMBOLIZER_AREA] = &symbolizer_area,
   [SYMBOLIZER_TEXT] = &symbolizer_text,
   [SYMBOLIZER_LINEIMG] = &symbolizer_lineimg,
+  [SYMBOLIZER_DISABLED] = &symbolizer_disabled,
 };
 
 struct mempool *sym_mp;
@@ -131,7 +136,8 @@ static void sym_draw(struct symbol *sym, z_index_t zindex, struct svg *svg)
   ASSERT(sym->type && sym->type < SYMBOLIZER_MAX);
   if (debug_dump_symbols)
     printf("Drawing symbol <%s> at z-index %u for %s\n", symbolizers[sym->type]->name, zindex, STK_OSM_NAME(sym->o));
-  symbolizers[sym->type]->draw(sym, svg);
+  if (symbolizers[sym->type]->draw)
+    symbolizers[sym->type]->draw(sym, svg);
 }
 
 void sym_draw_all(struct svg *svg)
@@ -146,3 +152,25 @@ void sym_draw_all(struct svg *svg)
   for (uns i = 0; i < GARY_SIZE(sym_planned); i++)
     sym_draw(sym_planned[i].sym, sym_planned[i].zindex, svg);
 }
+
+void sym_for_all_planned(void (*callback)(struct symbol *s))
+{
+  for (uns i = 0; i < GARY_SIZE(sym_planned); i++)
+    callback(sym_planned[i].sym);
+}
+
+bool sym_same_attrs_p(struct symbol *x, struct symbol *y)
+{
+  if (x->type != y->type)
+    return 0;
+
+  if (!symbolizers[x->type]->same_p)
+    return 0;
+
+  return (*symbolizers[x->type]->same_p)(x, y);
+}
+
+void sym_disable(struct symbol *sym)
+{
+  sym->type = SYMBOLIZER_DISABLED;
+}
diff --git a/sym.h b/sym.h
index e53409e7b8d9ecc9a35874bfae3ff72bdad4d1fa..f5d75241ea6d6000b1ba12b6abb5a2d1859eaefc 100644 (file)
--- a/sym.h
+++ b/sym.h
@@ -19,6 +19,7 @@ enum symbolizer_type {
   SYMBOLIZER_AREA,
   SYMBOLIZER_TEXT,
   SYMBOLIZER_LINEIMG,
+  SYMBOLIZER_DISABLED,
   SYMBOLIZER_MAX,
 };
 
@@ -33,6 +34,7 @@ struct symbolizer {
   void (*draw)(struct symbol *sym, struct svg *svg);
   void (*gen)(struct osm_object *o, struct style_info *si, struct svg *svg);
   void (*init)(void);
+  bool (*same_p)(struct symbol *x, struct symbol *y);
 };
 
 extern struct mempool *sym_mp;
@@ -55,8 +57,11 @@ void sym_init(void);
 void *sym_new(enum symbolizer_type type, struct osm_object *o, size_t size);
 void sym_plan(struct symbol *sym, z_index_t zindex);
 void sym_draw_all(struct svg *svg);
+void sym_for_all_planned(void (*callback)(struct symbol *s));
 void sym_from_style(struct osm_object *o, struct style_results *sr, struct svg *svg);
 z_index_t sym_zindex(struct osm_object *o, struct style_info *si, double default_mzi);
+bool sym_same_attrs_p(struct symbol *x, struct symbol *y);
+void sym_disable(struct symbol *s);
 
 /* sym-point.c handles point symbols and icons */