home *** CD-ROM | disk | FTP | other *** search
/ PC Pro 2002 April / pcpro0402.iso / essentials / graphics / Gimp / gimp-src-20001226.exe / src / gimp / app / airbrush.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-12-20  |  11.2 KB  |  424 lines

  1. /* The GIMP -- an image manipulation program
  2.  * Copyright (C) 1995 Spencer Kimball and Peter Mattis
  3.  *
  4.  * This program is free software; you can redistribute it and/or modify
  5.  * it under the terms of the GNU General Public License as published by
  6.  * the Free Software Foundation; either version 2 of the License, or
  7.  * (at your option) any later version.
  8.  *
  9.  * This program is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  * GNU General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU General Public License
  15.  * along with this program; if not, write to the Free Software
  16.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  17.  */
  18.  
  19. #include "config.h"
  20.  
  21. #include <gtk/gtk.h>
  22.  
  23. #include "apptypes.h"
  24.  
  25. #include "appenv.h"
  26. #include "airbrush.h"
  27. #include "drawable.h"
  28. #include "gdisplay.h"
  29. #include "gradient.h"
  30. #include "gimage.h"
  31. #include "gimpui.h"
  32. #include "paint_funcs.h"
  33. #include "paint_core.h"
  34. #include "paint_options.h"
  35. #include "selection.h"
  36. #include "tools.h"
  37.  
  38. #include "libgimp/gimpintl.h"
  39.  
  40.  
  41. /*  The maximum amount of pressure that can be exerted  */
  42. #define MAX_PRESSURE  0.075
  43.  
  44. /* Default pressure setting */
  45. #define AIRBRUSH_PRESSURE_DEFAULT    10.0
  46. #define AIRBRUSH_INCREMENTAL_DEFAULT FALSE
  47.  
  48. #define OFF           0
  49. #define ON            1
  50.  
  51. /*  the airbrush structures  */
  52.  
  53. typedef struct _AirbrushTimeout AirbrushTimeout;
  54.  
  55. struct _AirbrushTimeout
  56. {
  57.   PaintCore    *paint_core;
  58.   GimpDrawable *drawable;
  59. };
  60.  
  61. typedef struct _AirbrushOptions AirbrushOptions;
  62.  
  63. struct _AirbrushOptions
  64. {
  65.   PaintOptions paint_options;
  66.  
  67.   gdouble      rate;
  68.   gdouble      rate_d;
  69.   GtkObject   *rate_w;
  70.  
  71.   gdouble      pressure;
  72.   gdouble      pressure_d;
  73.   GtkObject   *pressure_w;
  74. };
  75.  
  76.  
  77. /*  the airbrush tool options  */
  78. static AirbrushOptions *airbrush_options = NULL; 
  79.  
  80. /*  local variables  */
  81. static gint             timer;  /*  timer for successive paint applications  */
  82. static gint             timer_state = OFF;       /*  state of airbrush tool  */
  83. static AirbrushTimeout  airbrush_timeout;
  84.  
  85. static gdouble          non_gui_pressure;
  86. static gboolean         non_gui_incremental;
  87.  
  88. /*  forward function declarations  */
  89. static void   airbrush_motion   (PaintCore *, GimpDrawable *,
  90.                  PaintPressureOptions *,
  91.                  gdouble, PaintApplicationMode);
  92. static gint   airbrush_time_out (gpointer);
  93.  
  94.  
  95. /*  functions  */
  96.  
  97. static void
  98. airbrush_options_reset (void)
  99. {
  100.   AirbrushOptions *options = airbrush_options;
  101.  
  102.   paint_options_reset ((PaintOptions *) options);
  103.  
  104.   gtk_adjustment_set_value (GTK_ADJUSTMENT (options->rate_w),
  105.                 options->rate_d);
  106.   gtk_adjustment_set_value (GTK_ADJUSTMENT (options->pressure_w),
  107.                 options->pressure_d);
  108. }
  109.  
  110. static AirbrushOptions *
  111. airbrush_options_new (void)
  112. {
  113.   AirbrushOptions *options;
  114.  
  115.   GtkWidget *vbox;
  116.   GtkWidget *table;
  117.   GtkWidget *scale;
  118.  
  119.   /*  the new airbrush tool options structure  */
  120.   options = g_new (AirbrushOptions, 1);
  121.   paint_options_init ((PaintOptions *) options,
  122.               AIRBRUSH,
  123.               airbrush_options_reset);
  124.   options->rate     = options->rate_d     = 80.0;
  125.   options->pressure = options->pressure_d = AIRBRUSH_PRESSURE_DEFAULT;
  126.  
  127.   /*  the main vbox  */
  128.   vbox = ((ToolOptions *) options)->main_vbox;
  129.  
  130.   /*  the rate scale  */
  131.   table = gtk_table_new (2, 2, FALSE);
  132.   gtk_table_set_col_spacing (GTK_TABLE (table), 0, 4);
  133.   gtk_table_set_row_spacings (GTK_TABLE (table), 1);
  134.   gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
  135.  
  136.   options->rate_w =
  137.     gtk_adjustment_new (options->rate_d, 0.0, 150.0, 1.0, 1.0, 0.0);
  138.   scale = gtk_hscale_new (GTK_ADJUSTMENT (options->rate_w));
  139.   gtk_scale_set_value_pos (GTK_SCALE (scale), GTK_POS_TOP);
  140.   gtk_range_set_update_policy (GTK_RANGE (scale), GTK_UPDATE_DELAYED);
  141.   gtk_signal_connect (GTK_OBJECT (options->rate_w), "value_changed",
  142.               GTK_SIGNAL_FUNC (gimp_double_adjustment_update),
  143.               &options->rate);
  144.   gimp_table_attach_aligned (GTK_TABLE (table), 0, 0,
  145.                  _("Rate:"), 1.0, 1.0,
  146.                  scale, 1, FALSE);
  147.  
  148.   /*  the pressure scale  */
  149.   options->pressure_w =
  150.     gtk_adjustment_new (options->pressure_d, 0.0, 100.0, 1.0, 1.0, 0.0);
  151.   scale = gtk_hscale_new (GTK_ADJUSTMENT (options->pressure_w));
  152.   gtk_scale_set_value_pos (GTK_SCALE (scale), GTK_POS_TOP);
  153.   gtk_range_set_update_policy (GTK_RANGE (scale), GTK_UPDATE_DELAYED);
  154.   gtk_signal_connect (GTK_OBJECT (options->pressure_w), "value_changed",
  155.               GTK_SIGNAL_FUNC (gimp_double_adjustment_update),
  156.               &options->pressure);
  157.   gimp_table_attach_aligned (GTK_TABLE (table), 0, 1,
  158.                  _("Pressure:"), 1.0, 1.0,
  159.                  scale, 1, FALSE);
  160.  
  161.   gtk_widget_show (table);
  162.  
  163.   return options;
  164. }
  165.  
  166. Tool *
  167. tools_new_airbrush (void)
  168. {
  169.   Tool * tool;
  170.   PaintCore * private;
  171.  
  172.   /*  The tool options  */
  173.   if (! airbrush_options)
  174.     {
  175.       airbrush_options = airbrush_options_new ();
  176.       tools_register (AIRBRUSH, (ToolOptions *) airbrush_options);
  177.     }
  178.  
  179.   tool = paint_core_new (AIRBRUSH);
  180.  
  181.   private = (PaintCore *) tool->private;
  182.   private->paint_func = airbrush_paint_func;
  183.   private->pick_colors = TRUE;
  184.   private->flags |= TOOL_CAN_HANDLE_CHANGING_BRUSH;
  185.  
  186.   return tool;
  187. }
  188.  
  189. void *
  190. airbrush_paint_func (PaintCore    *paint_core,
  191.              GimpDrawable *drawable,
  192.              int           state)
  193. {
  194.   GimpBrush *brush;
  195.   gdouble rate;
  196.  
  197.   if (!drawable) 
  198.     return NULL;
  199.  
  200.   brush = gimp_context_get_brush (NULL);
  201.   switch (state)
  202.     {
  203.     case INIT_PAINT :
  204.       /* timer_state = OFF; */
  205.       if (timer_state == ON)
  206.     {
  207.       g_warning ("killing stray timer, please report to lewing@gimp.org");
  208.       gtk_timeout_remove (timer);
  209.     }
  210.       timer_state = OFF;
  211.       break;
  212.  
  213.     case MOTION_PAINT :
  214.       if (timer_state == ON)
  215.     gtk_timeout_remove (timer);
  216.       timer_state = OFF;
  217.  
  218.       airbrush_motion (paint_core, drawable,
  219.                airbrush_options->paint_options.pressure_options,
  220.                airbrush_options->pressure,
  221.                airbrush_options->paint_options.incremental ?
  222.                INCREMENTAL : CONSTANT);
  223.  
  224.       if (airbrush_options->rate != 0.0)
  225.     {
  226.       airbrush_timeout.paint_core = paint_core;
  227.       airbrush_timeout.drawable = drawable;
  228.       rate = airbrush_options->paint_options.pressure_options->rate ? 
  229.         (10000 / (airbrush_options->rate * 2.0 * paint_core->curpressure)) : 
  230.         (10000 / airbrush_options->rate);
  231.       timer = gtk_timeout_add (rate, airbrush_time_out, NULL);
  232.       timer_state = ON;
  233.     }
  234.       break;
  235.  
  236.     case FINISH_PAINT :
  237.       if (timer_state == ON)
  238.     gtk_timeout_remove (timer);
  239.       timer_state = OFF;
  240.       break;
  241.  
  242.     default :
  243.       break;
  244.     }
  245.  
  246.   return NULL;
  247. }
  248.  
  249.  
  250. void
  251. tools_free_airbrush (Tool *tool)
  252. {
  253.   if (timer_state == ON)
  254.     gtk_timeout_remove (timer);
  255.   timer_state = OFF;
  256.  
  257.   paint_core_free (tool);
  258. }
  259.  
  260.  
  261. static gint
  262. airbrush_time_out (gpointer client_data)
  263. {
  264.   /*  service the timer  */
  265.   airbrush_motion (airbrush_timeout.paint_core,
  266.            airbrush_timeout.drawable,
  267.            airbrush_options->paint_options.pressure_options,
  268.            airbrush_options->pressure,
  269.            airbrush_options->paint_options.incremental ?
  270.            INCREMENTAL : CONSTANT);
  271.   gdisplays_flush ();
  272.  
  273.   /*  restart the timer  */
  274.   if (airbrush_options->rate != 0.0)
  275.     {
  276.       if (airbrush_options->paint_options.pressure_options->rate)
  277.     {
  278.       /* set a new timer */
  279.       timer = gtk_timeout_add ((10000 / (airbrush_options->rate * 2.0 * airbrush_timeout.paint_core->curpressure)), 
  280.                    airbrush_time_out, NULL);
  281.       return FALSE;
  282.     }
  283.       else 
  284.     return TRUE;
  285.     }
  286.   else
  287.     return FALSE;
  288. }
  289.  
  290.  
  291. static void
  292. airbrush_motion (PaintCore          *paint_core,
  293.          GimpDrawable          *drawable,
  294.          PaintPressureOptions *pressure_options,
  295.          double               pressure,
  296.          PaintApplicationMode  mode)
  297. {
  298.   GImage *gimage;
  299.   TempBuf * area;
  300.   unsigned char col[MAX_CHANNELS];
  301.   gdouble scale;
  302.  
  303.   if (!drawable) 
  304.     return;
  305.  
  306.   if (! (gimage = drawable_gimage (drawable)))
  307.     return;
  308.  
  309.   if (pressure_options->size)
  310.     scale = paint_core->curpressure;
  311.   else
  312.     scale = 1.0;
  313.  
  314.   if (! (area = paint_core_get_paint_area (paint_core, drawable, scale)))
  315.     return;
  316.  
  317.   /*  color the pixels  */
  318.   if (pressure_options->color)
  319.     {
  320.       gdouble r, g, b, a;
  321.       
  322.       gradient_get_color_at (gimp_context_get_gradient (NULL),
  323.                  paint_core->curpressure, &r, &g, &b, &a);
  324.       col[0] = r * 255.0;
  325.       col[1] = g * 255.0;
  326.       col[2] = b * 255.0;
  327.       col[3] = a * 255.0;
  328.       mode = INCREMENTAL;
  329.       color_pixels (temp_buf_data (area), col,
  330.             area->width * area->height, area->bytes);
  331.     }
  332.   else if (paint_core->brush && paint_core->brush->pixmap)
  333.     {
  334.       mode = INCREMENTAL;
  335.       paint_core_color_area_with_pixmap (paint_core, gimage, drawable, area, 
  336.                      scale, SOFT);
  337.     }
  338.   else
  339.     {
  340.       gimage_get_foreground (gimage, drawable, col);
  341.       col[area->bytes - 1] = OPAQUE_OPACITY;
  342.       color_pixels (temp_buf_data (area), col,
  343.             area->width * area->height, area->bytes);
  344.     }
  345.  
  346.   if (pressure_options->pressure)
  347.     pressure = pressure * 2.0 * paint_core->curpressure;
  348.  
  349.   /*  paste the newly painted area to the image  */
  350.   paint_core_paste_canvas (paint_core, drawable,
  351.                MIN (pressure, 255),
  352.                (gint) (gimp_context_get_opacity (NULL) * 255),
  353.                gimp_context_get_paint_mode (NULL),
  354.                SOFT, scale, mode);
  355. }
  356.  
  357. static void *
  358. airbrush_non_gui_paint_func (PaintCore    *paint_core,
  359.                  GimpDrawable *drawable,
  360.                  int           state)
  361. {
  362.   airbrush_motion (paint_core, drawable, &non_gui_pressure_options, 
  363.            non_gui_pressure, non_gui_incremental);
  364.  
  365.   return NULL;
  366. }
  367.  
  368. gboolean
  369. airbrush_non_gui_default (GimpDrawable *drawable,
  370.               int           num_strokes,
  371.               double       *stroke_array)
  372. {
  373.   AirbrushOptions *options = airbrush_options;
  374.   gdouble pressure = AIRBRUSH_PRESSURE_DEFAULT;
  375.  
  376.   if(options)
  377.     pressure = options->pressure;
  378.  
  379.   return airbrush_non_gui (drawable, pressure, num_strokes, stroke_array);
  380. }
  381.  
  382. gboolean
  383. airbrush_non_gui (GimpDrawable *drawable,
  384.               double        pressure,
  385.           int           num_strokes,
  386.           double       *stroke_array)
  387. {
  388.   int i;
  389.  
  390.   if (paint_core_init (&non_gui_paint_core, drawable,
  391.                stroke_array[0], stroke_array[1]))
  392.     {
  393.       /* Set the paint core's paint func */
  394.       non_gui_paint_core.paint_func = airbrush_non_gui_paint_func;
  395.  
  396.       non_gui_pressure = pressure;
  397.  
  398.       non_gui_paint_core.startx = non_gui_paint_core.lastx = stroke_array[0];
  399.       non_gui_paint_core.starty = non_gui_paint_core.lasty = stroke_array[1];
  400.  
  401.       airbrush_non_gui_paint_func (&non_gui_paint_core, drawable, 0);
  402.  
  403.       for (i = 1; i < num_strokes; i++)
  404.     {
  405.       non_gui_paint_core.curx = stroke_array[i * 2 + 0];
  406.       non_gui_paint_core.cury = stroke_array[i * 2 + 1];
  407.  
  408.       paint_core_interpolate (&non_gui_paint_core, drawable);
  409.  
  410.       non_gui_paint_core.lastx = non_gui_paint_core.curx;
  411.       non_gui_paint_core.lasty = non_gui_paint_core.cury;
  412.     }
  413.  
  414.       /* Finish the painting */
  415.       paint_core_finish (&non_gui_paint_core, drawable, -1);
  416.  
  417.       /* Cleanup */
  418.       paint_core_cleanup ();
  419.       return TRUE;
  420.     }
  421.   else
  422.     return FALSE;
  423. }
  424.