gimpbrushcore.c 49.6 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 <https://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 30
#include "operations/layer-modes/gimp-layer-modes.h"

31
#include "gegl/gimp-babl.h"
32

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

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

47
#include "gimppaintoptions.h"
48

49 50 51 52 53
#include "gimp-intl.h"


#define EPSILON  0.00001

54 55 56
enum
{
  SET_BRUSH,
57
  SET_DYNAMICS,
58 59 60 61
  LAST_SIGNAL
};


62 63
/*  local function prototypes  */

64
static void      gimp_brush_core_finalize           (GObject          *object);
65

66
static gboolean  gimp_brush_core_start              (GimpPaintCore    *core,
Alexia Death's avatar
Alexia Death committed
67
                                                     GimpDrawable     *drawable,
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
                                                     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);

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

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

101 102
static const GimpTempBuf *
                 gimp_brush_core_transform_mask     (GimpBrushCore     *core,
Jehan's avatar
Jehan committed
103 104
                                                     GimpBrush         *brush,
                                                     GeglNode          *op);
105 106
static const GimpTempBuf *
                 gimp_brush_core_transform_pixmap   (GimpBrushCore     *core,
Jehan's avatar
Jehan committed
107 108
                                                     GimpBrush         *brush,
                                                     GeglNode          *op);
109 110 111

static void      gimp_brush_core_invalidate_cache   (GimpBrush         *brush,
                                                     GimpBrushCore     *core);
112 113

/*  brush pipe utility functions  */
114
static void  gimp_brush_core_paint_line_pixmap_mask (const Babl        *fish,
115 116
                                                     const GimpTempBuf *pixmap_mask,
                                                     const GimpTempBuf *brush_mask,
117
                                                     gfloat            *d,
118 119
                                                     gint               x,
                                                     gint               y,
120
                                                     gint               width);
121 122


123
G_DEFINE_TYPE (GimpBrushCore, gimp_brush_core, GIMP_TYPE_PAINT_CORE)
124

Michael Natterer's avatar
Michael Natterer committed
125
#define parent_class gimp_brush_core_parent_class
126

Michael Natterer's avatar
Michael Natterer committed
127
static guint core_signals[LAST_SIGNAL] = { 0, };
128 129 130 131 132 133 134 135


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);

136 137
  core_signals[SET_BRUSH] =
    g_signal_new ("set-brush",
138 139 140 141 142 143 144
                  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);
145

146
  core_signals[SET_DYNAMICS] =
147
    g_signal_new ("set-dynamics",
148 149 150 151 152 153
                  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,
154
                  GIMP_TYPE_DYNAMICS);
155

156 157 158 159 160 161
  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;
162
  paint_core_class->get_paint_buffer        = gimp_brush_core_get_paint_buffer;
163 164 165 166 167 168 169

  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;
170 171 172 173 174 175 176
}

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

177 178
  core->main_brush                   = NULL;
  core->brush                        = NULL;
179
  core->dynamics                     = NULL;
180 181
  core->spacing                      = 1.0;
  core->scale                        = 1.0;
182
  core->angle                        = 1.0;
183
  core->hardness                     = 1.0;
184
  core->aspect_ratio                 = 0.0;
185

186
  core->pressure_brush               = NULL;
187

188
  core->last_solid_brush_mask        = NULL;
189 190 191 192 193
  core->solid_cache_invalid          = FALSE;

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

194 195
  core->last_subsample_brush_mask    = NULL;
  core->subsample_cache_invalid      = FALSE;
196

197
  core->rand                         = g_rand_new ();
198

199 200 201 202 203 204 205
  for (i = 0; i < BRUSH_CORE_SOLID_SUBSAMPLE; i++)
    {
      for (j = 0; j < BRUSH_CORE_SOLID_SUBSAMPLE; j++)
        {
          core->solid_brushes[i][j] = NULL;
        }
    }
206

207 208 209 210 211 212 213 214
  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));
    }

215
  gimp_assert (BRUSH_CORE_SUBSAMPLE == KERNEL_SUBSAMPLE);
216 217

  for (i = 0; i < KERNEL_SUBSAMPLE + 1; i++)
218 219 220
    {
      for (j = 0; j < KERNEL_SUBSAMPLE + 1; j++)
        {
221
          core->subsample_brushes[i][j] = NULL;
222 223
        }
    }
