Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
masks.h
Go to the documentation of this file.
1/*
2 This file is part of darktable,
3 Copyright (C) 2013-2014, 2016, 2019, 2021 Aldric Renaudin.
4 Copyright (C) 2013, 2018, 2020-2021 Pascal Obry.
5 Copyright (C) 2013 Simon Spannagel.
6 Copyright (C) 2013-2014, 2016-2018 Tobias Ellinghaus.
7 Copyright (C) 2013-2017, 2019-2020 Ulrich Pegelow.
8 Copyright (C) 2014-2016 Roman Lebedev.
9 Copyright (C) 2017-2019 Edgardo Hoszowski.
10 Copyright (C) 2021 Hanno Schwalm.
11 Copyright (C) 2021 Hubert Kowalski.
12 Copyright (C) 2021 luzpaz.
13 Copyright (C) 2021 Philipp Lutz.
14 Copyright (C) 2021 Ralf Brown.
15 Copyright (C) 2022 Martin Bařinka.
16 Copyright (C) 2023, 2025-2026 Aurélien PIERRE.
17 Copyright (C) 2023 Luca Zulberti.
18 Copyright (C) 2025 Alynx Zhou.
19 Copyright (C) 2025-2026 Guillaume Stutin.
20
21 darktable is free software: you can redistribute it and/or modify
22 it under the terms of the GNU General Public License as published by
23 the Free Software Foundation, either version 3 of the License, or
24 (at your option) any later version.
25
26 darktable is distributed in the hope that it will be useful,
27 but WITHOUT ANY WARRANTY; without even the implied warranty of
28 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 GNU General Public License for more details.
30
31 You should have received a copy of the GNU General Public License
32 along with darktable. If not, see <http://www.gnu.org/licenses/>.
33*/
34
35
36/*
37Typical forms tree structure :
38
39GList darktable.develop->forms
40 |
41 0) dt_masks_form_t circle --------------------> ID 1771813676, "circle #2"
42 | { GList *points
43 | | dt_masks_form_t --------------------> dt_masks_type_t type; const dt_masks_functions_t *functions;
44 | | float source[2]; char name[128]; int formid; int version;
45 | { GList *points;
46 | | dt_masks_node_circle_t ----> float center[2]; float radius; float border;
47 |
48 |
49 1) dt_masks_form_t group ---------------------> ID 1771813678, "grp retouch"
50 | { GList *points
51 | |-> dt_masks_form_group_t : ID 1771813676, parentid: 1771813678, state: use show union
52 | |-> dt_masks_form_group_t : ID 1771942330, parentid: 1771813678, state: use show union
53 |
54 |
55 2) dt_masks_form_t polygon -------------------> ID 1771815454, "polygon #1"
56 | { GList *points
57 | | dt_masks_form_t -------------------> dt_masks_type_t type; const dt_masks_functions_t *functions;
58 | | float source[2]; char name[128]; int formid; int version;
59 | { GList *points;
60 | | dt_masks_node_polygon_t ---> float node[2]; float ctrl1[2]; float ctrl2[2]; float border[2];
61 | | dt_masks_node_polygon_t ---> ...
62 | | ...
63 | | ...
64 |
65 |
66 3) dt_masks_form_t group ---------------------> ID 1771942331, "grp exposure"
67 | { GList *points
68 | |-> dt_masks_form_group_t : ID 1771815454, parentid: 1771942331, state: use show union
69 | |-> dt_masks_form_group_t : ID 1771877226, parentid: 1771942331, state: use show union
70 | |-> dt_masks_form_group_t : ID 1771877232, parentid: 1771942331, state: use show union
71 |
72 |
73 4) dt_masks_form_t ellipse -------------------> ID 1771877226, "ellipse #1"
74 | { GList *points
75 | | dt_masks_form_t --------------------> dt_masks_type_t type; const dt_masks_functions_t *functions;
76 | | float source[2]; char name[128]; int formid; int version;
77 | { GList *points;
78 | | dt_masks_node_ellipse_t ---> float center[2]; float radius[2]; float rotation;
79 | float border; dt_masks_ellipse_flags_t flags;
80 |
81 |
82 5) dt_masks_form_t brush ---------------------> ID 1771877232, "brush #1"
83 | { GList *points
84 | | dt_masks_form_t --------------------> dt_masks_type_t type; const dt_masks_functions_t *functions;
85 | | float source[2]; char name[128]; int formid; int version;
86 | { GList *points;
87 | | dt_masks_node_brush_t -----> float node[2]; float pressure; float hardness; float size;
88 | | dt_masks_pressure_sensitivity_t pressure_sensitivity;
89 | | dt_masks_node_brush_t -----> ...
90 | |
91 | | ...
92 | | ...
93 |
94 |
95 6) dt_masks_form_t gradient -------------------> ID 1771942330, "gradient #1"
96 | { GList *points
97 | | dt_masks_form_t ---------------------> dt_masks_type_t type; const dt_masks_functions_t *functions;
98 | | float source[2]; char name[128]; int formid; int version;
99 | { GList *points;
100 | | dt_masks_anchor_gradient_t -> float center[2]; float rotation; float extent; float steepness; float curvature;
101 |
102 7)...
103 |
104 ...
105
106
107*/
108
109#pragma once
110
111#include "common/darktable.h"
112#include "common/opencl.h"
113#include "develop/pixelpipe.h"
114#include "dtgtk/button.h"
115#include "dtgtk/gradientslider.h"
116#include "gui/draw.h"
117#include "control/control.h"
118
119#include <assert.h>
120
121#ifdef __cplusplus
122extern "C" {
123#endif
124
125#define DEVELOP_MASKS_VERSION (6)
126
152
179
185
191
198
205
215
221
228
231{
232 float center[2]; // point in normalized input space
233 float radius;
234 float border;
236
246
256
268
279
288
289struct dt_masks_form_t;
291struct dt_develop_t;
292
293/*
294* Type of user interaction to map with internal properties of masks.
295* Those were initially handled implicitly by Shift/Ctrl/Shift+Ctrl + mouse scroll
296* at the scope of each mask type, which is a shitty design when using Wacom tablets.
297* This case is now covered by the DT_MASK_INTERACTION_UNDEF.
298* Otherwise, when calling the mouse_scroll callback from GUI, we set the case
299* explicitly, along with a value.
300*/
302{
303 DT_MASKS_INTERACTION_UNDEF = 0, // let it be deduced contextually from key modifiers, implicit
304 DT_MASKS_INTERACTION_SIZE = 1, // property of the form (shape), explicit
305 DT_MASKS_INTERACTION_HARDNESS = 2, // property of the form (shape), explicit
306 DT_MASKS_INTERACTION_OPACITY = 3, // property of the group in which the form is included, explicit
309
313{
314 int point_struct_size; // sizeof(struct dt_masks_point_*_t)
316 void (*set_form_name)(struct dt_masks_form_t *const form, const size_t nb);
317 void (*set_hint_message)(const struct dt_masks_form_gui_t *const gui, const struct dt_masks_form_t *const form,
318 const int opacity, char *const __restrict__ msgbuf, const size_t msgbuf_len);
319 void (*duplicate_points)(struct dt_develop_t *const dev, struct dt_masks_form_t *base, struct dt_masks_form_t *dest);
320 void (*initial_source_pos)(const float iwd, const float iht, float *x, float *y);
321 // input coordinates are in absolute output-image space, dist is squared in the same space
322 void (*get_distance)(float x, float y, float as, struct dt_masks_form_gui_t *gui, int index, int num_points,
323 int *inside, int *inside_border, int *near, int *inside_source, float *dist);
324 int (*get_points)(struct dt_develop_t *dev, float x, float y, float radius_a, float radius_b, float rotation,
325 float **points, int *points_count);
326 int (*get_points_border)(struct dt_develop_t *dev, struct dt_masks_form_t *form, float **points, int *points_count,
327 float **border, int *border_count, int source, const dt_iop_module_t *const module);
328 int (*get_mask)(const dt_iop_module_t *const module, struct dt_dev_pixelpipe_t *pipe,
329 const dt_dev_pixelpipe_iop_t *const piece,
330 struct dt_masks_form_t *const form,
331 float **buffer, int *width, int *height, int *posx, int *posy);
332 int (*get_mask_roi)(const dt_iop_module_t *const fmodule, struct dt_dev_pixelpipe_t *pipe,
333 const dt_dev_pixelpipe_iop_t *const piece,
334 struct dt_masks_form_t *const form,
335 const dt_iop_roi_t *roi, float *buffer);
336 int (*get_area)(const dt_iop_module_t *const module, struct dt_dev_pixelpipe_t *pipe,
337 const dt_dev_pixelpipe_iop_t *const piece,
338 struct dt_masks_form_t *const form,
339 int *width, int *height, int *posx, int *posy);
341 dt_dev_pixelpipe_iop_t *piece, struct dt_masks_form_t *form,
342 int *width, int *height, int *posx, int *posy);
343 gboolean (*get_gravity_center)(const struct dt_masks_form_t *form, float center[2], float *area);
344 float (*get_interaction_value)(const struct dt_masks_form_t *form, dt_masks_interaction_t interaction);
345 float (*set_interaction_value)(struct dt_masks_form_t *form, dt_masks_interaction_t interaction, float value,
346 dt_masks_increment_t increment, int flow,
347 struct dt_masks_form_gui_t *gui, struct dt_iop_module_t *module);
348 /* Recompute hovered handles/nodes from the cached cursor state in gui. */
349 int (*update_hover)(struct dt_masks_form_t *form, struct dt_masks_form_gui_t *gui, int index);
350 /* Mouse x and y are widget-space coordinates from GTK/Cairo */
351 int (*mouse_moved)(struct dt_iop_module_t *module, double x, double y, double pressure, int which,
352 struct dt_masks_form_t *form, int parentid, struct dt_masks_form_gui_t *gui, int index);
353 /* Mouse x and y are widget-space coordinates from GTK/Cairo */
354 int (*mouse_scrolled)(struct dt_iop_module_t *module, double x, double y, int up, const int delta_y, uint32_t state,
355 struct dt_masks_form_t *form, int parentid, struct dt_masks_form_gui_t *gui, int index,
356 dt_masks_interaction_t interaction);
357 /* Mouse x and y are widget-space coordinates from GTK/Cairo */
358 int (*button_pressed)(struct dt_iop_module_t *module, double x, double y,
359 double pressure, int which, int type, uint32_t state,
360 struct dt_masks_form_t *form, int parentid, struct dt_masks_form_gui_t *gui, int index);
361 /* Mouse x and y are widget-space coordinates from GTK/Cairo */
362 int (*button_released)(struct dt_iop_module_t *module, double x, double y, int which, uint32_t state,
363 struct dt_masks_form_t *form, int parentid, struct dt_masks_form_gui_t *gui, int index);
364 /* Key event */
365 int (*key_pressed)(struct dt_iop_module_t *module, GdkEventKey *event, struct dt_masks_form_t *form, int parentid, struct dt_masks_form_gui_t *gui, int index);
366 void (*post_expose)(cairo_t *cr, float zoom_scale, struct dt_masks_form_gui_t *gui, int index, int num_points);
367 // The function to draw the shape in question.
368 void (*draw_shape)(cairo_t *cr, const float *points, const int points_count, const int nb, const gboolean border, const gboolean source);
371 int (*populate_context_menu)(GtkWidget *menu, struct dt_masks_form_t *form, struct dt_masks_form_gui_t *gui, const float pzx, const float pzy);
373
375typedef struct dt_masks_form_t
376{
377 GList *points; // list of point structures (nodes)
380 // TRUE when gui_points->points uses the Bezier layout (points[k*6+2])
382
383 // position of the origin point of source (used only for clone)
384 // in normalized coordinates in raw input space
385 float source[2];
386
387 // cached center of gravity
388 // in normalized coordinates in raw input space
390
391 // cached shape area, taken as a weight estimator to get
392 // the gravity center of multi-shapes by combining
393 // weight and gravity centers of all shapes
394 float area;
395 // name of the form
396 char name[128];
397 // id used to store the form
399 // version of the form
402
405{
406 float *points; // points in absolute coordinates in output image space
408 float *border; // border points in absolute coordinates in output image space
410 float *source; // source point in absolute coordinates in output image space
412 gboolean clockwise;
414
416typedef struct dt_masks_dynbuf_t
417{
418 float *buffer;
419 char tag[128];
420 size_t pos;
421 size_t size;
423
424
427{
429 // currently visible form when editing masks (GUI-only; may be a temporary copy)
431 // points used to draw the form
432 GList *points; // list of dt_masks_form_gui_points_t
433
434 // points used to sample mouse moves
437
438 // values for mouse positions, etc...
439
440 // Mouse position in absolute coordinates in final image space
441 // This is used to map input event handlers to *_post_expose() drawing functions
442 // and to record drag & drop starting coordinates.
443 float pos[2];
444
445 // Mouse position in normalized coordinates in output image space.
446 // This is cached once per top-level event and replaces ad-hoc pzx/pzy recomputation.
447 float rel_pos[2];
448
449 // Mouse position in absolute coordinates in raw input image space.
450 // This is cached once per top-level event so nested handlers can reuse it.
451 float raw_pos[2];
452
453 // delta movement of the mouse in absolute coordinates in final image space
454 // This is used to map input event handlers to *_post_expose() drawing functions
455 float delta[2];
456
457 // scroll offset
459
460 // Position of a clone mask's source point (in what coordinates space ?)
461 float pos_source[2];
462
464
465 int node_hovered; // this is the index of the node, refreshed on mouse_moved when a a group is selected
466 int handle_hovered; // this is the index of the node, refreshed on mouse_moved when a a group is selected
467 int seg_hovered; // this is the index of the segment, refreshed on mouse_moved when a a group is selected
468 int handle_border_hovered; // this is the index of the node, refreshed on mouse_moved when a a group is selected
469
470 gboolean node_selected; // this is the state of the node referenced by node_hovered
471 gboolean handle_selected; // this is the state of the handle referenced by handle_hovered
472 gboolean seg_selected; // this is the state of the segment referenced by segment_hovered
473 gboolean handle_border_selected; // this is the state of the border handle referenced by handle_border_hovered
474 int node_selected_idx; // stable selected node index, distinct from current hover
475
480
482
484
494
495 // Throttle GUI rebuilds while dragging to avoid heavy border recomputation.
499
500 // Throttle handle hit-testing when cursor barely moves.
502
503 gboolean creation;
506
508
509 // ids
513
516void dt_masks_gui_init(struct dt_develop_t *dev);
517void dt_masks_gui_cleanup(struct dt_develop_t *dev);
521
522// Test wether the form, the border, the source or the pivot is selected
524{
525 return gui && (gui->form_selected || gui->border_selected || gui->source_selected || gui->pivot_selected);
526}
527
529{
530 return (gui && gui->node_selected) ? gui->node_selected_idx : -1;
531}
532
534{
535 return (gui && gui->handle_selected) ? gui->handle_hovered : -1;
536}
537
539{
540 return (gui && gui->handle_border_selected) ? gui->handle_border_hovered : -1;
541}
542
544{
545 return (gui) ? gui->seg_hovered : -1;
546}
547
549 const int index)
550{
551 if(!gui) return TRUE;
552
553 const int selected_node = dt_masks_gui_selected_node_index(gui);
554 return selected_node < 0 || selected_node == index;
555}
556
557static inline float dt_masks_get_form_size_from_nodes(const GList *points)
558{
559 if(!points || !points->data) return 0.0f;
560
561 // Brush and polygon node payloads both start with `float node[2]`.
562 const float *first = (const float *)points->data;
563 float min_x = first[0];
564 float max_x = first[0];
565 float min_y = first[1];
566 float max_y = first[1];
567
568 for(const GList *point_node = points; point_node; point_node = g_list_next(point_node))
569 {
570 const float *node = (const float *)point_node->data;
571 if(!node) continue;
572 min_x = fminf(min_x, node[0]);
573 max_x = fmaxf(max_x, node[0]);
574 min_y = fminf(min_y, node[1]);
575 max_y = fmaxf(max_y, node[1]);
576 }
577
578 return fmaxf(max_x - min_x, max_y - min_y);
579}
580
582{
583 const float hit_thresh = DT_GUI_MOUSE_EFFECT_RADIUS_SCALED * 0.5f;
584 const float dx = gui->pos[0] - gui->last_hit_test_pos[0];
585 const float dy = gui->pos[1] - gui->last_hit_test_pos[1];
586 if(gui->last_hit_test_pos[0] < 0.0f || (dx * dx + dy * dy) > (hit_thresh * hit_thresh))
587 {
588 gui->last_hit_test_pos[0] = gui->pos[0];
589 gui->last_hit_test_pos[1] = gui->pos[1];
590 return TRUE;
591 }
592 return FALSE;
593}
594
595// High-level mask event dispatchers cache the current cursor in raw absolute coordinates.
596// Reuse that cache for current-cursor conversions instead of backtransforming `gui->pos` again.
597static inline void dt_masks_gui_cursor_to_raw_norm(dt_develop_t *dev, const dt_masks_form_gui_t *gui, float point[2])
598{
599 point[0] = gui->raw_pos[0];
600 point[1] = gui->raw_pos[1];
602}
603
604// Reuse the cached absolute output-image cursor and drag delta to derive a raw-normalized point.
605static inline void dt_masks_gui_delta_to_raw_norm(dt_develop_t *dev, const dt_masks_form_gui_t *gui, float point[2])
606{
607 point[0] = gui->pos[0] + gui->delta[0];
608 point[1] = gui->pos[1] + gui->delta[1];
610}
611
612static inline void dt_masks_gui_delta_to_image_abs(const dt_masks_form_gui_t *gui, float point[2])
613{
614 point[0] = gui->pos[0] + gui->delta[0];
615 point[1] = gui->pos[1] + gui->delta[1];
616}
617
618// Drag branches need the same "cursor + drag delta" converted back to raw space.
619// Keep that conversion in one place so all shapes use the same anchor semantics.
621 const float anchor[2], float *delta_x, float *delta_y)
622{
623 float point[2];
625 *delta_x = point[0] - anchor[0];
626 *delta_y = point[1] - anchor[1];
627}
628
629// Clone and spot forms share the same default presets, while regular drawn masks use their own.
630static inline gboolean dt_masks_form_uses_spot_defaults(const dt_masks_form_t *form)
631{
632 return (form->type & (DT_MASKS_CLONE | DT_MASKS_NON_CLONE)) != 0;
633}
634
635static inline gboolean dt_masks_form_is_clone(const dt_masks_form_t *form)
636{
637 return (form->type & DT_MASKS_CLONE) != 0;
638}
639
640static inline void dt_masks_reset_source(dt_masks_form_t *form)
641{
642 form->source[0] = 0.0f;
643 form->source[1] = 0.0f;
644}
645
646static inline void dt_masks_translate_source(dt_masks_form_t *form, const float delta_x, const float delta_y)
647{
648 form->source[0] += delta_x;
649 form->source[1] += delta_y;
650}
651
652static inline void dt_masks_translate_ctrl_node(float node[2], float ctrl1[2], float ctrl2[2],
653 const float delta_x, const float delta_y)
654{
655 node[0] += delta_x;
656 node[1] += delta_y;
657 ctrl1[0] += delta_x;
658 ctrl1[1] += delta_y;
659 ctrl2[0] += delta_x;
660 ctrl2[1] += delta_y;
661}
662
663static inline void dt_masks_set_ctrl_points(float ctrl1[2], float ctrl2[2], const float control_points[4])
664{
665 ctrl1[0] = control_points[0];
666 ctrl1[1] = control_points[1];
667 ctrl2[0] = control_points[2];
668 ctrl2[1] = control_points[3];
669}
670
671gboolean dt_masks_node_is_cusp(const dt_masks_form_gui_points_t *gpt, const int index);
673 struct dt_iop_module_t *module);
674
675// Brush and polygon nodes share the same node/control-point edit semantics.
676static inline gboolean dt_masks_toggle_bezier_node_type(struct dt_iop_module_t *module,
677 struct dt_masks_form_t *mask_form,
678 struct dt_masks_form_gui_t *mask_gui,
679 const int form_index,
680 const struct dt_masks_form_gui_points_t *gui_points,
681 const int node_index,
682 float node[2], float ctrl1[2], float ctrl2[2],
684{
685 if(!mask_form || !mask_gui || !gui_points || !state || node_index < 0) return FALSE;
686
687 if(dt_masks_node_is_cusp(gui_points, node_index))
688 {
690 if(mask_form->functions && mask_form->functions->init_ctrl_points)
691 mask_form->functions->init_ctrl_points(mask_form);
692 }
693 else
694 {
695 ctrl1[0] = ctrl2[0] = node[0];
696 ctrl1[1] = ctrl2[1] = node[1];
698 }
699
700 dt_masks_gui_form_create(mask_form, mask_gui, form_index, module);
701 return TRUE;
702}
703
704static inline gboolean dt_masks_reset_bezier_ctrl_points(struct dt_iop_module_t *module,
705 struct dt_masks_form_t *mask_form,
706 struct dt_masks_form_gui_t *mask_gui,
707 const int form_index,
708 const struct dt_masks_form_gui_points_t *gui_points,
709 const int node_index,
711{
712 if(!mask_form || !mask_gui || !gui_points || !state || node_index < 0) return FALSE;
713
714 if(*state != DT_MASKS_POINT_STATE_NORMAL && !dt_masks_node_is_cusp(gui_points, node_index))
715 {
717 if(mask_form->functions && mask_form->functions->init_ctrl_points)
718 mask_form->functions->init_ctrl_points(mask_form);
719 dt_masks_gui_form_create(mask_form, mask_gui, form_index, module);
720 }
721
722 return TRUE;
723}
724
725// Brush and polygon border handles both constrain the cursor to the node->handle axis.
726static inline void dt_masks_project_on_line(const float cursor[2], const float node[2],
727 const float handle[2], float point[2])
728{
729 const float dx_line = handle[0] - node[0];
730 const float dy_line = handle[1] - node[1];
731
732 if(fabsf(dx_line) < 1e-6f)
733 {
734 point[0] = node[0];
735 point[1] = cursor[1];
736 }
737 else
738 {
739 const float a = dy_line / dx_line;
740 const float b = node[1] - a * node[0];
741 const float denom = a * a + 1.0f;
742 const float xproj = (a * cursor[1] + cursor[0] - b * a) / denom;
743
744 point[0] = xproj;
745 point[1] = a * xproj + b;
746 }
747}
748
749// Border handles store normalized raw-space radii, but hit/drag code works in image space.
750// Convert both ends once here so all shapes derive border thickness the same way.
751static inline float dt_masks_border_from_projected_handle(dt_develop_t *dev, const float node[2],
752 const float projected_image_pos[2],
753 const float scale_ref)
754{
755 float projected_raw[2] = { projected_image_pos[0], projected_image_pos[1] };
756 float node_raw[2] = { node[0], node[1] };
757 dt_dev_coordinates_image_abs_to_raw_abs(dev, projected_raw, 1);
759
760 const float delta_x = projected_raw[0] - node_raw[0];
761 const float delta_y = projected_raw[1] - node_raw[1];
762 return sqrtf(delta_x * delta_x + delta_y * delta_y) / scale_ref;
763}
764
765// Circle, ellipse and gradient creation previews all follow the same drawing sequence:
766// optional save/restore, draw the shape, then draw the border preview if present.
767static inline void dt_masks_draw_preview_shape(cairo_t *cr, const float zoom_scale, const int num_points,
768 float *points, const int points_count,
769 float *border, const int border_count,
770 void (*const *draw_shape)(cairo_t *cr, const float *points,
771 const int points_count, const int nb,
772 const gboolean border,
773 const gboolean source),
774 const cairo_line_cap_t shape_cap,
775 const cairo_line_cap_t border_cap,
776 const gboolean save_restore)
777{
778 if(save_restore) cairo_save(cr);
779 if(points && points_count > 0)
780 dt_draw_shape_lines(DT_MASKS_NO_DASH, FALSE, cr, num_points, FALSE, zoom_scale, points, points_count,
781 draw_shape, shape_cap);
782 if(border && border_count > 0)
783 dt_draw_shape_lines(DT_MASKS_DASH_STICK, FALSE, cr, num_points, FALSE, zoom_scale, border, border_count,
784 draw_shape, border_cap);
785 if(save_restore) cairo_restore(cr);
786}
787
788// Shared scratch buffers for creation previews. Keeping them grouped makes the shape
789// preview helpers return a single value and centralizes cleanup.
797
803
805{
806 struct
807 {
808 float x;
809 float y;
811
812 struct
813 {
814 float x;
815 float y;
818
826
829
832int dt_masks_get_points_border(struct dt_develop_t *dev, dt_masks_form_t *form, float **points, int *points_count,
833 float **border, int *border_count, int source, dt_iop_module_t *module);
834
837 dt_masks_form_t *form,
838 int *width, int *height, int *posx, int *posy);
841 int *width, int *height, int *posx, int *posy);
843static inline int dt_masks_get_mask(const dt_iop_module_t *const module, dt_dev_pixelpipe_t *pipe,
844 const dt_dev_pixelpipe_iop_t *const piece,
845 dt_masks_form_t *const form,
846 float **buffer, int *width, int *height, int *posx, int *posy)
847{
848 return (form->functions && form->functions->get_mask)
849 ? form->functions->get_mask(module, pipe, piece, form, buffer, width, height, posx, posy)
850 : 1;
851}
852static inline int dt_masks_get_mask_roi(const dt_iop_module_t *const module, dt_dev_pixelpipe_t *pipe,
853 const dt_dev_pixelpipe_iop_t *const piece,
854 dt_masks_form_t *const form, const dt_iop_roi_t *roi, float *buffer)
855{
856 return (form->functions && form->functions->get_mask_roi)
857 ? form->functions->get_mask_roi(module, pipe, piece, form, roi, buffer)
858 : 1;
859}
860
862 const dt_dev_pixelpipe_iop_t *piece, dt_masks_form_t *form,
863 const dt_iop_roi_t *roi, float *buffer);
864
865// returns current masks version
866int dt_masks_version(void);
867
870void dt_masks_remove_node(struct dt_iop_module_t *module, dt_masks_form_t *form, int parentid,
871 dt_masks_form_gui_t *gui, int index, int node_index);
872
873// update masks from older versions
874int dt_masks_legacy_params(dt_develop_t *dev, void *params, const int old_version, const int new_version);
875/*
876 * TODO:
877 *
878 * int
879 * dt_masks_legacy_params(
880 * dt_develop_t *dev,
881 * const void *const old_params, const int old_version,
882 * void *new_params, const int new_version);
883 */
884
890void dt_masks_replace_current_forms(dt_develop_t *dev, GList *forms);
892GList *dt_masks_snapshot_current_forms(dt_develop_t *dev, gboolean reset_changed);
894dt_masks_form_t *dt_masks_get_from_id_ext(GList *forms, int id);
899 const struct dt_iop_module_t *mod_src);
902
904void dt_masks_read_masks_history(dt_develop_t *dev, const int32_t imgid);
906void dt_masks_write_masks_history_item(const int32_t imgid, const int num, dt_masks_form_t *form);
909
913void dt_masks_reset_form_gui(void);
916
917int dt_masks_events_mouse_moved(struct dt_iop_module_t *module, double x, double y, double pressure,
918 int which);
919int dt_masks_events_button_released(struct dt_iop_module_t *module, double x, double y, int which,
920 uint32_t state);
921int dt_masks_events_button_pressed(struct dt_iop_module_t *module, double x, double y, double pressure,
922 int which, int type, uint32_t state);
923int dt_masks_events_mouse_scrolled(struct dt_iop_module_t *module, double x, double y, int up, uint32_t state, int delta_y);
924
925int dt_masks_events_key_pressed(struct dt_iop_module_t *module, GdkEventKey *event);
937gboolean dt_masks_node_is_cusp(const dt_masks_form_gui_points_t *gpt, const int index);
938
949void dt_masks_draw_source(cairo_t *cr, dt_masks_form_gui_t *gui, const int index, const int nb,
950 const float zoom_scale, struct dt_masks_gui_center_point_t *center_point, const shape_draw_function_t *draw_shape_func);
951void dt_masks_draw_path_seg_by_seg(cairo_t *cr, dt_masks_form_gui_t *gui, const int index, const float *points,
952 const int points_count, const int node_count, const float zoom_scale);
953
954void dt_masks_events_post_expose(struct dt_iop_module_t *module, cairo_t *cr, int32_t width, int32_t height,
955 int32_t pointerx, int32_t pointery);
958
961 struct dt_iop_module_t *module);
963 struct dt_iop_module_t *module, float posx, float posy);
964
975gboolean dt_masks_gui_delete(struct dt_iop_module_t *module, dt_masks_form_t *form, dt_masks_form_gui_t *gui, const int parentid);
976
977// Remove a mask
979
980
988
992void dt_masks_iop_update(struct dt_iop_module_t *module);
993void dt_masks_iop_combo_populate(GtkWidget *w, void *module);
994void dt_masks_iop_use_same_as(struct dt_iop_module_t *module, struct dt_iop_module_t *src);
996
998int dt_masks_form_change_opacity(dt_masks_form_t *form, int parentid, int up, const int flow);
999void dt_masks_form_move(dt_masks_form_t *grp, int formid, int up);
1000int dt_masks_form_duplicate(dt_develop_t *dev, int formid);
1001/* returns a duplicate tof form, including the formid */
1003/* duplicate the list of forms, replace item in the list with form with the same formid */
1004GList *dt_masks_dup_forms_deep(GList *forms, dt_masks_form_t *form);
1005
1007int dt_masks_point_in_form_exact(const float *pts, int num_pts, const float *points, int points_start, int points_count);
1008
1010void dt_masks_select_form(struct dt_iop_module_t *module, dt_masks_form_t *sel);
1011
1013void dt_masks_set_source_pos_initial_state(dt_masks_form_gui_t *gui, const uint32_t state);
1015void dt_masks_calculate_source_pos_value(dt_masks_form_gui_t *gui, const float initial_xpos,
1016 const float initial_ypos, const float xpos, const float ypos, float *px,
1017 float *py, const int adding);
1018static inline void dt_masks_draw_source_preview(cairo_t *cr, const float zoom_scale, dt_masks_form_gui_t *gui,
1019 const float initial_xpos, const float initial_ypos,
1020 const float xpos, const float ypos, const int adding)
1021{
1022 float source_pos[2] = { 0.0f, 0.0f };
1023 dt_masks_calculate_source_pos_value(gui, initial_xpos, initial_ypos, xpos, ypos,
1024 &source_pos[0], &source_pos[1], adding);
1025 dt_draw_cross(cr, zoom_scale, source_pos[0], source_pos[1]);
1026}
1037float dt_masks_rotate_with_anchor(dt_develop_t *dev, const float anchor[2], const float center[2], dt_masks_form_gui_t *gui);
1038
1041int dt_masks_group_index_from_formid(const dt_masks_form_t *group_form, int formid);
1043 const struct dt_masks_form_gui_t *gui);
1044
1046gboolean dt_masks_is_anything_selected(const dt_masks_form_gui_t *mask_gui);
1047
1049gboolean dt_masks_is_anything_hovered(const dt_masks_form_gui_t *mask_gui);
1050
1060 const struct dt_masks_form_gui_t *gui);
1062 dt_masks_interaction_t interaction);
1063gboolean dt_masks_form_get_gravity_center(const struct dt_masks_form_t *form, float center[2], float *area);
1066 dt_masks_interaction_t interaction,
1067 float value, dt_masks_increment_t increment, int flow,
1068 struct dt_masks_form_gui_t *gui, struct dt_iop_module_t *module);
1069
1082float dt_masks_get_set_conf_value(dt_masks_form_t *form, char *feature, float new_value, float v_min, float v_max,
1083 dt_masks_increment_t increment, const int flow);
1090float dt_masks_get_set_conf_value_with_toast(dt_masks_form_t *form, const char *feature, float amount,
1091 float v_min, float v_max, dt_masks_increment_t increment, int flow,
1092 const char *toast_fmt, float toast_scale);
1093
1099void dt_masks_duplicate_points(const dt_masks_form_t *base, dt_masks_form_t *dest, size_t node_size);
1100
1104float dt_masks_apply_increment(float current, float amount, dt_masks_increment_t increment, int flow);
1105
1109float dt_masks_apply_increment_precomputed(float current, float amount, float scale_amount, float offset_amount,
1110 dt_masks_increment_t increment);
1111
1113void dt_masks_extend_border(float *const mask, const int width, const int height, const int border);
1114void dt_masks_blur_9x9_coeff(float *coeffs, const float sigma);
1115void dt_masks_blur_9x9(float *const src, float *const out, const int width, const int height, const float sigma);
1116void dt_masks_calc_rawdetail_mask(float *const src, float *const out, float *const tmp, const int width,
1117 const int height, const dt_aligned_pixel_t wb);
1118void dt_masks_calc_detail_mask(float *const src, float *const out, float *const tmp, const int width, const int height, const float threshold, const gboolean detail);
1119
1120void dt_group_events_post_expose(cairo_t *cr, float zoom_scale, dt_masks_form_t *form,
1121 dt_masks_form_gui_t *gui);
1122
1124static inline gboolean _dt_masks_dynbuf_growto(dt_masks_dynbuf_t *a, size_t size)
1125{
1126 const size_t newsize = dt_round_size_sse(sizeof(float) * size) / sizeof(float);
1127 float *newbuf = dt_pixelpipe_cache_alloc_align_float_cache(newsize, 0);
1128 if (!newbuf)
1129 {
1130 // not much we can do here except emit an error message
1131 fprintf(stderr, "critical: out of memory for dynbuf '%s' with size request %zu!\n", a->tag, size);
1132 return FALSE;
1133 }
1134 if (a->buffer)
1135 {
1136 memcpy(newbuf, a->buffer, a->size * sizeof(float));
1137 dt_print(DT_DEBUG_MASKS, "[masks dynbuf '%s'] grows to size %lu (is %p, was %p)\n", a->tag,
1138 (unsigned long)a->size, newbuf, a->buffer);
1140 }
1141 a->size = newsize;
1142 a->buffer = newbuf;
1143 return TRUE;
1144}
1145
1146static inline dt_masks_dynbuf_t *dt_masks_dynbuf_init(size_t size, const char *tag)
1147{
1148 assert(size > 0);
1149 dt_masks_dynbuf_t *a = (dt_masks_dynbuf_t *)calloc(1, sizeof(dt_masks_dynbuf_t));
1150
1151 if(a != NULL)
1152 {
1153 g_strlcpy(a->tag, tag, sizeof(a->tag)); //only for debugging purposes
1154 a->pos = 0;
1156 dt_print(DT_DEBUG_MASKS, "[masks dynbuf '%s'] with initial size %lu (is %p)\n", a->tag,
1157 (unsigned long)a->size, a->buffer);
1158 if(a->buffer == NULL)
1159 {
1160 dt_free(a);
1161 }
1162 }
1163 return a;
1164}
1165
1166static inline void dt_masks_dynbuf_add_2(dt_masks_dynbuf_t *a, float value1, float value2)
1167{
1168 assert(a != NULL);
1169 assert(a->pos <= a->size);
1170 if(__builtin_expect(a->pos + 2 >= a->size, 0))
1171 {
1172 if (a->size == 0 || !_dt_masks_dynbuf_growto(a, 2 * (a->size+1)))
1173 return;
1174 }
1175 a->buffer[a->pos++] = value1;
1176 a->buffer[a->pos++] = value2;
1177}
1178
1179// Return a pointer to N floats past the current end of the dynbuf's contents, marking them as already in use.
1180// The caller should then fill in the reserved elements using the returned pointer.
1181static inline float *dt_masks_dynbuf_reserve_n(dt_masks_dynbuf_t *a, const int n)
1182{
1183 assert(a != NULL);
1184 assert(a->pos <= a->size);
1185 if(__builtin_expect(a->pos + n >= a->size, 0))
1186 {
1187 if(a->size == 0) return NULL;
1188 size_t newsize = a->size;
1189 while(a->pos + n >= newsize) newsize *= 2;
1190 if (!_dt_masks_dynbuf_growto(a, newsize))
1191 {
1192 return NULL;
1193 }
1194 }
1195 // get the current end of the (possibly reallocated) buffer, then mark the next N items as in-use
1196 float *reserved = a->buffer + a->pos;
1197 a->pos += n;
1198 return reserved;
1199}
1200
1201static inline void dt_masks_dynbuf_add_zeros(dt_masks_dynbuf_t *a, const int n)
1202{
1203 assert(a != NULL);
1204 assert(a->pos <= a->size);
1205 if(__builtin_expect(a->pos + n >= a->size, 0))
1206 {
1207 if(a->size == 0) return;
1208 size_t newsize = a->size;
1209 while(a->pos + n >= newsize) newsize *= 2;
1210 if (!_dt_masks_dynbuf_growto(a, newsize))
1211 {
1212 return;
1213 }
1214 }
1215 // now that we've ensured a sufficiently large buffer add N zeros to the end of the existing data
1216 memset(a->buffer + a->pos, 0, n * sizeof(float));
1217 a->pos += n;
1218}
1219
1220
1221static inline float dt_masks_dynbuf_get(dt_masks_dynbuf_t *a, int offset)
1222{
1223 assert(a != NULL);
1224 // offset: must be negative distance relative to end of buffer
1225 assert(offset < 0);
1226 assert((long)a->pos + offset >= 0);
1227 return (a->buffer[a->pos + offset]);
1228}
1229
1230static inline void dt_masks_dynbuf_set(dt_masks_dynbuf_t *a, int offset, float value)
1231{
1232 assert(a != NULL);
1233 // offset: must be negative distance relative to end of buffer
1234 assert(offset < 0);
1235 assert((long)a->pos + offset >= 0);
1236 a->buffer[a->pos + offset] = value;
1237}
1238
1240{
1241 assert(a != NULL);
1242 return a->buffer;
1243}
1244
1245static inline gboolean dt_masks_center_of_gravity_from_points(const float *points, const int points_count,
1246 float center[2], float *area)
1247{
1248 if(!points || !center || !area || points_count <= 0)
1249 {
1250 if(center)
1251 {
1252 center[0] = 0.0f;
1253 center[1] = 0.0f;
1254 }
1255 if(area) *area = 0.0f;
1256 return FALSE;
1257 }
1258
1259 double start = 0.;
1261
1262 // Points must be ordered sequentially along the polygon boundary.
1263 // Use the shoelace formula to compute area and centroid.
1264 if(points_count >= 3)
1265 {
1266 double area2 = 0.0;
1267 double cx = 0.0;
1268 double cy = 0.0;
1269
1270 for(int i = 0; i < points_count; i++)
1271 {
1272 const int j = (i + 1 < points_count) ? (i + 1) : 0;
1273 const double x0 = points[i * 2];
1274 const double y0 = points[i * 2 + 1];
1275 const double x1 = points[j * 2];
1276 const double y1 = points[j * 2 + 1];
1277
1278 const double cross = x0 * y1 - x1 * y0;
1279 area2 += cross;
1280 cx += (x0 + x1) * cross;
1281 cy += (y0 + y1) * cross;
1282 }
1283
1284 if(fabs(area2) > 1e-12)
1285 {
1286 const double inv = 1.0 / (3.0 * area2);
1287 center[0] = (float)(cx * inv);
1288 center[1] = (float)(cy * inv);
1289
1290 *area = (float)(0.5 * fabs(area2));
1291 return TRUE;
1292 }
1293 }
1294
1295 // Fallback to arithmetic mean for degenerate polygons or short lists.
1296 float sum_x = 0.0f;
1297 float sum_y = 0.0f;
1298 const float inv_count = 1.0f / (float)points_count;
1299 for(int i = 0; i < points_count; i++)
1300 {
1301 sum_x += points[i * 2] * inv_count;
1302 sum_y += points[i * 2 + 1] * inv_count;
1303 }
1304
1306 dt_print(DT_DEBUG_MASKS, "[masks] computing centroid took %0.04f sec\n",
1307 dt_get_wtime() - start);
1308
1309
1310 center[0] = sum_x;
1311 center[1] = sum_y;
1312 *area = 0.0f;
1313 return TRUE;
1314}
1315
1317{
1318 assert(a != NULL);
1319 return a->pos;
1320}
1321
1323{
1324 assert(a != NULL);
1325 a->pos = 0;
1326}
1327
1329{
1330 // take out data buffer and make dynamic buffer obsolete
1331 if(a == NULL) return NULL;
1332 float *r = a->buffer;
1333 a->buffer = NULL;
1334 a->pos = a->size = 0;
1335 return r;
1336}
1337
1339{
1340 if(a == NULL) return;
1341 dt_print(DT_DEBUG_MASKS, "[masks dynbuf '%s'] freed (was %p)\n", a->tag,
1342 a->buffer);
1344 dt_free(a);
1345}
1346
1347static inline int dt_masks_roundup(int num, int mult)
1348{
1349 const int rem = num % mult;
1350
1351 return (rem == 0) ? num : num + mult - rem;
1352}
1353
1364gboolean dt_masks_point_is_within_radius(const float px, const float py,
1365 const float cx, const float cy,
1366 const float radius);
1367
1373typedef gboolean (*dt_masks_border_handle_fn)(const dt_masks_form_gui_points_t *gui_points, int node_count,
1374 int node_index, float *handle_x, float *handle_y, void *user_data);
1380typedef void (*dt_masks_curve_handle_fn)(const dt_masks_form_gui_points_t *gui_points, int node_index,
1381 float *handle_x, float *handle_y, void *user_data);
1387typedef void (*dt_masks_node_position_fn)(const dt_masks_form_gui_points_t *gui_points, int node_index,
1388 float *node_x, float *node_y, void *user_data);
1395typedef void (*dt_masks_distance_fn)(float pointer_x, float pointer_y, float cursor_radius,
1396 dt_masks_form_gui_t *mask_gui, int form_index, int node_count,
1397 int *inside, int *inside_border, int *near, int *inside_source, float *dist,
1398 void *user_data);
1402typedef void (*dt_masks_post_select_fn)(dt_masks_form_gui_t *mask_gui, int inside, int inside_border,
1403 int inside_source, void *user_data);
1404
1414 int form_index, int node_count_override,
1415 dt_masks_border_handle_fn border_handle_cb,
1416 dt_masks_curve_handle_fn curve_handle_cb,
1417 dt_masks_node_position_fn node_position_cb,
1418 dt_masks_distance_fn distance_cb,
1419 dt_masks_post_select_fn post_select_cb,
1420 void *user_data);
1421
1423void apply_operation(struct dt_masks_form_group_t *pt, const dt_masks_state_t apply_state);
1424
1427#define menu_item_set_fake_accel(menu_item, keyval, mods) \
1428 \
1429{ \
1430 GtkWidget *child = gtk_bin_get_child(GTK_BIN(menu_item)); \
1431 if(GTK_IS_ACCEL_LABEL(child)) \
1432 gtk_accel_label_set_accel(GTK_ACCEL_LABEL(child), keyval, mods); \
1433}
1434
1435void _masks_gui_delete_node_callback(GtkWidget *menu, gpointer user_data);
1436
1438
1440 const float pzx, const float pzy);
1441
1442#ifdef __cplusplus
1443}
1444#endif
1445
1446// clang-format off
1447// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
1448// vim: shiftwidth=2 expandtab tabstop=2 cindent
1449// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
1450// clang-format on
static double dist(double x1, double y1, double x2, double y2)
Definition ashift_lsd.c:250
static double * inv
Definition ashift_lsd.c:1077
#define TRUE
Definition ashift_lsd.c:162
#define FALSE
Definition ashift_lsd.c:158
int width
Definition bilateral.h:1
int height
Definition bilateral.h:1
const float i
Definition colorspaces_inline_conversions.h:669
const float denom
Definition colorspaces_inline_conversions.h:1334
const float threshold
Definition colorspaces_inline_conversions.h:340
const float r
Definition colorspaces_inline_conversions.h:1324
const float b
Definition colorspaces_inline_conversions.h:1326
const float a
Definition colorspaces_inline_conversions.h:1292
static const dt_colormatrix_t dt_aligned_pixel_t out
Definition colorspaces_inline_conversions.h:184
const float n
Definition colorspaces_inline_conversions.h:929
typedef void((*dt_cache_allocate_t)(void *userdata, dt_cache_entry_t *entry))
int type
Definition common/metadata.c:62
darktable_t darktable
Definition darktable.c:178
void dt_print(dt_debug_thread_t thread, const char *msg,...)
Definition darktable.c:1530
@ DT_DEBUG_PERF
Definition darktable.h:639
@ DT_DEBUG_MASKS
Definition darktable.h:647
#define dt_pixelpipe_cache_alloc_align_float_cache(pixels, id)
Definition darktable.h:371
static size_t dt_round_size_sse(const size_t size)
Definition darktable.h:327
#define dt_free(ptr)
Definition darktable.h:380
#define dt_pixelpipe_cache_free_align(mem)
Definition darktable.h:377
static const dt_aligned_pixel_simd_t value
Definition darktable.h:501
static double dt_get_wtime(void)
Definition darktable.h:846
void dt_dev_coordinates_raw_norm_to_raw_abs(dt_develop_t *dev, float *points, size_t num_points)
Definition develop.c:981
int dt_dev_coordinates_image_abs_to_raw_abs(dt_develop_t *dev, float *points, size_t points_count)
Definition develop.c:1390
void dt_dev_coordinates_raw_abs_to_raw_norm(dt_develop_t *dev, float *points, size_t num_points)
Definition develop.c:964
void dt_dev_coordinates_image_abs_to_raw_norm(dt_develop_t *dev, float *points, size_t num_points)
Definition develop.c:996
static void dt_draw_cross(cairo_t *cr, const float zoom_scale, const float x, const float y)
Definition draw.h:896
@ DT_MASKS_DASH_STICK
Definition draw.h:94
@ DT_MASKS_NO_DASH
Definition draw.h:93
static void dt_draw_shape_lines(const dt_draw_dash_type_t dash_type, const gboolean source, cairo_t *cr, const int nb, const gboolean selected, const float zoom_scale, const float *points, const int points_count, const shape_draw_function_t *draw_shape_func, const cairo_line_cap_t line_cap)
Draw the lines of a mask shape.
Definition draw.h:740
void(* shape_draw_function_t)(cairo_t *cr, const float *points, const int points_count, const int nb, const gboolean border, const gboolean source)
Definition draw.h:725
#define DT_GUI_MOUSE_EFFECT_RADIUS_SCALED
Definition gtk.h:71
static const float x
Definition iop_profile.h:239
GList * dt_masks_dup_forms_deep(GList *forms, dt_masks_form_t *form)
Duplicate the list of forms, replacing a single item by formid match.
Definition develop/masks/masks.c:718
GdkModifierType dt_masks_get_accel_mods(dt_masks_interaction_t interaction)
gboolean dt_masks_gui_delete(struct dt_iop_module_t *module, dt_masks_form_t *form, dt_masks_form_gui_t *gui, const int parentid)
Delete a mask shape or node form from the GUI. This function is to be used with a popupmenu "Delete" ...
Definition develop/masks/masks.c:1014
static void dt_masks_gui_delta_to_image_abs(const dt_masks_form_gui_t *gui, float point[2])
Definition masks.h:612
void apply_operation(struct dt_masks_form_group_t *pt, const dt_masks_state_t apply_state)
Apply a mask state operation on a group entry.
Definition develop/masks/masks.c:3974
int dt_masks_group_render_roi(dt_iop_module_t *module, dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, dt_masks_form_t *form, const dt_iop_roi_t *roi, float *buffer)
Definition group.c:737
void dt_masks_gui_form_remove(dt_masks_form_t *form, dt_masks_form_gui_t *gui, int index)
Definition develop/masks/masks.c:1039
static int dt_masks_gui_selected_segment_index(const dt_masks_form_gui_t *gui)
Definition masks.h:543
void dt_masks_blur_9x9(float *const src, float *const out, const int width, const int height, const float sigma)
void dt_masks_events_post_expose(struct dt_iop_module_t *module, cairo_t *cr, int32_t width, int32_t height, int32_t pointerx, int32_t pointery)
Definition develop/masks/masks.c:2651
static void dt_masks_draw_preview_shape(cairo_t *cr, const float zoom_scale, const int num_points, float *points, const int points_count, float *border, const int border_count, void(*const *draw_shape)(cairo_t *cr, const float *points, const int points_count, const int nb, const gboolean border, const gboolean source), const cairo_line_cap_t shape_cap, const cairo_line_cap_t border_cap, const gboolean save_restore)
Definition masks.h:767
void(* dt_masks_distance_fn)(float pointer_x, float pointer_y, float cursor_radius, dt_masks_form_gui_t *mask_gui, int form_index, int node_count, int *inside, int *inside_border, int *near, int *inside_source, float *dist, void *user_data)
Shape-specific callback for inside/border/segment hit testing.
Definition masks.h:1395
static int dt_masks_gui_selected_node_index(const dt_masks_form_gui_t *gui)
Definition masks.h:528
void dt_masks_gui_set_dragging(dt_masks_form_gui_t *gui)
Definition develop/masks/masks.c:389
void dt_masks_iop_update(struct dt_iop_module_t *module)
Definition blend_gui.c:3264
static int dt_masks_gui_selected_handle_index(const dt_masks_form_gui_t *gui)
Definition masks.h:533
int dt_masks_legacy_params(dt_develop_t *dev, void *params, const int old_version, const int new_version)
Definition develop/masks/masks.c:1634
static float * dt_masks_dynbuf_buffer(dt_masks_dynbuf_t *a)
Definition masks.h:1239
dt_masks_form_group_t * dt_masks_group_add_form(dt_masks_form_t *grp, dt_masks_form_t *form)
Definition develop/masks/masks.c:3447
void dt_masks_remove_form(dt_develop_t *dev, dt_masks_form_t *form)
Definition develop/masks/masks.c:1143
static gboolean dt_masks_toggle_bezier_node_type(struct dt_iop_module_t *module, struct dt_masks_form_t *mask_form, struct dt_masks_form_gui_t *mask_gui, const int form_index, const struct dt_masks_form_gui_points_t *gui_points, const int node_index, float node[2], float ctrl1[2], float ctrl2[2], dt_masks_points_states_t *state)
Definition masks.h:676
void dt_masks_gui_form_create(dt_masks_form_t *form, dt_masks_form_gui_t *gui, int index, struct dt_iop_module_t *module)
Definition develop/masks/masks.c:835
void dt_masks_change_form_gui(dt_masks_form_t *newform)
Definition develop/masks/masks.c:2768
int dt_masks_events_key_pressed(struct dt_iop_module_t *module, GdkEventKey *event)
Definition develop/masks/masks.c:2291
static void dt_masks_dynbuf_add_2(dt_masks_dynbuf_t *a, float value1, float value2)
Definition masks.h:1166
dt_masks_edit_mode_t
Definition masks.h:200
@ DT_MASKS_EDIT_RESTRICTED
Definition masks.h:203
@ DT_MASKS_EDIT_OFF
Definition masks.h:201
@ DT_MASKS_EDIT_FULL
Definition masks.h:202
gboolean dt_masks_node_is_cusp(const dt_masks_form_gui_points_t *gpt, const int index)
returns wether a node is a corner or not. A node is a corner if its 2 control handles are at the same...
Definition develop/masks/masks.c:2398
static void dt_masks_draw_source_preview(cairo_t *cr, const float zoom_scale, dt_masks_form_gui_t *gui, const float initial_xpos, const float initial_ypos, const float xpos, const float ypos, const int adding)
Definition masks.h:1018
struct dt_iop_module_t * dt_masks_get_mask_manager(struct dt_develop_t *dev)
Definition develop/masks/masks.c:1762
int dt_masks_form_change_opacity(dt_masks_form_t *form, int parentid, int up, const int flow)
Definition develop/masks/masks.c:3382
int dt_masks_point_in_form_exact(const float *pts, int num_pts, const float *points, int points_start, int points_count)
Check whether any 2D point in pts[] lies inside the form points[].
Definition develop/masks/masks.c:3687
void dt_masks_free_form(dt_masks_form_t *form)
Definition develop/masks/masks.c:1997
gboolean dt_masks_form_cancel_creation(dt_iop_module_t *module, dt_masks_form_gui_t *gui)
Definition develop/masks/masks.c:993
void dt_masks_gui_reset_dragging(dt_masks_form_gui_t *gui)
Definition develop/masks/masks.c:403
static dt_masks_dynbuf_t * dt_masks_dynbuf_init(size_t size, const char *tag)
Definition masks.h:1146
static void dt_masks_translate_source(dt_masks_form_t *form, const float delta_x, const float delta_y)
Definition masks.h:646
void dt_masks_iop_use_same_as(struct dt_iop_module_t *module, struct dt_iop_module_t *src)
Definition develop/masks/masks.c:2897
void dt_masks_reset_form_gui(void)
Definition develop/masks/masks.c:2774
void dt_masks_read_masks_history(dt_develop_t *dev, const int32_t imgid)
Definition develop/masks/masks.c:1853
void dt_masks_gui_init(struct dt_develop_t *dev)
Definition develop/masks/masks.c:364
void(* dt_masks_post_select_fn)(dt_masks_form_gui_t *mask_gui, int inside, int inside_border, int inside_source, void *user_data)
Optional hook to customize selection flags after inside/border/source resolution.
Definition masks.h:1402
int dt_masks_events_button_released(struct dt_iop_module_t *module, double x, double y, int which, uint32_t state)
Definition develop/masks/masks.c:2189
int dt_masks_events_mouse_moved(struct dt_iop_module_t *module, double x, double y, double pressure, int which)
Definition develop/masks/masks.c:2145
int dt_masks_events_mouse_scrolled(struct dt_iop_module_t *module, double x, double y, int up, uint32_t state, int delta_y)
Definition develop/masks/masks.c:2346
static float dt_masks_dynbuf_get(dt_masks_dynbuf_t *a, int offset)
Definition masks.h:1221
static void dt_masks_translate_ctrl_node(float node[2], float ctrl1[2], float ctrl2[2], const float delta_x, const float delta_y)
Definition masks.h:652
gboolean dt_masks_is_anything_selected(const dt_masks_form_gui_t *mask_gui)
Definition develop/masks/masks.c:2015
const dt_masks_functions_t dt_masks_functions_group
Definition group.c:819
dt_masks_form_t * dt_masks_dup_masks_form(const dt_masks_form_t *form)
Deep-copy a mask form, including its points list.
Definition develop/masks/masks.c:273
void dt_masks_duplicate_points(const dt_masks_form_t *base, dt_masks_form_t *dest, size_t node_size)
Duplicate a points list for a mask using a fixed node size.
Definition develop/masks/masks.c:3366
dt_masks_state_t
Definition masks.h:166
@ DT_MASKS_STATE_DIFFERENCE
Definition masks.h:173
@ DT_MASKS_STATE_INVERSE
Definition masks.h:170
@ DT_MASKS_STATE_INTERSECTION
Definition masks.h:172
@ DT_MASKS_STATE_IS_COMBINE_OP
Definition masks.h:177
@ DT_MASKS_STATE_SHOW
Definition masks.h:169
@ DT_MASKS_STATE_EXCLUSION
Definition masks.h:174
@ DT_MASKS_STATE_NONE
Definition masks.h:167
@ DT_MASKS_STATE_UNION
Definition masks.h:171
@ DT_MASKS_STATE_USE
Definition masks.h:168
@ DT_MASKS_STATE_NOOP
Definition masks.h:175
static float dt_masks_get_form_size_from_nodes(const GList *points)
Definition masks.h:557
void dt_masks_write_masks_history_item(const int32_t imgid, const int num, dt_masks_form_t *form)
Definition develop/masks/masks.c:1954
gboolean dt_masks_gui_form_create_throttled(dt_masks_form_t *form, dt_masks_form_gui_t *gui, int index, struct dt_iop_module_t *module, float posx, float posy)
Definition develop/masks/masks.c:871
static float * dt_masks_dynbuf_reserve_n(dt_masks_dynbuf_t *a, const int n)
Definition masks.h:1181
void dt_masks_gui_form_save_creation(dt_develop_t *dev, struct dt_iop_module_t *module, dt_masks_form_t *form, dt_masks_form_gui_t *gui)
Definition develop/masks/masks.c:1150
void dt_masks_select_form(struct dt_iop_module_t *module, dt_masks_form_t *sel)
Select or clear the current mask form, notifying the owning module if needed.
Definition develop/masks/masks.c:3733
void dt_masks_calc_detail_mask(float *const src, float *const out, float *const tmp, const int width, const int height, const float threshold, const gboolean detail)
static int dt_masks_gui_selected_handle_border_index(const dt_masks_form_gui_t *gui)
Definition masks.h:538
GList * dt_masks_snapshot_current_forms(dt_develop_t *dev, gboolean reset_changed)
Definition develop/masks/masks.c:1773
float dt_masks_get_set_conf_value(dt_masks_form_t *form, char *feature, float new_value, float v_min, float v_max, dt_masks_increment_t increment, const int flow)
Change a numerical property of a mask shape, either by in/de-crementing the current value or setting ...
Definition develop/masks/masks.c:3324
float dt_masks_form_get_interaction_value(dt_masks_form_group_t *form_group, dt_masks_interaction_t interaction)
Definition develop/masks/masks.c:3187
void dt_masks_clear_form_gui(dt_develop_t *dev)
Definition develop/masks/masks.c:2723
void dt_masks_draw_source(cairo_t *cr, dt_masks_form_gui_t *gui, const int index, const int nb, const float zoom_scale, struct dt_masks_gui_center_point_t *center_point, const shape_draw_function_t *draw_shape_func)
Draw the source for a correction mask.
Definition develop/masks/masks.c:2483
static gboolean _dt_masks_dynbuf_growto(dt_masks_dynbuf_t *a, size_t size)
Definition masks.h:1124
void dt_masks_blur_9x9_coeff(float *coeffs, const float sigma)
Definition detail.c:171
gboolean(* dt_masks_border_handle_fn)(const dt_masks_form_gui_points_t *gui_points, int node_count, int node_index, float *handle_x, float *handle_y, void *user_data)
Shape-specific callback to fetch a node's border handle in GUI space.
Definition masks.h:1373
dt_masks_type_t
Definition masks.h:129
@ DT_MASKS_NON_CLONE
Definition masks.h:138
@ DT_MASKS_ALL
Definition masks.h:140
@ DT_MASKS_POLYGON
Definition masks.h:132
@ DT_MASKS_BRUSH
Definition masks.h:137
@ DT_MASKS_IS_PATH_SHAPE
Definition masks.h:148
@ DT_MASKS_IS_OPEN_SHAPE
Definition masks.h:144
@ DT_MASKS_ELLIPSE
Definition masks.h:136
@ DT_MASKS_CLONE
Definition masks.h:134
@ DT_MASKS_GRADIENT
Definition masks.h:135
@ DT_MASKS_NONE
Definition masks.h:130
@ DT_MASKS_CIRCLE
Definition masks.h:131
@ DT_MASKS_GROUP
Definition masks.h:133
@ DT_MASKS_IS_PRIMITIVE_SHAPE
Definition masks.h:149
@ DT_MASKS_IS_CLOSED_SHAPE
Definition masks.h:143
@ DT_MASKS_IS_RETOUCHE
Definition masks.h:146
dt_masks_interaction_t
Definition masks.h:302
@ DT_MASKS_INTERACTION_OPACITY
Definition masks.h:306
@ DT_MASKS_INTERACTION_HARDNESS
Definition masks.h:305
@ DT_MASKS_INTERACTION_SIZE
Definition masks.h:304
@ DT_MASKS_INTERACTION_LAST
Definition masks.h:307
@ DT_MASKS_INTERACTION_UNDEF
Definition masks.h:303
int dt_masks_group_index_from_formid(const dt_masks_form_t *group_form, int formid)
Definition develop/masks/masks.c:332
void dt_masks_replace_current_forms(dt_develop_t *dev, GList *forms)
Definition develop/masks/masks.c:1723
void _masks_gui_delete_node_callback(GtkWidget *menu, gpointer user_data)
Definition masks_gui.c:300
static void dt_masks_gui_cursor_to_raw_norm(dt_develop_t *dev, const dt_masks_form_gui_t *gui, float point[2])
Definition masks.h:597
int dt_masks_version(void)
Definition develop/masks/masks.c:1315
dt_masks_form_group_t * dt_masks_form_get_selected_group(const struct dt_masks_form_t *form, const struct dt_masks_form_gui_t *gui)
static float dt_masks_border_from_projected_handle(dt_develop_t *dev, const float node[2], const float projected_image_pos[2], const float scale_ref)
Definition masks.h:751
static gboolean dt_masks_center_of_gravity_from_points(const float *points, const int points_count, float center[2], float *area)
Definition masks.h:1245
dt_masks_ellipse_flags_t
Definition masks.h:217
@ DT_MASKS_ELLIPSE_PROPORTIONAL
Definition masks.h:219
@ DT_MASKS_ELLIPSE_EQUIDISTANT
Definition masks.h:218
int dt_masks_events_mouse_leave(struct dt_iop_module_t *module)
Definition develop/masks/masks.c:2005
static size_t dt_masks_dynbuf_position(dt_masks_dynbuf_t *a)
Definition masks.h:1316
gboolean dt_masks_gui_is_dragging(const dt_masks_form_gui_t *gui)
Definition develop/masks/masks.c:415
void dt_masks_calc_rawdetail_mask(float *const src, float *const out, float *const tmp, const int width, const int height, const dt_aligned_pixel_t wb)
gboolean dt_masks_point_is_within_radius(const float px, const float py, const float cx, const float cy, const float radius)
Check if a point (px,py) is inside a radius from a center point (cx,cy)
Definition develop/masks/masks.c:64
static void dt_masks_preview_buffers_cleanup(dt_masks_preview_buffers_t *buffers)
Definition masks.h:798
dt_masks_source_pos_type_t
Definition masks.h:223
@ DT_MASKS_SOURCE_POS_RELATIVE_TEMP
Definition masks.h:225
@ DT_MASKS_SOURCE_POS_RELATIVE
Definition masks.h:224
@ DT_MASKS_SOURCE_POS_ABSOLUTE
Definition masks.h:226
static gboolean dt_masks_gui_was_anything_selected(const dt_masks_form_gui_t *gui)
Definition masks.h:523
const dt_masks_functions_t dt_masks_functions_polygon
Definition polygon.c:3659
static gboolean dt_masks_gui_change_affects_selected_node_or_all(const dt_masks_form_gui_t *gui, const int index)
Definition masks.h:548
void dt_masks_cleanup_unused(dt_develop_t *dev)
Cleanup unused masks and refresh the current forms snapshot.
Definition develop/masks/masks.c:3652
dt_masks_event_t
Definition masks.h:156
@ DT_MASKS_EVENT_NONE
Definition masks.h:157
@ DT_MASKS_EVENT_UPDATE
Definition masks.h:160
@ DT_MASKS_EVENT_RESET
Definition masks.h:163
@ DT_MASKS_EVENT_ADD
Definition masks.h:158
@ DT_MASKS_EVENT_DELETE
Definition masks.h:161
@ DT_MASKS_EVENT_REMOVE
Definition masks.h:159
@ DT_MASKS_EVENT_CHANGE
Definition masks.h:162
void dt_masks_group_ungroup(dt_masks_form_t *dest_grp, dt_masks_form_t *grp)
Definition develop/masks/masks.c:3470
dt_masks_form_t * dt_masks_create(dt_masks_type_t type)
Definition develop/masks/masks.c:1680
static gboolean dt_masks_gui_should_hit_test(dt_masks_form_gui_t *gui)
Definition masks.h:581
int dt_masks_events_button_pressed(struct dt_iop_module_t *module, double x, double y, double pressure, int which, int type, uint32_t state)
Definition develop/masks/masks.c:2236
static void dt_masks_gui_delta_from_raw_anchor(dt_develop_t *dev, const dt_masks_form_gui_t *gui, const float anchor[2], float *delta_x, float *delta_y)
Definition masks.h:620
float dt_masks_apply_increment(float current, float amount, dt_masks_increment_t increment, int flow)
Apply a scroll increment to a scalar value.
Definition develop/masks/masks.c:3295
static gboolean dt_masks_form_is_clone(const dt_masks_form_t *form)
Definition masks.h:635
float dt_masks_get_set_conf_value_with_toast(dt_masks_form_t *form, const char *feature, float amount, float v_min, float v_max, dt_masks_increment_t increment, int flow, const char *toast_fmt, float toast_scale)
Update a mask configuration value and emit a toast message.
Definition develop/masks/masks.c:3354
int dt_masks_events_mouse_enter(struct dt_iop_module_t *module)
Definition develop/masks/masks.c:2010
float dt_masks_rotate_with_anchor(dt_develop_t *dev, const float anchor[2], const float center[2], dt_masks_form_gui_t *gui)
Rotate a mask shape around its center. WARNING: gui->delta will be updated with the new position afte...
Definition develop/masks/masks.c:3909
float dt_masks_apply_increment_precomputed(float current, float amount, float scale_amount, float offset_amount, dt_masks_increment_t increment)
Apply a scroll increment using precomputed scale/offset factors.
Definition develop/masks/masks.c:3309
static void dt_masks_dynbuf_add_zeros(dt_masks_dynbuf_t *a, const int n)
Definition masks.h:1201
void dt_masks_form_move(dt_masks_form_t *grp, int formid, int up)
Definition develop/masks/masks.c:3395
dt_masks_increment_t
Definition masks.h:193
@ DT_MASKS_INCREMENT_SCALE
Definition masks.h:195
@ DT_MASKS_INCREMENT_OFFSET
Definition masks.h:196
@ DT_MASKS_INCREMENT_ABSOLUTE
Definition masks.h:194
dt_masks_pressure_sensitivity_t
Definition masks.h:207
@ DT_MASKS_PRESSURE_OPACITY_REL
Definition masks.h:211
@ DT_MASKS_PRESSURE_OPACITY_ABS
Definition masks.h:212
@ DT_MASKS_PRESSURE_BRUSHSIZE_REL
Definition masks.h:213
@ DT_MASKS_PRESSURE_HARDNESS_REL
Definition masks.h:209
@ DT_MASKS_PRESSURE_OFF
Definition masks.h:208
@ DT_MASKS_PRESSURE_HARDNESS_ABS
Definition masks.h:210
int dt_masks_get_points_border(struct dt_develop_t *dev, dt_masks_form_t *form, float **points, int *points_count, float **border, int *border_count, int source, dt_iop_module_t *module)
Definition develop/masks/masks.c:1277
float dt_masks_form_set_interaction_value(dt_masks_form_group_t *form_group, dt_masks_interaction_t interaction, float value, dt_masks_increment_t increment, int flow, struct dt_masks_form_gui_t *gui, struct dt_iop_module_t *module)
Definition develop/masks/masks.c:3240
dt_masks_form_t * dt_masks_get_from_id_ext(GList *forms, int id)
Definition develop/masks/masks.c:1744
void dt_masks_calculate_source_pos_value(dt_masks_form_gui_t *gui, const float initial_xpos, const float initial_ypos, const float xpos, const float ypos, float *px, float *py, const int adding)
Compute preview-space source position for drawing the clone indicator.
Definition develop/masks/masks.c:3846
const dt_masks_functions_t dt_masks_functions_ellipse
Definition ellipse.c:1698
const dt_masks_functions_t dt_masks_functions_circle
Definition circle.c:1141
dt_masks_form_t * dt_masks_get_from_id(dt_develop_t *dev, int id)
Definition develop/masks/masks.c:1754
dt_masks_points_states_t
Definition masks.h:181
@ DT_MASKS_POINT_STATE_NORMAL
Definition masks.h:182
@ DT_MASKS_POINT_STATE_USER
Definition masks.h:183
void dt_masks_append_form(dt_develop_t *dev, dt_masks_form_t *form)
Definition develop/masks/masks.c:1136
void dt_masks_soft_reset_form_gui(dt_masks_form_gui_t *gui)
Definition develop/masks/masks.c:811
dt_masks_form_group_t * dt_masks_form_get_selected_group_live(const struct dt_masks_form_t *form, const struct dt_masks_form_gui_t *gui)
Return the currently selected group entry, resolving to the live form group when the GUI is operating...
void dt_masks_set_source_pos_initial_value(dt_masks_form_gui_t *gui, dt_masks_form_t *form)
Initialize the clone source position based on current GUI state.
Definition develop/masks/masks.c:3776
dt_masks_edit_mode_t dt_masks_get_edit_mode(struct dt_iop_module_t *module)
Definition develop/masks/masks.c:2810
void dt_masks_iop_value_changed_callback(GtkWidget *widget, struct dt_iop_module_t *module)
Definition develop/masks/masks.c:3016
static int dt_masks_get_mask(const dt_iop_module_t *const module, dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *const piece, dt_masks_form_t *const form, float **buffer, int *width, int *height, int *posx, int *posy)
Definition masks.h:843
GtkWidget * dt_masks_create_menu(dt_masks_form_gui_t *gui, dt_masks_form_t *form, const dt_masks_form_group_t *fpt, const float pzx, const float pzy)
Definition masks_gui.c:415
void dt_masks_gui_cleanup(struct dt_develop_t *dev)
Definition develop/masks/masks.c:380
void dt_masks_init_form_gui(dt_masks_form_gui_t *gui)
Definition develop/masks/masks.c:783
static int dt_masks_get_mask_roi(const dt_iop_module_t *const module, dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *const piece, dt_masks_form_t *const form, const dt_iop_roi_t *roi, float *buffer)
Definition masks.h:852
static void dt_masks_project_on_line(const float cursor[2], const float node[2], const float handle[2], float point[2])
Definition masks.h:726
dt_masks_gradient_states_t
Definition masks.h:187
@ DT_MASKS_GRADIENT_STATE_SIGMOIDAL
Definition masks.h:189
@ DT_MASKS_GRADIENT_STATE_LINEAR
Definition masks.h:188
void dt_masks_reset_show_masks_icons(void)
Definition develop/masks/masks.c:2789
void dt_masks_extend_border(float *const mask, const int width, const int height, const int border)
void dt_masks_gui_form_test_create(dt_masks_form_t *form, dt_masks_form_gui_t *gui, struct dt_iop_module_t *module)
Definition develop/masks/masks.c:1058
static int dt_masks_roundup(int num, int mult)
Definition masks.h:1347
const dt_masks_functions_t dt_masks_functions_brush
Definition develop/masks/brush.c:3242
static float * dt_masks_dynbuf_harvest(dt_masks_dynbuf_t *a)
Definition masks.h:1328
void dt_masks_form_remove(struct dt_iop_module_t *module, dt_masks_form_t *grp, dt_masks_form_t *form)
Definition develop/masks/masks.c:3086
void(* dt_masks_node_position_fn)(const dt_masks_form_gui_points_t *gui_points, int node_index, float *node_x, float *node_y, void *user_data)
Shape-specific callback to fetch a node's position in GUI space.
Definition masks.h:1387
gboolean dt_masks_is_anything_hovered(const dt_masks_form_gui_t *mask_gui)
Definition develop/masks/masks.c:2025
int dt_masks_find_closest_handle_common(dt_masks_form_t *mask_form, dt_masks_form_gui_t *mask_gui, int form_index, int node_count_override, dt_masks_border_handle_fn border_handle_cb, dt_masks_curve_handle_fn curve_handle_cb, dt_masks_node_position_fn node_position_cb, dt_masks_distance_fn distance_cb, dt_masks_post_select_fn post_select_cb, void *user_data)
Shared selection logic for node/handle/segment hit testing.
Definition develop/masks/masks.c:90
int dt_masks_get_source_area(dt_iop_module_t *module, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece, dt_masks_form_t *form, int *width, int *height, int *posx, int *posy)
Definition develop/masks/masks.c:1298
void dt_masks_group_update_name(dt_iop_module_t *module)
Definition develop/masks/masks.c:2886
dt_masks_form_t * dt_masks_get_visible_form(const struct dt_develop_t *dev)
void dt_masks_remove_node(struct dt_iop_module_t *module, dt_masks_form_t *form, int parentid, dt_masks_form_gui_t *gui, int index, int node_index)
Definition develop/masks/masks.c:923
uint64_t dt_masks_group_get_hash(uint64_t hash, dt_masks_form_t *form)
Definition develop/masks/masks.c:3500
void dt_masks_set_edit_mode(struct dt_iop_module_t *module, dt_masks_edit_mode_t value)
Definition develop/masks/masks.c:2817
void dt_group_events_post_expose(cairo_t *cr, float zoom_scale, dt_masks_form_t *form, dt_masks_form_gui_t *gui)
Definition group.c:137
void(* dt_masks_curve_handle_fn)(const dt_masks_form_gui_points_t *gui_points, int node_index, float *handle_x, float *handle_y, void *user_data)
Shape-specific callback to fetch a node's curve handle in GUI space.
Definition masks.h:1380
int dt_masks_get_area(dt_iop_module_t *module, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece, dt_masks_form_t *form, int *width, int *height, int *posx, int *posy)
Definition develop/masks/masks.c:1288
static void dt_masks_dynbuf_set(dt_masks_dynbuf_t *a, int offset, float value)
Definition masks.h:1230
dt_masks_form_group_t * dt_masks_form_group_from_parentid(int parentid, int formid)
Return the group entry for a (parent, form) pair.
Definition develop/masks/masks.c:427
dt_masks_form_t * dt_masks_create_ext(dt_masks_type_t type)
Definition develop/masks/masks.c:1709
static gboolean dt_masks_reset_bezier_ctrl_points(struct dt_iop_module_t *module, struct dt_masks_form_t *mask_form, struct dt_masks_form_gui_t *mask_gui, const int form_index, const struct dt_masks_form_gui_points_t *gui_points, const int node_index, dt_masks_points_states_t *state)
Definition masks.h:704
int dt_masks_form_duplicate(dt_develop_t *dev, int formid)
Definition develop/masks/masks.c:1253
void dt_masks_draw_path_seg_by_seg(cairo_t *cr, dt_masks_form_gui_t *gui, const int index, const float *points, const int points_count, const int node_count, const float zoom_scale)
Definition develop/masks/masks.c:2598
static void dt_masks_gui_delta_to_raw_norm(dt_develop_t *dev, const dt_masks_form_gui_t *gui, float point[2])
Definition masks.h:605
void dt_masks_set_source_pos_initial_state(dt_masks_form_gui_t *gui, const uint32_t state)
Decide initial source positioning mode for clone masks.
Definition develop/masks/masks.c:3751
static gboolean dt_masks_form_uses_spot_defaults(const dt_masks_form_t *form)
Definition masks.h:630
const dt_masks_functions_t dt_masks_functions_gradient
Definition gradient.c:1546
static void dt_masks_dynbuf_reset(dt_masks_dynbuf_t *a)
Definition masks.h:1322
void dt_masks_iop_combo_populate(GtkWidget *w, void *module)
Definition develop/masks/masks.c:2932
void dt_masks_form_update_gravity_center(struct dt_masks_form_t *form)
Definition develop/masks/masks.c:3213
void dt_masks_set_visible_form(struct dt_develop_t *dev, dt_masks_form_t *form)
Definition develop/masks/masks.c:358
gboolean dt_masks_creation_mode(dt_iop_module_t *module, const dt_masks_type_t type)
Enter mask creation mode for a given shape type.
Definition develop/masks/masks.c:3953
static void dt_masks_dynbuf_free(dt_masks_dynbuf_t *a)
Definition masks.h:1338
static void dt_masks_reset_source(dt_masks_form_t *form)
Definition masks.h:640
static void dt_masks_set_ctrl_points(float ctrl1[2], float ctrl2[2], const float control_points[4])
Definition masks.h:663
gboolean dt_masks_form_get_gravity_center(const struct dt_masks_form_t *form, float center[2], float *area)
int dt_masks_copy_used_forms_for_module(dt_develop_t *dev_dest, dt_develop_t *dev_src, const struct dt_iop_module_t *mod_src)
size_t size
Definition mipmap_cache.c:3
struct _GtkWidget GtkWidget
Definition splash.h:29
unsigned __int64 uint64_t
Definition strptime.c:74
int32_t unmuted
Definition darktable.h:688
Definition pixelpipe_hb.h:95
Definition pixelpipe_hb.h:216
Definition develop.h:155
Definition imageop.h:216
uint64_t hash
Definition imageop.h:345
GtkWidget * widget
Definition imageop.h:302
struct dt_develop_t * dev
Definition imageop.h:261
Definition imageop.h:67
Definition masks.h:271
float extent
Definition masks.h:274
float curvature
Definition masks.h:276
float rotation
Definition masks.h:273
float center[2]
Definition masks.h:272
dt_masks_gradient_states_t state
Definition masks.h:277
float steepness
Definition masks.h:275
Definition masks.h:417
size_t size
Definition masks.h:421
char tag[128]
Definition masks.h:419
size_t pos
Definition masks.h:420
float * buffer
Definition masks.h:418
Definition masks.h:282
float opacity
Definition masks.h:286
int formid
Definition masks.h:283
int parentid
Definition masks.h:284
int state
Definition masks.h:285
Definition masks.h:405
float * source
Definition masks.h:410
float * border
Definition masks.h:408
gboolean clockwise
Definition masks.h:412
int source_count
Definition masks.h:411
int border_count
Definition masks.h:409
int points_count
Definition masks.h:407
float * points
Definition masks.h:406
Definition masks.h:427
gboolean rebuild_pending
Definition masks.h:498
gboolean node_selected
Definition masks.h:470
gboolean handle_border_selected
Definition masks.h:473
double last_rebuild_ts
Definition masks.h:496
gboolean border_toggling
Definition masks.h:488
dt_masks_dynbuf_t * guipoints_payload
Definition masks.h:435
gboolean source_selected
Definition masks.h:478
int handle_border_dragging
Definition masks.h:493
int node_selected_idx
Definition masks.h:474
int handle_border_hovered
Definition masks.h:468
gboolean source_dragging
Definition masks.h:486
dt_masks_edit_mode_t edit_mode
Definition masks.h:463
dt_iop_module_t * creation_module
Definition masks.h:505
int source_pos_type
Definition masks.h:483
int group_selected
Definition masks.h:481
gboolean creation_closing_form
Definition masks.h:504
int node_hovered
Definition masks.h:465
float pos[2]
Definition masks.h:443
uint64_t pipe_hash
Definition masks.h:511
dt_masks_pressure_sensitivity_t pressure_sensitivity
Definition masks.h:507
gboolean seg_selected
Definition masks.h:472
gboolean form_dragging
Definition masks.h:485
int guipoints_count
Definition masks.h:436
float scrolly
Definition masks.h:458
float scrollx
Definition masks.h:458
gboolean gradient_toggling
Definition masks.h:489
gboolean creation
Definition masks.h:503
int node_dragging
Definition masks.h:490
float pos_source[2]
Definition masks.h:461
dt_masks_type_t type
Definition masks.h:428
int seg_hovered
Definition masks.h:467
GList * points
Definition masks.h:432
dt_masks_form_t * form_visible
Definition masks.h:430
gboolean form_selected
Definition masks.h:476
int formid
Definition masks.h:510
gboolean handle_selected
Definition masks.h:471
gboolean form_rotating
Definition masks.h:487
dt_masks_dynbuf_t * guipoints
Definition masks.h:435
float rel_pos[2]
Definition masks.h:447
gboolean border_selected
Definition masks.h:477
float last_rebuild_pos[2]
Definition masks.h:497
int handle_dragging
Definition masks.h:491
gboolean pivot_selected
Definition masks.h:479
float raw_pos[2]
Definition masks.h:451
float last_hit_test_pos[2]
Definition masks.h:501
int seg_dragging
Definition masks.h:492
float delta[2]
Definition masks.h:455
int handle_hovered
Definition masks.h:466
Definition masks.h:376
const dt_masks_functions_t * functions
Definition masks.h:379
dt_masks_type_t type
Definition masks.h:378
float source[2]
Definition masks.h:385
int version
Definition masks.h:400
char name[128]
Definition masks.h:396
GList * points
Definition masks.h:377
int formid
Definition masks.h:398
float gravity_center[2]
Definition masks.h:389
float area
Definition masks.h:394
gboolean uses_bezier_points_layout
Definition masks.h:381
Definition masks.h:313
float(* get_interaction_value)(const struct dt_masks_form_t *form, dt_masks_interaction_t interaction)
Definition masks.h:344
int point_struct_size
Definition masks.h:314
gboolean(* get_gravity_center)(const struct dt_masks_form_t *form, float center[2], float *area)
Definition masks.h:343
int(* button_pressed)(struct dt_iop_module_t *module, double x, double y, double pressure, int which, int type, uint32_t state, struct dt_masks_form_t *form, int parentid, struct dt_masks_form_gui_t *gui, int index)
Definition masks.h:358
int(* get_points)(struct dt_develop_t *dev, float x, float y, float radius_a, float radius_b, float rotation, float **points, int *points_count)
Definition masks.h:324
int(* button_released)(struct dt_iop_module_t *module, double x, double y, int which, uint32_t state, struct dt_masks_form_t *form, int parentid, struct dt_masks_form_gui_t *gui, int index)
Definition masks.h:362
int(* get_mask_roi)(const dt_iop_module_t *const fmodule, struct dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *const piece, struct dt_masks_form_t *const form, const dt_iop_roi_t *roi, float *buffer)
Definition masks.h:332
int(* get_source_area)(dt_iop_module_t *module, struct dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece, struct dt_masks_form_t *form, int *width, int *height, int *posx, int *posy)
Definition masks.h:340
int(* key_pressed)(struct dt_iop_module_t *module, GdkEventKey *event, struct dt_masks_form_t *form, int parentid, struct dt_masks_form_gui_t *gui, int index)
Definition masks.h:365
int(* mouse_moved)(struct dt_iop_module_t *module, double x, double y, double pressure, int which, struct dt_masks_form_t *form, int parentid, struct dt_masks_form_gui_t *gui, int index)
Definition masks.h:351
void(* sanitize_config)(dt_masks_type_t type_flags)
Definition masks.h:315
void(* set_form_name)(struct dt_masks_form_t *const form, const size_t nb)
Definition masks.h:316
void(* duplicate_points)(struct dt_develop_t *const dev, struct dt_masks_form_t *base, struct dt_masks_form_t *dest)
Definition masks.h:319
int(* populate_context_menu)(GtkWidget *menu, struct dt_masks_form_t *form, struct dt_masks_form_gui_t *gui, const float pzx, const float pzy)
Definition masks.h:371
int(* update_hover)(struct dt_masks_form_t *form, struct dt_masks_form_gui_t *gui, int index)
Definition masks.h:349
float(* set_interaction_value)(struct dt_masks_form_t *form, dt_masks_interaction_t interaction, float value, dt_masks_increment_t increment, int flow, struct dt_masks_form_gui_t *gui, struct dt_iop_module_t *module)
Definition masks.h:345
int(* get_points_border)(struct dt_develop_t *dev, struct dt_masks_form_t *form, float **points, int *points_count, float **border, int *border_count, int source, const dt_iop_module_t *const module)
Definition masks.h:326
int(* get_area)(const dt_iop_module_t *const module, struct dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *const piece, struct dt_masks_form_t *const form, int *width, int *height, int *posx, int *posy)
Definition masks.h:336
void(* get_distance)(float x, float y, float as, struct dt_masks_form_gui_t *gui, int index, int num_points, int *inside, int *inside_border, int *near, int *inside_source, float *dist)
Definition masks.h:322
void(* draw_shape)(cairo_t *cr, const float *points, const int points_count, const int nb, const gboolean border, const gboolean source)
Definition masks.h:368
int(* mouse_scrolled)(struct dt_iop_module_t *module, double x, double y, int up, const int delta_y, uint32_t state, struct dt_masks_form_t *form, int parentid, struct dt_masks_form_gui_t *gui, int index, dt_masks_interaction_t interaction)
Definition masks.h:354
void(* initial_source_pos)(const float iwd, const float iht, float *x, float *y)
Definition masks.h:320
int(* get_mask)(const dt_iop_module_t *const module, struct dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *const piece, struct dt_masks_form_t *const form, float **buffer, int *width, int *height, int *posx, int *posy)
Definition masks.h:328
void(* post_expose)(cairo_t *cr, float zoom_scale, struct dt_masks_form_gui_t *gui, int index, int num_points)
Definition masks.h:366
void(* set_hint_message)(const struct dt_masks_form_gui_t *const gui, const struct dt_masks_form_t *const form, const int opacity, char *const __restrict__ msgbuf, const size_t msgbuf_len)
Definition masks.h:317
void(* init_ctrl_points)(struct dt_masks_form_t *form)
Definition masks.h:370
Definition masks.h:805
struct dt_masks_gui_center_point_t::@33 source
struct dt_masks_gui_center_point_t::@32 main
float x
Definition masks.h:808
float y
Definition masks.h:809
Definition masks.h:259
float ctrl2[2]
Definition masks.h:262
float node[2]
Definition masks.h:260
float ctrl1[2]
Definition masks.h:261
float hardness
Definition masks.h:265
dt_masks_points_states_t state
Definition masks.h:266
float border[2]
Definition masks.h:263
float density
Definition masks.h:264
Definition masks.h:231
float border
Definition masks.h:234
float center[2]
Definition masks.h:232
float radius
Definition masks.h:233
Definition masks.h:239
float border
Definition masks.h:243
float radius[2]
Definition masks.h:241
dt_masks_ellipse_flags_t flags
Definition masks.h:244
float center[2]
Definition masks.h:240
float rotation
Definition masks.h:242
Definition masks.h:249
dt_masks_points_states_t state
Definition masks.h:254
float node[2]
Definition masks.h:250
float ctrl2[2]
Definition masks.h:252
float border[2]
Definition masks.h:253
float ctrl1[2]
Definition masks.h:251
Definition masks.h:791
float * border
Definition masks.h:794
float * points
Definition masks.h:792
int points_count
Definition masks.h:793
int border_count
Definition masks.h:795
Definition ashift_lsd.c:192