diff --git a/ChangeLog b/ChangeLog index 688129b60c..007db2e22a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2005-03-09 Bill Skaggs + + * app/vectors/gimpvectors-warp.c + * app/vectors/gimpvectors-warp.h: new files implmenting + "path along a path" functionality. + + * app/vectors/Makefile.am: new stuff added + + * gimp/app/vectors/gimpvectors.[ch]: actually implement + gimp_vectors_real_stroke_get_length(). + + * app/tools/gimptexttool.c + * app/tools/gimptextoptions.c: first pass at "text + along a path", using new functions. See bug #169616. + 2005-03-09 Sven Neumann * app/core/gimppalette.[ch]: renamed again, to diff --git a/app/tools/gimptextoptions.c b/app/tools/gimptextoptions.c index 00a8564072..768d47003a 100644 --- a/app/tools/gimptextoptions.c +++ b/app/tools/gimptextoptions.c @@ -501,6 +501,14 @@ gimp_text_options_gui (GimpToolOptions *tool_options) g_object_set_data (G_OBJECT (tool_options), "gimp-text-to-vectors", button); + button = gtk_button_new_with_label (_("Text along path")); + gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0); + gtk_widget_set_sensitive (button, FALSE); + gtk_widget_show (button); + + g_object_set_data (G_OBJECT (tool_options), + "gimp-text-to-vectors-warped", button); + return vbox; } diff --git a/app/tools/gimptexttool.c b/app/tools/gimptexttool.c index 1c85e3e30a..e4592b5c88 100644 --- a/app/tools/gimptexttool.c +++ b/app/tools/gimptexttool.c @@ -54,6 +54,8 @@ #include "widgets/gimptexteditor.h" #include "widgets/gimpviewabledialog.h" +#include "vectors/gimpvectors-warp.h" + #include "display/gimpdisplay.h" #include "gimpeditselectiontool.h" @@ -106,6 +108,8 @@ static gboolean gimp_text_tool_idle_apply (GimpTextTool *text_tool); static void gimp_text_tool_apply (GimpTextTool *text_tool); static void gimp_text_tool_create_vectors (GimpTextTool *text_tool); +static void gimp_text_tool_create_vectors_warped + (GimpTextTool *text_tool); static void gimp_text_tool_create_layer (GimpTextTool *text_tool, GimpText *text); @@ -361,9 +365,11 @@ gimp_text_tool_connect (GimpTextTool *text_tool, { GimpTextOptions *options; GtkWidget *button; + GtkWidget *button2; options = GIMP_TEXT_OPTIONS (tool->tool_info->tool_options); - button = g_object_get_data (G_OBJECT (options), "gimp-text-to-vectors"); + button = g_object_get_data (G_OBJECT (options), "gimp-text-to-vectors"); + button2 = g_object_get_data (G_OBJECT (options), "gimp-text-to-vectors-warped"); if (text_tool->text) { @@ -382,6 +388,14 @@ gimp_text_tool_connect (GimpTextTool *text_tool, text_tool); } + if (button2) + { + gtk_widget_set_sensitive (button2, FALSE); + g_signal_handlers_disconnect_by_func (button2, + gimp_text_tool_create_vectors_warped, + text_tool); + } + g_object_unref (text_tool->text); text_tool->text = NULL; @@ -411,6 +425,14 @@ gimp_text_tool_connect (GimpTextTool *text_tool, gtk_widget_set_sensitive (button, TRUE); } + if (button2) + { + g_signal_connect_swapped (button2, "clicked", + G_CALLBACK (gimp_text_tool_create_vectors_warped), + text_tool); + gtk_widget_set_sensitive (button2, TRUE); + } + if (text_tool->editor) gimp_text_tool_editor_update (text_tool); } @@ -659,6 +681,32 @@ gimp_text_tool_create_vectors (GimpTextTool *text_tool) gimp_image_flush (text_tool->image); } +static void +gimp_text_tool_create_vectors_warped (GimpTextTool *text_tool) +{ + GimpVectors *vectors0; + GimpVectors *vectors; + GimpText *text = text_tool->text; + gdouble box_height; + + if (! text || ! text_tool->image || ! text_tool->layer) + return; + + box_height = gimp_item_height (GIMP_ITEM (text_tool->layer)); + + vectors0 = gimp_image_get_active_vectors (text_tool->image); + if (! vectors0) + return; + + vectors = gimp_text_vectors_new (text_tool->image, text_tool->text); + + gimp_vectors_warp_vectors (vectors0, vectors, 0.5 * box_height); + + gimp_image_add_vectors (text_tool->image, vectors, -1); + + gimp_image_flush (text_tool->image); +} + static void gimp_text_tool_create_layer (GimpTextTool *text_tool, GimpText *text) diff --git a/app/vectors/Makefile.am b/app/vectors/Makefile.am index 891f96a1c2..1e6650f63f 100644 --- a/app/vectors/Makefile.am +++ b/app/vectors/Makefile.am @@ -32,6 +32,8 @@ libappvectors_a_SOURCES = \ gimpvectors-import.c \ gimpvectors-import.h \ gimpvectors-preview.c \ - gimpvectors-preview.h + gimpvectors-preview.h \ + gimpvectors-warp.c \ + gimpvectors-warp.h EXTRA_DIST = makefile.msc diff --git a/app/vectors/gimpvectors-warp.c b/app/vectors/gimpvectors-warp.c new file mode 100644 index 0000000000..5b754bab83 --- /dev/null +++ b/app/vectors/gimpvectors-warp.c @@ -0,0 +1,162 @@ +/* The GIMP -- an image manipulation program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * gimpvectors-warp.c + * Copyright (C) 2005 Bill Skaggs + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include + +#include "vectors-types.h" + +#include "core/gimp-utils.h" +#include "core/gimpcoords.h" + +#include "gimpanchor.h" +#include "gimpstroke.h" +#include "gimpvectors.h" + +#define EPSILON 0.2 +#define DX 2.0 + +static void gimp_stroke_warp_point (const GimpStroke *stroke, + gdouble x, + gdouble y, + GimpCoords *point_warped, + gdouble y_offset); + +static void gimp_vectors_warp_stroke (const GimpVectors *vectors, + GimpStroke *stroke, + gdouble y_offset); + +void +gimp_vectors_warp_point (const GimpVectors *vectors, + GimpCoords *point, + GimpCoords *point_warped, + gdouble y_offset) +{ + gdouble x = point->x; + gdouble y = point->y; + gdouble len; + GList *list; + GimpStroke *stroke; + + for (list = vectors->strokes; list; list = g_list_next (list)) + { + stroke = list->data; + + len = gimp_vectors_stroke_get_length (vectors, stroke); + + if (x < len) + break; + + x -= len; + } + + if (! list) + { + point_warped->x = 0; + point_warped->y = 0; + return; + } + + gimp_stroke_warp_point (stroke, x, y, point_warped, y_offset); +} + + +static void +gimp_stroke_warp_point (const GimpStroke *stroke, + gdouble x, + gdouble y, + GimpCoords *point_warped, + gdouble y_offset) +{ + GimpCoords *point_zero; + GimpCoords *point_minus; + GimpCoords *point_plus; + gdouble slope; + gdouble dx, dy, nx, ny, len; + + point_zero = (GimpCoords*) g_new0 (GimpCoords, 1); + point_minus = (GimpCoords*) g_new0 (GimpCoords, 1); + point_plus = (GimpCoords*) g_new0 (GimpCoords, 1); + + if (! gimp_stroke_get_point_at_dist (stroke, x, EPSILON, point_zero, &slope)) + { + point_warped->x = 0; + point_warped->y = 0; + return; + } + + point_warped->x = point_zero->x; + point_warped->y = point_zero->y; + + if (! gimp_stroke_get_point_at_dist (stroke, x - DX, EPSILON, point_minus, &slope)) + return; + + if (! gimp_stroke_get_point_at_dist (stroke, x + DX, EPSILON, point_plus, &slope)) + return; + + dx = point_plus->x - point_minus->x; + dy = point_plus->y - point_minus->y; + + len = hypot (dx, dy); + + if (len < 0.01) + return; + + nx = - dy / len; + ny = dx / len; + + point_warped->x = point_zero->x + nx * (y - y_offset); + point_warped->y = point_zero->y + ny * (y - y_offset); +} + +static void +gimp_vectors_warp_stroke (const GimpVectors *vectors, + GimpStroke *stroke, + gdouble y_offset) +{ + GList *list; + + for (list = stroke->anchors; list; list = g_list_next (list)) + { + GimpAnchor *anchor = list->data; + + gimp_vectors_warp_point (vectors, + &anchor->position, &anchor->position, + y_offset); + } +} + +void +gimp_vectors_warp_vectors (const GimpVectors *vectors, + GimpVectors *vectors_in, + gdouble y_offset) +{ + GList *list; + + for (list = vectors_in->strokes; list; list = g_list_next (list)) + { + GimpStroke *stroke = list->data; + + gimp_vectors_warp_stroke (vectors, stroke, y_offset); + } +} + diff --git a/app/vectors/gimpvectors-warp.h b/app/vectors/gimpvectors-warp.h new file mode 100644 index 0000000000..cad76f0df0 --- /dev/null +++ b/app/vectors/gimpvectors-warp.h @@ -0,0 +1,36 @@ +/* The GIMP -- an image manipulation program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * gimpvectors-warp.h + * Copyright (C) 2005 Bill Skaggs + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __GIMP_VECTORS_WARP_H__ +#define __GIMP_VECTORS_WARP_H__ + +void gimp_vectors_warp_point (const GimpVectors *vectors, + GimpCoords *point, + GimpCoords *point_warped, + gdouble y_offset); + + +void gimp_vectors_warp_vectors (const GimpVectors *vectors, + GimpVectors *vectors_in, + gdouble yoffset); + +#endif /* __GIMP_VECTORS_WARP_H__ */ + diff --git a/app/vectors/gimpvectors.c b/app/vectors/gimpvectors.c index 0a65cd5ad9..c3dade26fc 100644 --- a/app/vectors/gimpvectors.c +++ b/app/vectors/gimpvectors.c @@ -263,6 +263,7 @@ gimp_vectors_init (GimpVectors *vectors) item->visible = FALSE; vectors->strokes = NULL; vectors->freeze_count = 0; + vectors->precision = 0.2; } static void @@ -811,18 +812,22 @@ gimp_vectors_real_stroke_get_next (const GimpVectors *vectors, gdouble gimp_vectors_stroke_get_length (const GimpVectors *vectors, - const GimpStroke *prev) + const GimpStroke *stroke) { g_return_val_if_fail (GIMP_IS_VECTORS (vectors), 0.0); + g_return_val_if_fail (GIMP_IS_STROKE (stroke), 0.0); - return GIMP_VECTORS_GET_CLASS (vectors)->stroke_get_length (vectors, prev); + return GIMP_VECTORS_GET_CLASS (vectors)->stroke_get_length (vectors, stroke); } static gdouble gimp_vectors_real_stroke_get_length (const GimpVectors *vectors, - const GimpStroke *prev) + const GimpStroke *stroke) { - g_printerr ("gimp_vectors_stroke_get_length: default implementation\n"); + g_return_val_if_fail (GIMP_IS_VECTORS (vectors), 0.0); + g_return_val_if_fail (GIMP_IS_STROKE (stroke), 0.0); + + return (gimp_stroke_get_length (stroke, vectors->precision)); return 0.0; } diff --git a/app/vectors/gimpvectors.h b/app/vectors/gimpvectors.h index a94b582844..683bbba0f6 100644 --- a/app/vectors/gimpvectors.h +++ b/app/vectors/gimpvectors.h @@ -42,6 +42,7 @@ struct _GimpVectors GList *strokes; /* The List of GimpStrokes */ gint freeze_count; + gdouble precision; /* Stuff missing */ };