Example #1
0
static GdkSegment *
gimp_region_select_tool_calculate (GimpRegionSelectTool *region_sel,
                                   GimpDisplay          *display,
                                   gint                 *num_segs)
{
  GimpTool                *tool    = GIMP_TOOL (region_sel);
  GimpRegionSelectOptions *options = GIMP_REGION_SELECT_TOOL_GET_OPTIONS (tool);
  GimpDisplayShell        *shell   = GIMP_DISPLAY_SHELL (display->shell);
  GimpDrawable            *drawable;
  GdkSegment              *segs;
  BoundSeg                *bsegs;
  PixelRegion              maskPR;

  drawable = gimp_image_get_active_drawable (display->image);

  gimp_display_shell_set_override_cursor (shell, GDK_WATCH);

  if (region_sel->region_mask)
    g_object_unref (region_sel->region_mask);

  region_sel->region_mask =
    GIMP_REGION_SELECT_TOOL_GET_CLASS (region_sel)->get_mask (region_sel,
                                                              display);

  if (! region_sel->region_mask)
    {
      gimp_display_shell_unset_override_cursor (shell);

      *num_segs = 0;
      return NULL;
    }

  /*  calculate and allocate a new segment array which represents the
   *  boundary of the contiguous region
   */
  pixel_region_init (&maskPR,
                     gimp_drawable_get_tiles (GIMP_DRAWABLE (region_sel->region_mask)),
                     0, 0,
                     gimp_item_width  (GIMP_ITEM (region_sel->region_mask)),
                     gimp_item_height (GIMP_ITEM (region_sel->region_mask)),
                     FALSE);

  bsegs = boundary_find (&maskPR, BOUNDARY_WITHIN_BOUNDS,
                         0, 0,
                         gimp_item_width  (GIMP_ITEM (region_sel->region_mask)),
                         gimp_item_height (GIMP_ITEM (region_sel->region_mask)),
                         BOUNDARY_HALF_WAY,
                         num_segs);

  segs = g_new (GdkSegment, *num_segs);

  gimp_display_shell_transform_segments (shell, bsegs, segs, *num_segs,
                                         ! options->sample_merged);
  g_free (bsegs);

  gimp_display_shell_unset_override_cursor (shell);

  return segs;
}
static void
selection_transform_segs (Selection      *selection,
                          const BoundSeg *src_segs,
                          GimpSegment    *dest_segs,
                          gint            n_segs)
{
  const gint xclamp = selection->shell->disp_width + 1;
  const gint yclamp = selection->shell->disp_height + 1;
  gint       i;

  gimp_display_shell_transform_segments (selection->shell,
                                         src_segs, dest_segs, n_segs,
                                         0.0, 0.0);

  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 (! src_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;
            }
        }
    }
}