[gimp] app: pass transformed segments to gimp_display_shell_draw_layer_boundary()



commit 3f6bb75129a6ff8c131070301332a47715610b2a
Author: Michael Natterer <mitch gimp org>
Date:   Wed Aug 25 01:58:00 2010 +0200

    app: pass transformed segments to gimp_display_shell_draw_layer_boundary()
    
    and duplicate quite some code in the spirit of the previous commit
    (rename stuff using GdkSegment to _old() and add new functions that
    return arrays of BoundSegs, for the lack of a nicer struct). This is
    all very ugly and will change.

 app/display/gimpdisplayshell-draw.c      |   42 ++-----------
 app/display/gimpdisplayshell-selection.c |  102 ++++++++++++++++++++---------
 app/display/gimpdisplayshell-transform.c |   58 +++++++++++++++++
 app/display/gimpdisplayshell-transform.h |    5 ++
 4 files changed, 138 insertions(+), 69 deletions(-)
---
diff --git a/app/display/gimpdisplayshell-draw.c b/app/display/gimpdisplayshell-draw.c
index 45b3d85..a37074e 100644
--- a/app/display/gimpdisplayshell-draw.c
+++ b/app/display/gimpdisplayshell-draw.c
@@ -549,47 +549,15 @@ gimp_display_shell_draw_layer_boundary (GimpDisplayShell *shell,
 
   for (i = 0; i < n_segs; i++)
     {
-      gint xclamp = shell->disp_width  + 1;
-      gint yclamp = shell->disp_height + 1;
-      gint x1, y1;
-      gint x2, y2;
-
-      gimp_display_shell_transform_xy (shell,
-                                       segs[i].x1, segs[i].y1,
-                                       &x1, &y1,
-                                       FALSE);
-      gimp_display_shell_transform_xy (shell,
-                                       segs[i].x2, segs[i].y2,
-                                       &x2, &y2,
-                                       FALSE);
-
-      x1 = CLAMP (x1, -1, xclamp);
-      y1 = CLAMP (y1, -1, yclamp);
-
-      x2 = CLAMP (x2, -1, xclamp);
-      y2 = CLAMP (y2, -1, yclamp);
-
-      if (x1 == x2)
+      if (segs[i].x1 == segs[i].x2)
         {
-          if (! segs[i].open)
-            {
-              x1 -= 1;
-              x2 -= 1;
-            }
-
-          cairo_move_to (cr, x1 + 0.5, y1);
-          cairo_line_to (cr, x2 + 0.5, y2);
+          cairo_move_to (cr, segs[i].x1 + 0.5, segs[i].y1);
+          cairo_line_to (cr, segs[i].x2 + 0.5, segs[i].y2);
         }
       else
         {
-          if (! segs[i].open)
-            {
-              y1 -= 1;
-              y2 -= 1;
-            }
-
-          cairo_move_to (cr, x1, y1 + 0.5);
-          cairo_line_to (cr, x2, y2 + 0.5);
+          cairo_move_to (cr, segs[i].x1, segs[i].y1 + 0.5);
+          cairo_line_to (cr, segs[i].x2, segs[i].y2 + 0.5);
         }
     }
 
diff --git a/app/display/gimpdisplayshell-selection.c b/app/display/gimpdisplayshell-selection.c
index c923f17..193f9e5 100644
--- a/app/display/gimpdisplayshell-selection.c
+++ b/app/display/gimpdisplayshell-selection.c
@@ -52,16 +52,13 @@ struct _Selection
   GimpDisplayShell *shell;            /*  shell that owns the selection     */
 
   GdkSegment       *segs_in;          /*  gdk segments of area boundary     */
-  gint              n_segs_in;        /*  number of segments in segs1       */
+  gint              n_segs_in;        /*  number of segments in segs_in     */
 
   GdkSegment       *segs_out;         /*  gdk segments of area boundary     */
-  gint              n_segs_out;       /*  number of segments in segs2       */
+  gint              n_segs_out;       /*  number of segments in segs_out    */
 
-  BoundSeg         *bound_segs_layer;
-  gint              n_bound_segs_layer;
-
-  GdkSegment       *segs_layer;       /*  gdk segments of layer boundary    */
-  gint              n_segs_layer;     /*  number of segments in segs3       */
+  BoundSeg         *segs_layer;       /*  segments of layer boundary        */
+  gint              n_segs_layer;     /*  number of segments in segs_layer  */
 
   guint             index;            /*  index of current stipple pattern  */
   gint              paused;           /*  count of pause requests           */
@@ -94,10 +91,14 @@ static void      selection_add_point      (GdkPoint       *points[8],
                                            gint            y);
 static void      selection_render_points  (Selection      *selection);
 
-static void      selection_transform_segs (Selection      *selection,
+static void  selection_transform_segs_old (Selection      *selection,
                                            const BoundSeg *src_segs,
                                            GdkSegment     *dest_segs,
                                            gint            n_segs);
+static void      selection_transform_segs (Selection      *selection,
+                                           const BoundSeg *src_segs,
+                                           BoundSeg       *dest_segs,
+                                           gint            n_segs);
 static void      selection_generate_segs  (Selection      *selection);
 static void      selection_free_segs      (Selection      *selection);
 
@@ -398,8 +399,8 @@ selection_layer_draw (Selection *selection)
       cr = gdk_cairo_create (gtk_widget_get_window (selection->shell->canvas));
 
       gimp_display_shell_draw_layer_boundary (selection->shell, cr, drawable,
-                                              selection->bound_segs_layer,
-                                              selection->n_bound_segs_layer);
+                                              selection->segs_layer,
+                                              selection->n_segs_layer);
 
       cairo_destroy (cr);
     }
