gimpbrushcore.c 59.4 KB
Newer Older
1
/* GIMP - The GNU Image Manipulation Program
2 3
 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
 *
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 3 of the License, or
7 8 9 10 11 12 13 14
 * (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
15
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 17 18 19 20 21
 */

#include "config.h"

#include <string.h>

22
#include <gdk-pixbuf/gdk-pixbuf.h>
23
#include <gegl.h>
24

25 26
#include "libgimpmath/gimpmath.h"

27 28
#include "paint-types.h"

29
#include "gegl/gimp-babl.h"
30

31
#include "core/gimp-layer-modes.h"
32
#include "core/gimpbrush.h"
33
#include "core/gimpbrushgenerated.h"
34
#include "core/gimpdrawable.h"
35 36
#include "core/gimpdynamics.h"
#include "core/gimpdynamicsoutput.h"
37
#include "core/gimperror.h"
38
#include "core/gimpimage.h"
39
#include "core/gimpmarshal.h"
40
#include "core/gimptempbuf.h"
41 42 43

#include "gimpbrushcore.h"
#include "gimpbrushcore-kernels.h"
Alexia Death's avatar
Alexia Death committed
44

45
#include "gimppaintoptions.h"
46

47 48 49 50 51
#include "gimp-intl.h"


#define EPSILON  0.00001

52 53 54
enum
{
  SET_BRUSH,
55
  SET_DYNAMICS,
56 57 58 59
  LAST_SIGNAL
};


60 61
/*  local function prototypes  */

62
static void      gimp_brush_core_finalize           (GObject          *object);
63

64
static gboolean  gimp_brush_core_start              (GimpPaintCore    *core,
Alexia Death's avatar
Alexia Death committed
65
                                                     GimpDrawable     *drawable,
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
                                                     GimpPaintOptions *paint_options,
                                                     const GimpCoords *coords,
                                                     GError          **error);
static gboolean  gimp_brush_core_pre_paint          (GimpPaintCore    *core,
                                                     GimpDrawable     *drawable,
                                                     GimpPaintOptions *paint_options,
                                                     GimpPaintState    paint_state,
                                                     guint32           time);
static void      gimp_brush_core_post_paint         (GimpPaintCore    *core,
                                                     GimpDrawable     *drawable,
                                                     GimpPaintOptions *paint_options,
                                                     GimpPaintState    paint_state,
                                                     guint32           time);
static void      gimp_brush_core_interpolate        (GimpPaintCore    *core,
                                                     GimpDrawable     *drawable,
                                                     GimpPaintOptions *paint_options,
                                                     guint32           time);

84
static GeglBuffer * gimp_brush_core_get_paint_buffer(GimpPaintCore    *paint_core,
85 86
                                                     GimpDrawable     *drawable,
                                                     GimpPaintOptions *paint_options,
87
                                                     GimpLayerMode     paint_mode,
88 89
                                                     const GimpCoords *coords,
                                                     gint             *paint_buffer_x,
Jehan's avatar
Jehan committed
90 91 92
                                                     gint             *paint_buffer_y,
                                                     gint             *paint_width,
                                                     gint             *paint_height);
93 94 95 96 97 98

static void      gimp_brush_core_real_set_brush     (GimpBrushCore    *core,
                                                     GimpBrush        *brush);
static void      gimp_brush_core_real_set_dynamics  (GimpBrushCore    *core,
                                                     GimpDynamics     *dynamics);

99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
static const GimpTempBuf *
                 gimp_brush_core_subsample_mask     (GimpBrushCore     *core,
                                                     const GimpTempBuf *mask,
                                                     gdouble            x,
                                                     gdouble            y);
static const GimpTempBuf *
                 gimp_brush_core_pressurize_mask    (GimpBrushCore     *core,
                                                     const GimpTempBuf *brush_mask,
                                                     gdouble            x,
                                                     gdouble            y,
                                                     gdouble            pressure);
static const GimpTempBuf *
                 gimp_brush_core_solidify_mask      (GimpBrushCore     *core,
                                                     const GimpTempBuf *brush_mask,
                                                     gdouble            x,
                                                     gdouble            y);
static const GimpTempBuf *
                 gimp_brush_core_transform_mask     (GimpBrushCore     *core,
Jehan's avatar
Jehan committed
117 118
                                                     GimpBrush         *brush,
                                                     GeglNode          *op);
119 120
static const GimpTempBuf *
                 gimp_brush_core_transform_pixmap   (GimpBrushCore     *core,
Jehan's avatar
Jehan committed
121 122
                                                     GimpBrush         *brush,
                                                     GeglNode          *op);
123 124 125

static void      gimp_brush_core_invalidate_cache   (GimpBrush         *brush,
                                                     GimpBrushCore     *core);
126 127

/*  brush pipe utility functions  */
128
static void  gimp_brush_core_paint_line_pixmap_mask (GimpDrawable      *drawable,
129 130
                                                     const GimpTempBuf *pixmap_mask,
                                                     const GimpTempBuf *brush_mask,
131
                                                     gfloat            *d,
132 133 134 135
                                                     gint               x,
                                                     gint               y,
                                                     gint               width,
                                                     GimpBrushApplicationMode  mode);
136 137