224 225 226 227 228 229 230 231
}

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

232
  g_clear_pointer (&core->pressure_brush, gimp_temp_buf_unref);
233 234 235

  for (i = 0; i < BRUSH_CORE_SOLID_SUBSAMPLE; i++)
    for (j = 0; j < BRUSH_CORE_SOLID_SUBSAMPLE; j++)
236
      g_clear_pointer (&core->solid_brushes[i][j], gimp_temp_buf_unref);
237

238
  g_clear_pointer (&core->rand, g_rand_free);
239

240 241
  for (i = 0; i < KERNEL_SUBSAMPLE + 1; i++)
    for (j = 0; j < KERNEL_SUBSAMPLE + 1; j++)
242
      g_clear_pointer (&core->subsample_brushes[i][j], gimp_temp_buf_unref);
243

244
  if (core->main_brush)
245
    {
246
      g_signal_handlers_disconnect_by_func (core->main_brush,
247 248
                                            gimp_brush_core_invalidate_cache,
                                            core);
249
      gimp_brush_end_use (core->main_brush);
250
      g_clear_object (&core->main_brush);
251 252
    }

253
  g_clear_object (&core->dynamics);
254

255 256 257 258
  G_OBJECT_CLASS (parent_class)->finalize (object);
}

static gboolean
259 260 261 262 263
gimp_brush_core_pre_paint (GimpPaintCore    *paint_core,
                           GimpDrawable     *drawable,
                           GimpPaintOptions *paint_options,
                           GimpPaintState    paint_state,
                           guint32           time)
264 265 266
{
  GimpBrushCore *core = GIMP_BRUSH_CORE (paint_core);

267
  if (paint_state == GIMP_PAINT_STATE_MOTION)
268
    {
269 270
      GimpCoords last_coords;
      GimpCoords current_coords;
271
      gdouble scale;
272 273

      gimp_paint_core_get_last_coords (paint_core, &last_coords);
274
      gimp_paint_core_get_current_coords (paint_core, &current_coords);
275

276 277 278 279 280
      /* 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.)
       */
281 282
      if (last_coords.x == current_coords.x &&
          last_coords.y == current_coords.y &&
283
          ! gimp_brush_want_null_motion (core->main_brush,
284 285
                                         &last_coords,
                                         &current_coords))
286 287 288
        {
          return FALSE;
        }
289 290
      /*No drawing anything if the scale is too small*/
      if (GIMP_BRUSH_CORE_GET_CLASS (core)->handles_transforming_brush)
291
        {
292 293 294 295 296
          GimpImage *image = gimp_item_get_image (GIMP_ITEM (drawable));
          gdouble    fade_point;

          if (GIMP_BRUSH_CORE_GET_CLASS (core)->handles_dynamic_transforming_brush)
            {
297 298 299
              gdouble width;
              gdouble height;

300 301
              fade_point = gimp_paint_options_get_fade (paint_options, image,
                                                        paint_core->pixel_dist);
302 303
              width = gimp_brush_get_width  (core->main_brush);
              height = gimp_brush_get_height (core->main_brush);
304

305
              scale = paint_options->brush_size /
306
                      MAX (width, height) *
307 308 309 310 311
                      gimp_dynamics_get_linear_value (core->dynamics,
                                                      GIMP_DYNAMICS_OUTPUT_SIZE,
                                                      &current_coords,
                                                      paint_options,
                                                      fade_point);
312

313
              if (paint_options->brush_lock_to_view &&
314
                  MAX (current_coords.xscale, current_coords.yscale) > 0)
315
                {
316
                  scale /= MAX (current_coords.xscale, current_coords.yscale);
317

318 319
                  /* Cap transform result for brushes or OOM can occur */
                  if ((scale * MAX (width, height)) > GIMP_BRUSH_MAX_SIZE)
320 321 322 323 324
                    {
                      scale = GIMP_BRUSH_MAX_SIZE / MAX (width, height);
                    }
                }

325
              if (scale < 0.0000001)
326
                return FALSE;
327
            }
328
        }
329

330
      if (GIMP_BRUSH_CORE_GET_CLASS (paint_core)->handles_changing_brush)
331
        {
332
          core->brush = gimp_brush_select_brush (core->main_brush,
333 334
                                                 &last_coords,
                                                 &current_coords);
335
        }
336 337 338 339 340
      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);
        }
