Commit 44a5a34d authored by Alexia Death's avatar Alexia Death
Browse files

app: Make brush boundaries dynamic aswell

parent 96bce380
......@@ -361,6 +361,49 @@ boundary_simplify (BoundSeg *sorted_segs,
return (BoundSeg *) g_array_free (new_bounds, FALSE);
}
/*Transform boundary based on a matrix*/
BoundSeg * boundary_transform (const BoundSeg *segs,
gint *num_segs,
GimpMatrix3 *matrix)
{
Boundary *boundary = boundary_new(NULL);
gint i;
for (i = 0; i < *num_segs; i++)
{
/*dont transform sorting sentinels*/
if (!(segs[i].x1 == -1 &&
segs[i].y1 == -1 &&
segs[i].x2 == -1 &&
segs[i].y2 == -1))
{
gdouble x1, y1, x2, y2;
gimp_matrix3_transform_point (matrix, segs[i].x1, segs[i].y1, &x1, &y1);
gimp_matrix3_transform_point (matrix, segs[i].x2, segs[i].y2, &x2, &y2);
boundary_add_seg (boundary,
(gint) ceil(x1), (gint) ceil(y1),
(gint) ceil(x2), (gint) ceil(y2),
segs[i].open);
}
else
{
/*Keep the sorting sentinel*/
boundary_add_seg (boundary,
-1, -1,
-1, -1,
segs[i].open);
}
}
*num_segs = boundary->num_segs;
return boundary_free(boundary, FALSE);
}
/* private functions */
......
......@@ -56,6 +56,9 @@ BoundSeg * boundary_simplify (BoundSeg *sorted_segs,
gint num_groups,
gint *num_segs);
BoundSeg * boundary_transform (const BoundSeg *segs,
gint *num_segs,
GimpMatrix3 *matrix);
#endif /* __BOUNDARY_H__ */
......@@ -213,6 +213,7 @@ gimp_brush_core_init (GimpBrushCore *core)
core->rand = g_rand_new ();
core->brush_bound_segs = NULL;
core->transformed_brush_bound_segs = NULL;
core->n_brush_bound_segs = 0;
core->brush_bound_width = 0;
core->brush_bound_height = 0;
......@@ -315,6 +316,12 @@ gimp_brush_core_finalize (GObject *object)
core->brush_bound_height = 0;
}
if (core->transformed_brush_bound_segs)
{
g_free (core->transformed_brush_bound_segs);
core->transformed_brush_bound_segs = NULL;
}
G_OBJECT_CLASS (parent_class)->finalize (object);
}
......@@ -432,33 +439,10 @@ gimp_brush_core_start (GimpPaintCore *paint_core,
if (GIMP_BRUSH_CORE_GET_CLASS (core)->handles_transforming_brush)
{
GimpImage *image = gimp_item_get_image (GIMP_ITEM (drawable));
gdouble fade_point;
core->scale = paint_options->brush_scale;
core->angle = paint_options->brush_angle;
core->aspect_ratio = paint_options->brush_aspect_ratio;
if (GIMP_BRUSH_CORE_GET_CLASS (core)->handles_dynamic_transforming_brush)
{
fade_point = gimp_paint_options_get_fade (paint_options, image,
paint_core->pixel_dist);
core->scale *= gimp_dynamics_output_get_linear_value (core->dynamics->size_output,
coords,
paint_options,
fade_point);
core->angle += gimp_dynamics_output_get_angular_value (core->dynamics->angle_output,
coords,
gimp_brush_core_eval_transform_dynamics (paint_core,
drawable,
paint_options,
fade_point);
core->aspect_ratio *= gimp_dynamics_output_get_aspect_value (core->dynamics->aspect_ratio_output,
coords,
paint_options,
fade_point);
}
coords);
}
core->spacing = (gdouble) gimp_brush_get_spacing (core->main_brush) / 100.0;
......@@ -845,42 +829,10 @@ gimp_brush_core_get_paint_area (GimpPaintCore *paint_core,
if (GIMP_BRUSH_CORE_GET_CLASS (core)->handles_transforming_brush)
{
GimpImage *image = gimp_item_get_image (GIMP_ITEM (drawable));
gdouble fade_point;
core->scale = paint_options->brush_scale;
core->angle = paint_options->brush_angle;
core->aspect_ratio = paint_options->brush_aspect_ratio;
if (GIMP_BRUSH_CORE_GET_CLASS (core)->handles_dynamic_transforming_brush)
{
fade_point = gimp_paint_options_get_fade (paint_options, image,
paint_core->pixel_dist);
core->scale *=
gimp_dynamics_output_get_linear_value (core->dynamics->size_output,
coords,
paint_options,
fade_point);
core->angle +=
gimp_dynamics_output_get_angular_value (core->dynamics->angle_output,
coords,
paint_options,
fade_point);
core->hardness =
gimp_dynamics_output_get_linear_value (core->dynamics->hardness_output,
coords,
paint_options,
fade_point);
core->aspect_ratio *=
gimp_dynamics_output_get_aspect_value (core->dynamics->aspect_ratio_output,
coords,
gimp_brush_core_eval_transform_dynamics (paint_core,
drawable,
paint_options,
fade_point);
}
coords);
}
core->scale = gimp_brush_core_clamp_brush_scale (core, core->scale);
......@@ -1006,7 +958,7 @@ gimp_brush_core_create_bound_segs (GimpBrushCore *core,
scale = gimp_brush_core_clamp_brush_scale (core, scale);
mask = gimp_brush_transform_mask (core->main_brush,
scale, aspect_ratio, angle, 1.0);
1.0, 1.0, 0.0, 1.0);
}
if (mask)
......@@ -1045,6 +997,74 @@ gimp_brush_core_create_bound_segs (GimpBrushCore *core,
}
}
void
gimp_brush_core_transform_bound_segs (GimpBrushCore *core,
GimpPaintOptions *paint_options)
{
gdouble scale;
gdouble angle;
gdouble aspect_ratio;
gdouble height;
gdouble width;
GimpMatrix3 matrix;
gdouble scale_x;
gdouble scale_y;
g_return_if_fail (GIMP_IS_BRUSH_CORE (core));
g_return_if_fail (core->main_brush != NULL);
g_return_if_fail (core->brush_bound_segs != NULL);
scale = core->scale;
angle = core->angle;
aspect_ratio = core->aspect_ratio;
height = core->main_brush->mask->height;
width = core->main_brush->mask->width;
if (aspect_ratio < 1.0)
{
scale_x = scale * aspect_ratio;
scale_y = scale;
}
else
{
scale_x = scale;
scale_y = scale / aspect_ratio;
}
if (core->transformed_brush_bound_segs)
{
g_free (core->transformed_brush_bound_segs);
core->transformed_brush_bound_segs = NULL;
}
if ((scale > 0.0) && (aspect_ratio > 0.0))
{
const gdouble center_x = width / 2;
const gdouble center_y = height / 2;
scale = gimp_brush_core_clamp_brush_scale (core, scale);
gimp_matrix3_identity (&matrix);
gimp_matrix3_translate (&matrix, - center_x, - center_y);
gimp_matrix3_rotate (&matrix, -2 * G_PI * angle);
gimp_matrix3_translate (&matrix, center_x, center_y);
gimp_matrix3_scale (&matrix, scale_x, scale_y);
core->transformed_brush_bound_segs
= boundary_transform (core->brush_bound_segs,
&core->n_brush_bound_segs,
&matrix);
core->transformed_brush_bound_width = core->brush_bound_width * scale_x;
core->transformed_brush_bound_height = core->brush_bound_height * scale_y;
}
}
void
gimp_brush_core_paste_canvas (GimpBrushCore *core,
GimpDrawable *drawable,
......@@ -1653,6 +1673,58 @@ gimp_brush_core_get_brush_mask (GimpBrushCore *core,
return mask;
}
void
gimp_brush_core_eval_transform_dynamics (GimpPaintCore *paint_core,
GimpDrawable *drawable,
GimpPaintOptions *paint_options,
const GimpCoords *coords)
{
GimpBrushCore *core = GIMP_BRUSH_CORE (paint_core);
GimpImage *image;
gdouble fade_point = 1.0;
core->scale = paint_options->brush_scale;
core->angle = paint_options->brush_angle;
core->aspect_ratio = paint_options->brush_aspect_ratio;
g_return_if_fail (GIMP_IS_DYNAMICS (core->dynamics));
if (GIMP_BRUSH_CORE_GET_CLASS (core)->handles_dynamic_transforming_brush)
{
if (drawable)
{
image = gimp_item_get_image (GIMP_ITEM (drawable));
fade_point = gimp_paint_options_get_fade (paint_options, image,
paint_core->pixel_dist);
}
core->scale *=
gimp_dynamics_output_get_linear_value (core->dynamics->size_output,
coords,
paint_options,
fade_point);
core->angle +=
gimp_dynamics_output_get_angular_value (core->dynamics->angle_output,
coords,
paint_options,
fade_point);
core->hardness =
gimp_dynamics_output_get_linear_value (core->dynamics->hardness_output,
coords,
paint_options,
fade_point);
core->aspect_ratio *=
gimp_dynamics_output_get_aspect_value (core->dynamics->aspect_ratio_output,
coords,
paint_options,
fade_point);
}
}
/**************************************************/
/* Brush pipe utility functions */
......
......@@ -84,9 +84,12 @@ struct _GimpBrushCore
/* don't use these... */
BoundSeg *brush_bound_segs;
BoundSeg *transformed_brush_bound_segs;
gint n_brush_bound_segs;
gint brush_bound_width;
gint brush_bound_height;
gint transformed_brush_bound_width;
gint transformed_brush_bound_height;
};
struct _GimpBrushCoreClass
......@@ -118,6 +121,8 @@ void gimp_brush_core_set_dynamics (GimpBrushCore *core,
void gimp_brush_core_create_bound_segs (GimpBrushCore *core,
GimpPaintOptions *options);
void gimp_brush_core_transform_bound_segs (GimpBrushCore *core,
GimpPaintOptions *paint_options);
void gimp_brush_core_paste_canvas (GimpBrushCore *core,
GimpDrawable *drawable,
......@@ -150,4 +155,9 @@ TempBuf * gimp_brush_core_get_brush_mask (GimpBrushCore *core,
gdouble dynamic_hardness);
void gimp_brush_core_eval_transform_dynamics (GimpPaintCore *paint_core,
GimpDrawable *drawable,
GimpPaintOptions *paint_options,
const GimpCoords *coords);
#endif /* __GIMP_BRUSH_CORE_H__ */
......@@ -220,6 +220,7 @@ gimp_brush_tool_oper_update (GimpTool *tool,
GimpPaintTool *paint_tool = GIMP_PAINT_TOOL (tool);
GimpBrushCore *brush_core = GIMP_BRUSH_CORE (paint_tool->core);
GimpBrush *brush;
GimpDynamics *dynamics;
brush_tool->brush_x = coords->x;
brush_tool->brush_y = coords->y;
......@@ -228,6 +229,19 @@ gimp_brush_tool_oper_update (GimpTool *tool,
if (brush_core->main_brush != brush)
gimp_brush_core_set_brush (brush_core, brush);
dynamics = gimp_context_get_dynamics (GIMP_CONTEXT (paint_options));
if (brush_core->dynamics != dynamics)
gimp_brush_core_set_dynamics (brush_core, dynamics);
if (GIMP_BRUSH_CORE_GET_CLASS (brush_core)->handles_transforming_brush)
{
gimp_brush_core_eval_transform_dynamics (paint_tool->core,
NULL,
paint_options,
coords);
}
}
gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
......@@ -302,10 +316,13 @@ gimp_brush_tool_draw_brush (GimpBrushTool *brush_tool,
}
if (brush_core->brush_bound_segs)
gimp_brush_core_transform_bound_segs (brush_core, options);
if (brush_core->transformed_brush_bound_segs)
{
GimpDisplayShell *shell = gimp_display_get_shell (draw_tool->display);
gdouble width = brush_core->brush_bound_width;
gdouble height = brush_core->brush_bound_height;
gdouble width = brush_core->transformed_brush_bound_width;
gdouble height = brush_core->transformed_brush_bound_height;
/* don't draw the boundary if it becomes too small */
if (SCALEX (shell, width) > 4 && SCALEY (shell, height) > 4)
......@@ -326,7 +343,7 @@ gimp_brush_tool_draw_brush (GimpBrushTool *brush_tool,
}
gimp_draw_tool_draw_boundary (draw_tool,
brush_core->brush_bound_segs,
brush_core->transformed_brush_bound_segs,
brush_core->n_brush_bound_segs,
x, y,
FALSE);
......
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