gboolean gimp_draw_tool_on_vectors_curve (GimpDrawTool *draw_tool, GimpDisplay *display, GimpVectors *vectors, const GimpCoords *coord, gint width, gint height, GimpCoords *ret_coords, gdouble *ret_pos, GimpAnchor **ret_segment_start, GimpAnchor **ret_segment_end, GimpStroke **ret_stroke) { GimpStroke *stroke = NULL; GimpAnchor *segment_start; GimpAnchor *segment_end; GimpCoords min_coords = GIMP_COORDS_DEFAULT_VALUES; GimpCoords cur_coords; gdouble min_dist, cur_dist, cur_pos; g_return_val_if_fail (GIMP_IS_DRAW_TOOL (draw_tool), FALSE); g_return_val_if_fail (GIMP_IS_DISPLAY (display), FALSE); g_return_val_if_fail (GIMP_IS_VECTORS (vectors), FALSE); g_return_val_if_fail (coord != NULL, FALSE); if (ret_coords) *ret_coords = *coord; if (ret_pos) *ret_pos = -1.0; if (ret_segment_start) *ret_segment_start = NULL; if (ret_segment_start) *ret_segment_end = NULL; if (ret_stroke) *ret_stroke = NULL; min_dist = -1.0; while ((stroke = gimp_vectors_stroke_get_next (vectors, stroke))) { cur_dist = gimp_stroke_nearest_point_get (stroke, coord, 1.0, &cur_coords, &segment_start, &segment_end, &cur_pos); if (cur_dist >= 0 && (min_dist < 0 || cur_dist < min_dist)) { min_dist = cur_dist; min_coords = cur_coords; if (ret_coords) *ret_coords = cur_coords; if (ret_pos) *ret_pos = cur_pos; if (ret_segment_start) *ret_segment_start = segment_start; if (ret_segment_end) *ret_segment_end = segment_end; if (ret_stroke) *ret_stroke = stroke; } } if (min_dist >= 0 && gimp_draw_tool_on_handle (draw_tool, display, coord->x, coord->y, GIMP_HANDLE_CIRCLE, min_coords.x, min_coords.y, width, height, GIMP_HANDLE_ANCHOR_CENTER)) { return TRUE; } return FALSE; }
gboolean gimp_image_snap_point (GimpImage *image, gdouble x, gdouble y, gdouble *tx, gdouble *ty, gdouble epsilon_x, gdouble epsilon_y, gboolean snap_to_guides, gboolean snap_to_grid, gboolean snap_to_canvas, gboolean snap_to_vectors) { gdouble mindist_x = G_MAXDOUBLE; gdouble mindist_y = G_MAXDOUBLE; gboolean snapped = FALSE; g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE); g_return_val_if_fail (tx != NULL, FALSE); g_return_val_if_fail (ty != NULL, FALSE); *tx = x; *ty = y; if (! gimp_image_get_guides (image)) snap_to_guides = FALSE; if (! gimp_image_get_grid (image)) snap_to_grid = FALSE; if (! gimp_image_get_active_vectors (image)) snap_to_vectors = FALSE; if (! (snap_to_guides || snap_to_grid || snap_to_canvas || snap_to_vectors)) return FALSE; if (x < -epsilon_x || x >= (gimp_image_get_width (image) + epsilon_x) || y < -epsilon_y || y >= (gimp_image_get_height (image) + epsilon_y)) { return FALSE; } if (snap_to_guides) { GList *list; for (list = gimp_image_get_guides (image); list; list = g_list_next (list)) { GimpGuide *guide = list->data; gint position = gimp_guide_get_position (guide); switch (gimp_guide_get_orientation (guide)) { case GIMP_ORIENTATION_HORIZONTAL: snapped |= gimp_image_snap_distance (y, position, epsilon_y, &mindist_y, ty); break; case GIMP_ORIENTATION_VERTICAL: snapped |= gimp_image_snap_distance (x, position, epsilon_x, &mindist_x, tx); break; default: break; } } } if (snap_to_grid) { GimpGrid *grid = gimp_image_get_grid (image); gdouble xspacing, yspacing; gdouble xoffset, yoffset; gdouble i; gimp_grid_get_spacing (grid, &xspacing, &yspacing); gimp_grid_get_offset (grid, &xoffset, &yoffset); while (xoffset > xspacing) xoffset -= xspacing; while (yoffset > yspacing) yoffset -= yspacing; for (i = xoffset; i <= gimp_image_get_width (image); i += xspacing) { if (i < 0) continue; snapped |= gimp_image_snap_distance (x, i, epsilon_x, &mindist_x, tx); } for (i = yoffset; i <= gimp_image_get_height (image); i += yspacing) { if (i < 0) continue; snapped |= gimp_image_snap_distance (y, i, epsilon_y, &mindist_y, ty); } } if (snap_to_canvas) { snapped |= gimp_image_snap_distance (x, 0, epsilon_x, &mindist_x, tx); snapped |= gimp_image_snap_distance (x, gimp_image_get_width (image), epsilon_x, &mindist_x, tx); snapped |= gimp_image_snap_distance (y, 0, epsilon_y, &mindist_y, ty); snapped |= gimp_image_snap_distance (y, gimp_image_get_height (image), epsilon_y, &mindist_y, ty); } if (snap_to_vectors) { GimpVectors *vectors = gimp_image_get_active_vectors (image); GimpStroke *stroke = NULL; GimpCoords coords = { 0, 0, 0, 0, 0 }; coords.x = x; coords.y = y; while ((stroke = gimp_vectors_stroke_get_next (vectors, stroke))) { GimpCoords nearest; if (gimp_stroke_nearest_point_get (stroke, &coords, 1.0, &nearest, NULL, NULL, NULL) >= 0) { snapped |= gimp_image_snap_distance (x, nearest.x, epsilon_x, &mindist_x, tx); snapped |= gimp_image_snap_distance (y, nearest.y, epsilon_y, &mindist_y, ty); } } } return snapped; }
gboolean gimp_image_snap_rectangle (GimpImage *image, gdouble x1, gdouble y1, gdouble x2, gdouble y2, gdouble *tx1, gdouble *ty1, gdouble epsilon_x, gdouble epsilon_y, gboolean snap_to_guides, gboolean snap_to_grid, gboolean snap_to_canvas, gboolean snap_to_vectors) { gdouble nx, ny; gdouble mindist_x = G_MAXDOUBLE; gdouble mindist_y = G_MAXDOUBLE; gdouble x_center = (x1 + x2) / 2.0; gdouble y_center = (y1 + y2) / 2.0; gboolean snapped = FALSE; g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE); g_return_val_if_fail (tx1 != NULL, FALSE); g_return_val_if_fail (ty1 != NULL, FALSE); *tx1 = x1; *ty1 = y1; if (! gimp_image_get_guides (image)) snap_to_guides = FALSE; if (! gimp_image_get_grid (image)) snap_to_grid = FALSE; if (! gimp_image_get_active_vectors (image)) snap_to_vectors = FALSE; if (! (snap_to_guides || snap_to_grid || snap_to_canvas || snap_to_vectors)) return FALSE; /* left edge */ if (gimp_image_snap_x (image, x1, &nx, MIN (epsilon_x, mindist_x), snap_to_guides, snap_to_grid, snap_to_canvas)) { mindist_x = ABS (nx - x1); *tx1 = nx; snapped = TRUE; } /* right edge */ if (gimp_image_snap_x (image, x2, &nx, MIN (epsilon_x, mindist_x), snap_to_guides, snap_to_grid, snap_to_canvas)) { mindist_x = ABS (nx - x2); *tx1 = RINT (x1 + (nx - x2)); snapped = TRUE; } /* center, vertical */ if (gimp_image_snap_x (image, x_center, &nx, MIN (epsilon_x, mindist_x), snap_to_guides, snap_to_grid, snap_to_canvas)) { mindist_x = ABS (nx - x_center); *tx1 = RINT (x1 + (nx - x_center)); snapped = TRUE; } /* top edge */ if (gimp_image_snap_y (image, y1, &ny, MIN (epsilon_y, mindist_y), snap_to_guides, snap_to_grid, snap_to_canvas)) { mindist_y = ABS (ny - y1); *ty1 = ny; snapped = TRUE; } /* bottom edge */ if (gimp_image_snap_y (image, y2, &ny, MIN (epsilon_y, mindist_y), snap_to_guides, snap_to_grid, snap_to_canvas)) { mindist_y = ABS (ny - y2); *ty1 = RINT (y1 + (ny - y2)); snapped = TRUE; } /* center, horizontal */ if (gimp_image_snap_y (image, y_center, &ny, MIN (epsilon_y, mindist_y), snap_to_guides, snap_to_grid, snap_to_canvas)) { mindist_y = ABS (ny - y_center); *ty1 = RINT (y1 + (ny - y_center)); snapped = TRUE; } if (snap_to_vectors) { GimpVectors *vectors = gimp_image_get_active_vectors (image); GimpStroke *stroke = NULL; GimpCoords coords1 = GIMP_COORDS_DEFAULT_VALUES; GimpCoords coords2 = GIMP_COORDS_DEFAULT_VALUES; while ((stroke = gimp_vectors_stroke_get_next (vectors, stroke))) { GimpCoords nearest; gdouble dist; /* top edge */ coords1.x = x1; coords1.y = y1; coords2.x = x2; coords2.y = y1; if (gimp_stroke_nearest_tangent_get (stroke, &coords1, &coords2, 1.0, &nearest, NULL, NULL, NULL) >= 0) { snapped |= gimp_image_snap_distance (y1, nearest.y, epsilon_y, &mindist_y, ty1); } if (gimp_stroke_nearest_intersection_get (stroke, &coords1, &coords2, 1.0, &nearest, NULL, NULL, NULL) >= 0) { snapped |= gimp_image_snap_distance (x1, nearest.x, epsilon_x, &mindist_x, tx1); } if (gimp_stroke_nearest_intersection_get (stroke, &coords2, &coords1, 1.0, &nearest, NULL, NULL, NULL) >= 0) { dist = ABS (nearest.x - x2); if (dist < MIN (epsilon_x, mindist_x)) { mindist_x = dist; *tx1 = RINT (x1 + (nearest.x - x2)); snapped = TRUE; } } /* bottom edge */ coords1.x = x1; coords1.y = y2; coords2.x = x2; coords2.y = y2; if (gimp_stroke_nearest_tangent_get (stroke, &coords1, &coords2, 1.0, &nearest, NULL, NULL, NULL) >= 0) { dist = ABS (nearest.y - y2); if (dist < MIN (epsilon_y, mindist_y)) { mindist_y = dist; *ty1 = RINT (y1 + (nearest.y - y2)); snapped = TRUE; } } if (gimp_stroke_nearest_intersection_get (stroke, &coords1, &coords2, 1.0, &nearest, NULL, NULL, NULL) >= 0) { snapped |= gimp_image_snap_distance (x1, nearest.x, epsilon_x, &mindist_x, tx1); } if (gimp_stroke_nearest_intersection_get (stroke, &coords2, &coords1, 1.0, &nearest, NULL, NULL, NULL) >= 0) { dist = ABS (nearest.x - x2); if (dist < MIN (epsilon_x, mindist_x)) { mindist_x = dist; *tx1 = RINT (x1 + (nearest.x - x2)); snapped = TRUE; } } /* left edge */ coords1.x = x1; coords1.y = y1; coords2.x = x1; coords2.y = y2; if (gimp_stroke_nearest_tangent_get (stroke, &coords1, &coords2, 1.0, &nearest, NULL, NULL, NULL) >= 0) { snapped |= gimp_image_snap_distance (x1, nearest.x, epsilon_x, &mindist_x, tx1); } if (gimp_stroke_nearest_intersection_get (stroke, &coords1, &coords2, 1.0, &nearest, NULL, NULL, NULL) >= 0) { snapped |= gimp_image_snap_distance (y1, nearest.y, epsilon_y, &mindist_y, ty1); } if (gimp_stroke_nearest_intersection_get (stroke, &coords2, &coords1, 1.0, &nearest, NULL, NULL, NULL) >= 0) { dist = ABS (nearest.y - y2); if (dist < MIN (epsilon_y, mindist_y)) { mindist_y = dist; *ty1 = RINT (y1 + (nearest.y - y2)); snapped = TRUE; } } /* right edge */ coords1.x = x2; coords1.y = y1; coords2.x = x2; coords2.y = y2; if (gimp_stroke_nearest_tangent_get (stroke, &coords1, &coords2, 1.0, &nearest, NULL, NULL, NULL) >= 0) { dist = ABS (nearest.x - x2); if (dist < MIN (epsilon_x, mindist_x)) { mindist_x = dist; *tx1 = RINT (x1 + (nearest.x - x2)); snapped = TRUE; } } if (gimp_stroke_nearest_intersection_get (stroke, &coords1, &coords2, 1.0, &nearest, NULL, NULL, NULL) >= 0) { snapped |= gimp_image_snap_distance (y1, nearest.y, epsilon_y, &mindist_y, ty1); } if (gimp_stroke_nearest_intersection_get (stroke, &coords2, &coords1, 1.0, &nearest, NULL, NULL, NULL) >= 0) { dist = ABS (nearest.y - y2); if (dist < MIN (epsilon_y, mindist_y)) { mindist_y = dist; *ty1 = RINT (y1 + (nearest.y - y2)); snapped = TRUE; } } /* center */ coords1.x = x_center; coords1.y = y_center; if (gimp_stroke_nearest_point_get (stroke, &coords1, 1.0, &nearest, NULL, NULL, NULL) >= 0) { if (gimp_image_snap_distance (x_center, nearest.x, epsilon_x, &mindist_x, &nx)) { mindist_x = ABS (nx - x_center); *tx1 = RINT (x1 + (nx - x_center)); snapped = TRUE; } if (gimp_image_snap_distance (y_center, nearest.y, epsilon_y, &mindist_y, &ny)) { mindist_y = ABS (ny - y_center); *ty1 = RINT (y1 + (ny - y_center)); snapped = TRUE; } } } } return snapped; }
gboolean gimp_image_snap_point (GimpImage *image, gdouble x, gdouble y, gdouble *tx, gdouble *ty, gdouble epsilon_x, gdouble epsilon_y, gboolean snap_to_guides, gboolean snap_to_grid, gboolean snap_to_canvas, gboolean snap_to_vectors) { gdouble mindist_x = G_MAXDOUBLE; gdouble mindist_y = G_MAXDOUBLE; gdouble dist; gboolean snapped = FALSE; g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE); g_return_val_if_fail (tx != NULL, FALSE); g_return_val_if_fail (ty != NULL, FALSE); *tx = x; *ty = y; if (! gimp_image_get_guides (image)) snap_to_guides = FALSE; if (! gimp_image_get_grid (image)) snap_to_grid = FALSE; if (! gimp_image_get_active_vectors (image)) snap_to_vectors = FALSE; if (! (snap_to_guides || snap_to_grid || snap_to_canvas || snap_to_vectors)) return FALSE; if (x < -epsilon_x || x >= (gimp_image_get_width (image) + epsilon_x) || y < -epsilon_y || y >= (gimp_image_get_height (image) + epsilon_y)) { return FALSE; } if (snap_to_guides) { GList *list; for (list = gimp_image_get_guides (image); list; list = g_list_next (list)) { GimpGuide *guide = list->data; gint position = gimp_guide_get_position (guide); if (position < 0) continue; switch (gimp_guide_get_orientation (guide)) { case GIMP_ORIENTATION_HORIZONTAL: dist = ABS (position - y); if (dist < MIN (epsilon_y, mindist_y)) { mindist_y = dist; *ty = position; snapped = TRUE; } break; case GIMP_ORIENTATION_VERTICAL: dist = ABS (position - x); if (dist < MIN (epsilon_x, mindist_x)) { mindist_x = dist; *tx = position; snapped = TRUE; } break; default: break; } } } if (snap_to_grid) { GimpGrid *grid = gimp_image_get_grid (image); gdouble xspacing, yspacing; gdouble xoffset, yoffset; gdouble i; g_object_get (grid, "xspacing", &xspacing, "yspacing", &yspacing, "xoffset", &xoffset, "yoffset", &yoffset, NULL); while (xoffset > xspacing) xoffset -= xspacing; while (yoffset > yspacing) yoffset -= yspacing; for (i = xoffset; i <= gimp_image_get_width (image); i += xspacing) { if (i < 0) continue; dist = ABS (i - x); if (dist < MIN (epsilon_x, mindist_x)) { mindist_x = dist; *tx = i; snapped = TRUE; } } for (i = yoffset; i <= gimp_image_get_height (image); i += yspacing) { if (i < 0) continue; dist = ABS (i - y); if (dist < MIN (epsilon_y, mindist_y)) { mindist_y = dist; *ty = i; snapped = TRUE; } } } if (snap_to_canvas) { dist = ABS (x); if (dist < MIN (epsilon_x, mindist_x)) { mindist_x = dist; *tx = 0; snapped = TRUE; } dist = ABS (gimp_image_get_width (image) - x); if (dist < MIN (epsilon_x, mindist_x)) { mindist_x = dist; *tx = gimp_image_get_width (image); snapped = TRUE; } dist = ABS (y); if (dist < MIN (epsilon_y, mindist_y)) { mindist_y = dist; *ty = 0; snapped = TRUE; } dist = ABS (gimp_image_get_height (image) - y); if (dist < MIN (epsilon_y, mindist_y)) { mindist_y = dist; *ty = gimp_image_get_height (image); snapped = TRUE; } } if (snap_to_vectors) { GimpVectors *vectors = gimp_image_get_active_vectors (image); GimpStroke *stroke = NULL; GimpCoords coords = { 0, 0, 0, 0, 0 }; coords.x = x; coords.y = y; while ((stroke = gimp_vectors_stroke_get_next (vectors, stroke))) { GimpCoords nearest; if (gimp_stroke_nearest_point_get (stroke, &coords, 1.0, &nearest, NULL, NULL, NULL) >= 0) { dist = ABS (nearest.x - x); if (dist < MIN (epsilon_x, mindist_x)) { mindist_x = dist; *tx = nearest.x; snapped = TRUE; } dist = ABS (nearest.y - y); if (dist < MIN (epsilon_y, mindist_y)) { mindist_y = dist; *ty = nearest.y; snapped = TRUE; } } } } return snapped; }