[libshumate] vector: Draw line labels right side up



commit e95081b9d522006ca2931ab6952538c91a96dea6
Author: James Westman <james jwestman net>
Date:   Tue May 17 22:44:08 2022 -0500

    vector: Draw line labels right side up

 shumate/vector/shumate-vector-symbol.c        | 19 +++++++++++++++++++
 shumate/vector/shumate-vector-utils-private.h |  1 +
 shumate/vector/shumate-vector-utils.c         | 27 ++++++++++++++++++++++-----
 3 files changed, 42 insertions(+), 5 deletions(-)
---
diff --git a/shumate/vector/shumate-vector-symbol.c b/shumate/vector/shumate-vector-symbol.c
index 3dccc6a..c26610d 100644
--- a/shumate/vector/shumate-vector-symbol.c
+++ b/shumate/vector/shumate-vector-symbol.c
@@ -213,6 +213,13 @@ shumate_vector_symbol_set_property (GObject      *object,
 }
 
 
+static double
+positive_mod (double i, double n)
+{
+  return fmod (fmod (i, n) + n, n);
+}
+
+
 static void
 shumate_vector_symbol_snapshot (GtkWidget   *widget,
                                 GtkSnapshot *snapshot)
@@ -226,6 +233,7 @@ shumate_vector_symbol_snapshot (GtkWidget   *widget,
       ShumateVectorPointIter iter;
       double rotation = 0.0;
       double scale = 512.0;
+      double avg_angle;
 
       if (SHUMATE_IS_VECTOR_SYMBOL_CONTAINER (parent))
         {
@@ -247,6 +255,17 @@ shumate_vector_symbol_snapshot (GtkWidget   *widget,
       shumate_vector_point_iter_init (&iter, &self->symbol_info->line);
       shumate_vector_point_iter_advance (&iter, (self->line_length - self->glyphs_length / scale) / 2.0);
 
+      /* If the label is upside down on average, draw it the other way around */
+      avg_angle = shumate_vector_point_iter_get_average_angle (&iter, self->glyphs_length / scale);
+      avg_angle = positive_mod (avg_angle + rotation, G_PI * 2.0);
+      if (avg_angle > G_PI / 2.0 && avg_angle < 3.0 * G_PI / 2.0)
+        {
+          iter.reversed = TRUE;
+          iter.current_point = iter.num_points - 1;
+          iter.distance = 0;
+          shumate_vector_point_iter_advance (&iter, (self->line_length - self->glyphs_length / scale) / 2.0);
+        }
+
       for (i = 0; i < self->glyphs->len; i ++)
         {
           Glyph *glyph = &((Glyph *)self->glyphs->data)[i];
diff --git a/shumate/vector/shumate-vector-utils-private.h b/shumate/vector/shumate-vector-utils-private.h
index 712992c..822dd45 100644
--- a/shumate/vector/shumate-vector-utils-private.h
+++ b/shumate/vector/shumate-vector-utils-private.h
@@ -38,6 +38,7 @@ struct _ShumateVectorPointIter {
   ShumateVectorPoint *points;
   gsize current_point;
   float distance;
+  guint reversed : 1;
 };
 
 gboolean shumate_vector_json_get_object (JsonNode    *node,
diff --git a/shumate/vector/shumate-vector-utils.c b/shumate/vector/shumate-vector-utils.c
index 09596b9..1833429 100644
--- a/shumate/vector/shumate-vector-utils.c
+++ b/shumate/vector/shumate-vector-utils.c
@@ -164,6 +164,7 @@ shumate_vector_point_iter_init (ShumateVectorPointIter  *iter,
     .points = linestring->points,
     .current_point = 0,
     .distance = 0,
+    .reversed = FALSE,
   };
 }
 
@@ -173,7 +174,12 @@ shumate_vector_point_iter_next_segment (ShumateVectorPointIter *iter)
 {
   double res = shumate_vector_point_iter_get_segment_length (iter) - iter->distance;
   iter->distance = 0;
-  iter->current_point ++;
+
+  if (iter->reversed)
+    iter->current_point --;
+  else
+    iter->current_point ++;
+
   return res;
 }
 
@@ -203,10 +209,20 @@ get_prev_point (ShumateVectorPointIter *iter)
 static ShumateVectorPoint *
 get_next_point (ShumateVectorPointIter *iter)
 {
-  if (iter->current_point >= iter->num_points - 1)
-    return &iter->points[iter->num_points - 1];
+  if (iter->reversed)
+    {
+      if (iter->current_point == 0)
+        return &iter->points[0];
+      else
+        return &iter->points[iter->current_point - 1];
+    }
   else
-    return &iter->points[iter->current_point + 1];
+    {
+      if (iter->current_point >= iter->num_points - 1)
+        return &iter->points[iter->num_points - 1];
+      else
+        return &iter->points[iter->current_point + 1];
+    }
 }
 
 static void
@@ -278,7 +294,8 @@ shumate_vector_point_iter_advance (ShumateVectorPointIter *iter,
 {
   while (distance > 0)
     {
-      if (iter->current_point >= iter->num_points - 1)
+      if ((iter->reversed && iter->current_point == 0)
+          || (!iter->reversed && iter->current_point >= iter->num_points - 1))
         return;
 
       if (iter->distance + distance > shumate_vector_point_iter_get_segment_length (iter))


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]