341 342 343 344 345
    }

  return TRUE;
}

346
static void
347 348 349 350 351
gimp_brush_core_post_paint (GimpPaintCore    *paint_core,
                            GimpDrawable     *drawable,
                            GimpPaintOptions *paint_options,
                            GimpPaintState    paint_state,
                            guint32           time)
352 353
{
  GimpBrushCore *core = GIMP_BRUSH_CORE (paint_core);
354

355
  if (paint_state == GIMP_PAINT_STATE_MOTION)
356 357 358 359 360
    {
      core->brush = core->main_brush;
    }
}

361
static gboolean
362 363 364
gimp_brush_core_start (GimpPaintCore     *paint_core,
                       GimpDrawable      *drawable,
                       GimpPaintOptions  *paint_options,
365
                       const GimpCoords  *coords,
366
                       GError           **error)
367
{
368 369
  GimpBrushCore *core    = GIMP_BRUSH_CORE (paint_core);
  GimpContext   *context = GIMP_CONTEXT (paint_options);
370

371
  gimp_brush_core_set_brush (core, gimp_context_get_brush (context));
372

373
  gimp_brush_core_set_dynamics (core, gimp_context_get_dynamics (context));
374

375
  if (! core->main_brush)
376
    {
377
      g_set_error_literal (error, GIMP_ERROR, GIMP_FAILED,
378
                           _("No brushes available for use with this tool."));
379
      return FALSE;
380 381
    }

382 383 384 385 386 387 388
  if (! core->dynamics)
    {
      g_set_error_literal (error, GIMP_ERROR, GIMP_FAILED,
                           _("No paint dynamics available for use with this tool."));
      return FALSE;
    }

389 390
  if (GIMP_BRUSH_CORE_GET_CLASS (core)->handles_transforming_brush)
    {
391
      gimp_brush_core_eval_transform_dynamics (core,
392 393 394
                                               drawable,
                                               paint_options,
                                               coords);
395
    }
Michael Natterer's avatar
Michael Natterer committed
396

397
  core->spacing = paint_options->brush_spacing;
398

399
  core->brush = core->main_brush;
400

401 402 403 404
  core->jitter =
    gimp_paint_options_get_jitter (paint_options,
                                   gimp_item_get_image (GIMP_ITEM (drawable)));

405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420
  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)
{
421 422
  const gdouble integral   = floor (*x);
  const gdouble fractional = *x - integral;
423 424

  if (fractional < EPSILON)
425 426 427 428 429 430 431
    {
      *x = integral + EPSILON;
    }
  else if (fractional > (1 -EPSILON))
    {
      *x = integral + (1 - EPSILON);
    }
432 433 434 435
}

static void
gimp_brush_core_interpolate (GimpPaintCore    *paint_core,
436
                             GimpDrawable     *drawable,
437 438
                             GimpPaintOptions *paint_options,
                             guint32           time)
439
{
440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464
  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;
465

Sven Neumann's avatar
Sven Neumann committed
466 467
  g_return_if_fail (GIMP_IS_BRUSH (core->brush));

468
  gimp_paint_core_get_last_coords (paint_core, &last_coords);
469
  gimp_paint_core_get_current_coords (paint_core, &current_coords);
470

471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497
  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;

498
  /*  Zero sized brushes are unfit for interpolate, so we just let
499
   *  paint core fail on its own
500
   */
501 502 503 504 505 506
  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);
507

508
      paint_core->pixel_dist = pixel_initial + pixel_dist; /* Don't forget to update pixel distance*/
509

510 511 512
      return;
    }

513
  /* Handle dynamic spacing */
514 515 516
  spacing_output = gimp_dynamics_get_output (core->dynamics,
                                             GIMP_DYNAMICS_OUTPUT_SPACING);

517 518 519
  fade_point = gimp_paint_options_get_fade (paint_options, image,
                                            paint_core->pixel_dist);

520
  use_dyn_spacing = gimp_dynamics_output_is_enabled (spacing_output);
521 522 523

  if (use_dyn_spacing)
    {
524 525 526 527
      dyn_spacing = gimp_dynamics_output_get_linear_value (spacing_output,
                                                           &current_coords,
                                                           paint_options,
                                                           fade_point);
528 529 530 531 532 533

      /* 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.
534
       */
535
      dyn_spacing = (core->spacing +
536
                     ((2.0 - core->spacing) * (1.0 - dyn_spacing)));
537

538 539
      /*  Limiting spacing to minimum 1%  */
      dyn_spacing = MAX (core->spacing, dyn_spacing);
540
    }