138
G_DEFINE_TYPE (GimpBrushCore, gimp_brush_core, GIMP_TYPE_PAINT_CORE)
139

Michael Natterer's avatar
Michael Natterer committed
140
#define parent_class gimp_brush_core_parent_class
141

Michael Natterer's avatar
Michael Natterer committed
142
static guint core_signals[LAST_SIGNAL] = { 0, };
143 144 145 146 147 148 149 150


static void
gimp_brush_core_class_init (GimpBrushCoreClass *klass)
{
  GObjectClass       *object_class     = G_OBJECT_CLASS (klass);
  GimpPaintCoreClass *paint_core_class = GIMP_PAINT_CORE_CLASS (klass);

151 152
  core_signals[SET_BRUSH] =
    g_signal_new ("set-brush",
153 154 155 156 157 158 159
                  G_TYPE_FROM_CLASS (klass),
                  G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET (GimpBrushCoreClass, set_brush),
                  NULL, NULL,
                  gimp_marshal_VOID__OBJECT,
                  G_TYPE_NONE, 1,
                  GIMP_TYPE_BRUSH);
160

161
  core_signals[SET_DYNAMICS] =
162
    g_signal_new ("set-dynamics",
163 164 165 166 167 168
                  G_TYPE_FROM_CLASS (klass),
                  G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET (GimpBrushCoreClass, set_dynamics),
                  NULL, NULL,
                  gimp_marshal_VOID__OBJECT,
                  G_TYPE_NONE, 1,
169
                  GIMP_TYPE_DYNAMICS);
170

171 172 173 174 175 176
  object_class->finalize                    = gimp_brush_core_finalize;

  paint_core_class->start                   = gimp_brush_core_start;
  paint_core_class->pre_paint               = gimp_brush_core_pre_paint;
  paint_core_class->post_paint              = gimp_brush_core_post_paint;
  paint_core_class->interpolate             = gimp_brush_core_interpolate;
177
  paint_core_class->get_paint_buffer        = gimp_brush_core_get_paint_buffer;
178 179 180 181 182 183 184

  klass->handles_changing_brush             = FALSE;
  klass->handles_transforming_brush         = TRUE;
  klass->handles_dynamic_transforming_brush = TRUE;

  klass->set_brush                          = gimp_brush_core_real_set_brush;
  klass->set_dynamics                       = gimp_brush_core_real_set_dynamics;
185 186 187 188 189 190 191
}

static void
gimp_brush_core_init (GimpBrushCore *core)
{
  gint i, j;

192 193
  core->main_brush                   = NULL;
  core->brush                        = NULL;
194
  core->dynamics                     = NULL;
195 196
  core->spacing                      = 1.0;
  core->scale                        = 1.0;
Sven Neumann's avatar
Sven Neumann committed
197
  core->angle                        = 1.0;
198
  core->hardness                     = 1.0;
199
  core->aspect_ratio                 = 0.0;
200

201
  core->pressure_brush               = NULL;
202

203
  core->last_solid_brush_mask        = NULL;
204 205 206 207 208
  core->solid_cache_invalid          = FALSE;

  core->transform_brush              = NULL;
  core->transform_pixmap             = NULL;

209 210
  core->last_subsample_brush_mask    = NULL;
  core->subsample_cache_invalid      = FALSE;
211

212
  core->rand                         = g_rand_new ();
213

214 215 216 217 218 219 220
  for (i = 0; i < BRUSH_CORE_SOLID_SUBSAMPLE; i++)
    {
      for (j = 0; j < BRUSH_CORE_SOLID_SUBSAMPLE; j++)
        {
          core->solid_brushes[i][j] = NULL;
        }
    }
221

222 223 224 225 226 227 228 229
  for (i = 0; i < BRUSH_CORE_JITTER_LUTSIZE - 1; ++i)
    {
      core->jitter_lut_y[i] = cos (gimp_deg_to_rad (i * 360 /
                                                    BRUSH_CORE_JITTER_LUTSIZE));
      core->jitter_lut_x[i] = sin (gimp_deg_to_rad (i * 360 /
                                                    BRUSH_CORE_JITTER_LUTSIZE));
    }

230 231 232
  g_assert (BRUSH_CORE_SUBSAMPLE == KERNEL_SUBSAMPLE);

  for (i = 0; i < KERNEL_SUBSAMPLE + 1; i++)
233 234 235
    {
      for (j = 0; j < KERNEL_SUBSAMPLE + 1; j++)
        {
236
          core->subsample_brushes[i][j] = NULL;
237 238
        }
    }
239 240 241 242 243 244 245 246 247 248
}

