Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
draw.h
Go to the documentation of this file.
1/*
2 This file is part of darktable,
3 Copyright (C) 2009-2013, 2016 johannes hanika.
4 Copyright (C) 2010-2011 Henrik Andersson.
5 Copyright (C) 2010, 2012-2014, 2016, 2018 Tobias Ellinghaus.
6 Copyright (C) 2011 Jochen Schroeder.
7 Copyright (C) 2011 Robert Bieber.
8 Copyright (C) 2012 Richard Wonka.
9 Copyright (C) 2014, 2016 Roman Lebedev.
10 Copyright (C) 2018-2020, 2025 Aurélien PIERRE.
11 Copyright (C) 2019 Andreas Schneider.
12 Copyright (C) 2019 Edgardo Hoszowski.
13 Copyright (C) 2019 Heiko Bauke.
14 Copyright (C) 2019 Jakub Filipowicz.
15 Copyright (C) 2019-2020, 2022 Pascal Obry.
16 Copyright (C) 2019 Philippe Weyland.
17 Copyright (C) 2020, 2022 Chris Elston.
18 Copyright (C) 2020-2021 Dan Torop.
19 Copyright (C) 2020 Ralf Brown.
20 Copyright (C) 2022 Aldric Renaudin.
21 Copyright (C) 2022 Martin Bařinka.
22 Copyright (C) 2025 Alynx Zhou.
23 Copyright (C) 2026 Guillaume Stutin.
24
25 darktable is free software: you can redistribute it and/or modify
26 it under the terms of the GNU General Public License as published by
27 the Free Software Foundation, either version 3 of the License, or
28 (at your option) any later version.
29
30 darktable is distributed in the hope that it will be useful,
31 but WITHOUT ANY WARRANTY; without even the implied warranty of
32 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33 GNU General Public License for more details.
34
35 You should have received a copy of the GNU General Public License
36 along with darktable. If not, see <http://www.gnu.org/licenses/>.
37*/
38
39#pragma once
40
43#ifdef HAVE_CONFIG_H
44#include "config.h"
45#endif
46
47#include "common/curve_tools.h"
48#include "common/darktable.h"
49#include "common/splines.h"
50#include "control/conf.h"
51#include "develop/develop.h"
52#include <cairo.h>
53#include <glib.h>
54#include <math.h>
55#include <stdint.h>
56#include <stdlib.h>
57#include <gui/gtk.h>
58
59#ifdef __cplusplus
60extern "C" {
61#endif
62
63#ifndef M_PI
64#define M_PI 3.141592654
65#endif
66
67// TODO: enter directly the values applied to this factor in each following macro later once
68// we're happy with it.
69#define DT_DRAW_SIZE_GLOBAL_FACTOR 0.75f
70
72#define DT_DRAW_SIZE_LINE DT_PIXEL_APPLY_DPI_DPP(1.5f * DT_DRAW_SIZE_GLOBAL_FACTOR)
73#define DT_DRAW_SIZE_LINE_SELECTED DT_PIXEL_APPLY_DPI_DPP(3.0f * DT_DRAW_SIZE_GLOBAL_FACTOR)
74#define DT_DRAW_SIZE_LINE_HIGHLIGHT (DT_PIXEL_APPLY_DPI_DPP(4.0f * DT_DRAW_SIZE_GLOBAL_FACTOR) + DT_DRAW_SIZE_LINE)
75#define DT_DRAW_SIZE_LINE_HIGHLIGHT_SELECTED (DT_PIXEL_APPLY_DPI_DPP(5.0f * DT_DRAW_SIZE_GLOBAL_FACTOR) + DT_DRAW_SIZE_LINE_SELECTED)
76#define DT_DRAW_SIZE_CROSS DT_PIXEL_APPLY_DPI_DPP(7.0f * DT_DRAW_SIZE_GLOBAL_FACTOR)
77
79#define DT_DRAW_SCALE_DASH DT_PIXEL_APPLY_DPI_DPP(12.0f * DT_DRAW_SIZE_GLOBAL_FACTOR)
80#define DT_DRAW_SCALE_ARROW DT_PIXEL_APPLY_DPI_DPP(18.0f * DT_DRAW_SIZE_GLOBAL_FACTOR)
81
82// radius/width of node (handles are set to be 3/4 of a node size)
83#define DT_DRAW_RADIUS_NODE DT_PIXEL_APPLY_DPI_DPP(5.0f * DT_DRAW_SIZE_GLOBAL_FACTOR)
84#define DT_DRAW_RADIUS_NODE_SELECTED (1.25f * DT_DRAW_RADIUS_NODE)
85
86// used to detect the area where rotation of a shape is possible. Don't apply the global factor here since it's an user interaction area.
87#define DT_DRAW_SELECTION_ROTATION_AREA DT_PIXEL_APPLY_DPI_DPP(50.0f)
88#define DT_DRAW_SELECTION_ROTATION_RADIUS(dev) (DT_DRAW_SELECTION_ROTATION_AREA / dt_dev_get_zoom_level((dt_develop_t *)dev))
89
97
104
106static inline void dt_draw_set_color_overlay(cairo_t *cr, gboolean bright, double alpha)
107{
108 double amt;
109
110 if(bright)
111 amt = 0.5 + darktable.gui->overlay_contrast * 0.5;
112 else
113 amt = (1.0 - darktable.gui->overlay_contrast) * 0.5;
114
115 cairo_set_source_rgba(cr, darktable.gui->overlay_red * amt, darktable.gui->overlay_green * amt, darktable.gui->overlay_blue * amt, alpha);
116}
117
120static inline void dt_draw_star(cairo_t *cr, float x, float y, float r1, float r2)
121{
122 const float d = 2.0 * M_PI * 0.1f;
123 const float dx[10] = { sinf(0.0), sinf(d), sinf(2 * d), sinf(3 * d), sinf(4 * d),
124 sinf(5 * d), sinf(6 * d), sinf(7 * d), sinf(8 * d), sinf(9 * d) };
125 const float dy[10] = { cosf(0.0), cosf(d), cosf(2 * d), cosf(3 * d), cosf(4 * d),
126 cosf(5 * d), cosf(6 * d), cosf(7 * d), cosf(8 * d), cosf(9 * d) };
127
128 cairo_move_to(cr, x + r1 * dx[0], y - r1 * dy[0]);
129 for(int k = 1; k < 10; k++)
130 if(k & 1)
131 cairo_line_to(cr, x + r2 * dx[k], y - r2 * dy[k]);
132 else
133 cairo_line_to(cr, x + r1 * dx[k], y - r1 * dy[k]);
134 cairo_close_path(cr);
135}
136
137static inline void dt_draw_line(cairo_t *cr, float left, float top, float right, float bottom)
138{
139 cairo_move_to(cr, left, top);
140 cairo_line_to(cr, right, bottom);
141}
142
143static inline void dt_draw_grid(cairo_t *cr, const int num, const int left, const int top, const int right,
144 const int bottom)
145{
146 float width = right - left;
147 float height = bottom - top;
148
149 for(int k = 1; k < num; k++)
150 {
151 dt_draw_line(cr, left + k / (float)num * width, top, left + k / (float)num * width, bottom);
152 cairo_stroke(cr);
153 dt_draw_line(cr, left, top + k / (float)num * height, right, top + k / (float)num * height);
154 cairo_stroke(cr);
155 }
156}
157
158static inline float dt_curve_to_mouse(const float x, const float zoom_factor, const float offset)
159{
160 return (x - offset) * zoom_factor;
161}
162
163/* left, right, top, bottom are in curve coordinates [0..1] */
164static inline void dt_draw_grid_zoomed(cairo_t *cr, const int num, const float left, const float top,
165 const float right, const float bottom, const float width,
166 const float height, const float zoom_factor, const float zoom_offset_x,
167 const float zoom_offset_y)
168{
169 for(int k = 1; k < num; k++)
170 {
171 dt_draw_line(cr, dt_curve_to_mouse(left + k / (float)num, zoom_factor, zoom_offset_x) * width,
172 dt_curve_to_mouse(top, zoom_factor, zoom_offset_y) * -height,
173 dt_curve_to_mouse(left + k / (float)num, zoom_factor, zoom_offset_x) * width,
174 dt_curve_to_mouse(bottom, zoom_factor, zoom_offset_y) * -height);
175 cairo_stroke(cr);
176
177 dt_draw_line(cr, dt_curve_to_mouse(left, zoom_factor, zoom_offset_x) * width,
178 dt_curve_to_mouse(top + k / (float)num, zoom_factor, zoom_offset_y) * -height,
179 dt_curve_to_mouse(right, zoom_factor, zoom_offset_x) * width,
180 dt_curve_to_mouse(top + k / (float)num, zoom_factor, zoom_offset_y) * -height);
181 cairo_stroke(cr);
182 }
183}
184
185#ifdef _OPENMP
186#pragma omp declare simd uniform(base)
187#endif
188static inline float dt_log_scale_axis(const float x, const float base)
189{
190 return logf(x * (base - 1.0f) + 1.f) / logf(base);
191}
192
193static inline void dt_draw_loglog_grid(cairo_t *cr, const int num, const int left, const int top, const int right,
194 const int bottom, const float base)
195{
196 float width = right - left;
197 float height = bottom - top;
198
199 for(int k = 1; k < num; k++)
200 {
201 const float x = dt_log_scale_axis(k / (float)num, base);
202 dt_draw_line(cr, left + x * width, top, left + x * width, bottom);
203 cairo_stroke(cr);
204 dt_draw_line(cr, left, top + x * height, right, top + x * height);
205 cairo_stroke(cr);
206 }
207}
208
209static inline void dt_draw_semilog_x_grid(cairo_t *cr, const int num, const int left, const int top,
210 const int right, const int bottom, const float base)
211{
212 float width = right - left;
213 float height = bottom - top;
214
215 for(int k = 1; k < num; k++)
216 {
217 const float x = dt_log_scale_axis(k / (float)num, base);
218 dt_draw_line(cr, left + x * width, top, left + x * width, bottom);
219 cairo_stroke(cr);
220 dt_draw_line(cr, left, top + k / (float)num * height, right, top + k / (float)num * height);
221 cairo_stroke(cr);
222 }
223}
224
225static inline void dt_draw_semilog_y_grid(cairo_t *cr, const int num, const int left, const int top,
226 const int right, const int bottom, const float base)
227{
228 float width = right - left;
229 float height = bottom - top;
230
231 for(int k = 1; k < num; k++)
232 {
233 const float x = dt_log_scale_axis(k / (float)num, base);
234 dt_draw_line(cr, left + k / (float)num * width, top, left + k / (float)num * width, bottom);
235 cairo_stroke(cr);
236 dt_draw_line(cr, left, top + x * height, right, top + x * height);
237 cairo_stroke(cr);
238 }
239}
240
241
242static inline void dt_draw_vertical_lines(cairo_t *cr, const int num, const int left, const int top,
243 const int right, const int bottom)
244{
245 float width = right - left;
246
247 for(int k = 1; k < num; k++)
248 {
249 cairo_move_to(cr, left + k / (float)num * width, top);
250 cairo_line_to(cr, left + k / (float)num * width, bottom);
251 cairo_stroke(cr);
252 }
253}
254
255static inline void dt_draw_horizontal_lines(cairo_t *cr, const int num, const int left, const int top,
256 const int right, const int bottom)
257{
258 float height = bottom - top;
259
260 for(int k = 1; k < num; k++)
261 {
262 cairo_move_to(cr, left, top + k / (float)num * height);
263 cairo_line_to(cr, right, top + k / (float)num * height);
264 cairo_stroke(cr);
265 }
266}
267
268static inline dt_draw_curve_t *dt_draw_curve_new(const float min, const float max, unsigned int type)
269{
270 dt_draw_curve_t *c = (dt_draw_curve_t *)malloc(sizeof(dt_draw_curve_t));
271 c->csample.m_samplingRes = 0x10000;
272 c->csample.m_outputRes = 0x10000;
273 c->csample.m_Samples = (uint16_t *)malloc(sizeof(uint16_t) * 0x10000);
274
275 c->c.m_spline_type = type;
276 c->c.m_numAnchors = 0;
277 c->c.m_min_x = 0.0;
278 c->c.m_max_x = 1.0;
279 c->c.m_min_y = 0.0;
280 c->c.m_max_y = 1.0;
281 return c;
282}
283
285{
286 dt_free(c->csample.m_Samples);
287 dt_free(c);
288}
289
290static inline void dt_draw_curve_set_point(dt_draw_curve_t *c, const int num, const float x, const float y)
291{
292 c->c.m_anchors[num].x = x;
293 c->c.m_anchors[num].y = y;
294}
295
296static inline void dt_draw_curve_smaple_values(dt_draw_curve_t *c, const float min, const float max, const int res,
297 float *x, float *y)
298{
299 if(x)
300 {
301#ifdef _OPENMP
302#pragma omp parallel for SIMD() default(none) dt_omp_firstprivate(res) shared(x) schedule(static)
303#endif
304 for(int k = 0; k < res; k++) x[k] = k * (1.0f / res);
305 }
306 if(y)
307 {
308#ifdef _OPENMP
309#pragma omp parallel for SIMD() default(none) dt_omp_firstprivate(min, max, res) shared(y, c) schedule(static)
310#endif
311 for(int k = 0; k < res; k++) y[k] = min + (max - min) * c->csample.m_Samples[k] * (1.0f / 0x10000);
312 }
313}
314
315static inline void dt_draw_curve_calc_values(dt_draw_curve_t *c, const float min, const float max, const int res,
316 float *x, float *y)
317{
318 c->csample.m_samplingRes = res;
319 c->csample.m_outputRes = 0x10000;
320 CurveDataSample(&c->c, &c->csample);
322}
323
324static inline void dt_draw_curve_calc_values_V2_nonperiodic(dt_draw_curve_t *c, const float min, const float max,
325 const int res, float *x, float *y)
326{
327 c->csample.m_samplingRes = res;
328 c->csample.m_outputRes = 0x10000;
329 CurveDataSampleV2(&c->c, &c->csample);
331}
332
333static inline void dt_draw_curve_calc_values_V2_periodic(dt_draw_curve_t *c, const float min, const float max,
334 const int res, float *x, float *y)
335{
336 c->csample.m_samplingRes = res;
337 c->csample.m_outputRes = 0x10000;
338 CurveDataSampleV2Periodic(&c->c, &c->csample);
340}
341
342static inline void dt_draw_curve_calc_values_V2(dt_draw_curve_t *c, const float min, const float max,
343 const int res, float *x, float *y, const gboolean periodic)
344{
345 if(periodic)
347 else
349 }
350
351static inline float dt_draw_curve_calc_value(dt_draw_curve_t *c, const float x)
352{
353 float xa[20], ya[20];
354 float val = 0.f;
355 float *ypp = NULL;
356 for(int i = 0; i < c->c.m_numAnchors; i++)
357 {
358 xa[i] = c->c.m_anchors[i].x;
359 ya[i] = c->c.m_anchors[i].y;
360 }
361 ypp = interpolate_set(c->c.m_numAnchors, xa, ya, c->c.m_spline_type);
362 if(ypp)
363 {
364 val = interpolate_val(c->c.m_numAnchors, xa, x, ya, ypp, c->c.m_spline_type);
365 dt_free(ypp);
366 }
367 return MIN(MAX(val, c->c.m_min_y), c->c.m_max_y);
368}
369
370static inline int dt_draw_curve_add_point(dt_draw_curve_t *c, const float x, const float y)
371{
372 c->c.m_anchors[c->c.m_numAnchors].x = x;
373 c->c.m_anchors[c->c.m_numAnchors].y = y;
374 c->c.m_numAnchors++;
375 return 0;
376}
377
378// linear x linear y
379static inline void dt_draw_histogram_8_linxliny(cairo_t *cr, const uint32_t *hist, int32_t channels,
380 int32_t channel)
381{
382 cairo_move_to(cr, 0, 0);
383 for(int k = 0; k < 256; k++) cairo_line_to(cr, k, hist[channels * k + channel]);
384 cairo_line_to(cr, 255, 0);
385 cairo_close_path(cr);
386 cairo_fill(cr);
387}
388
389static inline void dt_draw_histogram_8_zoomed(cairo_t *cr, const uint32_t *hist, int32_t channels, int32_t channel,
390 const float zoom_factor, const float zoom_offset_x,
391 const float zoom_offset_y, gboolean linear)
392{
393 cairo_move_to(cr, -zoom_offset_x, -zoom_offset_y);
394 for(int k = 0; k < 256; k++)
395 {
396 const float value = ((float)hist[channels * k + channel] - zoom_offset_y) * zoom_factor;
397 const float hist_value = value < 0 ? 0.f : value;
398 cairo_line_to(cr, ((float)k - zoom_offset_x) * zoom_factor, linear ? hist_value : logf(1.0f + hist_value));
399 }
400 cairo_line_to(cr, (255.f - zoom_offset_x), -zoom_offset_y * zoom_factor);
401 cairo_close_path(cr);
402 cairo_fill(cr);
403}
404
405// log x (scalable) & linear y
406static inline void dt_draw_histogram_8_logxliny(cairo_t *cr, const uint32_t *hist, int32_t channels,
407 int32_t channel, float base_log)
408{
409 cairo_move_to(cr, 0, 0);
410 for(int k = 0; k < 256; k++)
411 {
412 const float x = logf((float)k / 255.0f * (base_log - 1.0f) + 1.0f) / logf(base_log) * 255.0f;
413 const float y = hist[channels * k + channel];
414 cairo_line_to(cr, x, y);
415 }
416 cairo_line_to(cr, 255, 0);
417 cairo_close_path(cr);
418 cairo_fill(cr);
419}
420
421// log x (scalable) & log y
422static inline void dt_draw_histogram_8_logxlogy(cairo_t *cr, const uint32_t *hist, int32_t channels,
423 int32_t channel, float base_log)
424{
425 cairo_move_to(cr, 0, 0);
426 for(int k = 0; k < 256; k++)
427 {
428 const float x = logf((float)k / 255.0f * (base_log - 1.0f) + 1.0f) / logf(base_log) * 255.0f;
429 const float y = logf(1.0 + hist[channels * k + channel]);
430 cairo_line_to(cr, x, y);
431 }
432 cairo_line_to(cr, 255, 0);
433 cairo_close_path(cr);
434 cairo_fill(cr);
435}
436
437// linear x log y
438static inline void dt_draw_histogram_8_linxlogy(cairo_t *cr, const uint32_t *hist, int32_t channels,
439 int32_t channel)
440{
441 cairo_move_to(cr, 0, 0);
442 for(int k = 0; k < 256; k++) cairo_line_to(cr, k, logf(1.0 + hist[channels * k + channel]));
443 cairo_line_to(cr, 255, 0);
444 cairo_close_path(cr);
445 cairo_fill(cr);
446}
447
448// log x (scalable)
449static inline void dt_draw_histogram_8_log_base(cairo_t *cr, const uint32_t *hist, int32_t channels,
450 int32_t channel, const gboolean linear, float base_log)
451{
452
453 if(linear) // linear y
454 dt_draw_histogram_8_logxliny(cr, hist, channels, channel, base_log);
455 else // log y
456 dt_draw_histogram_8_logxlogy(cr, hist, channels, channel, base_log);
457}
458
459// linear x
460static inline void dt_draw_histogram_8(cairo_t *cr, const uint32_t *hist, int32_t channels, int32_t channel,
461 const gboolean linear)
462{
463 if(linear) // linear y
464 dt_draw_histogram_8_linxliny(cr, hist, channels, channel);
465 else // log y
466 dt_draw_histogram_8_linxlogy(cr, hist, channels, channel);
467}
468
470static inline void dt_draw_cairo_to_gdk_pixbuf(uint8_t *data, unsigned int width, unsigned int height)
471{
472 for(uint32_t y = 0; y < height; y++)
473 for(uint32_t x = 0; x < width; x++)
474 {
475 uint8_t *r, *g, *b, *a, tmp;
476 r = &data[(y * width + x) * 4 + 0];
477 g = &data[(y * width + x) * 4 + 1];
478 b = &data[(y * width + x) * 4 + 2];
479 a = &data[(y * width + x) * 4 + 3];
480
481 // switch r and b
482 tmp = *r;
483 *r = *b;
484 *b = tmp;
485
486 // cairo uses premultiplied alpha, reverse that
487 if(*a != 0)
488 {
489 float inv_a = 255.0 / *a;
490 *r *= inv_a;
491 *g *= inv_a;
492 *b *= inv_a;
493 }
494 }
495}
496
497static inline void dt_cairo_perceptual_gradient(cairo_pattern_t *grad, double alpha)
498{
499 // Create a linear gradient from black to white
500 cairo_pattern_add_color_stop_rgba(grad, 0.0, 0.0, 0.0, 0.0, alpha);
501 cairo_pattern_add_color_stop_rgba(grad, 1.0, 1.0, 1.0, 1.0, alpha);
502}
503
504static inline GdkPixbuf *dt_draw_paint_to_pixbuf
505 (GtkWidget *widget, const guint pixbuf_size, const int flags,
506 void (*dtgtk_cairo_paint_fct)(cairo_t *cr, gint x, gint y, gint w, gint h, gint flags, void *data))
507{
508 GdkRGBA fg_color;
509 GtkStyleContext *context = gtk_widget_get_style_context(widget);
510 GtkStateFlags state = gtk_widget_get_state_flags(widget);
511 gtk_style_context_get_color(context, state, &fg_color);
512
513 const int dim = DT_PIXEL_APPLY_DPI(pixbuf_size);
514 cairo_surface_t *cst = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, dim, dim);
515 cairo_t *cr = cairo_create(cst);
516 gdk_cairo_set_source_rgba(cr, &fg_color);
517 (*dtgtk_cairo_paint_fct)(cr, 0, 0, dim, dim, flags, NULL);
518 cairo_destroy(cr);
519 uint8_t *data = cairo_image_surface_get_data(cst);
520 dt_draw_cairo_to_gdk_pixbuf(data, dim, dim);
521 const size_t size = (size_t)dim * dim * 4;
522 uint8_t *buf = (uint8_t *)malloc(size);
523 memcpy(buf, data, size);
524 GdkPixbuf *pixbuf = gdk_pixbuf_new_from_data(buf, GDK_COLORSPACE_RGB, TRUE, 8, dim, dim, dim * 4,
525 (GdkPixbufDestroyNotify)free, NULL);
526 cairo_surface_destroy(cst);
527 return pixbuf;
528}
529
530/***** SHAPES */
531
532// Helper that fills the current path with CAIRO_OPERATOR_CLEAR,
533// effectively erasing all drawings below,
534// but preserving the path for further drawing.
535static void _draw_fill_clear(cairo_t *cr, gboolean preserve)
536{
537 cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
538 if(preserve)
539 cairo_fill_preserve(cr);
540 else
541 cairo_fill(cr);
542 cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
543}
544
545static void _fill_clear(cairo_t *cr)
546{
548}
549
550static void _fill_clear_preserve(cairo_t *cr)
551{
553}
554
555static inline void dt_draw_set_dash_style(cairo_t *cr, dt_draw_dash_type_t type, float zoom_scale)
556{
557 // return early if no dash is needed
559 {
560 cairo_set_dash(cr, NULL, 0, 0);
561 return;
562 }
563
564 double pattern[2];
565
566 switch(type)
567 {
568 case DT_MASKS_NO_DASH:
569 pattern[0] = 0.0f;
570 pattern[1] = 0.0f;
571 break;
572
574 pattern[0] = DT_DRAW_SCALE_DASH / zoom_scale;
575 pattern[1] = DT_DRAW_SCALE_DASH / zoom_scale;
576 break;
577
579 pattern[0] = (DT_DRAW_SCALE_DASH * 0.25f) / zoom_scale;
580 pattern[1] = DT_DRAW_SCALE_DASH / zoom_scale;
581 break;
582
583 default:
584 cairo_set_dash(cr, NULL, 0, 0);
585 return;
586
587 }
588 const int pattern_len = 2;
589 cairo_set_dash(cr, pattern, pattern_len, 0);
590}
591
603static inline void dt_draw_node(cairo_t *cr, const gboolean square, const gboolean point_action, const gboolean selected, const float zoom_scale, const float x, const float y)
604{
605 cairo_save(cr);
606
607 const float node_width = (selected || point_action) ? DT_DRAW_RADIUS_NODE_SELECTED / zoom_scale : DT_DRAW_RADIUS_NODE / zoom_scale;
608 // square for corner nodes, circle for others (curve)
609 if(square)
610 {
611 const float pos = node_width * 0.7071f; // radius * sin(45°) to have the same diagonal as the circle
612 cairo_rectangle(cr, x - pos, y - pos, node_width * 2.f, node_width * 2.f);
613 }
614 else
615 cairo_arc(cr, x, y, node_width * 1.2f, 0.0, 2.0 * M_PI);
616
617 // Erase all drawings below
619
620 const float line_width = (point_action && selected) ? DT_DRAW_SIZE_LINE_SELECTED / zoom_scale
621 : DT_DRAW_SIZE_LINE / zoom_scale;
622
623 cairo_set_line_width(cr, line_width);
624 dt_draw_set_color_overlay(cr, TRUE, selected || point_action ? 1 : 0.8);
625 cairo_fill_preserve(cr);
626
627 // draw dark border
628 cairo_set_line_width(cr, (selected && !point_action) ? line_width * 2. : line_width);
630 cairo_stroke(cr);
631
633 {
634 const float debug_radius = DT_GUI_MOUSE_EFFECT_RADIUS_SCALED;
635 cairo_arc(cr, x, y, debug_radius, 0.0, 2.0 * M_PI);
636 cairo_set_line_width(cr, line_width);
637 cairo_set_source_rgba(cr, 0.0, 1.0, 0.0, 1.0);
638 cairo_stroke(cr);
639 }
640
641 cairo_restore(cr);
642}
643
654static inline void dt_draw_handle(cairo_t *cr, const float pt[2], const float zoom_scale,
655 const float handle[2], const gboolean selected, const gboolean square)
656{
657 cairo_save(cr);
658
659
660 // Draw only if the line is long enough
661 // and shorten the line by the size of the nodes so it does not overlap with them
662 //float shorten = 0; //(DT_DRAW_RADIUS_NODE / zoom_scale) * 0.5f;
663 //float f = shorten / tail_len;
664 if(pt)
665 {
666 float delta_x = handle[0] - pt[0];
667 float delta_y = handle[1] - pt[1];
668 float start_x = pt[0] + delta_x;
669 float start_y = pt[1] + delta_y;
670 float end_x = handle[0] - delta_x;
671 float end_y = handle[1] - delta_y;
672 cairo_move_to(cr, start_x, start_y);
673 cairo_line_to(cr, end_x, end_y);
674
675 cairo_set_line_width(cr, DT_DRAW_SIZE_LINE_HIGHLIGHT * 0.6 / zoom_scale);
677 cairo_stroke_preserve(cr);
678 cairo_set_line_width(cr, DT_DRAW_SIZE_LINE * 0.6 / zoom_scale);
680 cairo_stroke(cr);
681 }
682
683 // Draw the control handle (1/4 smaller than a node)
684 const float handle_radius = 0.75 * (selected ? DT_DRAW_RADIUS_NODE_SELECTED / zoom_scale
685 : DT_DRAW_RADIUS_NODE / zoom_scale);
686
687 if(square)
688 {
689 const float square_width = handle_radius * 0.7071f; // handle_radius * sin(45°) to have the same diagonal as the circle
690 cairo_rectangle(cr, handle[0] - square_width, handle[1] - square_width, square_width * 2.f, square_width * 2.f);
691 }
692 else
693 cairo_arc(cr, handle[0], handle[1], handle_radius, 0, 2.0 * M_PI);
694
695 const float line_width_dark = selected
697 : (DT_DRAW_SIZE_LINE_HIGHLIGHT / zoom_scale);
698 const float line_width_bright = selected
699 ? (DT_DRAW_SIZE_LINE_SELECTED / zoom_scale)
700 : (DT_DRAW_SIZE_LINE / zoom_scale);
701
702 // OUTLINE (dark)
703 cairo_set_line_width(cr, line_width_dark * 1.125);
705 cairo_stroke_preserve(cr);
706 // NORMAL (bright)
707 cairo_set_line_width(cr, line_width_bright * 1.5);
709 cairo_stroke_preserve(cr);
710 // Erase all drawings below
711 _fill_clear(cr);
712
713
714 // uncomment this part if you want to see "real" control points
715 /*cairo_move_to(cr, gpt->points[n*6+2],gpt->points[n*6+3]);
716 cairo_line_to(cr, gpt->points[n*6],gpt->points[n*6+1]);
717 cairo_stroke(cr);
718 cairo_move_to(cr, gpt->points[n*6+2],gpt->points[n*6+3]);
719 cairo_line_to(cr, gpt->points[n*6+4],gpt->points[n*6+5]);
720 cairo_stroke(cr);*/
721
722 cairo_restore(cr);
723}
724
725typedef void (*shape_draw_function_t)(cairo_t *cr, const float *points, const int points_count, const int nb, const gboolean border, const gboolean source);
726
740static inline 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,
741 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)
742{
743 cairo_save(cr);
744
745 cairo_set_line_cap(cr, line_cap);
746 // Are we drawing a border ?
747 const gboolean border = (dash_type != DT_MASKS_NO_DASH);
748
749 // Draw the shape from the integrated function if any
750 if(points && points_count >= 2 && draw_shape_func)
751 (*draw_shape_func)(cr, points, points_count, nb, border, FALSE);
752
753 const dt_draw_dash_type_t dash = (dash_type && !source)
754 ? dash_type : DT_MASKS_NO_DASH;
755
756 dt_draw_set_dash_style(cr, dash, zoom_scale);
757
758 const float line_width_dark = selected
760 : DT_DRAW_SIZE_LINE_HIGHLIGHT / zoom_scale;
761 const float line_width_bright = selected
762 ? DT_DRAW_SIZE_LINE_SELECTED / zoom_scale
763 : DT_DRAW_SIZE_LINE / zoom_scale;
764
765 // OUTLINE (dark)
766 cairo_set_line_width(cr, line_width_dark);
767 dt_draw_set_color_overlay(cr, FALSE, dash_type ? 0.3f : 0.9f);
768 cairo_stroke_preserve(cr);
769
770 // NORMAL (bright)
771 cairo_set_line_width(cr, line_width_bright);
773 cairo_stroke(cr);
774
775 cairo_restore(cr);
776}
777
787static inline void dt_draw_stroke_line(const dt_draw_dash_type_t dash_type, const gboolean source, cairo_t *cr,
788 const gboolean selected, const float zoom_scale, const cairo_line_cap_t line_cap)
789{
790 dt_draw_shape_lines(dash_type, source, cr, 0, selected, zoom_scale, NULL, 0, NULL, line_cap);
791}
792
793static void _draw_arrow_head(cairo_t *cr, const float arrow[2], const float arrow_x_a, const float arrow_y_a,
794 const float arrow_x_b, const float arrow_y_b)
795{
796 //draw the arrow head
797 cairo_move_to(cr, arrow_x_a, arrow_y_a);
798 cairo_line_to(cr, arrow[0], arrow[1]);
799 cairo_line_to(cr, arrow_x_b, arrow_y_b);
800 // close the arrow head
801 cairo_close_path(cr);
802}
803
804static void _draw_arrow_tail(cairo_t *cr, const float arrow_bud_x, const float arrow_bud_y,
805 const float tail[2], const gboolean draw_tail)
806{
807 if(draw_tail) dt_draw_line(cr, arrow_bud_x, arrow_bud_y, tail[0], tail[1]);
808}
809
823static inline void dt_draw_arrow(cairo_t *cr, const float zoom_scale,const gboolean selected, const gboolean draw_tail,
824 const dt_draw_dash_type_t dash_style, const float arrow[2], const float tail[2], const float angle)
825{
826 // calculate the coordinates of the two base points of the arrow head
827 const float arrow_x_a = arrow[0] + (DT_DRAW_SCALE_ARROW / zoom_scale) * cosf(angle + (0.4f));
828 const float arrow_y_a = arrow[1] + (DT_DRAW_SCALE_ARROW / zoom_scale) * sinf(angle + (0.4f));
829 const float arrow_x_b = arrow[0] + (DT_DRAW_SCALE_ARROW / zoom_scale) * cosf(angle - (0.4f));
830 const float arrow_y_b = arrow[1] + (DT_DRAW_SCALE_ARROW / zoom_scale) * sinf(angle - (0.4f));
831 // Calculate the coordinates of the arrow base's midpoint
832 const float arrow_bud_x = (arrow_x_a + arrow_x_b) * 0.5f;
833 const float arrow_bud_y = (arrow_y_a + arrow_y_b) * 0.5f;
834
835 cairo_save(cr);
836 cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND);
837
838 // we need to draw the arrow head and tail in two passes to get the dark and bright effect correctly
839
840 // dark
841 {
842 // arrow head
843 _draw_arrow_head(cr, arrow, arrow_x_a, arrow_y_a, arrow_x_b, arrow_y_b);
844 // Erase all drawings below
846
849
850 if(selected)
851 cairo_set_line_width(cr, 0.8f * DT_DRAW_SIZE_LINE_HIGHLIGHT_SELECTED / zoom_scale);
852 else
853 cairo_set_line_width(cr, 0.8f * DT_DRAW_SIZE_LINE_HIGHLIGHT / zoom_scale);
854 cairo_stroke(cr);
855
856 // arrow tail
857 _draw_arrow_tail(cr, arrow_bud_x, arrow_bud_y, tail, draw_tail);
858 dt_draw_set_dash_style(cr, dash_style, zoom_scale);
860 if(selected)
861 cairo_set_line_width(cr, DT_DRAW_SIZE_LINE_HIGHLIGHT_SELECTED / zoom_scale);
862 else
863 cairo_set_line_width(cr, DT_DRAW_SIZE_LINE_HIGHLIGHT / zoom_scale);
864 cairo_stroke(cr);
865 }
866
867 // bright
868 {
869 // arrow head
870 _draw_arrow_head(cr, arrow, arrow_x_a, arrow_y_a, arrow_x_b, arrow_y_b);
871 // erase all drawings below
872 cairo_set_source_rgba(cr, 0., 0., 0., 0.);
873 cairo_fill_preserve(cr);
874
877 if(selected)
878 cairo_set_line_width(cr, (2 * DT_DRAW_SIZE_LINE) / zoom_scale);
879 else
880 cairo_set_line_width(cr, (DT_DRAW_SIZE_LINE) / zoom_scale);
881 cairo_stroke(cr);
882
883 // arrow tail
884 _draw_arrow_tail(cr, arrow_bud_x, arrow_bud_y, tail, draw_tail);
885 dt_draw_set_dash_style(cr, dash_style, zoom_scale);
887 if(selected)
888 cairo_set_line_width(cr, (3 * DT_DRAW_SIZE_LINE) / zoom_scale);
889 else
890 cairo_set_line_width(cr, (2 * DT_DRAW_SIZE_LINE) / zoom_scale);
891 cairo_stroke(cr);
892 }
893 cairo_restore(cr);
894}
895
896static inline void dt_draw_cross(cairo_t *cr, const float zoom_scale, const float x, const float y)
897{
898 const float dx = DT_DRAW_SIZE_CROSS / zoom_scale;
899 const float dy = DT_DRAW_SIZE_CROSS / zoom_scale;
900 cairo_save(cr);
901
902 cairo_set_line_cap(cr, CAIRO_LINE_CAP_SQUARE);
904 cairo_set_line_width(cr, DT_DRAW_SIZE_LINE_HIGHLIGHT / zoom_scale);
906
907 cairo_move_to(cr, x + dx, y);
908 cairo_line_to(cr, x - dx, y);
909 cairo_move_to(cr, x, y + dy);
910 cairo_line_to(cr, x, y - dy);
911 cairo_stroke_preserve(cr);
912
913 cairo_set_line_width(cr, DT_DRAW_SIZE_LINE / zoom_scale);
915 cairo_stroke(cr);
916
917 cairo_restore(cr);
918}
919
920static inline void dt_draw_source_shape(cairo_t *cr, const float zoom_scale, const gboolean selected,
921 const float *source_pts, const int source_pts_count, const int nodes_nb, const shape_draw_function_t *draw_shape_func)
922{
923 cairo_save(cr);
924
925 cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND);
927
928 if(draw_shape_func)
929 (*draw_shape_func)(cr, source_pts, source_pts_count, nodes_nb, FALSE, TRUE);
930
931 //dark line
932 if(selected)
933 cairo_set_line_width(cr, DT_DRAW_SIZE_LINE_HIGHLIGHT_SELECTED / zoom_scale);
934 else
935 cairo_set_line_width(cr, DT_DRAW_SIZE_LINE_HIGHLIGHT / zoom_scale);
937 cairo_stroke_preserve(cr);
938
939 //bright line
940 if(selected)
941 cairo_set_line_width(cr, DT_DRAW_SIZE_LINE_SELECTED / zoom_scale);
942 else
943 cairo_set_line_width(cr, (1.5f * DT_DRAW_SIZE_LINE) / zoom_scale);
945 cairo_stroke(cr);
946
947 cairo_restore(cr);
948}
949
950static inline GdkPixbuf *dt_draw_get_pixbuf_from_cairo(DTGTKCairoPaintIconFunc paint, const int width, const int height)
951{
952 cairo_surface_t *cst = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
953 cairo_t *cr = cairo_create(cst);
955 paint(cr, 0, 0, width, height, 0, NULL);
956 cairo_destroy(cr);
957 guchar *data = cairo_image_surface_get_data(cst);
959 return gdk_pixbuf_new_from_data(data, GDK_COLORSPACE_RGB, TRUE, 8, width, height,
960 cairo_image_surface_get_stride(cst), NULL, NULL);
961}
962
963#ifdef __cplusplus
964}
965#endif
966
967// clang-format off
968// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
969// vim: shiftwidth=2 expandtab tabstop=2 cindent
970// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
971// clang-format on
#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 h
Definition colorspaces_inline_conversions.h:1366
const float c
Definition colorspaces_inline_conversions.h:1365
const float g
Definition colorspaces_inline_conversions.h:925
const float d
Definition colorspaces_inline_conversions.h:931
static const float const float const float min
Definition colorspaces_inline_conversions.h:667
const float r
Definition colorspaces_inline_conversions.h:1324
const float max
Definition colorspaces_inline_conversions.h:721
const float b
Definition colorspaces_inline_conversions.h:1326
const float a
Definition colorspaces_inline_conversions.h:1292
const float top
Definition colorspaces_inline_conversions.h:672
typedef void((*dt_cache_allocate_t)(void *userdata, dt_cache_entry_t *entry))
int type
Definition common/metadata.c:62
float * interpolate_set(int n, float x[], float y[], unsigned int type)
Definition curve_tools.c:514
int CurveDataSample(CurveData *curve, CurveSample *sample)
Definition curve_tools.c:677
float interpolate_val(int n, float x[], float xval, float y[], float tangents[], unsigned int type)
Definition curve_tools.c:519
darktable_t darktable
Definition darktable.c:178
@ DT_DEBUG_MASKS
Definition darktable.h:647
#define dt_free(ptr)
Definition darktable.h:380
static const dt_aligned_pixel_simd_t value
Definition darktable.h:501
static float dt_curve_to_mouse(const float x, const float zoom_factor, const float offset)
Definition draw.h:158
#define DT_DRAW_SCALE_DASH
Definition draw.h:79
#define DT_DRAW_SIZE_LINE
Definition draw.h:72
static void _draw_fill_clear(cairo_t *cr, gboolean preserve)
Definition draw.h:535
#define DT_DRAW_RADIUS_NODE_SELECTED
Definition draw.h:84
static void dt_draw_set_dash_style(cairo_t *cr, dt_draw_dash_type_t type, float zoom_scale)
Definition draw.h:555
static GdkPixbuf * dt_draw_paint_to_pixbuf(GtkWidget *widget, const guint pixbuf_size, const int flags, void(*dtgtk_cairo_paint_fct)(cairo_t *cr, gint x, gint y, gint w, gint h, gint flags, void *data))
Definition draw.h:505
static void dt_draw_curve_calc_values(dt_draw_curve_t *c, const float min, const float max, const int res, float *x, float *y)
Definition draw.h:315
static void dt_draw_stroke_line(const dt_draw_dash_type_t dash_type, const gboolean source, cairo_t *cr, const gboolean selected, const float zoom_scale, const cairo_line_cap_t line_cap)
Stroke a line with style.
Definition draw.h:787
static void dt_draw_horizontal_lines(cairo_t *cr, const int num, const int left, const int top, const int right, const int bottom)
Definition draw.h:255
static void dt_draw_histogram_8_zoomed(cairo_t *cr, const uint32_t *hist, int32_t channels, int32_t channel, const float zoom_factor, const float zoom_offset_x, const float zoom_offset_y, gboolean linear)
Definition draw.h:389
static void dt_draw_handle(cairo_t *cr, const float pt[2], const float zoom_scale, const float handle[2], const gboolean selected, const gboolean square)
Draw a control handle attached to a point with a tail between the node and the handle.
Definition draw.h:654
#define DT_DRAW_SIZE_LINE_HIGHLIGHT
Definition draw.h:74
static void dt_draw_cross(cairo_t *cr, const float zoom_scale, const float x, const float y)
Definition draw.h:896
#define DT_DRAW_SIZE_LINE_SELECTED
Definition draw.h:73
static void dt_draw_histogram_8_logxlogy(cairo_t *cr, const uint32_t *hist, int32_t channels, int32_t channel, float base_log)
Definition draw.h:422
static void dt_draw_cairo_to_gdk_pixbuf(uint8_t *data, unsigned int width, unsigned int height)
Definition draw.h:470
static void dt_draw_histogram_8_linxlogy(cairo_t *cr, const uint32_t *hist, int32_t channels, int32_t channel)
Definition draw.h:438
static float dt_log_scale_axis(const float x, const float base)
Definition draw.h:188
static void _fill_clear_preserve(cairo_t *cr)
Definition draw.h:550
static void dt_draw_set_color_overlay(cairo_t *cr, gboolean bright, double alpha)
Definition draw.h:106
static void dt_draw_line(cairo_t *cr, float left, float top, float right, float bottom)
Definition draw.h:137
static void dt_draw_curve_smaple_values(dt_draw_curve_t *c, const float min, const float max, const int res, float *x, float *y)
Definition draw.h:296
static void dt_draw_histogram_8_linxliny(cairo_t *cr, const uint32_t *hist, int32_t channels, int32_t channel)
Definition draw.h:379
static void dt_draw_vertical_lines(cairo_t *cr, const int num, const int left, const int top, const int right, const int bottom)
Definition draw.h:242
static void dt_draw_grid(cairo_t *cr, const int num, const int left, const int top, const int right, const int bottom)
Definition draw.h:143
static void dt_draw_semilog_y_grid(cairo_t *cr, const int num, const int left, const int top, const int right, const int bottom, const float base)
Definition draw.h:225
static float dt_draw_curve_calc_value(dt_draw_curve_t *c, const float x)
Definition draw.h:351
static void dt_cairo_perceptual_gradient(cairo_pattern_t *grad, double alpha)
Definition draw.h:497
dt_draw_dash_type_t
Definition draw.h:92
@ DT_MASKS_DASH_STICK
Definition draw.h:94
@ DT_MASKS_DASH_ROUND
Definition draw.h:95
@ DT_MASKS_NO_DASH
Definition draw.h:93
static void dt_draw_star(cairo_t *cr, float x, float y, float r1, float r2)
Definition draw.h:120
static void dt_draw_curve_calc_values_V2_nonperiodic(dt_draw_curve_t *c, const float min, const float max, const int res, float *x, float *y)
Definition draw.h:324
#define DT_DRAW_SCALE_ARROW
Definition draw.h:80
static void dt_draw_curve_destroy(dt_draw_curve_t *c)
Definition draw.h:284
static void dt_draw_curve_calc_values_V2(dt_draw_curve_t *c, const float min, const float max, const int res, float *x, float *y, const gboolean periodic)
Definition draw.h:342
#define DT_DRAW_SIZE_CROSS
Definition draw.h:76
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
static void dt_draw_histogram_8_log_base(cairo_t *cr, const uint32_t *hist, int32_t channels, int32_t channel, const gboolean linear, float base_log)
Definition draw.h:449
#define DT_DRAW_RADIUS_NODE
Definition draw.h:83
static void dt_draw_curve_set_point(dt_draw_curve_t *c, const int num, const float x, const float y)
Definition draw.h:290
static void dt_draw_arrow(cairo_t *cr, const float zoom_scale, const gboolean selected, const gboolean draw_tail, const dt_draw_dash_type_t dash_style, const float arrow[2], const float tail[2], const float angle)
Draw an arrow with head and, if needed, tail. The length of the arrow head is defined by DT_DRAW_SCAL...
Definition draw.h:823
static int dt_draw_curve_add_point(dt_draw_curve_t *c, const float x, const float y)
Definition draw.h:370
static void dt_draw_histogram_8_logxliny(cairo_t *cr, const uint32_t *hist, int32_t channels, int32_t channel, float base_log)
Definition draw.h:406
static GdkPixbuf * dt_draw_get_pixbuf_from_cairo(DTGTKCairoPaintIconFunc paint, const int width, const int height)
Definition draw.h:950
static void _fill_clear(cairo_t *cr)
Definition draw.h:545
#define DT_DRAW_SIZE_LINE_HIGHLIGHT_SELECTED
Definition draw.h:75
static void dt_draw_semilog_x_grid(cairo_t *cr, const int num, const int left, const int top, const int right, const int bottom, const float base)
Definition draw.h:209
static void dt_draw_histogram_8(cairo_t *cr, const uint32_t *hist, int32_t channels, int32_t channel, const gboolean linear)
Definition draw.h:460
static dt_draw_curve_t * dt_draw_curve_new(const float min, const float max, unsigned int type)
Definition draw.h:268
#define M_PI
Definition draw.h:64
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
static void dt_draw_loglog_grid(cairo_t *cr, const int num, const int left, const int top, const int right, const int bottom, const float base)
Definition draw.h:193
static void _draw_arrow_head(cairo_t *cr, const float arrow[2], const float arrow_x_a, const float arrow_y_a, const float arrow_x_b, const float arrow_y_b)
Definition draw.h:793
static void dt_draw_curve_calc_values_V2_periodic(dt_draw_curve_t *c, const float min, const float max, const int res, float *x, float *y)
Definition draw.h:333
static void dt_draw_source_shape(cairo_t *cr, const float zoom_scale, const gboolean selected, const float *source_pts, const int source_pts_count, const int nodes_nb, const shape_draw_function_t *draw_shape_func)
Definition draw.h:920
static void dt_draw_grid_zoomed(cairo_t *cr, const int num, const float left, const float top, const float right, const float bottom, const float width, const float height, const float zoom_factor, const float zoom_offset_x, const float zoom_offset_y)
Definition draw.h:164
static void dt_draw_node(cairo_t *cr, const gboolean square, const gboolean point_action, const gboolean selected, const float zoom_scale, const float x, const float y)
Draw an node point of a mask.
Definition draw.h:603
static void _draw_arrow_tail(cairo_t *cr, const float arrow_bud_x, const float arrow_bud_y, const float tail[2], const gboolean draw_tail)
Definition draw.h:804
void(* DTGTKCairoPaintIconFunc)(cairo_t *cr, gint x, gint y, gint w, gint h, gint flags, void *data)
Definition dtgtk/paint.h:74
void dt_gui_gtk_set_source_rgba(cairo_t *cr, dt_gui_color_t color, float opacity_coef)
Definition gtk.c:369
@ DT_GUI_COLOR_BUTTON_FG
Definition gtk.h:107
#define DT_GUI_MOUSE_EFFECT_RADIUS_SCALED
Definition gtk.h:71
#define DT_PIXEL_APPLY_DPI(value)
Definition gtk.h:75
static const float x
Definition iop_profile.h:239
@ linear
Definition lightroom.c:368
size_t size
Definition mipmap_cache.c:3
dt_mipmap_buffer_dsc_flags flags
Definition mipmap_cache.c:4
struct _GtkWidget GtkWidget
Definition splash.h:29
int CurveDataSampleV2Periodic(CurveData *curve, CurveSample *sample)
Definition splines.cpp:847
int CurveDataSampleV2(CurveData *curve, CurveSample *sample)
Definition splines.cpp:751
Definition curve_tools.h:64
Definition curve_tools.h:84
unsigned int m_samplingRes
Definition curve_tools.h:86
struct dt_gui_gtk_t * gui
Definition darktable.h:703
int32_t unmuted
Definition darktable.h:688
Definition draw.h:100
CurveSample csample
Definition draw.h:102
CurveData c
Definition draw.h:101
double overlay_contrast
Definition gtk.h:160
double overlay_red
Definition gtk.h:160
double overlay_green
Definition gtk.h:160
double overlay_blue
Definition gtk.h:160
#define MIN(a, b)
Definition thinplate.c:32
#define MAX(a, b)
Definition thinplate.c:29