541

542
  /* calculate the distance traveled in the coordinate space of the brush */
543
  temp_vec = gimp_brush_get_x_axis (core->brush);
544
  gimp_vector2_mul (&temp_vec, core->scale);
545
  gimp_vector2_rotate (&temp_vec, core->angle * G_PI * 2);
546 547 548 549

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

550
  temp_vec = gimp_brush_get_y_axis (core->brush);
551
  gimp_vector2_mul (&temp_vec, core->scale);
552
  gimp_vector2_rotate (&temp_vec, core->angle * G_PI * 2);
553

554 555
  mag = gimp_vector2_length (&temp_vec);
  yd  = gimp_vector2_inner_product (&delta_vec, &temp_vec) / (mag * mag);
556 557 558 559 560 561 562 563 564

  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;
565
      st_offset = last_coords.x - 0.5;
566 567 568 569
    }
  else
    {
      st_factor = delta_vec.y;
570
      st_offset = last_coords.y - 0.5;
571 572
    }

573 574 575 576 577 578 579 580 581 582 583 584 585 586
  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)
587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610
    {
      /*  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))
611
        return;
612 613 614 615
    }
  else if (fabs (st_factor) < EPSILON)
    {
      /* Hm, we've hardly moved at all. Don't draw anything, but reset the
616
       * old coordinates and hope we've gone longer the next time...
617
       */
618 619 620 621 622
      current_coords.x = last_coords.x;
      current_coords.y = last_coords.y;

      gimp_paint_core_set_current_coords (paint_core, &current_coords);

623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653
      /* ... 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;

654 655
      x = (gint) floor (last_coords.x + t0 * delta_vec.x);
      y = (gint) floor (last_coords.y + t0 * delta_vec.y);
656

657 658
      if (t0 < 0.0 && !( x == (gint) floor (last_coords.x) &&
                         y == (gint) floor (last_coords.y) ))
659 660 661
        {
          /*  Exception A: If the first stripe's brush position is
           *  EXTRApolated into a different pixel square than the
662
           *  ideal starting point, don't plot it.
663 664 665
           */
          s0 += direction;
        }
666 667
      else if (x == (gint) floor (paint_core->last_paint.x) &&
               y == (gint) floor (paint_core->last_paint.y))