static void
gimp_brush_core_finalize (GObject *object)
{
  GimpBrushCore *core = GIMP_BRUSH_CORE (object);
  gint           i, j;

  if (core->pressure_brush)
    {
249
      gimp_temp_buf_unref (core->pressure_brush);
250 251 252 253 254 255 256
      core->pressure_brush = NULL;
    }

  for (i = 0; i < BRUSH_CORE_SOLID_SUBSAMPLE; i++)
    for (j = 0; j < BRUSH_CORE_SOLID_SUBSAMPLE; j++)
      if (core->solid_brushes[i][j])
        {
257
          gimp_temp_buf_unref (core->solid_brushes[i][j]);
258 259 260
          core->solid_brushes[i][j] = NULL;
        }

261 262 263 264 265 266
  if (core->rand)
    {
      g_rand_free (core->rand);
      core->rand = NULL;
    }

267 268
  for (i = 0; i < KERNEL_SUBSAMPLE + 1; i++)
    for (j = 0; j < KERNEL_SUBSAMPLE + 1; j++)
269
      if (core->subsample_brushes[i][j])
270
        {
271
          gimp_temp_buf_unref (core->subsample_brushes[i][j]);
272
          core->subsample_brushes[i][j] = NULL;
273 274
        }

275
  if (core->main_brush)
276
    {
277
      g_signal_handlers_disconnect_by_func (core->main_brush,
278 279
                                            gimp_brush_core_invalidate_cache,
                                            core);
280
      gimp_brush_end_use (core->main_brush);
281 282
      g_object_unref (core->main_brush);
      core->main_brush = NULL;
283 284
    }

285 286 287 288 289 290
  if (core->dynamics)
    {
      g_object_unref (core->dynamics);
      core->dynamics = NULL;
    }

291 292 293 294
  G_OBJECT_CLASS (parent_class)->finalize (object);
}

static gboolean
295 296 297 298 299
gimp_brush_core_pre_paint (GimpPaintCore    *paint_core,
                           GimpDrawable     *drawable,
                           GimpPaintOptions *paint_options,
                           GimpPaintState    paint_state,
                           guint32           time)
300 301 302
{
  GimpBrushCore *core = GIMP_BRUSH_CORE (paint_core);

303
  if (paint_state == GIMP_PAINT_STATE_MOTION)
304
    {
305 306
      GimpCoords last_coords;
      GimpCoords current_coords;
307
      gdouble scale;
308 309

      gimp_paint_core_get_last_coords (paint_core, &last_coords);
310
      gimp_paint_core_get_current_coords (paint_core, &current_coords);
311

312 313 314 315 316
      /* If we current point == last point, check if the brush
       * wants to be painted in that case. (Direction dependent
       * pixmap brush pipes don't, as they don't know which
       * pixmap to select.)
       */
317 318
      if (last_coords.x == current_coords.x &&
          last_coords.y == current_coords.y &&
319
          ! gimp_brush_want_null_motion (core->main_brush,
320 321
                                         &last_coords,
                                         &current_coords))
322 323 324
        {
          return FALSE;
        }
325 326
      /*No drawing anything if the scale is too small*/
      if (GIMP_BRUSH_CORE_GET_CLASS (core)->handles_transforming_brush)
327
        {
328 329 330 331 332
          GimpImage *image = gimp_item_get_image (GIMP_ITEM (drawable));
          gdouble    fade_point;

          if (GIMP_BRUSH_CORE_GET_CLASS (core)->handles_dynamic_transforming_brush)
            {
Alexia Death's avatar
Alexia Death committed
333 334 335
              gdouble width;
              gdouble height;

336 337
              fade_point = gimp_paint_options_get_fade (paint_options, image,
                                                        paint_core->pixel_dist);
Alexia Death's avatar
Alexia Death committed
338 339
              width = gimp_brush_get_width  (core->main_brush);
              height = gimp_brush_get_height (core->main_brush);
340

341
              scale = paint_options->brush_size /
Alexia Death's avatar
Alexia Death committed
342
                      MAX (width, height) *
343 344 345 346 347
                      gimp_dynamics_get_linear_value (core->dynamics,
                                                      GIMP_DYNAMICS_OUTPUT_SIZE,
                                                      &current_coords,
                                                      paint_options,
                                                      fade_point);
348

Alexia Death's avatar
Alexia Death committed
349 350 351 352 353 354 355 356 357 358 359
              if (paint_options->brush_zoom)
                {
                  scale = scale / MAX (current_coords.xscale, current_coords.xscale);

                  /*Cap transform result for brushes or OOM can occur*/
                  if ((MAX (width, height)) > GIMP_BRUSH_MAX_SIZE)
                    {
                      scale = GIMP_BRUSH_MAX_SIZE / MAX (width, height);
                    }
                }

360
              if (scale < 0.0000001)
361
                return FALSE;
362
            }
363
        }
364

365
      if (GIMP_BRUSH_CORE_GET_CLASS (paint_core)->handles_changing_brush)
366
        {
367
          core->brush = gimp_brush_select_brush (core->main_brush,
368 369
                                                 &last_coords,
                                                 &current_coords);
370
        }
371 372 373 374 375
      if ((! GIMP_IS_BRUSH_GENERATED(core->main_brush)) &&
          (paint_options->brush_hardness != gimp_brush_get_blur_hardness(core->main_brush)))
        {
          gimp_brush_flush_blur_caches(core->main_brush);
        }
376 377 378 379 380
    }

  return TRUE;
}

381
static void
382 383 384 385 386
gimp_brush_core_post_paint (GimpPaintCore    *paint_core,
                            GimpDrawable     *drawable,
                            GimpPaintOptions *paint_options,
                            GimpPaintState    paint_state,
                            guint32           time)
