gimpbrushcore.c 49.8 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
#define GEGL_ITERATOR2_API
24
#include <gegl.h>
25

26 27
#include "libgimpmath/gimpmath.h"

28 29
#include "paint-types.h"

30 31
#include "operations/layer-modes/gimp-layer-modes.h"

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

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

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

48
#include "gimppaintoptions.h"
49

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


#define EPSILON  0.00001

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


63 64
/*  local function prototypes  */

65
static void      gimp_brush_core_finalize           (GObject          *object);
66

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

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

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

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

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

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


124
G_DEFINE_TYPE (GimpBrushCore, gimp_brush_core, GIMP_TYPE_PAINT_CORE)
125

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

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


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

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

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

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

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

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

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

187
  core->pressure_brush               = NULL;
188

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

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

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

198
  core->rand                         = g_rand_new ();
199

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

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

216
  gimp_assert (BRUSH_CORE_SUBSAMPLE == KERNEL_SUBSAMPLE);
217 218

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

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

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

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

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

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

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

254
  g_clear_object (&core->dynamics);
255

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

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

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

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

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

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

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

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

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

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

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

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

  return TRUE;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

static void
gimp_brush_core_interpolate (GimpPaintCore    *paint_core,
437
                             GimpDrawable     *drawable,
438 439
                             GimpPaintOptions *paint_options,
                             guint32           time)
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 465
  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;
466

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

469
  gimp_paint_core_get_last_coords (paint_core, &last_coords);
470
  gimp_paint_core_get_current_coords (paint_core, &current_coords);
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 498
  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;

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

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

511 512 513
      return;
    }

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

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

521
  use_dyn_spacing = gimp_dynamics_output_is_enabled (spacing_output);
522 523 524

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

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

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

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

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

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

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

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

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

      gimp_paint_core_set_current_coords (paint_core, &current_coords);

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 654
      /* ... 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;

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

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

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

680 681
      if (tn > 1.0 && !( x == (gint) floor (current_coords.x) &&
                         y == (gint) floor (current_coords.y)))
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 714
        {
          /*  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++)
    {
715 716
      gdouble t = t0 + n * dt;
      gdouble p = (gdouble) n / num_points;
717

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

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

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

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

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

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

762 763
      gimp_paint_core_set_current_coords (paint_core, &current_coords);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

          return paint_core->paint_buffer;
        }

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

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

857
      g_clear_object (&paint_core->paint_buffer);
858

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

      gimp_temp_buf_unref (temp_buf);
862

863
      return paint_core->paint_buffer;
864 865 866
    }

  return NULL;
867 868
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

1020
  /* Notify of the brush change */
1021

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

1025

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

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

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

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

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

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

1055
  return core->transform_brush;
1056 1057
}

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

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

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

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

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

1082
  return core->transform_pixmap;
1083 1084
}

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

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

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

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

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

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

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

1124
  g_return_val_if_reached (NULL);
1125 1126
}

1127
void
1128
gimp_brush_core_eval_transform_dynamics (GimpBrushCore     *core,
1129 1130 1131 1132
                                         GimpDrawable      *drawable,
                                         GimpPaintOptions  *paint_options,
                                         const GimpCoords  *coords)
{
1133
  if (core->main_brush)
1134 1135 1136 1137 1138 1139 1140 1141
    {
      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;

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

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

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

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

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

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

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

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

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

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

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

1202 1203
      if (gimp_dynamics_is_output_enabled (core->dynamics,
                                           GIMP_DYNAMICS_OUTPUT_ASPECT_RATIO))
1204
        {
1205 1206 1207 1208 1209 1210 1211 1212 1213 1214
          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
1215
           * in disappearing stamp if applied to maximum.
1216
           */
1217
          if (core->aspect_ratio == 0.0)