void
gimp_channel_select_polygon (GimpChannel    *channel,
                             const gchar    *undo_desc,
                             gint            n_points,
                             GimpVector2    *points,
                             GimpChannelOps  op,
                             gboolean        antialias,
                             gboolean        feather,
                             gdouble         feather_radius_x,
                             gdouble         feather_radius_y,
                             gboolean        push_undo)
{
  GimpScanConvert *scan_convert;

  g_return_if_fail (GIMP_IS_CHANNEL (channel));
  g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (channel)));
  g_return_if_fail (undo_desc != NULL);

  scan_convert = gimp_scan_convert_new ();

  gimp_scan_convert_add_polyline (scan_convert, n_points, points, TRUE);

  gimp_channel_select_scan_convert (channel, undo_desc, scan_convert, 0, 0,
                                    op, antialias, feather,
                                    feather_radius_x, feather_radius_y,
                                    push_undo);

  gimp_scan_convert_free (scan_convert);
}
void
gimp_channel_select_vectors (GimpChannel    *channel,
                             const gchar    *undo_desc,
                             GimpVectors    *vectors,
                             GimpChannelOps  op,
                             gboolean        antialias,
                             gboolean        feather,
                             gdouble         feather_radius_x,
                             gdouble         feather_radius_y,
                             gboolean        push_undo)
{
  const GimpBezierDesc *bezier;

  g_return_if_fail (GIMP_IS_CHANNEL (channel));
  g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (channel)));
  g_return_if_fail (undo_desc != NULL);
  g_return_if_fail (GIMP_IS_VECTORS (vectors));

  bezier = gimp_vectors_get_bezier (vectors);

  if (bezier && bezier->num_data > 4)
    {
      GimpScanConvert *scan_convert;

      scan_convert = gimp_scan_convert_new ();
      gimp_scan_convert_add_bezier (scan_convert, bezier);

      gimp_channel_select_scan_convert (channel, undo_desc, scan_convert, 0, 0,
                                        op, antialias, feather,
                                        feather_radius_x, feather_radius_y,
                                        push_undo);

      gimp_scan_convert_free (scan_convert);
    }
}
Example #3
0
void
gimp_drawable_stroke_boundary (GimpDrawable       *drawable,
                               GimpStrokeOptions  *options,
                               const GimpBoundSeg *bound_segs,
                               gint                n_bound_segs,
                               gint                offset_x,
                               gint                offset_y,
                               gboolean            push_undo)
{
  GimpScanConvert *scan_convert;

  g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
  g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)));
  g_return_if_fail (GIMP_IS_STROKE_OPTIONS (options));
  g_return_if_fail (bound_segs == NULL || n_bound_segs != 0);
  g_return_if_fail (gimp_fill_options_get_style (GIMP_FILL_OPTIONS (options)) !=
                    GIMP_FILL_STYLE_PATTERN ||
                    gimp_context_get_pattern (GIMP_CONTEXT (options)) != NULL);

  scan_convert = gimp_scan_convert_new_from_boundary (bound_segs, n_bound_segs,
                                                      offset_x, offset_y);

  if (scan_convert)
    {
      gimp_drawable_stroke_scan_convert (drawable, options,
                                         scan_convert, push_undo);
      gimp_scan_convert_free (scan_convert);
    }
}
Example #4
0
static void
gimp_foreground_select_tool_stroke (GimpChannel    *mask,
                                    FgSelectStroke *stroke)
{
  GimpScanConvert *scan_convert = gimp_scan_convert_new ();

  if (stroke->num_points == 1)
    {
      GimpVector2 points[2];

      points[0] = points[1] = stroke->points[0];

      points[1].x += 0.01;
      points[1].y += 0.01;

      gimp_scan_convert_add_polyline (scan_convert, 2, points, FALSE);
    }
  else
    {
      gimp_scan_convert_add_polyline (scan_convert,
                                      stroke->num_points, stroke->points,
                                      FALSE);
    }

  gimp_scan_convert_stroke (scan_convert,
                            stroke->width,
                            GIMP_JOIN_ROUND, GIMP_CAP_ROUND, 10.0,
                            0.0, NULL);
  gimp_scan_convert_compose_value (scan_convert,
                             gimp_drawable_get_tiles (GIMP_DRAWABLE (mask)),
                             0, 0, stroke->background ? 0 : 255);
  gimp_scan_convert_free (scan_convert);
}
Example #5
0
void
gimp_drawable_stroke_vectors (GimpDrawable      *drawable,
                              GimpStrokeOptions *options,
                              GimpVectors       *vectors)
{
  GimpScanConvert *scan_convert;
  GimpStroke      *stroke;
  gint             num_coords = 0;

  g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
  g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)));
  g_return_if_fail (GIMP_IS_STROKE_OPTIONS (options));
  g_return_if_fail (GIMP_IS_VECTORS (vectors));

  scan_convert = gimp_scan_convert_new ();

  /* For each Stroke in the vector, interpolate it, and add it to the
   * ScanConvert
   */
  for (stroke = gimp_vectors_stroke_get_next (vectors, NULL);
       stroke;
       stroke = gimp_vectors_stroke_get_next (vectors, stroke))
    {
      GArray   *coords;
      gboolean  closed;

      /* Get the interpolated version of this stroke, and add it to our
       * scanconvert.
       */
      coords = gimp_stroke_interpolate (stroke, 0.2, &closed);

      if (coords && coords->len)
        {
          GimpVector2 *points = g_new0 (GimpVector2, coords->len);
          gint         i;

          for (i = 0; i < coords->len; i++)
            {
              points[i].x = g_array_index (coords, GimpCoords, i).x;
              points[i].y = g_array_index (coords, GimpCoords, i).y;
              num_coords++;
            }

          gimp_scan_convert_add_polyline (scan_convert, coords->len,
                                          points, closed);

          g_free (points);
        }

      if (coords)
        g_array_free (coords, TRUE);
    }

  if (num_coords > 0)
    gimp_drawable_stroke_scan_convert (drawable, options, scan_convert);

  gimp_scan_convert_free (scan_convert);
}
static void
gimp_foreground_select_tool_stroke_paint (GimpForegroundSelectTool    *fg_select,
                                          GimpDisplay                 *display,
                                          GimpForegroundSelectOptions *options)
{
  GimpScanConvert *scan_convert;
  gint             width;
  gdouble          opacity;

  g_return_if_fail (fg_select->stroke != NULL);

  scan_convert = gimp_scan_convert_new ();

  if (fg_select->stroke->len == 1)
    {
      GimpVector2 points[2];

      points[0] = points[1] = ((GimpVector2 *) fg_select->stroke->data)[0];

      points[1].x += 0.01;
      points[1].y += 0.01;

      gimp_scan_convert_add_polyline (scan_convert, 2, points, FALSE);
    }
  else
    {
      gimp_scan_convert_add_polyline (scan_convert,
                                      fg_select->stroke->len,
                                      (GimpVector2 *) fg_select->stroke->data,
                                      FALSE);
    }

  width = ROUND ((gdouble) options->stroke_width);

  gimp_scan_convert_stroke (scan_convert,
                            width,
                            GIMP_JOIN_ROUND, GIMP_CAP_ROUND, 10.0,
                            0.0, NULL);

  if (options->draw_mode == GIMP_MATTING_DRAW_MODE_FOREGROUND)
    opacity = 1.0;
  else if (options->draw_mode == GIMP_MATTING_DRAW_MODE_BACKGROUND)
    opacity = 0.0;
  else
    opacity = 0.5;

  gimp_scan_convert_compose_value (scan_convert, fg_select->trimap,
                                   0, 0,
                                   opacity);

  gimp_scan_convert_free (scan_convert);

  g_array_free (fg_select->stroke, TRUE);
  fg_select->stroke = NULL;

}
static void
gimp_foreground_select_tool_select (GimpFreeSelectTool *free_sel,
                                    GimpDisplay        *display)
{
  GimpForegroundSelectTool *fg_select;
  GimpImage                *image = gimp_display_get_image (display);
  GimpDrawable             *drawable;
  GimpScanConvert          *scan_convert;
  const GimpVector2        *points;
  gint                      n_points;

  drawable  = gimp_image_get_active_drawable (image);
  fg_select = GIMP_FOREGROUND_SELECT_TOOL (free_sel);

  if (! drawable)
    return;

  if (fg_select->state == MATTING_STATE_FREE_SELECT)
    {
      scan_convert = gimp_scan_convert_new ();

      gimp_free_select_tool_get_points (free_sel,
                                        &points,
                                        &n_points);

      gimp_scan_convert_add_polyline (scan_convert,
                                      n_points,
                                      points,
                                      TRUE);

      fg_select->trimap = gegl_buffer_new (GEGL_RECTANGLE (0, 0,
                                                           gimp_image_get_width  (image),
                                                           gimp_image_get_height (image)),
                                           gimp_image_get_mask_format (image));

      gimp_scan_convert_render_value (scan_convert, fg_select->trimap,
                                      0, 0, 1.0);
      gimp_scan_convert_free (scan_convert);

      gimp_foreground_select_tool_set_trimap (fg_select, display);
    }
}
Example #8
0
gboolean
gimp_drawable_stroke_vectors (GimpDrawable       *drawable,
                              GimpStrokeOptions  *options,
                              GimpVectors        *vectors,
                              gboolean            push_undo,
                              GError            **error)
{
  const GimpBezierDesc *bezier;

  g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), FALSE);
  g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)), FALSE);
  g_return_val_if_fail (GIMP_IS_STROKE_OPTIONS (options), FALSE);
  g_return_val_if_fail (GIMP_IS_VECTORS (vectors), FALSE);
  g_return_val_if_fail (gimp_fill_options_get_style (GIMP_FILL_OPTIONS (options)) !=
                        GIMP_FILL_STYLE_PATTERN ||
                        gimp_context_get_pattern (GIMP_CONTEXT (options)) != NULL,
                        FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  bezier = gimp_vectors_get_bezier (vectors);

  if (bezier && bezier->num_data >= 2)
    {
      GimpScanConvert *scan_convert = gimp_scan_convert_new ();

      gimp_scan_convert_add_bezier (scan_convert, bezier);
      gimp_drawable_stroke_scan_convert (drawable, options,
                                         scan_convert, push_undo);

      gimp_scan_convert_free (scan_convert);

      return TRUE;
    }

  g_set_error_literal (error, GIMP_ERROR, GIMP_FAILED,
                       _("Not enough points to stroke"));

  return FALSE;
}
Example #9
0
static void
gimp_foreground_select_tool_select (GimpFreeSelectTool *free_sel,
                                    GimpDisplay        *display)
{
  GimpForegroundSelectTool    *fg_select;
  GimpForegroundSelectOptions *options;
  GimpImage                   *image = gimp_display_get_image (display);
  GimpDrawable                *drawable;
  GimpScanConvert             *scan_convert;
  GimpChannel                 *mask;
  const GimpVector2           *points;
  gint                         n_points;

  drawable  = gimp_image_get_active_drawable (image);
  fg_select = GIMP_FOREGROUND_SELECT_TOOL (free_sel);
  options   = GIMP_FOREGROUND_SELECT_TOOL_GET_OPTIONS (free_sel);

  if (fg_select->idle_id)
    {
      g_source_remove (fg_select->idle_id);
      fg_select->idle_id = 0;
    }

  if (! drawable)
    return;

  scan_convert = gimp_scan_convert_new ();

  gimp_free_select_tool_get_points (free_sel,
                                    &points,
                                    &n_points);

  gimp_scan_convert_add_polyline (scan_convert,
                                  n_points,
                                  points,
                                  TRUE);

  mask = gimp_channel_new (image,
                           gimp_image_get_width (image),
                           gimp_image_get_height (image),
                           "foreground-extraction", NULL);

  gimp_scan_convert_render_value (scan_convert,
                                  gimp_drawable_get_tiles (GIMP_DRAWABLE (mask)),
                                  0, 0, 128);
  gimp_scan_convert_free (scan_convert);

  if (fg_select->strokes)
    {
      GList *list;

      gimp_set_busy (image->gimp);

      /*  apply foreground and background markers  */
      for (list = fg_select->strokes; list; list = list->next)
        gimp_foreground_select_tool_stroke (mask, list->data);

      if (fg_select->state)
        gimp_drawable_foreground_extract_siox (GIMP_DRAWABLE (mask),
                                               fg_select->state,
                                               fg_select->refinement,
                                               options->smoothness,
                                               options->sensitivity,
                                               ! options->contiguous,
                                               GIMP_PROGRESS (fg_select));

      fg_select->refinement = SIOX_REFINEMENT_NO_CHANGE;

      gimp_unset_busy (image->gimp);
    }
  else
    {
      gint x1, y1;
      gint x2, y2;

      g_object_set (options, "background", FALSE, NULL);

      gimp_foreground_select_tool_get_area (mask, &x1, &y1, &x2, &y2);

      if (fg_select->state)
        g_warning ("state should be NULL here");

      fg_select->state =
        gimp_drawable_foreground_extract_siox_init (drawable,
                                                    x1, y1, x2 - x1, y2 - y1);
    }

  gimp_foreground_select_tool_set_mask (fg_select, display, mask);

  g_object_unref (mask);
}
Example #10
0
void
gimp_channel_select_vectors (GimpChannel    *channel,
                             const gchar    *undo_desc,
                             GimpVectors    *vectors,
                             GimpChannelOps  op,
                             gboolean        antialias,
                             gboolean        feather,
                             gdouble         feather_radius_x,
                             gdouble         feather_radius_y,
                             gboolean        push_undo)
{
  GimpScanConvert *scan_convert;
  GList           *stroke;
  gboolean         coords_added = FALSE;

  g_return_if_fail (GIMP_IS_CHANNEL (channel));
  g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (channel)));
  g_return_if_fail (undo_desc != NULL);
  g_return_if_fail (GIMP_IS_VECTORS (vectors));

  scan_convert = gimp_scan_convert_new ();

  for (stroke = vectors->strokes; stroke; stroke = stroke->next)
    {
      GArray   *coords;
      gboolean  closed;

      coords = gimp_stroke_interpolate (GIMP_STROKE (stroke->data),
                                        1.0, &closed);

      if (coords && coords->len)
        {
          GimpVector2 *points;
          gint         i;

          points = g_new0 (GimpVector2, coords->len);

          for (i = 0; i < coords->len; i++)
            {
              points[i].x = g_array_index (coords, GimpCoords, i).x;
              points[i].y = g_array_index (coords, GimpCoords, i).y;
            }

          gimp_scan_convert_add_polyline (scan_convert, coords->len,
                                          points, TRUE);
          coords_added = TRUE;

          g_free (points);
        }

      if (coords)
        g_array_free (coords, TRUE);
    }

  if (coords_added)
    gimp_channel_select_scan_convert (channel, undo_desc, scan_convert, 0, 0,
                                      op, antialias, feather,
                                      feather_radius_x, feather_radius_y,
                                      push_undo);

  gimp_scan_convert_free (scan_convert);
}
Example #11
0
void
gimp_drawable_stroke_boundary (GimpDrawable      *drawable,
                               GimpStrokeOptions *options,
                               const BoundSeg    *bound_segs,
                               gint               n_bound_segs,
                               gint               offset_x,
                               gint               offset_y)
{
  GimpScanConvert *scan_convert;
  BoundSeg        *stroke_segs;
  gint             n_stroke_segs;
  GimpVector2     *points;
  gint             n_points;
  gint             seg;
  gint             i;

  g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
  g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)));
  g_return_if_fail (GIMP_IS_STROKE_OPTIONS (options));

  if (n_bound_segs == 0)
    return;

  g_return_if_fail (bound_segs != NULL);

  stroke_segs = boundary_sort (bound_segs, n_bound_segs, &n_stroke_segs);

  if (n_stroke_segs == 0)
    return;

  scan_convert = gimp_scan_convert_new ();

  points = g_new0 (GimpVector2, n_bound_segs + 4);

  seg = 0;
  n_points = 0;

  points[n_points].x = (gdouble) (stroke_segs[0].x1 + offset_x);
  points[n_points].y = (gdouble) (stroke_segs[0].y1 + offset_y);

  n_points++;

  for (i = 0; i < n_stroke_segs; i++)
    {
      while (stroke_segs[seg].x1 != -1 ||
             stroke_segs[seg].x2 != -1 ||
             stroke_segs[seg].y1 != -1 ||
             stroke_segs[seg].y2 != -1)
        {
          points[n_points].x = (gdouble) (stroke_segs[seg].x1 + offset_x);
          points[n_points].y = (gdouble) (stroke_segs[seg].y1 + offset_y);

          n_points++;
          seg++;
        }

      /* Close the stroke points up */
      points[n_points] = points[0];

      n_points++;

      gimp_scan_convert_add_polyline (scan_convert, n_points, points, TRUE);

      n_points = 0;
      seg++;

      points[n_points].x = (gdouble) (stroke_segs[seg].x1 + offset_x);
      points[n_points].y = (gdouble) (stroke_segs[seg].y1 + offset_y);

      n_points++;
    }

  g_free (points);
  g_free (stroke_segs);

  gimp_drawable_stroke_scan_convert (drawable, options, scan_convert);

  gimp_scan_convert_free (scan_convert);
}