Bug 753412 - New Canvas rotation feature rotates brush.

Replace the "lock brush size to zoom" paint option with a "lock
brush to view" option, which links the entire brush transform to
the view transform, so that the brush remains invariant in display
space under scaling, rotation, and reflection.
This commit is contained in:
Ell 2017-12-22 16:59:13 -05:00
parent a0b73420ec
commit eded91e118
10 changed files with 83 additions and 52 deletions

View File

@ -249,8 +249,10 @@ struct _GimpCoords
gdouble wheel;
gdouble velocity;
gdouble direction;
gdouble xscale; /* the view scale */
gdouble xscale; /* the view scale */
gdouble yscale;
gdouble angle; /* the view rotation angle */
gboolean reflect; /* whether the view is reflected */
gboolean extended;
};

View File

@ -582,9 +582,9 @@ gimp_brush_transform_size (GimpBrush *brush,
g_return_if_fail (width != NULL);
g_return_if_fail (height != NULL);
if (scale == 1.0 &&
aspect_ratio == 0.0 &&
((angle == 0.0) || (angle == 0.5) || (angle == 1.0)))
if (scale == 1.0 &&
aspect_ratio == 0.0 &&
fmod (angle, 0.5) == 0.0)
{
*width = gimp_temp_buf_get_width (brush->priv->mask);
*height = gimp_temp_buf_get_height (brush->priv->mask);

View File

@ -324,8 +324,10 @@ gimp_coords_interpolate_catmull (const GimpCoords catmul_pt1,
coords.direction = coords.direction - floor (coords.direction);
coords.xscale = end_coords.xscale;
coords.yscale = end_coords.yscale;
coords.xscale = end_coords.xscale;
coords.yscale = end_coords.yscale;
coords.angle = end_coords.angle;
coords.reflect = end_coords.reflect;
g_array_append_val (*ret_coords, coords);

View File

@ -553,8 +553,19 @@ gimp_dynamics_output_get_angular_value (GimpDynamicsOutput *output,
if (private->use_direction)
{
total += gimp_curve_map_value (private->direction_curve,
coords->direction);
gdouble angle = gimp_curve_map_value (private->direction_curve,
coords->direction);
if (options->brush_lock_to_view)
{
if (coords->reflect)
angle = 0.5 - angle;
angle -= coords->angle;
angle = fmod (fmod (angle, 1.0) + 1.0, 1.0);
}
total += angle;
factors++;
}

View File

@ -613,9 +613,13 @@ gimp_display_shell_untransform_coords (GimpDisplayShell *shell,
image_coords->x /= shell->scale_x;
image_coords->y /= shell->scale_y;
image_coords->xscale = shell->scale_x;
image_coords->yscale = shell->scale_y;
image_coords->xscale = shell->scale_x;
image_coords->yscale = shell->scale_y;
image_coords->angle = shell->rotate_angle / 360.0;
image_coords->reflect = shell->flip_horizontally ^ shell->flip_vertically;
if (shell->flip_vertically)
image_coords->angle += 0.5;
}
/**

View File

@ -326,7 +326,7 @@ gimp_brush_core_pre_paint (GimpPaintCore *paint_core,
paint_options,
fade_point);
if (paint_options->brush_zoom &&
if (paint_options->brush_lock_to_view &&
MAX (current_coords.xscale, current_coords.yscale) > 0)
{
scale /= MAX (current_coords.xscale, current_coords.yscale);
@ -740,6 +740,8 @@ gimp_brush_core_interpolate (GimpPaintCore *paint_core,
current_coords.direction = temp_direction;
current_coords.xscale = last_coords.xscale;
current_coords.yscale = last_coords.yscale;
current_coords.angle = last_coords.angle;
current_coords.reflect = last_coords.reflect;
if (core->jitter > 0.0)
{
@ -790,6 +792,8 @@ gimp_brush_core_interpolate (GimpPaintCore *paint_core,
current_coords.velocity = last_coords.velocity + delta_velocity;
current_coords.xscale = last_coords.xscale;
current_coords.yscale = last_coords.yscale;
current_coords.angle = last_coords.angle;
current_coords.reflect = last_coords.reflect;
gimp_paint_core_set_current_coords (paint_core, &current_coords);
gimp_paint_core_set_last_coords (paint_core, &current_coords);
@ -1500,7 +1504,8 @@ gimp_brush_core_eval_transform_dynamics (GimpBrushCore *core,
core->scale = paint_options->brush_size / max_side;
if (paint_options->brush_zoom && MAX (coords->xscale, coords->yscale) > 0)
if (paint_options->brush_lock_to_view &&
MAX (coords->xscale, coords->yscale) > 0)
{
core->scale /= MAX (coords->xscale, coords->yscale);
@ -1519,6 +1524,12 @@ gimp_brush_core_eval_transform_dynamics (GimpBrushCore *core,
core->reflect = FALSE;
core->hardness = paint_options->brush_hardness;
if (paint_options->brush_lock_to_view)
{
core->angle += coords->angle;
core->reflect = coords->reflect;
}
if (! GIMP_IS_DYNAMICS (core->dynamics))
return;

View File

@ -40,15 +40,20 @@
#define DEFAULT_BRUSH_SIZE 20.0
#define DEFAULT_BRUSH_ZOOM FALSE
#define DEFAULT_BRUSH_ASPECT_RATIO 0.0
#define DEFAULT_BRUSH_ANGLE 0.0
#define DEFAULT_BRUSH_SPACING 0.1
#define DEFAULT_BRUSH_HARDNESS 1.0 /* Generated brushes have their own */
#define DEFAULT_BRUSH_FORCE 0.5
#define DEFAULT_BRUSH_LINK_SIZE TRUE
#define DEFAULT_BRUSH_LINK_ASPECT_RATIO TRUE
#define DEFAULT_BRUSH_LINK_ANGLE TRUE
#define DEFAULT_BRUSH_LINK_SPACING TRUE
#define DEFAULT_BRUSH_LINK_HARDNESS TRUE
#define DEFAULT_BRUSH_LOCK_TO_VIEW FALSE
#define DEFAULT_APPLICATION_MODE GIMP_PAINT_CONSTANT
#define DEFAULT_HARD FALSE
@ -73,12 +78,6 @@
#define DEFAULT_SMOOTHING_QUALITY 20
#define DEFAULT_SMOOTHING_FACTOR 50
#define DEFAULT_BRUSH_LINK_SIZE TRUE
#define DEFAULT_BRUSH_LINK_ASPECT_RATIO TRUE
#define DEFAULT_BRUSH_LINK_ANGLE TRUE
#define DEFAULT_BRUSH_LINK_SPACING TRUE
#define DEFAULT_BRUSH_LINK_HARDNESS TRUE
enum
{
PROP_0,
@ -88,13 +87,20 @@ enum
PROP_USE_APPLICATOR, /* temp debug */
PROP_BRUSH_SIZE,
PROP_BRUSH_ZOOM,
PROP_BRUSH_ASPECT_RATIO,
PROP_BRUSH_ANGLE,
PROP_BRUSH_SPACING,
PROP_BRUSH_HARDNESS,
PROP_BRUSH_FORCE,
PROP_BRUSH_LINK_SIZE,
PROP_BRUSH_LINK_ASPECT_RATIO,
PROP_BRUSH_LINK_ANGLE,
PROP_BRUSH_LINK_SPACING,
PROP_BRUSH_LINK_HARDNESS,
PROP_BRUSH_LOCK_TO_VIEW,
PROP_APPLICATION_MODE,
PROP_HARD,
@ -121,13 +127,7 @@ enum
PROP_USE_SMOOTHING,
PROP_SMOOTHING_QUALITY,
PROP_SMOOTHING_FACTOR,
PROP_BRUSH_LINK_SIZE,
PROP_BRUSH_LINK_ASPECT_RATIO,
PROP_BRUSH_LINK_ANGLE,
PROP_BRUSH_LINK_SPACING,
PROP_BRUSH_LINK_HARDNESS
PROP_SMOOTHING_FACTOR
};
@ -193,13 +193,6 @@ gimp_paint_options_class_init (GimpPaintOptionsClass *klass)
1.0, GIMP_BRUSH_MAX_SIZE, DEFAULT_BRUSH_SIZE,
GIMP_PARAM_STATIC_STRINGS);
GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_BRUSH_ZOOM,
"brush-zoom",
_("Brush Zoom"),
_("Link brush size with canvas zoom"),
DEFAULT_BRUSH_ZOOM,
GIMP_PARAM_STATIC_STRINGS);
GIMP_CONFIG_PROP_DOUBLE (object_class, PROP_BRUSH_ASPECT_RATIO,
"brush-aspect-ratio",
_("Aspect Ratio"),
@ -270,6 +263,13 @@ gimp_paint_options_class_init (GimpPaintOptionsClass *klass)
DEFAULT_BRUSH_LINK_HARDNESS,
GIMP_PARAM_STATIC_STRINGS);
GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_BRUSH_LOCK_TO_VIEW,
"brush-lock-to-view",
_("Lock brush to view"),
_("Keep brush appearance fixed realtive to the view"),
DEFAULT_BRUSH_LOCK_TO_VIEW,
GIMP_PARAM_STATIC_STRINGS);
GIMP_CONFIG_PROP_ENUM (object_class, PROP_APPLICATION_MODE,
"application-mode",
_("Incremental"),
@ -493,10 +493,6 @@ gimp_paint_options_set_property (GObject *object,
options->brush_size = g_value_get_double (value);
break;
case PROP_BRUSH_ZOOM:
options->brush_zoom = g_value_get_boolean (value);
break;
case PROP_BRUSH_ASPECT_RATIO:
options->brush_aspect_ratio = g_value_get_double (value);
break;
@ -537,6 +533,10 @@ gimp_paint_options_set_property (GObject *object,
options->brush_link_hardness = g_value_get_boolean (value);
break;
case PROP_BRUSH_LOCK_TO_VIEW:
options->brush_lock_to_view = g_value_get_boolean (value);
break;
case PROP_APPLICATION_MODE:
options->application_mode = g_value_get_enum (value);
break;
@ -653,10 +653,6 @@ gimp_paint_options_get_property (GObject *object,
g_value_set_double (value, options->brush_size);
break;
case PROP_BRUSH_ZOOM:
g_value_set_boolean (value, options->brush_zoom);
break;
case PROP_BRUSH_ASPECT_RATIO:
g_value_set_double (value, options->brush_aspect_ratio);
break;
@ -697,6 +693,10 @@ gimp_paint_options_get_property (GObject *object,
g_value_set_boolean (value, options->brush_link_hardness);
break;
case PROP_BRUSH_LOCK_TO_VIEW:
g_value_set_boolean (value, options->brush_lock_to_view);
break;
case PROP_APPLICATION_MODE:
g_value_set_enum (value, options->application_mode);
break;
@ -1110,7 +1110,6 @@ gimp_paint_options_copy_brush_props (GimpPaintOptions *src,
GimpPaintOptions *dest)
{
gdouble brush_size;
gboolean brush_zoom;
gdouble brush_angle;
gdouble brush_aspect_ratio;
gdouble brush_spacing;
@ -1123,12 +1122,13 @@ gimp_paint_options_copy_brush_props (GimpPaintOptions *src,
gboolean brush_link_spacing;
gboolean brush_link_hardness;
gboolean brush_lock_to_view;
g_return_if_fail (GIMP_IS_PAINT_OPTIONS (src));
g_return_if_fail (GIMP_IS_PAINT_OPTIONS (dest));
g_object_get (src,
"brush-size", &brush_size,
"brush-zoom", &brush_zoom,
"brush-angle", &brush_angle,
"brush-aspect-ratio", &brush_aspect_ratio,
"brush-spacing", &brush_spacing,
@ -1139,11 +1139,11 @@ gimp_paint_options_copy_brush_props (GimpPaintOptions *src,
"brush-link-aspect-ratio", &brush_link_aspect_ratio,
"brush-link-spacing", &brush_link_spacing,
"brush-link-hardness", &brush_link_hardness,
"brush-lock-to-view", &brush_lock_to_view,
NULL);
g_object_set (dest,
"brush-size", brush_size,
"brush-zoom", brush_zoom,
"brush-angle", brush_angle,
"brush-aspect-ratio", brush_aspect_ratio,
"brush-spacing", brush_spacing,
@ -1154,6 +1154,7 @@ gimp_paint_options_copy_brush_props (GimpPaintOptions *src,
"brush-link-aspect-ratio", brush_link_aspect_ratio,
"brush-link-spacing", brush_link_spacing,
"brush-link-hardness", brush_link_hardness,
"brush-lock-to-view", brush_lock_to_view,
NULL);
}

View File

@ -85,7 +85,6 @@ struct _GimpPaintOptions
GimpBrush *brush; /* weak-refed storage for the GUI */
gdouble brush_size;
gboolean brush_zoom;
gdouble brush_angle;
gdouble brush_aspect_ratio;
gdouble brush_spacing;
@ -98,6 +97,8 @@ struct _GimpPaintOptions
gboolean brush_link_spacing;
gboolean brush_link_hardness;
gboolean brush_lock_to_view;
GimpPaintApplicationMode application_mode;
GimpPaintApplicationMode application_mode_save;

View File

@ -488,7 +488,7 @@ gimp_smudge_accumulator_size (GimpPaintOptions *paint_options,
gdouble max_view_scale = 1.0;
gdouble max_brush_size;
if (paint_options->brush_zoom)
if (paint_options->brush_lock_to_view)
max_view_scale = MAX (coords->xscale, coords->yscale);
max_brush_size = MIN (paint_options->brush_size / max_view_scale,

View File

@ -253,13 +253,12 @@ gimp_paint_options_gui (GimpToolOptions *tool_options)
gtk_widget_show (frame);
}
/* the "Link size to zoom" toggle */
/* the "Lock brush to view" toggle */
if (g_type_is_a (tool_type, GIMP_TYPE_BRUSH_TOOL))
{
GtkWidget *button;
button = gimp_prop_check_button_new (config, "brush-zoom",
_("Lock brush size to zoom"));
button = gimp_prop_check_button_new (config, "brush-lock-to-view", NULL);
gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
gtk_widget_show (button);
}