387 388
{
  GimpBrushCore *core = GIMP_BRUSH_CORE (paint_core);
389

390
  if (paint_state == GIMP_PAINT_STATE_MOTION)
391 392 393 394 395
    {
      core->brush = core->main_brush;
    }
}

396
static gboolean
397 398 399
gimp_brush_core_start (GimpPaintCore     *paint_core,
                       GimpDrawable      *drawable,
                       GimpPaintOptions  *paint_options,
400
                       const GimpCoords  *coords,
401
                       GError           **error)
402
{
403 404
  GimpBrushCore *core    = GIMP_BRUSH_CORE (paint_core);
  GimpContext   *context = GIMP_CONTEXT (paint_options);
405

406
  gimp_brush_core_set_brush (core, gimp_context_get_brush (context));
407

408
  gimp_brush_core_set_dynamics (core, gimp_context_get_dynamics (context));
409

410
  if (! core->main_brush)
411
    {
412
      g_set_error_literal (error, GIMP_ERROR, GIMP_FAILED,
413
                           _("No brushes available for use with this tool."));
414
      return FALSE;
415 416
    }

417 418 419 420 421 422 423
  if (! core->dynamics)
    {
      g_set_error_literal (error, GIMP_ERROR, GIMP_FAILED,
                           _("No paint dynamics available for use with this tool."));
      return FALSE;
    }

Sven Neumann's avatar
Sven Neumann committed
424 425
  if (GIMP_BRUSH_CORE_GET_CLASS (core)->handles_transforming_brush)
    {
426
      gimp_brush_core_eval_transform_dynamics (core,
427 428 429
                                               drawable,
                                               paint_options,
                                               coords);
Sven Neumann's avatar
Sven Neumann committed
430
    }
Michael Natterer's avatar
Michael Natterer committed
431

432
  core->spacing = paint_options->brush_spacing;
433

434
  core->brush = core->main_brush;
435

436 437 438 439
  core->jitter =
    gimp_paint_options_get_jitter (paint_options,
                                   gimp_item_get_image (GIMP_ITEM (drawable)));

440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455
  return TRUE;
}

/**
 * gimp_avoid_exact_integer
 * @x: points to a gdouble
 *
 * Adjusts *x such that it is not too close to an integer. This is used
 * for decision algorithms that would be vulnerable to rounding glitches
 * if exact integers were input.
 *
 * Side effects: Changes the value of *x
 **/
static void
gimp_avoid_exact_integer (gdouble *x)
{
456 457
  const gdouble integral   = floor (*x);
  const gdouble fractional = *x - integral;
458 459

  if (fractional < EPSILON)
460 461 462 463 464 465 466
    {
      *x = integral + EPSILON;
    }
  else if (fractional > (1 -EPSILON))
    {
      *x = integral + (1 - EPSILON);
    }
467 468 469 470
}

static void
gimp_brush_core_interpolate (GimpPaintCore    *paint_core,
471
                             GimpDrawable     *drawable,
472 473
                             GimpPaintOptions *paint_options,
                             guint32           time)
