static void gimp_rotate_tool_motion (GimpTransformTool *tr_tool) { GimpTransformOptions *options = GIMP_TRANSFORM_TOOL_GET_OPTIONS (tr_tool); gdouble angle1, angle2, angle; gdouble px, py; gdouble x1, y1, x2, y2; if (tr_tool->function == TRANSFORM_HANDLE_PIVOT) { tr_tool->trans_info[PIVOT_X] = tr_tool->curx; tr_tool->trans_info[PIVOT_Y] = tr_tool->cury; return; } px = tr_tool->trans_info[PIVOT_X]; py = tr_tool->trans_info[PIVOT_Y]; x1 = tr_tool->curx - px; x2 = tr_tool->lastx - px; y1 = py - tr_tool->cury; y2 = py - tr_tool->lasty; /* find the first angle */ angle1 = atan2 (y1, x1); /* find the angle */ angle2 = atan2 (y2, x2); angle = angle2 - angle1; if (angle > G_PI || angle < -G_PI) angle = angle2 - ((angle1 < 0) ? 2.0 * G_PI + angle1 : angle1 - 2.0 * G_PI); /* increment the transform tool's angle */ tr_tool->trans_info[REAL_ANGLE] += angle; /* limit the angle to between -180 and 180 degrees */ if (tr_tool->trans_info[REAL_ANGLE] < - G_PI) { tr_tool->trans_info[REAL_ANGLE] += 2.0 * G_PI; } else if (tr_tool->trans_info[REAL_ANGLE] > G_PI) { tr_tool->trans_info[REAL_ANGLE] -= 2.0 * G_PI; } /* constrain the angle to 15-degree multiples if ctrl is held down */ if (options->constrain_rotate) { tr_tool->trans_info[ANGLE] = FIFTEEN_DEG * (gint) ((tr_tool->trans_info[REAL_ANGLE] + FIFTEEN_DEG / 2.0) / FIFTEEN_DEG); } else { tr_tool->trans_info[ANGLE] = tr_tool->trans_info[REAL_ANGLE]; } }
static void gimp_scale_tool_dialog_update (GimpTransformTool *tr_tool) { GimpTransformOptions *options = GIMP_TRANSFORM_TOOL_GET_OPTIONS (tr_tool); gint width = ROUND (tr_tool->trans_info[X1] - tr_tool->trans_info[X0]); gint height = ROUND (tr_tool->trans_info[Y1] - tr_tool->trans_info[Y0]); g_object_set (GIMP_SCALE_TOOL (tr_tool)->box, "width", width, "height", height, "keep-aspect", options->constrain, NULL); }
static void gimp_scale_tool_prepare (GimpTransformTool *tr_tool) { GimpScaleTool *scale = GIMP_SCALE_TOOL (tr_tool); GimpTransformOptions *options = GIMP_TRANSFORM_TOOL_GET_OPTIONS (tr_tool); GimpDisplay *display = GIMP_TOOL (tr_tool)->display; gdouble xres; gdouble yres; tr_tool->trans_info[X0] = (gdouble) tr_tool->x1; tr_tool->trans_info[Y0] = (gdouble) tr_tool->y1; tr_tool->trans_info[X1] = (gdouble) tr_tool->x2; tr_tool->trans_info[Y1] = (gdouble) tr_tool->y2; gimp_image_get_resolution (gimp_display_get_image (display), &xres, &yres); if (scale->box) { g_signal_handlers_disconnect_by_func (scale->box, gimp_scale_tool_size_notify, tr_tool); gtk_widget_destroy (scale->box); } /* Need to create a new GimpSizeBox widget because the initial * width and height is what counts as 100%. */ scale->box = g_object_new (GIMP_TYPE_SIZE_BOX, "width", tr_tool->x2 - tr_tool->x1, "height", tr_tool->y2 - tr_tool->y1, "keep-aspect", options->constrain_scale, "unit", gimp_display_get_shell (display)->unit, "xresolution", xres, "yresolution", yres, NULL); gtk_box_pack_start (GTK_BOX (gimp_tool_gui_get_vbox (tr_tool->gui)), scale->box, FALSE, FALSE, 0); gtk_widget_show (scale->box); g_signal_connect (scale->box, "notify", G_CALLBACK (gimp_scale_tool_size_notify), tr_tool); }
static void gimp_scale_tool_prepare (GimpTransformTool *tr_tool, GimpDisplay *display) { GimpScaleTool *scale = GIMP_SCALE_TOOL (tr_tool); GimpTransformOptions *options = GIMP_TRANSFORM_TOOL_GET_OPTIONS (tr_tool); tr_tool->trans_info[X0] = (gdouble) tr_tool->x1; tr_tool->trans_info[Y0] = (gdouble) tr_tool->y1; tr_tool->trans_info[X1] = (gdouble) tr_tool->x2; tr_tool->trans_info[Y1] = (gdouble) tr_tool->y2; if (scale->box) { g_signal_handlers_disconnect_by_func (scale->box, gimp_scale_tool_size_notify, tr_tool); gtk_widget_destroy (scale->box); } /* Need to create a new GimpSizeBox widget because the initial * width and height is what counts as 100%. */ scale->box = g_object_new (GIMP_TYPE_SIZE_BOX, "width", tr_tool->x2 - tr_tool->x1, "height", tr_tool->y2 - tr_tool->y1, "keep-aspect", options->constrain, "unit", GIMP_DISPLAY_SHELL (display->shell)->unit, "xresolution", display->image->xresolution, "yresolution", display->image->yresolution, NULL); gtk_container_set_border_width (GTK_CONTAINER (scale->box), 6); gtk_box_pack_start (GTK_BOX (GTK_DIALOG (tr_tool->dialog)->vbox), scale->box, FALSE, FALSE, 0); gtk_widget_show (scale->box); g_signal_connect (scale->box, "notify", G_CALLBACK (gimp_scale_tool_size_notify), tr_tool); }
static GeglBuffer * gimp_flip_tool_transform (GimpTransformTool *tr_tool, GimpItem *active_item, GeglBuffer *orig_buffer, gint orig_offset_x, gint orig_offset_y, GimpColorProfile **buffer_profile, gint *new_offset_x, gint *new_offset_y) { GimpFlipTool *flip = GIMP_FLIP_TOOL (tr_tool); GimpFlipOptions *options = GIMP_FLIP_TOOL_GET_OPTIONS (tr_tool); GimpTransformOptions *tr_options = GIMP_TRANSFORM_TOOL_GET_OPTIONS (tr_tool); GimpContext *context = GIMP_CONTEXT (options); GimpOrientationType flip_type = GIMP_ORIENTATION_UNKNOWN; gdouble axis = 0.0; gboolean clip_result = FALSE; GeglBuffer *ret = NULL; flip_type = gimp_flip_tool_get_flip_type (flip); if (flip->guide) { axis = gimp_guide_get_position (flip->guide); } else { switch (flip_type) { case GIMP_ORIENTATION_HORIZONTAL: axis = ((gdouble) tr_tool->x1 + (gdouble) (tr_tool->x2 - tr_tool->x1) / 2.0); break; case GIMP_ORIENTATION_VERTICAL: axis = ((gdouble) tr_tool->y1 + (gdouble) (tr_tool->y2 - tr_tool->y1) / 2.0); break; default: break; } } switch (tr_options->clip) { case GIMP_TRANSFORM_RESIZE_ADJUST: clip_result = FALSE; break; case GIMP_TRANSFORM_RESIZE_CLIP: clip_result = TRUE; break; default: g_return_val_if_reached (NULL); } if (orig_buffer) { /* this happens when transforming a selection cut out of a * normal drawable, or the selection */ /* always clip the selection and unfloated channels * so they keep their size */ if (GIMP_IS_CHANNEL (active_item) && ! babl_format_has_alpha (gegl_buffer_get_format (orig_buffer))) clip_result = TRUE; ret = gimp_drawable_transform_buffer_flip (GIMP_DRAWABLE (active_item), context, orig_buffer, orig_offset_x, orig_offset_y, flip_type, axis, clip_result, buffer_profile, new_offset_x, new_offset_y); } else { /* this happens for entire drawables, paths and layer groups */ /* always clip layer masks so they keep their size */ if (GIMP_IS_CHANNEL (active_item)) clip_result = TRUE; if (gimp_item_get_linked (active_item)) { gimp_item_linked_flip (active_item, context, flip_type, axis, clip_result); } else { gimp_item_flip (active_item, context, flip_type, axis, clip_result); } } return ret; }
static void gimp_scale_tool_size_notify (GtkWidget *box, GParamSpec *pspec, GimpTransformTool *tr_tool) { GimpTransformOptions *options = GIMP_TRANSFORM_TOOL_GET_OPTIONS (tr_tool); if (! strcmp (pspec->name, "width") || ! strcmp (pspec->name, "height")) { gint width; gint height; gint old_width; gint old_height; g_object_get (box, "width", &width, "height", &height, NULL); old_width = ROUND (tr_tool->trans_info[X1] - tr_tool->trans_info[X0]); old_height = ROUND (tr_tool->trans_info[Y1] - tr_tool->trans_info[Y0]); if ((width != old_width) || (height != old_height)) { gimp_draw_tool_pause (GIMP_DRAW_TOOL (tr_tool)); tr_tool->trans_info[X1] = tr_tool->trans_info[X0] + width; tr_tool->trans_info[Y1] = tr_tool->trans_info[Y0] + height; gimp_transform_tool_recalc (tr_tool, GIMP_TOOL (tr_tool)->display); gimp_transform_tool_expose_preview (tr_tool); gimp_draw_tool_resume (GIMP_DRAW_TOOL (tr_tool)); } } else if (! strcmp (pspec->name, "keep-aspect")) { gboolean constrain; g_object_get (box, "keep-aspect", &constrain, NULL); if (constrain != options->constrain) { gint width; gint height; g_object_get (box, "width", &width, "height", &height, NULL); /* Take the aspect ratio from the size box when the user * activates the constraint by pressing the chain button. */ tr_tool->aspect = (gdouble) width / (gdouble) height; g_object_set (options, "constrain", constrain, NULL); } } }
static void gimp_scale_tool_motion (GimpTransformTool *tr_tool, GimpDisplay *display) { GimpTransformOptions *options = GIMP_TRANSFORM_TOOL_GET_OPTIONS (tr_tool); gdouble *x1; gdouble *y1; gdouble *x2; gdouble *y2; gint dir_x; gint dir_y; gdouble diff_x = tr_tool->curx - tr_tool->lastx; gdouble diff_y = tr_tool->cury - tr_tool->lasty; switch (tr_tool->function) { case TRANSFORM_HANDLE_N: diff_x = 0; /* and fall through */ case TRANSFORM_HANDLE_NW: x1 = &tr_tool->trans_info[X0]; y1 = &tr_tool->trans_info[Y0]; x2 = &tr_tool->trans_info[X1]; y2 = &tr_tool->trans_info[Y1]; dir_x = dir_y = 1; break; case TRANSFORM_HANDLE_E: diff_y = 0; /* and fall through */ case TRANSFORM_HANDLE_NE: x1 = &tr_tool->trans_info[X1]; y1 = &tr_tool->trans_info[Y0]; x2 = &tr_tool->trans_info[X0]; y2 = &tr_tool->trans_info[Y1]; dir_x = -1; dir_y = 1; break; case TRANSFORM_HANDLE_W: diff_y = 0; /* and fall through */ case TRANSFORM_HANDLE_SW: x1 = &tr_tool->trans_info[X0]; y1 = &tr_tool->trans_info[Y1]; x2 = &tr_tool->trans_info[X1]; y2 = &tr_tool->trans_info[Y0]; dir_x = 1; dir_y = -1; break; case TRANSFORM_HANDLE_S: diff_x = 0; /* and fall through */ case TRANSFORM_HANDLE_SE: x1 = &tr_tool->trans_info[X1]; y1 = &tr_tool->trans_info[Y1]; x2 = &tr_tool->trans_info[X0]; y2 = &tr_tool->trans_info[Y0]; dir_x = dir_y = -1; break; case TRANSFORM_HANDLE_CENTER: tr_tool->trans_info[X0] += diff_x; tr_tool->trans_info[Y0] += diff_y; tr_tool->trans_info[X1] += diff_x; tr_tool->trans_info[Y1] += diff_y; tr_tool->trans_info[X2] += diff_x; tr_tool->trans_info[Y2] += diff_y; tr_tool->trans_info[X3] += diff_x; tr_tool->trans_info[Y3] += diff_y; return; default: return; } *x1 += diff_x; *y1 += diff_y; /* if control is being held, constrain the aspect ratio */ if (options->constrain) { /* FIXME: improve this */ gdouble h = tr_tool->trans_info[Y1] - tr_tool->trans_info[Y0]; switch (tr_tool->function) { case TRANSFORM_HANDLE_NW: case TRANSFORM_HANDLE_SW: tr_tool->trans_info[X0] = tr_tool->trans_info[X1] - tr_tool->aspect * h; break; case TRANSFORM_HANDLE_NE: case TRANSFORM_HANDLE_SE: tr_tool->trans_info[X1] = tr_tool->trans_info[X0] + tr_tool->aspect * h; break; default: break; } } if (dir_x > 0) { if (*x1 >= *x2) *x1 = *x2 - 1; } else { if (*x1 <= *x2) *x1 = *x2 + 1; } if (dir_y > 0) { if (*y1 >= *y2) *y1 = *y2 - 1; } else { if (*y1 <= *y2) *y1 = *y2 + 1; } }