668 669 670 671 672 673 674 675
        {
          /*  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;
        }

676 677
      x = (gint) floor (last_coords.x + tn * delta_vec.x);
      y = (gint) floor (last_coords.y + tn * delta_vec.y);
678

679 680
      if (tn > 1.0 && !( x == (gint) floor (current_coords.x) &&
                         y == (gint) floor (current_coords.y)))
681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713
        {
          /*  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++)
    {
714 715
      gdouble t = t0 + n * dt;
      gdouble p = (gdouble) n / num_points;
716

717 718 719 720 721 722 723 724
      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;
725 726
      current_coords.xscale    = last_coords.xscale;
      current_coords.yscale    = last_coords.yscale;
727 728
      current_coords.angle     = last_coords.angle;
      current_coords.reflect   = last_coords.reflect;
729

730
      if (core->jitter > 0.0)
731
        {
732 733 734 735 736 737 738 739
          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);
740

741
          dyn_jitter = (core->jitter *
742 743 744 745 746
                        gimp_dynamics_get_linear_value (core->dynamics,
                                                        GIMP_DYNAMICS_OUTPUT_JITTER,
                                                        &current_coords,
                                                        paint_options,
                                                        fade_point));
Michael Natterer's avatar
Michael Natterer committed
747

748
          jitter_dist  = g_rand_double_range (core->rand, 0, dyn_jitter);
749 750
          jitter_angle = g_rand_int_range (core->rand,
                                           0, BRUSH_CORE_JITTER_LUTSIZE);
751

752
          current_coords.x +=
753
            (x_axis.x + y_axis.x) *
754
            jitter_dist * core->jitter_lut_x[jitter_angle] * core->scale;
755

756
          current_coords.y +=
757
            (y_axis.y + x_axis.y) *
758
            jitter_dist * core->jitter_lut_y[jitter_angle] * core->scale;
759
        }
760

761 762
      gimp_paint_core_set_current_coords (paint_core, &current_coords);

763 764
      paint_core->distance   = initial       + t * dist;
      paint_core->pixel_dist = pixel_initial + t * pixel_dist;
765

766
      gimp_paint_core_paint (paint_core, drawable, paint_options,
767
                             GIMP_PAINT_STATE_MOTION, time);
768 769
    }

770 771 772 773 774 775 776
  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;
777 778
  current_coords.xscale   = last_coords.xscale;
  current_coords.yscale   = last_coords.yscale;
779 780
  current_coords.angle    = last_coords.angle;
  current_coords.reflect  = last_coords.reflect;
781 782

  gimp_paint_core_set_current_coords (paint_core, &current_coords);
783
  gimp_paint_core_set_last_coords (paint_core, &current_coords);
784 785 786 787 788

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

789 790 791 792
static GeglBuffer *
gimp_brush_core_get_paint_buffer (GimpPaintCore    *paint_core,
                                  GimpDrawable     *drawable,
                                  GimpPaintOptions *paint_options,
793
                                  GimpLayerMode     paint_mode,
794 795
                                  const GimpCoords *coords,
                                  gint             *paint_buffer_x,
Jehan's avatar
Jehan committed
796 797 798
                                  gint             *paint_buffer_y,
                                  gint             *paint_width,
                                  gint             *paint_height)
799 800 801 802
{
  GimpBrushCore *core = GIMP_BRUSH_CORE (paint_core);
  gint           x, y;
  gint           x1, y1, x2, y2;
803 804
  gint           drawable_width, drawable_height;
  gint           brush_width, brush_height;
805

Michael Natterer's avatar
Michael Natterer committed
806
  gimp_brush_transform_size (core->brush,
807 808
                             core->scale, core->aspect_ratio,
                             core->angle, core->reflect,
Michael Natterer's avatar
Michael Natterer committed
809
                             &brush_width, &brush_height);
810

Jehan's avatar
Jehan committed
811 812 813 814 815
  if (paint_width)
    *paint_width  = brush_width;
  if (paint_height)
    *paint_height = brush_height;

816
  /*  adjust the x and y coordinates to the upper left corner of the brush  */
817 818
  x = (gint) floor (coords->x) - (brush_width  / 2);
  y = (gint) floor (coords->y) - (brush_height / 2);
819

820 821
  drawable_width  = gimp_item_get_width  (GIMP_ITEM (drawable));
  drawable_height = gimp_item_get_height (GIMP_ITEM (drawable));
822

823 824 825 826
  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);
827 828 829

  /*  configure the canvas buffer  */
  if ((x2 - x1) && (y2 - y1))
830
    {
831
      GimpTempBuf *temp_buf;
Daniel Sabo's avatar
Daniel Sabo committed
832 833
      const Babl  *format;

834 835 836
      format = gimp_layer_mode_get_format (paint_mode,
                                           GIMP_LAYER_COLOR_SPACE_AUTO,
                                           GIMP_LAYER_COLOR_SPACE_AUTO,
837
                                           gimp_drawable_get_format (drawable));
838

839 840
      if (paint_core->paint_buffer                                       &&
          gegl_buffer_get_width  (paint_core->paint_buffer) == (x2 - x1) &&
Daniel Sabo's avatar
Daniel Sabo committed
841
          gegl_buffer_get_height (paint_core->paint_buffer) == (y2 - y1) &&
842
          gegl_buffer_get_format (paint_core->paint_buffer) == format)
843 844 845 846 847 848 849
        {
          *paint_buffer_x = x1;
          *paint_buffer_y = y1;

          return paint_core->paint_buffer;
        }

850
      temp_buf = gimp_temp_buf_new ((x2 - x1), (y2 - y1),
Daniel Sabo's avatar
Daniel Sabo committed
851
                                    format);
852

853 854
      *paint_buffer_x = x1;
      *paint_buffer_y = y1;
855

856
      g_clear_object (&paint_core->paint_buffer);
857

858 859 860
      paint_core->paint_buffer = gimp_temp_buf_create_buffer (temp_buf);

      gimp_temp_buf_unref (temp_buf);
861

862
      return paint_core->paint_buffer;
863 864 865
    }

  return NULL;
866 867
}