474
{
475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499
  GimpBrushCore      *core  = GIMP_BRUSH_CORE (paint_core);
  GimpImage          *image = gimp_item_get_image (GIMP_ITEM (drawable));
  GimpDynamicsOutput *spacing_output;
  GimpCoords          last_coords;
  GimpCoords          current_coords;
  GimpVector2         delta_vec;
  gdouble             delta_pressure;
  gdouble             delta_xtilt, delta_ytilt;
  gdouble             delta_wheel;
  gdouble             delta_velocity;
  gdouble             temp_direction;
  GimpVector2         temp_vec;
  gint                n, num_points;
  gdouble             t0, dt, tn;
  gdouble             st_factor, st_offset;
  gdouble             initial;
  gdouble             dist;
  gdouble             total;
  gdouble             pixel_dist;
  gdouble             pixel_initial;
  gdouble             xd, yd;
  gdouble             mag;
  gdouble             dyn_spacing = core->spacing;
  gdouble             fade_point;
  gboolean            use_dyn_spacing;
500

Sven Neumann's avatar
Sven Neumann committed
501 502
  g_return_if_fail (GIMP_IS_BRUSH (core->brush));

503
  gimp_paint_core_get_last_coords (paint_core, &last_coords);
504
  gimp_paint_core_get_current_coords (paint_core, &current_coords);
505

506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532
  gimp_avoid_exact_integer (&last_coords.x);
  gimp_avoid_exact_integer (&last_coords.y);
  gimp_avoid_exact_integer (&current_coords.x);
  gimp_avoid_exact_integer (&current_coords.y);

  delta_vec.x    = current_coords.x        - last_coords.x;
  delta_vec.y    = current_coords.y        - last_coords.y;
  delta_pressure = current_coords.pressure - last_coords.pressure;
  delta_xtilt    = current_coords.xtilt    - last_coords.xtilt;
  delta_ytilt    = current_coords.ytilt    - last_coords.ytilt;
  delta_wheel    = current_coords.wheel    - last_coords.wheel;
  delta_velocity = current_coords.velocity - last_coords.velocity;
  temp_direction = current_coords.direction;

  /*  return if there has been no motion  */
  if (! delta_vec.x    &&
      ! delta_vec.y    &&
      ! delta_pressure &&
      ! delta_xtilt    &&
      ! delta_ytilt    &&
      ! delta_wheel    &&
      ! delta_velocity)
    return;

  pixel_dist    = gimp_vector2_length (&delta_vec);
  pixel_initial = paint_core->pixel_dist;

533
  /*  Zero sized brushes are unfit for interpolate, so we just let
534
   *  paint core fail on its own
535
   */
536 537 538 539 540 541
  if (core->scale == 0.0)
    {
      gimp_paint_core_set_last_coords (paint_core, &current_coords);

      gimp_paint_core_paint (paint_core, drawable, paint_options,
                             GIMP_PAINT_STATE_MOTION, time);
542 543 544

      paint_core->pixel_dist = pixel_initial + pixel_dist; /* Dont forget to update pixel distance*/

545 546 547
      return;
    }

548
  /* Handle dynamic spacing */
549 550 551
  spacing_output = gimp_dynamics_get_output (core->dynamics,
                                             GIMP_DYNAMICS_OUTPUT_SPACING);

552 553 554
  fade_point = gimp_paint_options_get_fade (paint_options, image,
                                            paint_core->pixel_dist);

555
  use_dyn_spacing = gimp_dynamics_output_is_enabled (spacing_output);
556 557 558

  if (use_dyn_spacing)
    {
559 560 561 562
      dyn_spacing = gimp_dynamics_output_get_linear_value (spacing_output,
                                                           &current_coords,
                                                           paint_options,
                                                           fade_point);
563 564 565 566 567 568

      /* Dynamic spacing assumes that the value set in core is the min
       * value and the max is full 200% spacing. This approach differs
       * from the usual factor from user input approach because making
       * spacing smaller than the nominal value is unlikely and
       * spacing has a hard defined max.
569
       */
570
      dyn_spacing = (core->spacing +
571
                     ((2.0 - core->spacing) * (1.0 - dyn_spacing)));
572

573 574
      /*  Limiting spacing to minimum 1%  */
      dyn_spacing = MAX (core->spacing, dyn_spacing);
575
    }
576

577
  /* calculate the distance traveled in the coordinate space of the brush */
578
  temp_vec = gimp_brush_get_x_axis (core->brush);
579
  gimp_vector2_mul (&temp_vec, core->scale);
580
  gimp_vector2_rotate (&temp_vec, core->angle * G_PI * 2);
581 582 583 584

  mag = gimp_vector2_length (&temp_vec);
  xd  = gimp_vector2_inner_product (&delta_vec, &temp_vec) / (mag * mag);

585
  temp_vec = gimp_brush_get_y_axis (core->brush);
586
  gimp_vector2_mul (&temp_vec, core->scale);
587
  gimp_vector2_rotate (&temp_vec, core->angle * G_PI * 2);
588

589 590
  mag = gimp_vector2_length (&temp_vec);
  yd  = gimp_vector2_inner_product (&delta_vec, &temp_vec) / (mag * mag);
591 592 593 594 595 596 597 598 599

  dist    = 0.5 * sqrt (xd * xd + yd * yd);
  total   = dist + paint_core->distance;
  initial = paint_core->distance;


  if (delta_vec.x * delta_vec.x > delta_vec.y * delta_vec.y)
    {
      st_factor = delta_vec.x;
600
      st_offset = last_coords.x - 0.5;
601 602 603 604
    }
  else
    {
      st_factor = delta_vec.y;
605
      st_offset = last_coords.y - 0.5;
606 607
    }

608 609 610 611 612 613 614 615 616 617 618 619 620 621
  if (use_dyn_spacing)
    {
      gint s0;

      num_points = dist / dyn_spacing;

      s0 = (gint) floor (st_offset + 0.5);
      t0 = (s0 - st_offset) / st_factor;
      dt = dyn_spacing / dist;

      if (num_points == 0)
        return;
    }
  else if (fabs (st_factor) > dist / core->spacing)
622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645
    {
      /*  The stripe principle leads to brush positions that are spaced
       *  *closer* than the official brush spacing. Use the official
       *  spacing instead. This is the common case when the brush spacing
       *  is large.
       *  The net effect is then to put a lower bound on the spacing, but
       *  one that varies with the slope of the line. This is suppose to
       *  make thin lines (say, with a 1x1 brush) prettier while leaving
       *  lines with larger brush spacing as they used to look in 1.2.x.
       */

      dt = core->spacing / dist;
      n = (gint) (initial / core->spacing + 1.0 + EPSILON);
      t0 = (n * core->spacing - initial) / dist;
      num_points = 1 + (gint) floor ((1 + EPSILON - t0) / dt);

      /* if we arnt going to paint anything this time and the brush
       * has only moved on one axis return without updating the brush
       * position, distance etc. so that we can more accurately space
       * brush strokes when curves are supplied to us in single pixel
       * chunks.
       */

      if (num_points == 0 && (delta_vec.x == 0 || delta_vec.y == 0))
646
        return;
647 648 649 650
    }
  else if (fabs (st_factor) < EPSILON)
    {
      /* Hm, we've hardly moved at all. Don't draw anything, but reset the
651
       * old coordinates and hope we've gone longer the next time...
652
       */
653 654 655 656 657
      current_coords.x = last_coords.x;
      current_coords.y = last_coords.y;

      gimp_paint_core_set_current_coords (paint_core, &current_coords);

658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688
      /* ... but go along with the current pressure, tilt and wheel */
      return;
    }
  else
    {
      gint direction = st_factor > 0 ? 1 : -1;
      gint x, y;
      gint s0, sn;

      /*  Choose the first and last stripe to paint.
       *    FIRST PRIORITY is to avoid gaps painting with a 1x1 aliasing
       *  brush when a horizontalish line segment follows a verticalish
       *  one or vice versa - no matter what the angle between the two
       *  lines is. This will also limit the local thinning that a 1x1
       *  subsampled brush may suffer in the same situation.
       *    SECOND PRIORITY is to avoid making free-hand drawings
       *  unpleasantly fat by plotting redundant points.
       *    These are achieved by the following rules, but it is a little
       *  tricky to see just why. Do not change this algorithm unless you
       *  are sure you know what you're doing!
       */

      /*  Basic case: round the beginning and ending point to nearest
       *  stripe center.
       */
      s0 = (gint) floor (st_offset + 0.5);
      sn = (gint) floor (st_offset + st_factor + 0.5);

      t0 = (s0 - st_offset) / st_factor;
      tn = (sn - st_offset) / st_factor;

689 690
      x = (gint) floor (last_coords.x + t0 * delta_vec.x);
      y = (gint) floor (last_coords.y + t0 * delta_vec.y);
691

692 693
      if (t0 < 0.0 && !( x == (gint) floor (last_coords.x) &&
                         y == (gint) floor (last_coords.y) ))
694 695 696 697 698 699 700
        {
          /*  Exception A: If the first stripe's brush position is
           *  EXTRApolated into a different pixel square than the
           *  ideal starting point, dont't plot it.
           */
          s0 += direction;
        }
701 702
      else if (x == (gint) floor (paint_core->last_paint.x) &&
               y == (gint) floor (paint_core->last_paint.y))
703 704 705 706 707 708 709 710
        {
          /*  Exception B: If first stripe's brush position is within the
           *  same pixel square as the last plot of the previous line,
           *  don't plot it either.
           */
          s0 += direction;
        }

711 712
      x = (gint) floor (last_coords.x + tn * delta_vec.x);
      y = (gint) floor (last_coords.y + tn * delta_vec.y);
713

714 715
      if (tn > 1.0 && !( x == (gint) floor (current_coords.x) &&
                         y == (gint) floor (current_coords.y)))
716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748
        {
          /*  Exception C: If the last stripe's brush position is
           *  EXTRApolated into a different pixel square than the
           *  ideal ending point, don't plot it.
           */
          sn -= direction;
        }

      t0 = (s0 - st_offset) / st_factor;
      tn = (sn - st_offset) / st_factor;
      dt         =     direction * 1.0 / st_factor;
      num_points = 1 + direction * (sn - s0);

      if (num_points >= 1)
        {
          /*  Hack the reported total distance such that it looks to the
           *  next line as if the the last pixel plotted were at an integer
           *  multiple of the brush spacing. This helps prevent artifacts
           *  for connected lines when the brush spacing is such that some
           *  slopes will use the stripe regime and other slopes will use
           *  the nominal brush spacing.
           */

          if (tn < 1)
            total = initial + tn * dist;

          total = core->spacing * (gint) (total / core->spacing + 0.5);
          total += (1.0 - tn) * dist;
        }
    }

  for (n = 0; n < num_points; n++)
    {
749 750
      gdouble t = t0 + n * dt;
      gdouble p = (gdouble) n / num_points;
751

752 753 754 755 756 757 758 759
      current_coords.x         = last_coords.x        + t * delta_vec.x;
      current_coords.y         = last_coords.y        + t * delta_vec.y;
      current_coords.pressure  = last_coords.pressure + p * delta_pressure;
      current_coords.xtilt     = last_coords.xtilt    + p * delta_xtilt;
      current_coords.ytilt     = last_coords.ytilt    + p * delta_ytilt;
      current_coords.wheel     = last_coords.wheel    + p * delta_wheel;
      current_coords.velocity  = last_coords.velocity + p * delta_velocity;
      current_coords.direction = temp_direction;
760 761
      current_coords.xscale    = last_coords.xscale;
      current_coords.yscale    = last_coords.yscale;
762

763
      if (core->jitter > 0.0)
764
        {
765 766 767 768 769 770 771 772
          GimpVector2 x_axis;
          GimpVector2 y_axis;
          gdouble     dyn_jitter;
          gdouble     jitter_dist;
          gint32      jitter_angle;

          x_axis = gimp_brush_get_x_axis (core->brush);
          y_axis = gimp_brush_get_y_axis (core->brush);
773

774
          dyn_jitter = (core->jitter *
775 776 777 778 779
                        gimp_dynamics_get_linear_value (core->dynamics,
                                                        GIMP_DYNAMICS_OUTPUT_JITTER,
                                                        &current_coords,
                                                        paint_options,
                                                        fade_point));
Michael Natterer's avatar
Michael Natterer committed
780

781
          jitter_dist  = g_rand_double_range (core->rand, 0, dyn_jitter);
782 783
          jitter_angle = g_rand_int_range (core->rand,
                                           0, BRUSH_CORE_JITTER_LUTSIZE);
784

785
          current_coords.x +=
786
            (x_axis.x + y_axis.x) *
787
            jitter_dist * core->jitter_lut_x[jitter_angle] * core->scale;
788

789
          current_coords.y +=
790
            (y_axis.y + x_axis.y) *
791
            jitter_dist * core->jitter_lut_y[jitter_angle] * core->scale;
792
        }
793

794 795
      gimp_paint_core_set_current_coords (paint_core, &current_coords);

796 797
      paint_core->distance   = initial       + t * dist;
      paint_core->pixel_dist = pixel_initial + t * pixel_dist;
798

799
      gimp_paint_core_paint (paint_core, drawable, paint_options,
800
                             GIMP_PAINT_STATE_MOTION, time);
801 802
    }

803 804 805 806 807 808 809
  current_coords.x        = last_coords.x        + delta_vec.x;
  current_coords.y        = last_coords.y        + delta_vec.y;
  current_coords.pressure = last_coords.pressure + delta_pressure;
  current_coords.xtilt    = last_coords.xtilt    + delta_xtilt;
  current_coords.ytilt    = last_coords.ytilt    + delta_ytilt;
  current_coords.wheel    = last_coords.wheel    + delta_wheel;
  current_coords.velocity = last_coords.velocity + delta_velocity;
Alexia Death's avatar
Alexia Death committed
810 811
  current_coords.xscale   = last_coords.xscale;
  current_coords.yscale   = last_coords.yscale;
812 813

  gimp_paint_core_set_current_coords (paint_core, &current_coords);
814
  gimp_paint_core_set_last_coords (paint_core, &current_coords);
815 816 817 818 819

  paint_core->distance   = total;
  paint_core->pixel_dist = pixel_initial + pixel_dist;
}