@@ -573,10 +574,10 @@ selection_render_points (Selection *selection)
 }
 
 static void
-selection_transform_segs (Selection      *selection,
-                          const BoundSeg *src_segs,
-                          GdkSegment     *dest_segs,
-                          gint            n_segs)
+selection_transform_segs_old (Selection      *selection,
+                              const BoundSeg *src_segs,
+                              GdkSegment     *dest_segs,
+                              gint            n_segs)
 {
   gint xclamp = selection->shell->disp_width + 1;
   gint yclamp = selection->shell->disp_height + 1;
@@ -616,6 +617,49 @@ selection_transform_segs (Selection      *selection,
 }
 
 static void
+selection_transform_segs (Selection      *selection,
+                          const BoundSeg *src_segs,
+                          BoundSeg       *dest_segs,
+                          gint            n_segs)
+{
+  gint xclamp = selection->shell->disp_width + 1;
+  gint yclamp = selection->shell->disp_height + 1;
+  gint i;
+
+  gimp_display_shell_transform_segments (selection->shell,
+                                         src_segs, dest_segs, n_segs, FALSE);
+
+  for (i = 0; i < n_segs; i++)
+    {
+      dest_segs[i].x1 = CLAMP (dest_segs[i].x1, -1, xclamp);
+      dest_segs[i].y1 = CLAMP (dest_segs[i].y1, -1, yclamp);
+
+      dest_segs[i].x2 = CLAMP (dest_segs[i].x2, -1, xclamp);
+      dest_segs[i].y2 = CLAMP (dest_segs[i].y2, -1, yclamp);
+
+      /*  If this segment is a closing segment && the segments lie inside
+       *  the region, OR if this is an opening segment and the segments
+       *  lie outside the region...
+       *  we need to transform it by one display pixel
+       */
+      if (! dest_segs[i].open)
+        {
+          /*  If it is vertical  */
+          if (dest_segs[i].x1 == dest_segs[i].x2)
+            {
+              dest_segs[i].x1 -= 1;
+              dest_segs[i].x2 -= 1;
+            }
+          else
+            {
+              dest_segs[i].y1 -= 1;
+              dest_segs[i].y2 -= 1;
+            }
+        }
+    }
+}
+
+static void
 selection_generate_segs (Selection *selection)
 {
   GimpImage      *image = gimp_display_get_image (selection->shell->display);
@@ -634,8 +678,8 @@ selection_generate_segs (Selection *selection)
   if (selection->n_segs_in)
     {
       selection->segs_in = g_new (GdkSegment, selection->n_segs_in);
-      selection_transform_segs (selection, segs_in,
-                                selection->segs_in, selection->n_segs_in);
+      selection_transform_segs_old (selection, segs_in,
+                                    selection->segs_in, selection->n_segs_in);
 
 #ifdef USE_DRAWPOINTS
       selection_render_points (selection);
@@ -650,8 +694,8 @@ selection_generate_segs (Selection *selection)
   if (selection->n_segs_out)
     {
       selection->segs_out = g_new (GdkSegment, selection->n_segs_out);
-      selection_transform_segs (selection, segs_out,
-                                selection->segs_out, selection->n_segs_out);
+      selection_transform_segs_old (selection, segs_out,
+                                    selection->segs_out, selection->n_segs_out);
     }
   else
     {
@@ -662,20 +706,21 @@ selection_generate_segs (Selection *selection)
 
   if (layer)
     {
-      selection->bound_segs_layer =
-        gimp_layer_boundary (layer, &selection->n_bound_segs_layer);
+      BoundSeg *segs;
+
+      segs = gimp_layer_boundary (layer, &selection->n_segs_layer);
 
-      if (selection->n_bound_segs_layer)
+      if (selection->n_segs_layer)
         {
-          selection->segs_layer   = g_new (GdkSegment,
-                                           selection->n_bound_segs_layer);
-          selection->n_segs_layer = selection->n_bound_segs_layer;
+          selection->segs_layer = g_new (BoundSeg, selection->n_segs_layer);
 
           selection_transform_segs (selection,
-                                    selection->bound_segs_layer,
+                                    segs,
                                     selection->segs_layer,
                                     selection->n_segs_layer);
         }
+
+      g_free (segs);
     }
 }
 
@@ -698,13 +743,6 @@ selection_free_segs (Selection *selection)
       selection->n_segs_out = 0;
     }
 
-  if (selection->bound_segs_layer)
-    {
-      g_free (selection->bound_segs_layer);
-      selection->bound_segs_layer   = NULL;
-      selection->n_bound_segs_layer = 0;
-    }
-
   if (selection->segs_layer)
     {
       g_free (selection->segs_layer);
diff --git a/app/display/gimpdisplayshell-transform.c b/app/display/gimpdisplayshell-transform.c
index ce17e7c..f78be28 100644
--- a/app/display/gimpdisplayshell-transform.c
+++ b/app/display/gimpdisplayshell-transform.c
@@ -431,6 +431,64 @@ gimp_display_shell_transform_segments_old (const GimpDisplayShell *shell,
 }
 
 /**
+ * gimp_display_shell_transform_segments:
+ * @shell:       a #GimpDisplayShell
+ * @src_segs:    array of segments in image coordinates
+ * @dest_segs:   returns the corresponding segments in display coordinates
+ * @n_segs:      number of segments
+ * @use_offsets: if %TRUE, the source coordinates are in the coordinate
+ *               system of the active drawable instead of the image
+ *
+ * Transforms from image coordinates to display coordinates, so that
+ * objects can be rendered at the correct points on the display.
+ **/
+void
+gimp_display_shell_transform_segments (const GimpDisplayShell *shell,
+                                       const BoundSeg         *src_segs,
+                                       BoundSeg               *dest_segs,
+                                       gint                    n_segs,
+                                       gboolean                use_offsets)
+{
+  gint offset_x = 0;
+  gint offset_y = 0;
+  gint i;
+
+  g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
+
+  if (use_offsets)
+    {
+      GimpImage *image = gimp_display_get_image (shell->display);
+      GimpItem  *item  = GIMP_ITEM (gimp_image_get_active_drawable (image));
+
+      gimp_item_get_offset (item, &offset_x, &offset_y);
+    }
+
+  for (i = 0; i < n_segs ; i++)
+    {
+      gint64 x1, x2;
+      gint64 y1, y2;
+
+      x1 = src_segs[i].x1 + offset_x;
+      x2 = src_segs[i].x2 + offset_x;
+      y1 = src_segs[i].y1 + offset_y;
+      y2 = src_segs[i].y2 + offset_y;
+
+      x1 = (x1 * shell->x_src_dec) / shell->x_dest_inc;
+      x2 = (x2 * shell->x_src_dec) / shell->x_dest_inc;
+      y1 = (y1 * shell->y_src_dec) / shell->y_dest_inc;
+      y2 = (y2 * shell->y_src_dec) / shell->y_dest_inc;
+
+      dest_segs[i].x1 = CLAMP (x1 - shell->offset_x, G_MININT, G_MAXINT);
+      dest_segs[i].x2 = CLAMP (x2 - shell->offset_x, G_MININT, G_MAXINT);
+      dest_segs[i].y1 = CLAMP (y1 - shell->offset_y, G_MININT, G_MAXINT);
+      dest_segs[i].y2 = CLAMP (y2 - shell->offset_y, G_MININT, G_MAXINT);
+
+      dest_segs[i].open    = src_segs[i].open;
+      dest_segs[i].visited = FALSE;
+    }
+}
+
+/**
  * gimp_display_shell_untransform_viewport:
  * @shell:  a #GimpDisplayShell
  * @x:      returns image x coordinate of display upper left corner
diff --git a/app/display/gimpdisplayshell-transform.h b/app/display/gimpdisplayshell-transform.h
index d57fecc..5a4b3e0 100644
--- a/app/display/gimpdisplayshell-transform.h
+++ b/app/display/gimpdisplayshell-transform.h
@@ -68,6 +68,11 @@ void  gimp_display_shell_transform_segments_old (const GimpDisplayShell *shell,
                                                  GdkSegment             *dest_segs,
                                                  gint                    n_segs,
                                                  gboolean                use_offsets);
+void  gimp_display_shell_transform_segments     (const GimpDisplayShell *shell,
+                                                 const BoundSeg         *src_segs,
+                                                 BoundSeg               *dest_segs,
+                                                 gint                    n_segs,
+                                                 gboolean                use_offsets);
 
 void  gimp_display_shell_untransform_viewport   (const GimpDisplayShell *shell,
                                                  gint                   *x,



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