868 869 870 871
static void
gimp_brush_core_real_set_brush (GimpBrushCore *core,
                                GimpBrush     *brush)
{
872 873 874
  if (brush == core->main_brush)
    return;

875 876 877 878 879
  if (core->main_brush)
    {
      g_signal_handlers_disconnect_by_func (core->main_brush,
                                            gimp_brush_core_invalidate_cache,
                                            core);
880
      gimp_brush_end_use (core->main_brush);
881 882
    }

883
  g_set_object (&core->main_brush, brush);
884 885 886

  if (core->main_brush)
    {
887
      gimp_brush_begin_use (core->main_brush);
888
      g_signal_connect (core->main_brush, "invalidate-preview",
889 890 891 892 893
                        G_CALLBACK (gimp_brush_core_invalidate_cache),
                        core);
    }
}

894
static void
895 896
gimp_brush_core_real_set_dynamics (GimpBrushCore *core,
                                   GimpDynamics  *dynamics)
897
{
898
  g_set_object (&core->dynamics, dynamics);
899 900
}

901 902 903 904
void
gimp_brush_core_set_brush (GimpBrushCore *core,
                           GimpBrush     *brush)
{
Michael Natterer's avatar
Michael Natterer committed
905 906 907
  g_return_if_fail (GIMP_IS_BRUSH_CORE (core));
  g_return_if_fail (brush == NULL || GIMP_IS_BRUSH (brush));

908 909
  if (brush != core->main_brush)
    g_signal_emit (core, core_signals[SET_BRUSH], 0, brush);
910 911
}

912
void
913 914
gimp_brush_core_set_dynamics (GimpBrushCore *core,
                              GimpDynamics  *dynamics)
915 916
{
  g_return_if_fail (GIMP_IS_BRUSH_CORE (core));
917
  g_return_if_fail (dynamics == NULL || GIMP_IS_DYNAMICS (dynamics));
918

919 920
  if (dynamics != core->dynamics)
    g_signal_emit (core, core_signals[SET_DYNAMICS], 0, dynamics);
921 922
}

923 924
void
gimp_brush_core_paste_canvas (GimpBrushCore            *core,
Michael Natterer's avatar
Michael Natterer committed
925
                              GimpDrawable             *drawable,
926
                              const GimpCoords         *coords,
Michael Natterer's avatar
Michael Natterer committed
927 928
                              gdouble                   brush_opacity,
                              gdouble                   image_opacity,
929
                              GimpLayerMode             paint_mode,
930
                              GimpBrushApplicationMode  brush_hardness,
931
                              gdouble                   dynamic_force,
Jehan's avatar
Jehan committed
932 933
                              GimpPaintApplicationMode  mode,
                              GeglNode                 *op)
934
{
935 936
  const GimpTempBuf *brush_mask;

Jehan's avatar
Jehan committed
937
  brush_mask = gimp_brush_core_get_brush_mask (core, coords, op,
938 939
                                               brush_hardness,
                                               dynamic_force);
940 941

  if (brush_mask)
942 943 944 945
    {
      GimpPaintCore *paint_core = GIMP_PAINT_CORE (core);
      gint           x;
      gint           y;
Michael Natterer's avatar
Michael Natterer committed
946 947
      gint           off_x;
      gint           off_y;
948

949 950
      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);
951

Michael Natterer's avatar
Michael Natterer committed
952 953
      off_x = (x < 0) ? -x : 0;
      off_y = (y < 0) ? -y : 0;
954

Daniel Sabo's avatar
Daniel Sabo committed
955 956
      gimp_paint_core_paste (paint_core, brush_mask,
                             off_x, off_y,
957
                             drawable,
958
                             brush_opacity,
959 960
                             image_opacity,
                             paint_mode,
961 962
                             mode);
    }
963 964
}

965
/* Similar to gimp_brush_core_paste_canvas, but replaces the alpha channel
966 967 968 969 970
 * 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
971
                                GimpDrawable             *drawable,
972
                                const GimpCoords         *coords,
973 974 975
                                gdouble                   brush_opacity,
                                gdouble                   image_opacity,
                                GimpBrushApplicationMode  brush_hardness,
976
                                gdouble                   dynamic_force,
Jehan's avatar
Jehan committed
977 978
                                GimpPaintApplicationMode  mode,
                                GeglNode                 *op)
979
{
980 981
  const GimpTempBuf *brush_mask;

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

  if (brush_mask)
987 988 989 990
    {
      GimpPaintCore *paint_core = GIMP_PAINT_CORE (core);
      gint           x;
      gint           y;
991 992
      gint           off_x;
      gint           off_y;
993

994 995
      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);
996

997 998
      off_x = (x < 0) ? -x : 0;
      off_y = (y < 0) ? -y : 0;
999

Daniel Sabo's avatar
Daniel Sabo committed
1000 1001
      gimp_paint_core_replace (paint_core, brush_mask,
                               off_x, off_y,
1002
                               drawable,
1003 1004 1005 1006
                               brush_opacity,
                               image_opacity,
                               mode);
    }
1007 1008 1009 1010 1011
}


static void
gimp_brush_core_invalidate_cache (GimpBrush     *brush,
1012
                                  GimpBrushCore *core)
1013 1014 1015
{
  /* Make sure we don't cache data for a brush that has changed */

1016 1017
  core->subsample_cache_invalid = TRUE;
  core->solid_cache_invalid     = TRUE;
1018

1019
  /* Notify of the brush change */
1020

1021
  g_signal_emit (core, core_signals[SET_BRUSH], 0, brush);
1022 1023
}

1024

1025 1026 1027 1028
/************************************************************
 *             LOCAL FUNCTION DEFINITIONS                   *
 ************************************************************/

1029
static const GimpTempBuf *
1030
gimp_brush_core_transform_mask (GimpBrushCore *core,
Jehan's avatar
Jehan committed
1031 1032
                                GimpBrush     *brush,
                                GeglNode      *op)
1033
{
1034
  const GimpTempBuf *mask;
1035

1036
  if (core->scale <= 0.0)
1037
    return NULL;
1038

1039
  mask = gimp_brush_transform_mask (brush,
Jehan's avatar
Jehan committed
1040
                                    op,
1041 1042 1043
                                    core->scale,
                                    core->aspect_ratio,
                                    core->angle,
1044
                                    core->reflect,
1045
                                    core->hardness);
1046

1047 1048
  if (mask == core->transform_brush)
    return mask;
1049

1050 1051 1052
  core->transform_brush         = mask;
  core->subsample_cache_invalid = TRUE;
  core->solid_cache_invalid     = TRUE;
1053

1054
  return core->transform_brush;
1055 1056
}

1057
static const GimpTempBuf *
1058
gimp_brush_core_transform_pixmap (GimpBrushCore *core,
Jehan's avatar
Jehan committed
1059 1060
                                  GimpBrush     *brush,
                                  GeglNode      *op)
1061
{
1062
  const GimpTempBuf *pixmap;
1063

1064
  if (core->scale <= 0.0)
1065 1066
    return NULL;

1067
  pixmap = gimp_brush_transform_pixmap (brush,
Jehan's avatar
Jehan committed
1068
                                        op,
1069 1070 1071
                                        core->scale,
                                        core->aspect_ratio,
                                        core->angle,
1072
                                        core->reflect,
1073
                                        core->hardness);
1074

1075 1076
  if (pixmap == core->transform_pixmap)
    return pixmap;
1077

1078 1079
  core->transform_pixmap        = pixmap;
  core->subsample_cache_invalid = TRUE;
1080

1081
  return core->transform_pixmap;
1082 1083
}

1084
const GimpTempBuf *
1085
gimp_brush_core_get_brush_mask (GimpBrushCore            *core,
1086
                                const GimpCoords         *coords,
Jehan's avatar
Jehan committed
1087
                                GeglNode                 *op,
1088
                                GimpBrushApplicationMode  brush_hardness,
1089
                                gdouble                   dynamic_force)
1090
{
1091
  const GimpTempBuf *mask;
1092

Ell's avatar
Ell committed
1093 1094 1095
  if (dynamic_force <= 0.0)
    return NULL;

Jehan's avatar
Jehan committed
1096
  mask = gimp_brush_core_transform_mask (core, core->brush, op);
1097

1098
  if (! mask)
1099 1100 1101 1102 1103
    return NULL;

  switch (brush_hardness)
    {
    case GIMP_BRUSH_SOFT:
1104
      return gimp_brush_core_subsample_mask (core, mask,
1105 1106
                                             coords->x,
                                             coords->y);
1107 1108 1109
      break;

    case GIMP_BRUSH_HARD:
1110
      return gimp_brush_core_solidify_mask (core, mask,
1111 1112
                                            coords->x,
                                            coords->y);
1113 1114 1115
      break;

    case GIMP_BRUSH_PRESSURE:
1116
      return gimp_brush_core_pressurize_mask (core, mask,
1117 1118
                                              coords->x,
                                              coords->y,
1119
                                              dynamic_force);
1120 1121 1122
      break;
    }

1123
  g_return_val_if_reached (NULL);
1124 1125
}

1126
void
1127
gimp_brush_core_eval_transform_dynamics (GimpBrushCore     *core,
1128 1129 1130 1131
                                         GimpDrawable      *drawable,
                                         GimpPaintOptions  *paint_options,
                                         const GimpCoords  *coords)
{
1132
  if (core->main_brush)
1133 1134 1135 1136 1137 1138 1139 1140
    {
      gdouble max_side;

      max_side = MAX (gimp_brush_get_width  (core->main_brush),
                      gimp_brush_get_height (core->main_brush));

      core->scale = paint_options->brush_size / max_side;

1141 1142
      if (paint_options->brush_lock_to_view &&
          MAX (coords->xscale, coords->yscale) > 0)
1143 1144
        {
          core->scale /= MAX (coords->xscale, coords->yscale);
1145 1146 1147 1148

          /* Cap transform result for brushes or OOM can occur */
          if ((core->scale * max_side) > GIMP_BRUSH_MAX_SIZE)
            {
1149
              core->scale = GIMP_BRUSH_MAX_SIZE / max_side;
1150
            }
1151 1152
        }
   }
1153
  else
1154 1155
    core->scale = -1;

1156
  core->aspect_ratio = paint_options->brush_aspect_ratio;
1157 1158
  core->angle        = paint_options->brush_angle;
  core->reflect      = FALSE;
1159
  core->hardness     = paint_options->brush_hardness;
1160

1161 1162 1163 1164 1165 1166
  if (paint_options->brush_lock_to_view)
    {
      core->angle   += coords->angle;
      core->reflect  = coords->reflect;
    }

1167
  if (! GIMP_IS_DYNAMICS (core->dynamics))
1168
    return;
1169 1170 1171

  if (GIMP_BRUSH_CORE_GET_CLASS (core)->handles_dynamic_transforming_brush)
    {
1172
      gdouble fade_point = 1.0;
1173

1174 1175
      if (drawable)
        {
1176 1177
          GimpImage     *image      = gimp_item_get_image (GIMP_ITEM (drawable));
          GimpPaintCore *paint_core = GIMP_PAINT_CORE (core);
1178

1179 1180 1181 1182
          fade_point = gimp_paint_options_get_fade (paint_options, image,
                                                    paint_core->pixel_dist);
        }

1183 1184 1185 1186 1187
      core->scale *= gimp_dynamics_get_linear_value (core->dynamics,
                                                     GIMP_DYNAMICS_OUTPUT_SIZE,
                                                     coords,
                                                     paint_options,
                                                     fade_point);
1188

1189 1190 1191 1192 1193
      core->angle += gimp_dynamics_get_angular_value (core->dynamics,
                                                      GIMP_DYNAMICS_OUTPUT_ANGLE,
                                                      coords,
                                                      paint_options,
                                                      fade_point);
1194

1195 1196 1197 1198 1199
      core->hardness *= gimp_dynamics_get_linear_value (core->dynamics,
                                                        GIMP_DYNAMICS_OUTPUT_HARDNESS,
                                                        coords,
                                                        paint_options,
                                                        fade_point);
1200

1201 1202
      if (gimp_dynamics_is_output_enabled (core->dynamics,
                                           GIMP_DYNAMICS_OUTPUT_ASPECT_RATIO))
1203
        {
1204 1205 1206 1207 1208 1209 1210 1211 1212 1213
          gdouble dyn_aspect;

          dyn_aspect = gimp_dynamics_get_aspect_value (core->dynamics,
                                                       GIMP_DYNAMICS_OUTPUT_ASPECT_RATIO,
                                                       coords,
                                                       paint_options,
                                                       fade_point);

          /* Zero aspect ratio is special cased to half of all ar range,
           * to force dynamics to have any effect. Forcing to full results
1214
           * in disappearing stamp if applied to maximum.