820 821 822 823
static GeglBuffer *
gimp_brush_core_get_paint_buffer (GimpPaintCore    *paint_core,
                                  GimpDrawable     *drawable,
                                  GimpPaintOptions *paint_options,
824
                                  GimpLayerMode     paint_mode,
825 826
                                  const GimpCoords *coords,
                                  gint             *paint_buffer_x,
Jehan's avatar
Jehan committed
827 828 829
                                  gint             *paint_buffer_y,
                                  gint             *paint_width,
                                  gint             *paint_height)
830 831 832 833
{
  GimpBrushCore *core = GIMP_BRUSH_CORE (paint_core);
  gint           x, y;
  gint           x1, y1, x2, y2;
834 835
  gint           drawable_width, drawable_height;
  gint           brush_width, brush_height;
836

Michael Natterer's avatar
Michael Natterer committed
837 838 839
  gimp_brush_transform_size (core->brush,
                             core->scale, core->aspect_ratio, core->angle,
                             &brush_width, &brush_height);
840

Jehan's avatar
Jehan committed
841 842 843 844 845
  if (paint_width)
    *paint_width  = brush_width;
  if (paint_height)
    *paint_height = brush_height;

846
  /*  adjust the x and y coordinates to the upper left corner of the brush  */
847 848
  x = (gint) floor (coords->x) - (brush_width  / 2);
  y = (gint) floor (coords->y) - (brush_height / 2);
849

850 851
  drawable_width  = gimp_item_get_width  (GIMP_ITEM (drawable));
  drawable_height = gimp_item_get_height (GIMP_ITEM (drawable));
852

853 854 855 856
  x1 = CLAMP (x - 1, 0, drawable_width);
  y1 = CLAMP (y - 1, 0, drawable_height);
  x2 = CLAMP (x + brush_width  + 1, 0, drawable_width);
  y2 = CLAMP (y + brush_height + 1, 0, drawable_height);
857 858 859

  /*  configure the canvas buffer  */
  if ((x2 - x1) && (y2 - y1))
860
    {
861
      GimpTempBuf *temp_buf;
Daniel Sabo's avatar
Daniel Sabo committed
862 863
      const Babl  *format;

864
      if (gimp_layer_mode_wants_linear_data (paint_mode))
Daniel Sabo's avatar
Daniel Sabo committed
865 866 867
        format = babl_format ("RGBA float");
      else
        format = babl_format ("R'G'B'A float");
868

869 870
      if (paint_core->paint_buffer                                       &&
          gegl_buffer_get_width  (paint_core->paint_buffer) == (x2 - x1) &&
Daniel Sabo's avatar
Daniel Sabo committed
871 872
          gegl_buffer_get_height (paint_core->paint_buffer) == (y2 - y1) &&
          gegl_buffer_get_format (paint_core->paint_buffer) == format )
873 874 875 876 877 878 879
        {
          *paint_buffer_x = x1;
          *paint_buffer_y = y1;

          return paint_core->paint_buffer;
        }

880
      temp_buf = gimp_temp_buf_new ((x2 - x1), (y2 - y1),
Daniel Sabo's avatar
Daniel Sabo committed
881
                                    format);
882

883 884
      *paint_buffer_x = x1;
      *paint_buffer_y = y1;
885 886 887 888

      if (paint_core->paint_buffer)
        g_object_unref (paint_core->paint_buffer);

889 890 891
      paint_core->paint_buffer = gimp_temp_buf_create_buffer (temp_buf);

      gimp_temp_buf_unref (temp_buf);
892

893
      return paint_core->paint_buffer;
894 895 896
    }

  return NULL;
897 898
}

899 900 901 902
static void
gimp_brush_core_real_set_brush (GimpBrushCore *core,
                                GimpBrush     *brush)
{
903 904 905
  if (brush == core->main_brush)
    return;

906 907 908 909 910
  if (core->main_brush)
    {
      g_signal_handlers_disconnect_by_func (core->main_brush,
                                            gimp_brush_core_invalidate_cache,
                                            core);
911
      gimp_brush_end_use (core->main_brush);
912 913 914 915 916 917 918 919 920
      g_object_unref (core->main_brush);
      core->main_brush = NULL;
    }

  core->main_brush = brush;

  if (core->main_brush)
    {
      g_object_ref (core->main_brush);
921
      gimp_brush_begin_use (core->main_brush);
922
      g_signal_connect (core->main_brush, "invalidate-preview",
923 924 925 926 927
                        G_CALLBACK (gimp_brush_core_invalidate_cache),
                        core);
    }
}

928
static void
929 930
gimp_brush_core_real_set_dynamics (GimpBrushCore *core,
                                   GimpDynamics  *dynamics)
931
{
932 933 934
  if (dynamics == core->dynamics)
    return;

935
  if (core->dynamics)
936
    g_object_unref (core->dynamics);
937 938 939

  core->dynamics = dynamics;

940 941
  if (core->dynamics)
    g_object_ref (core->dynamics);
942 943
}

944 945 946 947
void
gimp_brush_core_set_brush (GimpBrushCore *core,
                           GimpBrush     *brush)
{
Michael Natterer's avatar
Michael Natterer committed
948 949 950
  g_return_if_fail (GIMP_IS_BRUSH_CORE (core));
  g_return_if_fail (brush == NULL || GIMP_IS_BRUSH (brush));

951 952
  if (brush != core->main_brush)
    g_signal_emit (core, core_signals[SET_BRUSH], 0, brush);
953 954
}

955
void
956 957
gimp_brush_core_set_dynamics (GimpBrushCore *core,
                              GimpDynamics  *dynamics)
958 959
{
  g_return_if_fail (GIMP_IS_BRUSH_CORE (core));
960
  g_return_if_fail (dynamics == NULL || GIMP_IS_DYNAMICS (dynamics));
961

962 963
  if (dynamics != core->dynamics)
    g_signal_emit (core, core_signals[SET_DYNAMICS], 0, dynamics);
964 965
}

966 967
void
gimp_brush_core_paste_canvas (GimpBrushCore            *core,
Michael Natterer's avatar
Michael Natterer committed
968
                              GimpDrawable             *drawable,
969
                              const GimpCoords         *coords,
Michael Natterer's avatar
Michael Natterer committed
970 971
                              gdouble                   brush_opacity,
                              gdouble                   image_opacity,
972
                              GimpLayerMode             paint_mode,
973
                              GimpBrushApplicationMode  brush_hardness,
974
                              gdouble                   dynamic_force,
Jehan's avatar
Jehan committed
975 976
                              GimpPaintApplicationMode  mode,
                              GeglNode                 *op)
977
{
978 979
  const GimpTempBuf *brush_mask;

Jehan's avatar
Jehan committed
980
  brush_mask = gimp_brush_core_get_brush_mask (core, coords, op,
981 982
                                               brush_hardness,
                                               dynamic_force);
983 984

  if (brush_mask)
985 986 987 988
    {
      GimpPaintCore *paint_core = GIMP_PAINT_CORE (core);
      gint           x;
      gint           y;
Michael Natterer's avatar
Michael Natterer committed
989 990
      gint           off_x;
      gint           off_y;
991

992 993
      x = (gint) floor (coords->x) - (gimp_temp_buf_get_width  (brush_mask) >> 1);
      y = (gint) floor (coords->y) - (gimp_temp_buf_get_height (brush_mask) >> 1);
994

Michael Natterer's avatar
Michael Natterer committed
995 996
      off_x = (x < 0) ? -x : 0;
      off_y = (y < 0) ? -y : 0;
997

Daniel Sabo's avatar
Daniel Sabo committed
998 999
      gimp_paint_core_paste (paint_core, brush_mask,
                             off_x, off_y,
1000
                             drawable,
1001
                             brush_opacity,
1002 1003
                             image_opacity,
                             paint_mode,
1004 1005
                             mode);
    }
1006 1007
}

1008
/* Similar to gimp_brush_core_paste_canvas, but replaces the alpha channel
1009 1010 1011 1012 1013
 * rather than using it to composite (i.e. transparent over opaque
 * becomes transparent rather than opauqe.
 */
void
gimp_brush_core_replace_canvas (GimpBrushCore            *core,
Michael Natterer's avatar
Michael Natterer committed
1014
                                GimpDrawable             *drawable,
1015
                                const GimpCoords         *coords,
1016 1017 1018
                                gdouble                   brush_opacity,
                                gdouble                   image_opacity,
                                GimpBrushApplicationMode  brush_hardness,