Commit 185cc412 authored by Øyvind Kolås's avatar Øyvind Kolås

Make changes to subpaths cause a full invalidation of the parent path

* gegl/property-types/gegl-path.c: (subpath_changed),
(gegl_path_add_parameter_path), Make changes to subpaths cause a full
invalidation of the parent path object.
(gegl_path_stamp), (gegl_path_stroke): take parameter scaling factors
from "linewidth" and "opacity" path parameters if they are available.
* gegl/property-types/gegl-path.h:
* operations/external/stroke.c: (get_bounding_box), (process),
(gegl_chant_class_init): pass in extra information that might be
useful to limit un-needed composites of stamps outside the roi.

svn path=/trunk/; revision=2685
parent 9b4e4ee0
2008-11-02 Øyvind Kolås <pippin@gimp.org>
* gegl/property-types/gegl-path.c: (subpath_changed),
(gegl_path_add_parameter_path), Make changes to subpaths cause a full
invalidation of the parent path object.
(gegl_path_stamp), (gegl_path_stroke): take parameter scaling factors
from "linewidth" and "opacity" path parameters if they are available.
* gegl/property-types/gegl-path.h:
* operations/external/stroke.c: (get_bounding_box), (process),
(gegl_chant_class_init): pass in extra information that might be
useful to limit un-needed composites of stamps outside the roi.
2008-11-02 Michael Natterer <mitch@gimp.org>
* operations/common/opacity.c: always take the "value" property
......
......@@ -1395,6 +1395,16 @@ GeglPath *gegl_path_get_parameter_path (GeglPath *path,
return NULL;
}
static void subpath_changed (GeglPath *path, const GeglRectangle *roi,
gpointer userdata)
{
gegl_path_emit_changed (userdata, NULL); /* change the full path for
now, shouldbe possible to
limit for the bounding box
of the length that has been
changed. */
}
/* creates a new path if one doesn't already exist */
GeglPath *gegl_path_add_parameter_path (GeglPath *self,
const gchar *parameter_name)
......@@ -1408,6 +1418,8 @@ GeglPath *gegl_path_add_parameter_path (GeglPath *self,
priv->parameter_names = g_slist_append (priv->parameter_names, g_strdup (parameter_name));
parameter_path = gegl_path_new ();
g_signal_connect (parameter_path, "changed", G_CALLBACK (subpath_changed), self);
GEGL_PATH_GET_PRIVATE (parameter_path)->parent_path = self;
#if 0
/* hard coded for line width,.. */
......@@ -1793,19 +1805,24 @@ typedef struct StampStatic {
gdouble radius;
}StampStatic;
#if 0
void gegl_path_stamp (GeglBuffer *buffer,
gdouble x,
gdouble y,
gdouble radius,
gdouble hardness,
GeglColor *color);
GeglColor *color,
gdouble opacity);
#endif
void gegl_path_stamp (GeglBuffer *buffer,
gdouble x,
gdouble y,
gdouble radius,
gdouble hardness,
GeglColor *color)
static void gegl_path_stamp (GeglBuffer *buffer,
const GeglRectangle *clip_rect,
gdouble x,
gdouble y,
gdouble radius,
gdouble hardness,
GeglColor *color,
gdouble opacity)
{
const gfloat *col = gegl_color_float4 (color);
static StampStatic s = {FALSE,}; /* XXX:
......@@ -1820,11 +1837,14 @@ void gegl_path_stamp (GeglBuffer *buffer,
GeglRectangle temp;
/* bail out if we wouldn't leave a mark on the buffer */
if (!gegl_rectangle_intersect (&temp, &roi, gegl_buffer_get_extent (buffer)))
if (!gegl_rectangle_intersect (&temp, &roi, clip_rect))
{
g_print ("bailing\n");
return;
}
if (s.format == NULL)
s.format = babl_format ("RGBA float");
s.format = babl_format ("RaGaBaA float");
if (s.buf == NULL ||
s.radius != radius)
......@@ -1869,6 +1889,7 @@ void gegl_path_stamp (GeglBuffer *buffer,
if (o!=0.0)
{
gint c;
o = o*opacity;
for (c=0;c<4;c++)
s.buf[i*4+c] = (s.buf[i*4+c] * (1.0-o) + col[c] * o);
}
......@@ -1881,10 +1902,12 @@ void gegl_path_stamp (GeglBuffer *buffer,
void gegl_path_stroke (GeglBuffer *buffer,
const GeglRectangle *clip_rect,
GeglPath *vector,
GeglColor *color,
gdouble linewidth,
gdouble hardness)
gdouble hardness,
gdouble opacity)
{
GeglPathPrivate *priv = GEGL_PATH_GET_PRIVATE (vector);
GeglRectangle bufext;
......@@ -1899,6 +1922,11 @@ void gegl_path_stroke (GeglBuffer *buffer,
if (!vector)
return;
if (!clip_rect)
{
clip_rect = gegl_buffer_get_extent (buffer);
}
ensure_flattened (vector);
iter = priv->flat_path;
......@@ -1963,16 +1991,22 @@ void gegl_path_stroke (GeglBuffer *buffer,
{
Point spot;
gfloat ratio = local_pos / distance;
gfloat radius = linewidth/2; /* XXX: gegl_path_parameter_calc (vector, "linewidth",
gfloat radius = linewidth/2;
/* XXX: gegl_path_parameter_calc (vector, "linewidth",
traveled_length) / 2;*/
/* horizon used to refetch the radius
* for each step from the tool, to be
* able to have variable line width
*/
if (gegl_path_get_parameter_path (vector, "linewidth"))
radius = gegl_path_parameter_calc (vector, "linewidth", traveled_length) /2;
if (gegl_path_get_parameter_path (vector, "opacity"))
radius = gegl_path_parameter_calc (vector, "opacity", traveled_length);
lerp (&spot, &a, &b, ratio);
gegl_path_stamp (buffer,
spot.x, spot.y, radius, hardness, color);
gegl_path_stamp (buffer, clip_rect,
spot.x, spot.y, radius, hardness, color, opacity);
traveled_length += spacing;
}
......
......@@ -199,10 +199,12 @@ void gegl_path_fill (GeglBuffer *buffer,
* (code from horizon)
*/
void gegl_path_stroke (GeglBuffer *buffer,
GeglPath *path,
const GeglRectangle *clip_rect,
GeglPath *vector,
GeglColor *color,
gdouble linewidth,
gdouble hardness);
gdouble hardness,
gdouble opacity);
......
......@@ -27,9 +27,11 @@ gegl_chant_path (path, _("Vector"),
_("A GeglVector representing the path of the stroke"))
gegl_chant_color (color, _("Color"), "rgba(0.1,0.2,0.3,0.1)",
_("Color of paint to use"))
gegl_chant_double (linewidth,_("Linewidth"), 0.0, 100.0, 3.0,
gegl_chant_double (linewidth,_("Linewidth"), 0.0, 100.0, 12.0,
_("width of stroke"))
gegl_chant_double (hardness, _("Hardness"), 0.0, 1.0, 0.7,
gegl_chant_double (opacity, _("Opacity"), -2.0, 2.0, 1.0,
_("opacity of stroke"))
gegl_chant_double (hardness, _("Hardness"), 0.0, 1.0, 0.6,
_("hardness of brush, 0.0 for soft brush 1.0 for hard brush."))
#else
......@@ -79,19 +81,21 @@ get_bounding_box (GeglOperation *operation)
gdouble x0, x1, y0, y1;
gegl_path_get_bounds (o->path, &x0, &x1, &y0, &y1);
defined.x = x0 - o->linewidth;
defined.y = y0 - o->linewidth;
defined.width = x1 - x0 + o->linewidth * 2;
defined.height = y1 - y0 + o->linewidth * 2;
defined.x = x0 - o->linewidth/2;
defined.y = y0 - o->linewidth/2;
defined.width = x1 - x0 + o->linewidth;
defined.height = y1 - y0 + o->linewidth;
return defined;
}
#if 0
static GeglRectangle
get_cached_region (GeglOperation *operation)
{
return get_bounding_box (operation);
}
#endif
static gboolean
process (GeglOperation *operation,
......@@ -103,7 +107,12 @@ process (GeglOperation *operation,
gegl_buffer_clear (output, &box);
g_object_set_data (G_OBJECT (operation), "path-radius", GINT_TO_POINTER((gint)(o->linewidth+1)/2));
gegl_path_stroke (output, o->path, o->color, o->linewidth, o->hardness);
gegl_path_stroke (output, result,
o->path,
o->color,
o->linewidth,
o->hardness,
o->opacity);
return TRUE;
}
......@@ -181,7 +190,9 @@ gegl_chant_class_init (GeglChantClass *klass)
operation_class->name = "gegl:stroke";
operation_class->categories = "render";
operation_class->description = _("Renders a brush stroke");
#if 0
operation_class->get_cached_region = (void*)get_cached_region;
#endif
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment