1 /* GIMP - The GNU Image Manipulation Program
2 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
3 *
4 * gimp-layer-modes.c
5 * Copyright (C) 2017 Michael Natterer <mitch@gimp.org>
6 * Øyvind Kolås <pippin@gimp.org>
7 *
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 */
21
22 #include "config.h"
23
24 #include <glib-object.h>
25 #include <gegl.h>
26
27 #include "../operations-types.h"
28
29 #include "gegl/gimp-babl.h"
30
31 #include "gimpoperationlayermode.h"
32 #include "gimpoperationlayermode-blend.h"
33
34 #include "gimp-layer-modes.h"
35
36
37 typedef struct _GimpLayerModeInfo GimpLayerModeInfo;
38
39 struct _GimpLayerModeInfo
40 {
41 GimpLayerMode layer_mode;
42 const gchar *op_name;
43 GimpLayerModeBlendFunc blend_function;
44 GimpLayerModeFlags flags;
45 GimpLayerModeContext context;
46 GimpLayerCompositeMode paint_composite_mode;
47 GimpLayerCompositeMode composite_mode;
48 GimpLayerColorSpace composite_space;
49 GimpLayerColorSpace blend_space;
50 };
51
52
53 /* static variables */
54
55 static const GimpLayerModeInfo layer_mode_infos[] =
56 {
57 { GIMP_LAYER_MODE_NORMAL_LEGACY,
58
59 .op_name = "gimp:normal",
60 .flags = GIMP_LAYER_MODE_FLAG_LEGACY |
61 GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE |
62 GIMP_LAYER_MODE_FLAG_COMPOSITE_SPACE_IMMUTABLE |
63 GIMP_LAYER_MODE_FLAG_COMPOSITE_MODE_IMMUTABLE |
64 GIMP_LAYER_MODE_FLAG_TRIVIAL,
65 .context = GIMP_LAYER_MODE_CONTEXT_ALL,
66 .paint_composite_mode = GIMP_LAYER_COMPOSITE_UNION,
67 .composite_mode = GIMP_LAYER_COMPOSITE_UNION,
68 .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL
69 },
70
71 { GIMP_LAYER_MODE_DISSOLVE,
72
73 .op_name = "gimp:dissolve",
74 .flags = GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE |
75 GIMP_LAYER_MODE_FLAG_COMPOSITE_SPACE_IMMUTABLE |
76 GIMP_LAYER_MODE_FLAG_TRIVIAL,
77 .context = GIMP_LAYER_MODE_CONTEXT_ALL,
78 .paint_composite_mode = GIMP_LAYER_COMPOSITE_UNION,
79 .composite_mode = GIMP_LAYER_COMPOSITE_UNION
80 },
81
82 { GIMP_LAYER_MODE_BEHIND_LEGACY,
83
84 .op_name = "gimp:behind",
85 .flags = GIMP_LAYER_MODE_FLAG_LEGACY |
86 GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE |
87 GIMP_LAYER_MODE_FLAG_COMPOSITE_SPACE_IMMUTABLE |
88 GIMP_LAYER_MODE_FLAG_COMPOSITE_MODE_IMMUTABLE,
89 .context = GIMP_LAYER_MODE_CONTEXT_PAINT |
90 GIMP_LAYER_MODE_CONTEXT_FILTER,
91 .paint_composite_mode = GIMP_LAYER_COMPOSITE_UNION,
92 .composite_mode = GIMP_LAYER_COMPOSITE_UNION,
93 .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL
94 },
95
96 { GIMP_LAYER_MODE_MULTIPLY_LEGACY,
97
98 .op_name = "gimp:multiply-legacy",
99 .flags = GIMP_LAYER_MODE_FLAG_LEGACY |
100 GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE |
101 GIMP_LAYER_MODE_FLAG_COMPOSITE_SPACE_IMMUTABLE |
102 GIMP_LAYER_MODE_FLAG_COMPOSITE_MODE_IMMUTABLE,
103 .context = GIMP_LAYER_MODE_CONTEXT_ALL,
104 .paint_composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
105 .composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
106 .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL,
107 .blend_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL
108 },
109
110 { GIMP_LAYER_MODE_SCREEN_LEGACY,
111
112 .op_name = "gimp:screen-legacy",
113 .flags = GIMP_LAYER_MODE_FLAG_LEGACY |
114 GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE |
115 GIMP_LAYER_MODE_FLAG_COMPOSITE_SPACE_IMMUTABLE |
116 GIMP_LAYER_MODE_FLAG_COMPOSITE_MODE_IMMUTABLE,
117 .context = GIMP_LAYER_MODE_CONTEXT_ALL,
118 .paint_composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
119 .composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
120 .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL,
121 .blend_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL
122 },
123
124 { GIMP_LAYER_MODE_OVERLAY_LEGACY,
125
126 .op_name = "gimp:softlight-legacy",
127 .flags = GIMP_LAYER_MODE_FLAG_LEGACY |
128 GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE |
129 GIMP_LAYER_MODE_FLAG_COMPOSITE_SPACE_IMMUTABLE |
130 GIMP_LAYER_MODE_FLAG_COMPOSITE_MODE_IMMUTABLE,
131 .context = GIMP_LAYER_MODE_CONTEXT_ALL,
132 .paint_composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
133 .composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
134 .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL,
135 .blend_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL
136 },
137
138 { GIMP_LAYER_MODE_DIFFERENCE_LEGACY,
139
140 .op_name = "gimp:difference-legacy",
141 .flags = GIMP_LAYER_MODE_FLAG_LEGACY |
142 GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE |
143 GIMP_LAYER_MODE_FLAG_COMPOSITE_SPACE_IMMUTABLE |
144 GIMP_LAYER_MODE_FLAG_COMPOSITE_MODE_IMMUTABLE,
145 .context = GIMP_LAYER_MODE_CONTEXT_ALL,
146 .paint_composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
147 .composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
148 .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL,
149 .blend_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL
150 },
151
152 { GIMP_LAYER_MODE_ADDITION_LEGACY,
153
154 .op_name = "gimp:addition-legacy",
155 .flags = GIMP_LAYER_MODE_FLAG_LEGACY |
156 GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE |
157 GIMP_LAYER_MODE_FLAG_COMPOSITE_SPACE_IMMUTABLE |
158 GIMP_LAYER_MODE_FLAG_COMPOSITE_MODE_IMMUTABLE,
159 .context = GIMP_LAYER_MODE_CONTEXT_ALL,
160 .paint_composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
161 .composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
162 .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL,
163 .blend_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL
164 },
165
166 { GIMP_LAYER_MODE_SUBTRACT_LEGACY,
167
168 .op_name = "gimp:subtract-legacy",
169 .flags = GIMP_LAYER_MODE_FLAG_LEGACY |
170 GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE |
171 GIMP_LAYER_MODE_FLAG_COMPOSITE_SPACE_IMMUTABLE |
172 GIMP_LAYER_MODE_FLAG_COMPOSITE_MODE_IMMUTABLE,
173 .context = GIMP_LAYER_MODE_CONTEXT_ALL,
174 .paint_composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
175 .composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
176 .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL,
177 .blend_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL
178 },
179
180 { GIMP_LAYER_MODE_DARKEN_ONLY_LEGACY,
181
182 .op_name = "gimp:darken-only-legacy",
183 .flags = GIMP_LAYER_MODE_FLAG_LEGACY |
184 GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE |
185 GIMP_LAYER_MODE_FLAG_COMPOSITE_SPACE_IMMUTABLE |
186 GIMP_LAYER_MODE_FLAG_COMPOSITE_MODE_IMMUTABLE,
187 .context = GIMP_LAYER_MODE_CONTEXT_ALL,
188 .paint_composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
189 .composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
190 .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL,
191 .blend_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL
192 },
193
194 { GIMP_LAYER_MODE_LIGHTEN_ONLY_LEGACY,
195
196 .op_name = "gimp:lighten-only-legacy",
197 .flags = GIMP_LAYER_MODE_FLAG_LEGACY |
198 GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE |
199 GIMP_LAYER_MODE_FLAG_COMPOSITE_SPACE_IMMUTABLE |
200 GIMP_LAYER_MODE_FLAG_COMPOSITE_MODE_IMMUTABLE,
201 .context = GIMP_LAYER_MODE_CONTEXT_ALL,
202 .paint_composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
203 .composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
204 .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL,
205 .blend_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL
206 },
207
208 { GIMP_LAYER_MODE_HSV_HUE_LEGACY,
209
210 .op_name = "gimp:hsv-hue-legacy",
211 .flags = GIMP_LAYER_MODE_FLAG_LEGACY |
212 GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE |
213 GIMP_LAYER_MODE_FLAG_COMPOSITE_SPACE_IMMUTABLE |
214 GIMP_LAYER_MODE_FLAG_COMPOSITE_MODE_IMMUTABLE,
215 .context = GIMP_LAYER_MODE_CONTEXT_ALL,
216 .paint_composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
217 .composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
218 .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL,
219 .blend_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL
220 },
221
222 { GIMP_LAYER_MODE_HSV_SATURATION_LEGACY,
223
224 .op_name = "gimp:hsv-saturation-legacy",
225 .flags = GIMP_LAYER_MODE_FLAG_LEGACY |
226 GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE |
227 GIMP_LAYER_MODE_FLAG_COMPOSITE_SPACE_IMMUTABLE |
228 GIMP_LAYER_MODE_FLAG_COMPOSITE_MODE_IMMUTABLE,
229 .context = GIMP_LAYER_MODE_CONTEXT_ALL,
230 .paint_composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
231 .composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
232 .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL,
233 .blend_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL
234 },
235
236 { GIMP_LAYER_MODE_HSL_COLOR_LEGACY,
237
238 .op_name = "gimp:hsl-color-legacy",
239 .flags = GIMP_LAYER_MODE_FLAG_LEGACY |
240 GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE |
241 GIMP_LAYER_MODE_FLAG_COMPOSITE_SPACE_IMMUTABLE |
242 GIMP_LAYER_MODE_FLAG_COMPOSITE_MODE_IMMUTABLE,
243 .context = GIMP_LAYER_MODE_CONTEXT_ALL,
244 .paint_composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
245 .composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
246 .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL,
247 .blend_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL
248 },
249
250 { GIMP_LAYER_MODE_HSV_VALUE_LEGACY,
251
252 .op_name = "gimp:hsv-value-legacy",
253 .flags = GIMP_LAYER_MODE_FLAG_LEGACY |
254 GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE |
255 GIMP_LAYER_MODE_FLAG_COMPOSITE_SPACE_IMMUTABLE |
256 GIMP_LAYER_MODE_FLAG_COMPOSITE_MODE_IMMUTABLE,
257 .context = GIMP_LAYER_MODE_CONTEXT_ALL,
258 .paint_composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
259 .composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
260 .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL,
261 .blend_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL
262 },
263
264 { GIMP_LAYER_MODE_DIVIDE_LEGACY,
265
266 .op_name = "gimp:divide-legacy",
267 .flags = GIMP_LAYER_MODE_FLAG_LEGACY |
268 GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE |
269 GIMP_LAYER_MODE_FLAG_COMPOSITE_SPACE_IMMUTABLE |
270 GIMP_LAYER_MODE_FLAG_COMPOSITE_MODE_IMMUTABLE,
271 .context = GIMP_LAYER_MODE_CONTEXT_ALL,
272 .paint_composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
273 .composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
274 .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL,
275 .blend_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL
276 },
277
278 { GIMP_LAYER_MODE_DODGE_LEGACY,
279
280 .op_name = "gimp:dodge-legacy",
281 .flags = GIMP_LAYER_MODE_FLAG_LEGACY |
282 GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE |
283 GIMP_LAYER_MODE_FLAG_COMPOSITE_SPACE_IMMUTABLE |
284 GIMP_LAYER_MODE_FLAG_COMPOSITE_MODE_IMMUTABLE,
285 .context = GIMP_LAYER_MODE_CONTEXT_ALL,
286 .paint_composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
287 .composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
288 .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL,
289 .blend_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL
290 },
291
292 { GIMP_LAYER_MODE_BURN_LEGACY,
293
294 .op_name = "gimp:burn-legacy",
295 .flags = GIMP_LAYER_MODE_FLAG_LEGACY |
296 GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE |
297 GIMP_LAYER_MODE_FLAG_COMPOSITE_SPACE_IMMUTABLE |
298 GIMP_LAYER_MODE_FLAG_COMPOSITE_MODE_IMMUTABLE,
299 .context = GIMP_LAYER_MODE_CONTEXT_ALL,
300 .paint_composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
301 .composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
302 .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL,
303 .blend_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL
304 },
305
306 { GIMP_LAYER_MODE_HARDLIGHT_LEGACY,
307
308 .op_name = "gimp:hardlight-legacy",
309 .flags = GIMP_LAYER_MODE_FLAG_LEGACY |
310 GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE |
311 GIMP_LAYER_MODE_FLAG_COMPOSITE_SPACE_IMMUTABLE |
312 GIMP_LAYER_MODE_FLAG_COMPOSITE_MODE_IMMUTABLE,
313 .context = GIMP_LAYER_MODE_CONTEXT_ALL,
314 .paint_composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
315 .composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
316 .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL,
317 .blend_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL
318 },
319
320 { GIMP_LAYER_MODE_SOFTLIGHT_LEGACY,
321
322 .op_name = "gimp:softlight-legacy",
323 .flags = GIMP_LAYER_MODE_FLAG_LEGACY |
324 GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE |
325 GIMP_LAYER_MODE_FLAG_COMPOSITE_SPACE_IMMUTABLE |
326 GIMP_LAYER_MODE_FLAG_COMPOSITE_MODE_IMMUTABLE,
327 .context = GIMP_LAYER_MODE_CONTEXT_ALL,
328 .paint_composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
329 .composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
330 .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL,
331 .blend_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL
332 },
333
334 { GIMP_LAYER_MODE_GRAIN_EXTRACT_LEGACY,
335
336 .op_name = "gimp:grain-extract-legacy",
337 .flags = GIMP_LAYER_MODE_FLAG_LEGACY |
338 GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE |
339 GIMP_LAYER_MODE_FLAG_COMPOSITE_SPACE_IMMUTABLE |
340 GIMP_LAYER_MODE_FLAG_COMPOSITE_MODE_IMMUTABLE,
341 .context = GIMP_LAYER_MODE_CONTEXT_ALL,
342 .paint_composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
343 .composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
344 .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL,
345 .blend_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL
346 },
347
348 { GIMP_LAYER_MODE_GRAIN_MERGE_LEGACY,
349
350 .op_name = "gimp:grain-merge-legacy",
351 .flags = GIMP_LAYER_MODE_FLAG_LEGACY |
352 GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE |
353 GIMP_LAYER_MODE_FLAG_COMPOSITE_SPACE_IMMUTABLE |
354 GIMP_LAYER_MODE_FLAG_COMPOSITE_MODE_IMMUTABLE,
355 .context = GIMP_LAYER_MODE_CONTEXT_ALL,
356 .paint_composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
357 .composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
358 .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL,
359 .blend_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL
360 },
361
362 { GIMP_LAYER_MODE_COLOR_ERASE_LEGACY,
363
364 .op_name = "gimp:layer-mode",
365 .blend_function = gimp_operation_layer_mode_blend_color_erase,
366 .flags = GIMP_LAYER_MODE_FLAG_LEGACY |
367 GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE |
368 GIMP_LAYER_MODE_FLAG_COMPOSITE_SPACE_IMMUTABLE |
369 GIMP_LAYER_MODE_FLAG_COMPOSITE_MODE_IMMUTABLE |
370 GIMP_LAYER_MODE_FLAG_SUBTRACTIVE,
371 .context = GIMP_LAYER_MODE_CONTEXT_PAINT |
372 GIMP_LAYER_MODE_CONTEXT_FILTER,
373 .paint_composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
374 .composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
375 .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL,
376 .blend_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL
377 },
378
379 { GIMP_LAYER_MODE_OVERLAY,
380
381 .op_name = "gimp:layer-mode",
382 .blend_function = gimp_operation_layer_mode_blend_overlay,
383 .context = GIMP_LAYER_MODE_CONTEXT_ALL,
384 .paint_composite_mode = GIMP_LAYER_COMPOSITE_UNION,
385 .composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
386 .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_LINEAR,
387 .blend_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL
388 },
389
390 { GIMP_LAYER_MODE_LCH_HUE,
391
392 .op_name = "gimp:layer-mode",
393 .blend_function = gimp_operation_layer_mode_blend_lch_hue,
394 .flags = GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE,
395 .context = GIMP_LAYER_MODE_CONTEXT_ALL,
396 .paint_composite_mode = GIMP_LAYER_COMPOSITE_UNION,
397 .composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
398 .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_LINEAR,
399 .blend_space = GIMP_LAYER_COLOR_SPACE_LAB
400 },
401
402 { GIMP_LAYER_MODE_LCH_CHROMA,
403
404 .op_name = "gimp:layer-mode",
405 .blend_function = gimp_operation_layer_mode_blend_lch_chroma,
406 .flags = GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE,
407 .context = GIMP_LAYER_MODE_CONTEXT_ALL,
408 .paint_composite_mode = GIMP_LAYER_COMPOSITE_UNION,
409 .composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
410 .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_LINEAR,
411 .blend_space = GIMP_LAYER_COLOR_SPACE_LAB
412 },
413
414 { GIMP_LAYER_MODE_LCH_COLOR,
415
416 .op_name = "gimp:layer-mode",
417 .blend_function = gimp_operation_layer_mode_blend_lch_color,
418 .flags = GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE,
419 .context = GIMP_LAYER_MODE_CONTEXT_ALL,
420 .paint_composite_mode = GIMP_LAYER_COMPOSITE_UNION,
421 .composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
422 .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_LINEAR,
423 .blend_space = GIMP_LAYER_COLOR_SPACE_LAB
424 },
425
426 { GIMP_LAYER_MODE_LCH_LIGHTNESS,
427
428 .op_name = "gimp:layer-mode",
429 .blend_function = gimp_operation_layer_mode_blend_lch_lightness,
430 .flags = GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE,
431 .context = GIMP_LAYER_MODE_CONTEXT_ALL,
432 .paint_composite_mode = GIMP_LAYER_COMPOSITE_UNION,
433 .composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
434 .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_LINEAR,
435 .blend_space = GIMP_LAYER_COLOR_SPACE_LAB
436 },
437
438 { GIMP_LAYER_MODE_NORMAL,
439
440 .op_name = "gimp:normal",
441 .flags = GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE |
442 GIMP_LAYER_MODE_FLAG_TRIVIAL,
443 .context = GIMP_LAYER_MODE_CONTEXT_ALL,
444 .paint_composite_mode = GIMP_LAYER_COMPOSITE_UNION,
445 .composite_mode = GIMP_LAYER_COMPOSITE_UNION,
446 .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_LINEAR
447 },
448
449 { GIMP_LAYER_MODE_BEHIND,
450
451 .op_name = "gimp:behind",
452 .flags = GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE,
453 .context = GIMP_LAYER_MODE_CONTEXT_PAINT |
454 GIMP_LAYER_MODE_CONTEXT_FILTER,
455 .paint_composite_mode = GIMP_LAYER_COMPOSITE_UNION,
456 .composite_mode = GIMP_LAYER_COMPOSITE_UNION,
457 .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_LINEAR
458 },
459
460 { GIMP_LAYER_MODE_MULTIPLY,
461
462 .op_name = "gimp:layer-mode",
463 .blend_function = gimp_operation_layer_mode_blend_multiply,
464 .context = GIMP_LAYER_MODE_CONTEXT_ALL,
465 .paint_composite_mode = GIMP_LAYER_COMPOSITE_UNION,
466 .composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
467 .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_LINEAR,
468 .blend_space = GIMP_LAYER_COLOR_SPACE_RGB_LINEAR
469 },
470
471 { GIMP_LAYER_MODE_SCREEN,
472
473 .op_name = "gimp:layer-mode",
474 .blend_function = gimp_operation_layer_mode_blend_screen,
475 .context = GIMP_LAYER_MODE_CONTEXT_ALL,
476 .paint_composite_mode = GIMP_LAYER_COMPOSITE_UNION,
477 .composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
478 .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_LINEAR,
479 .blend_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL
480 },
481
482 { GIMP_LAYER_MODE_DIFFERENCE,
483
484 .op_name = "gimp:layer-mode",
485 .blend_function = gimp_operation_layer_mode_blend_difference,
486 .context = GIMP_LAYER_MODE_CONTEXT_ALL,
487 .paint_composite_mode = GIMP_LAYER_COMPOSITE_UNION,
488 .composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
489 .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_LINEAR,
490 .blend_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL
491 },
492
493 { GIMP_LAYER_MODE_ADDITION,
494
495 .op_name = "gimp:layer-mode",
496 .blend_function = gimp_operation_layer_mode_blend_addition,
497 .context = GIMP_LAYER_MODE_CONTEXT_ALL,
498 .paint_composite_mode = GIMP_LAYER_COMPOSITE_UNION,
499 .composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
500 .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_LINEAR,
501 .blend_space = GIMP_LAYER_COLOR_SPACE_RGB_LINEAR
502 },
503
504 { GIMP_LAYER_MODE_SUBTRACT,
505
506 .op_name = "gimp:layer-mode",
507 .blend_function = gimp_operation_layer_mode_blend_subtract,
508 .context = GIMP_LAYER_MODE_CONTEXT_ALL,
509 .paint_composite_mode = GIMP_LAYER_COMPOSITE_UNION,
510 .composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
511 .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_LINEAR,
512 .blend_space = GIMP_LAYER_COLOR_SPACE_RGB_LINEAR
513 },
514
515 { GIMP_LAYER_MODE_DARKEN_ONLY,
516
517 .op_name = "gimp:layer-mode",
518 .blend_function = gimp_operation_layer_mode_blend_darken_only,
519 .flags = GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE,
520 .context = GIMP_LAYER_MODE_CONTEXT_ALL,
521 .paint_composite_mode = GIMP_LAYER_COMPOSITE_UNION,
522 .composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
523 .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_LINEAR
524 /* no blend_space: reuse composite space, no conversion thus fewer copies */
525 },
526
527 { GIMP_LAYER_MODE_LIGHTEN_ONLY,
528
529 .op_name = "gimp:layer-mode",
530 .blend_function = gimp_operation_layer_mode_blend_lighten_only,
531 .flags = GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE,
532 .context = GIMP_LAYER_MODE_CONTEXT_ALL,
533 .paint_composite_mode = GIMP_LAYER_COMPOSITE_UNION,
534 .composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
535 .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_LINEAR
536 /* no blend_space: reuse composite space, no conversion thus fewer copies */
537 },
538
539 { GIMP_LAYER_MODE_HSV_HUE,
540
541 .op_name = "gimp:layer-mode",
542 .blend_function = gimp_operation_layer_mode_blend_hsv_hue,
543 .flags = GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE,
544 .context = GIMP_LAYER_MODE_CONTEXT_ALL,
545 .paint_composite_mode = GIMP_LAYER_COMPOSITE_UNION,
546 .composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
547 .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_LINEAR,
548 .blend_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL
549 },
550
551 { GIMP_LAYER_MODE_HSV_SATURATION,
552
553 .op_name = "gimp:layer-mode",
554 .blend_function = gimp_operation_layer_mode_blend_hsv_saturation,
555 .flags = GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE,
556 .context = GIMP_LAYER_MODE_CONTEXT_ALL,
557 .paint_composite_mode = GIMP_LAYER_COMPOSITE_UNION,
558 .composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
559 .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_LINEAR,
560 .blend_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL
561 },
562
563 { GIMP_LAYER_MODE_HSL_COLOR,
564
565 .op_name = "gimp:layer-mode",
566 .blend_function = gimp_operation_layer_mode_blend_hsl_color,
567 .flags = GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE,
568 .context = GIMP_LAYER_MODE_CONTEXT_ALL,
569 .paint_composite_mode = GIMP_LAYER_COMPOSITE_UNION,
570 .composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
571 .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_LINEAR,
572 .blend_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL
573 },
574
575 { GIMP_LAYER_MODE_HSV_VALUE,
576
577 .op_name = "gimp:layer-mode",
578 .blend_function = gimp_operation_layer_mode_blend_hsv_value,
579 .flags = GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE,
580 .context = GIMP_LAYER_MODE_CONTEXT_ALL,
581 .paint_composite_mode = GIMP_LAYER_COMPOSITE_UNION,
582 .composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
583 .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_LINEAR,
584 .blend_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL
585 },
586
587 { GIMP_LAYER_MODE_DIVIDE,
588
589 .op_name = "gimp:layer-mode",
590 .blend_function = gimp_operation_layer_mode_blend_divide,
591 .context = GIMP_LAYER_MODE_CONTEXT_ALL,
592 .paint_composite_mode = GIMP_LAYER_COMPOSITE_UNION,
593 .composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
594 .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_LINEAR,
595 .blend_space = GIMP_LAYER_COLOR_SPACE_RGB_LINEAR
596 },
597
598 { GIMP_LAYER_MODE_DODGE,
599
600 .op_name = "gimp:layer-mode",
601 .blend_function = gimp_operation_layer_mode_blend_dodge,
602 .context = GIMP_LAYER_MODE_CONTEXT_ALL,
603 .paint_composite_mode = GIMP_LAYER_COMPOSITE_UNION,
604 .composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
605 .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_LINEAR,
606 .blend_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL
607 },
608
609 { GIMP_LAYER_MODE_BURN,
610
611 .op_name = "gimp:layer-mode",
612 .blend_function = gimp_operation_layer_mode_blend_burn,
613 .context = GIMP_LAYER_MODE_CONTEXT_ALL,
614 .paint_composite_mode = GIMP_LAYER_COMPOSITE_UNION,
615 .composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
616 .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_LINEAR,
617 .blend_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL
618 },
619
620 { GIMP_LAYER_MODE_HARDLIGHT,
621
622 .op_name = "gimp:layer-mode",
623 .blend_function = gimp_operation_layer_mode_blend_hardlight,
624 .context = GIMP_LAYER_MODE_CONTEXT_ALL,
625 .paint_composite_mode = GIMP_LAYER_COMPOSITE_UNION,
626 .composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
627 .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_LINEAR,
628 .blend_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL
629 },
630
631 { GIMP_LAYER_MODE_SOFTLIGHT,
632
633 .op_name = "gimp:layer-mode",
634 .blend_function = gimp_operation_layer_mode_blend_softlight,
635 .context = GIMP_LAYER_MODE_CONTEXT_ALL,
636 .paint_composite_mode = GIMP_LAYER_COMPOSITE_UNION,
637 .composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
638 .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_LINEAR,
639 .blend_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL
640 },
641
642 { GIMP_LAYER_MODE_GRAIN_EXTRACT,
643
644 .op_name = "gimp:layer-mode",
645 .blend_function = gimp_operation_layer_mode_blend_grain_extract,
646 .context = GIMP_LAYER_MODE_CONTEXT_ALL,
647 .paint_composite_mode = GIMP_LAYER_COMPOSITE_UNION,
648 .composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
649 .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_LINEAR,
650 .blend_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL
651 },
652
653 { GIMP_LAYER_MODE_GRAIN_MERGE,
654
655 .op_name = "gimp:layer-mode",
656 .blend_function = gimp_operation_layer_mode_blend_grain_merge,
657 .context = GIMP_LAYER_MODE_CONTEXT_ALL,
658 .paint_composite_mode = GIMP_LAYER_COMPOSITE_UNION,
659 .composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
660 .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_LINEAR,
661 .blend_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL
662 },
663
664 { GIMP_LAYER_MODE_VIVID_LIGHT,
665
666 .op_name = "gimp:layer-mode",
667 .blend_function = gimp_operation_layer_mode_blend_vivid_light,
668 .context = GIMP_LAYER_MODE_CONTEXT_ALL,
669 .paint_composite_mode = GIMP_LAYER_COMPOSITE_UNION,
670 .composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
671 .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_LINEAR,
672 .blend_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL
673 },
674
675 { GIMP_LAYER_MODE_PIN_LIGHT,
676
677 .op_name = "gimp:layer-mode",
678 .blend_function = gimp_operation_layer_mode_blend_pin_light,
679 .context = GIMP_LAYER_MODE_CONTEXT_ALL,
680 .paint_composite_mode = GIMP_LAYER_COMPOSITE_UNION,
681 .composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
682 .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_LINEAR,
683 .blend_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL
684 },
685
686 { GIMP_LAYER_MODE_LINEAR_LIGHT,
687
688 .op_name = "gimp:layer-mode",
689 .blend_function = gimp_operation_layer_mode_blend_linear_light,
690 .context = GIMP_LAYER_MODE_CONTEXT_ALL,
691 .paint_composite_mode = GIMP_LAYER_COMPOSITE_UNION,
692 .composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
693 .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_LINEAR,
694 .blend_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL
695 },
696
697 { GIMP_LAYER_MODE_HARD_MIX,
698
699 .op_name = "gimp:layer-mode",
700 .blend_function = gimp_operation_layer_mode_blend_hard_mix,
701 .context = GIMP_LAYER_MODE_CONTEXT_ALL,
702 .paint_composite_mode = GIMP_LAYER_COMPOSITE_UNION,
703 .composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
704 .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_LINEAR,
705 .blend_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL
706 },
707
708 { GIMP_LAYER_MODE_EXCLUSION,
709
710 .op_name = "gimp:layer-mode",
711 .blend_function = gimp_operation_layer_mode_blend_exclusion,
712 .context = GIMP_LAYER_MODE_CONTEXT_ALL,
713 .paint_composite_mode = GIMP_LAYER_COMPOSITE_UNION,
714 .composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
715 .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_LINEAR,
716 .blend_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL
717 },
718
719 { GIMP_LAYER_MODE_LINEAR_BURN,
720
721 .op_name = "gimp:layer-mode",
722 .blend_function = gimp_operation_layer_mode_blend_linear_burn,
723 .context = GIMP_LAYER_MODE_CONTEXT_ALL,
724 .paint_composite_mode = GIMP_LAYER_COMPOSITE_UNION,
725 .composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
726 .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_LINEAR,
727 .blend_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL
728 },
729
730 { GIMP_LAYER_MODE_LUMA_DARKEN_ONLY,
731
732 .op_name = "gimp:layer-mode",
733 .blend_function = gimp_operation_layer_mode_blend_luma_darken_only,
734 .context = GIMP_LAYER_MODE_CONTEXT_ALL,
735 .paint_composite_mode = GIMP_LAYER_COMPOSITE_UNION,
736 .composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
737 .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_LINEAR,
738 .blend_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL
739 },
740
741 { GIMP_LAYER_MODE_LUMA_LIGHTEN_ONLY,
742
743 .op_name = "gimp:layer-mode",
744 .blend_function = gimp_operation_layer_mode_blend_luma_lighten_only,
745 .context = GIMP_LAYER_MODE_CONTEXT_ALL,
746 .paint_composite_mode = GIMP_LAYER_COMPOSITE_UNION,
747 .composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
748 .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_LINEAR,
749 .blend_space = GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL
750 },
751
752 { GIMP_LAYER_MODE_LUMINANCE,
753
754 .op_name = "gimp:layer-mode",
755 .blend_function = gimp_operation_layer_mode_blend_luminance,
756 .flags = GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE,
757 .context = GIMP_LAYER_MODE_CONTEXT_ALL,
758 .paint_composite_mode = GIMP_LAYER_COMPOSITE_UNION,
759 .composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
760 .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_LINEAR,
761 .blend_space = GIMP_LAYER_COLOR_SPACE_RGB_LINEAR
762 },
763
764 { GIMP_LAYER_MODE_COLOR_ERASE,
765
766 .op_name = "gimp:layer-mode",
767 .blend_function = gimp_operation_layer_mode_blend_color_erase,
768 .flags = GIMP_LAYER_MODE_FLAG_SUBTRACTIVE,
769 .context = GIMP_LAYER_MODE_CONTEXT_ALL,
770 .paint_composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
771 .composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
772 .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_LINEAR,
773 .blend_space = GIMP_LAYER_COLOR_SPACE_RGB_LINEAR
774 },
775
776 { GIMP_LAYER_MODE_ERASE,
777
778 .op_name = "gimp:erase",
779 .flags = GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE |
780 GIMP_LAYER_MODE_FLAG_SUBTRACTIVE |
781 GIMP_LAYER_MODE_FLAG_ALPHA_ONLY |
782 GIMP_LAYER_MODE_FLAG_TRIVIAL,
783 .context = GIMP_LAYER_MODE_CONTEXT_ALL,
784 .paint_composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
785 .composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
786 .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_LINEAR
787 },
788
789 { GIMP_LAYER_MODE_MERGE,
790
791 .op_name = "gimp:merge",
792 .flags = GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE |
793 GIMP_LAYER_MODE_FLAG_TRIVIAL,
794 .context = GIMP_LAYER_MODE_CONTEXT_ALL,
795 .paint_composite_mode = GIMP_LAYER_COMPOSITE_UNION,
796 .composite_mode = GIMP_LAYER_COMPOSITE_UNION,
797 .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_LINEAR
798 },
799
800 { GIMP_LAYER_MODE_SPLIT,
801
802 .op_name = "gimp:split",
803 .flags = GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE |
804 GIMP_LAYER_MODE_FLAG_COMPOSITE_SPACE_IMMUTABLE |
805 GIMP_LAYER_MODE_FLAG_SUBTRACTIVE |
806 GIMP_LAYER_MODE_FLAG_ALPHA_ONLY |
807 GIMP_LAYER_MODE_FLAG_TRIVIAL,
808 .context = GIMP_LAYER_MODE_CONTEXT_ALL,
809 .paint_composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP,
810 .composite_mode = GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP
811 },
812
813 { GIMP_LAYER_MODE_PASS_THROUGH,
814
815 .op_name = "gimp:pass-through",
816 .flags = GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE |
817 GIMP_LAYER_MODE_FLAG_COMPOSITE_MODE_IMMUTABLE |
818 GIMP_LAYER_MODE_FLAG_TRIVIAL,
819 .context = GIMP_LAYER_MODE_CONTEXT_GROUP,
820 .composite_mode = GIMP_LAYER_COMPOSITE_UNION,
821 .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_LINEAR
822 },
823
824 { GIMP_LAYER_MODE_REPLACE,
825
826 .op_name = "gimp:replace",
827 .flags = GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE |
828 GIMP_LAYER_MODE_FLAG_TRIVIAL,
829 .context = GIMP_LAYER_MODE_CONTEXT_FILTER,
830 .paint_composite_mode = GIMP_LAYER_COMPOSITE_UNION,
831 .composite_mode = GIMP_LAYER_COMPOSITE_UNION,
832 .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_LINEAR
833 },
834
835 { GIMP_LAYER_MODE_ANTI_ERASE,
836
837 .op_name = "gimp:anti-erase",
838 .flags = GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE |
839 GIMP_LAYER_MODE_FLAG_COMPOSITE_SPACE_IMMUTABLE |
840 GIMP_LAYER_MODE_FLAG_ALPHA_ONLY,
841 .paint_composite_mode = GIMP_LAYER_COMPOSITE_UNION,
842 .composite_mode = GIMP_LAYER_COMPOSITE_UNION
843 }
844 };
845
846 static const GimpLayerMode layer_mode_group_default[] =
847 {
848 GIMP_LAYER_MODE_PASS_THROUGH,
849
850 GIMP_LAYER_MODE_SEPARATOR,
851
852 GIMP_LAYER_MODE_REPLACE,
853
854 GIMP_LAYER_MODE_SEPARATOR,
855
856 GIMP_LAYER_MODE_NORMAL,
857 GIMP_LAYER_MODE_DISSOLVE,
858 GIMP_LAYER_MODE_BEHIND,
859 GIMP_LAYER_MODE_COLOR_ERASE,
860 GIMP_LAYER_MODE_ERASE,
861 GIMP_LAYER_MODE_ANTI_ERASE,
862 GIMP_LAYER_MODE_MERGE,
863 GIMP_LAYER_MODE_SPLIT,
864
865 GIMP_LAYER_MODE_SEPARATOR,
866
867 GIMP_LAYER_MODE_LIGHTEN_ONLY,
868 GIMP_LAYER_MODE_LUMA_LIGHTEN_ONLY,
869 GIMP_LAYER_MODE_SCREEN,
870 GIMP_LAYER_MODE_DODGE,
871 GIMP_LAYER_MODE_ADDITION,
872
873 GIMP_LAYER_MODE_SEPARATOR,
874
875 GIMP_LAYER_MODE_DARKEN_ONLY,
876 GIMP_LAYER_MODE_LUMA_DARKEN_ONLY,
877 GIMP_LAYER_MODE_MULTIPLY,
878 GIMP_LAYER_MODE_BURN,
879 GIMP_LAYER_MODE_LINEAR_BURN,
880
881 GIMP_LAYER_MODE_SEPARATOR,
882
883 GIMP_LAYER_MODE_OVERLAY,
884 GIMP_LAYER_MODE_SOFTLIGHT,
885 GIMP_LAYER_MODE_HARDLIGHT,
886 GIMP_LAYER_MODE_VIVID_LIGHT,
887 GIMP_LAYER_MODE_PIN_LIGHT,
888 GIMP_LAYER_MODE_LINEAR_LIGHT,
889 GIMP_LAYER_MODE_HARD_MIX,
890
891 GIMP_LAYER_MODE_SEPARATOR,
892
893 GIMP_LAYER_MODE_DIFFERENCE,
894 GIMP_LAYER_MODE_EXCLUSION,
895 GIMP_LAYER_MODE_SUBTRACT,
896 GIMP_LAYER_MODE_GRAIN_EXTRACT,
897 GIMP_LAYER_MODE_GRAIN_MERGE,
898 GIMP_LAYER_MODE_DIVIDE,
899
900 GIMP_LAYER_MODE_SEPARATOR,
901
902 GIMP_LAYER_MODE_HSV_HUE,
903 GIMP_LAYER_MODE_HSV_SATURATION,
904 GIMP_LAYER_MODE_HSL_COLOR,
905 GIMP_LAYER_MODE_HSV_VALUE,
906
907 GIMP_LAYER_MODE_SEPARATOR,
908
909 GIMP_LAYER_MODE_LCH_HUE,
910 GIMP_LAYER_MODE_LCH_CHROMA,
911 GIMP_LAYER_MODE_LCH_COLOR,
912 GIMP_LAYER_MODE_LCH_LIGHTNESS,
913 GIMP_LAYER_MODE_LUMINANCE
914 };
915
916 static const GimpLayerMode layer_mode_group_legacy[] =
917 {
918 GIMP_LAYER_MODE_NORMAL_LEGACY,
919 GIMP_LAYER_MODE_DISSOLVE,
920 GIMP_LAYER_MODE_BEHIND_LEGACY,
921 GIMP_LAYER_MODE_COLOR_ERASE_LEGACY,
922
923 GIMP_LAYER_MODE_SEPARATOR,
924
925 GIMP_LAYER_MODE_LIGHTEN_ONLY_LEGACY,
926 GIMP_LAYER_MODE_SCREEN_LEGACY,
927 GIMP_LAYER_MODE_DODGE_LEGACY,
928 GIMP_LAYER_MODE_ADDITION_LEGACY,
929
930 GIMP_LAYER_MODE_SEPARATOR,
931
932 GIMP_LAYER_MODE_DARKEN_ONLY_LEGACY,
933 GIMP_LAYER_MODE_MULTIPLY_LEGACY,
934 GIMP_LAYER_MODE_BURN_LEGACY,
935
936 GIMP_LAYER_MODE_SEPARATOR,
937
938 GIMP_LAYER_MODE_OVERLAY,
939 GIMP_LAYER_MODE_SOFTLIGHT_LEGACY,
940 GIMP_LAYER_MODE_HARDLIGHT_LEGACY,
941
942 GIMP_LAYER_MODE_SEPARATOR,
943
944 GIMP_LAYER_MODE_DIFFERENCE_LEGACY,
945 GIMP_LAYER_MODE_SUBTRACT_LEGACY,
946 GIMP_LAYER_MODE_GRAIN_EXTRACT_LEGACY,
947 GIMP_LAYER_MODE_GRAIN_MERGE_LEGACY,
948 GIMP_LAYER_MODE_DIVIDE_LEGACY,
949
950 GIMP_LAYER_MODE_SEPARATOR,
951
952 GIMP_LAYER_MODE_HSV_HUE_LEGACY,
953 GIMP_LAYER_MODE_HSV_SATURATION_LEGACY,
954 GIMP_LAYER_MODE_HSL_COLOR_LEGACY,
955 GIMP_LAYER_MODE_HSV_VALUE_LEGACY
956 };
957
958 static const GimpLayerMode layer_mode_groups[][2] =
959 {
960 { [GIMP_LAYER_MODE_GROUP_DEFAULT] = GIMP_LAYER_MODE_NORMAL,
961 [GIMP_LAYER_MODE_GROUP_LEGACY ] = GIMP_LAYER_MODE_NORMAL_LEGACY
962 },
963
964 { [GIMP_LAYER_MODE_GROUP_DEFAULT] = GIMP_LAYER_MODE_DISSOLVE,
965 [GIMP_LAYER_MODE_GROUP_LEGACY ] = GIMP_LAYER_MODE_DISSOLVE
966 },
967
968 { [GIMP_LAYER_MODE_GROUP_DEFAULT] = GIMP_LAYER_MODE_BEHIND,
969 [GIMP_LAYER_MODE_GROUP_LEGACY ] = GIMP_LAYER_MODE_BEHIND_LEGACY
970 },
971
972 { [GIMP_LAYER_MODE_GROUP_DEFAULT] = GIMP_LAYER_MODE_MULTIPLY,
973 [GIMP_LAYER_MODE_GROUP_LEGACY ] = GIMP_LAYER_MODE_MULTIPLY_LEGACY
974 },
975
976 { [GIMP_LAYER_MODE_GROUP_DEFAULT] = GIMP_LAYER_MODE_SCREEN,
977 [GIMP_LAYER_MODE_GROUP_LEGACY ] = GIMP_LAYER_MODE_SCREEN_LEGACY
978 },
979
980 { [GIMP_LAYER_MODE_GROUP_DEFAULT] = GIMP_LAYER_MODE_OVERLAY,
981 [GIMP_LAYER_MODE_GROUP_LEGACY ] = -1
982 },
983
984 { [GIMP_LAYER_MODE_GROUP_DEFAULT] = GIMP_LAYER_MODE_DIFFERENCE,
985 [GIMP_LAYER_MODE_GROUP_LEGACY ] = GIMP_LAYER_MODE_DIFFERENCE_LEGACY
986 },
987
988 { [GIMP_LAYER_MODE_GROUP_DEFAULT] = GIMP_LAYER_MODE_ADDITION,
989 [GIMP_LAYER_MODE_GROUP_LEGACY ] = GIMP_LAYER_MODE_ADDITION_LEGACY
990 },
991
992 { [GIMP_LAYER_MODE_GROUP_DEFAULT] = GIMP_LAYER_MODE_SUBTRACT,
993 [GIMP_LAYER_MODE_GROUP_LEGACY ] = GIMP_LAYER_MODE_SUBTRACT_LEGACY
994 },
995
996 { [GIMP_LAYER_MODE_GROUP_DEFAULT] = GIMP_LAYER_MODE_DARKEN_ONLY,
997 [GIMP_LAYER_MODE_GROUP_LEGACY ] = GIMP_LAYER_MODE_DARKEN_ONLY_LEGACY
998 },
999
1000 { [GIMP_LAYER_MODE_GROUP_DEFAULT] = GIMP_LAYER_MODE_LIGHTEN_ONLY,
1001 [GIMP_LAYER_MODE_GROUP_LEGACY ] = GIMP_LAYER_MODE_LIGHTEN_ONLY_LEGACY
1002 },
1003
1004 { [GIMP_LAYER_MODE_GROUP_DEFAULT] = GIMP_LAYER_MODE_HSV_HUE,
1005 [GIMP_LAYER_MODE_GROUP_LEGACY ] = GIMP_LAYER_MODE_HSV_HUE_LEGACY
1006 },
1007
1008 { [GIMP_LAYER_MODE_GROUP_DEFAULT] = GIMP_LAYER_MODE_HSV_SATURATION,
1009 [GIMP_LAYER_MODE_GROUP_LEGACY ] = GIMP_LAYER_MODE_HSV_SATURATION_LEGACY
1010 },
1011
1012 { [GIMP_LAYER_MODE_GROUP_DEFAULT] = GIMP_LAYER_MODE_HSL_COLOR,
1013 [GIMP_LAYER_MODE_GROUP_LEGACY ] = GIMP_LAYER_MODE_HSL_COLOR_LEGACY
1014 },
1015
1016 { [GIMP_LAYER_MODE_GROUP_DEFAULT] = GIMP_LAYER_MODE_HSV_VALUE,
1017 [GIMP_LAYER_MODE_GROUP_LEGACY ] = GIMP_LAYER_MODE_HSV_VALUE_LEGACY
1018 },
1019
1020 { [GIMP_LAYER_MODE_GROUP_DEFAULT] = GIMP_LAYER_MODE_DIVIDE,
1021 [GIMP_LAYER_MODE_GROUP_LEGACY ] = GIMP_LAYER_MODE_DIVIDE_LEGACY
1022 },
1023
1024 { [GIMP_LAYER_MODE_GROUP_DEFAULT] = GIMP_LAYER_MODE_DODGE,
1025 [GIMP_LAYER_MODE_GROUP_LEGACY ] = GIMP_LAYER_MODE_DODGE_LEGACY
1026 },
1027
1028 { [GIMP_LAYER_MODE_GROUP_DEFAULT] = GIMP_LAYER_MODE_BURN,
1029 [GIMP_LAYER_MODE_GROUP_LEGACY ] = GIMP_LAYER_MODE_BURN_LEGACY
1030 },
1031
1032 { [GIMP_LAYER_MODE_GROUP_DEFAULT] = GIMP_LAYER_MODE_HARDLIGHT,
1033 [GIMP_LAYER_MODE_GROUP_LEGACY ] = GIMP_LAYER_MODE_HARDLIGHT_LEGACY
1034 },
1035
1036 { [GIMP_LAYER_MODE_GROUP_DEFAULT] = GIMP_LAYER_MODE_SOFTLIGHT,
1037 [GIMP_LAYER_MODE_GROUP_LEGACY ] = GIMP_LAYER_MODE_SOFTLIGHT_LEGACY
1038 },
1039
1040 { [GIMP_LAYER_MODE_GROUP_DEFAULT] = GIMP_LAYER_MODE_GRAIN_EXTRACT,
1041 [GIMP_LAYER_MODE_GROUP_LEGACY ] = GIMP_LAYER_MODE_GRAIN_EXTRACT_LEGACY
1042 },
1043
1044 { [GIMP_LAYER_MODE_GROUP_DEFAULT] = GIMP_LAYER_MODE_GRAIN_MERGE,
1045 [GIMP_LAYER_MODE_GROUP_LEGACY ] = GIMP_LAYER_MODE_GRAIN_MERGE_LEGACY
1046 },
1047
1048 { [GIMP_LAYER_MODE_GROUP_DEFAULT] = GIMP_LAYER_MODE_COLOR_ERASE,
1049 [GIMP_LAYER_MODE_GROUP_LEGACY ] = GIMP_LAYER_MODE_COLOR_ERASE_LEGACY,
1050 },
1051
1052 { [GIMP_LAYER_MODE_GROUP_DEFAULT] = GIMP_LAYER_MODE_VIVID_LIGHT,
1053 [GIMP_LAYER_MODE_GROUP_LEGACY ] = -1
1054 },
1055
1056 { [GIMP_LAYER_MODE_GROUP_DEFAULT] = GIMP_LAYER_MODE_PIN_LIGHT,
1057 [GIMP_LAYER_MODE_GROUP_LEGACY ] = -1
1058 },
1059
1060 { [GIMP_LAYER_MODE_GROUP_DEFAULT] = GIMP_LAYER_MODE_LINEAR_LIGHT,
1061 [GIMP_LAYER_MODE_GROUP_LEGACY ] = -1
1062 },
1063
1064 { [GIMP_LAYER_MODE_GROUP_DEFAULT] = GIMP_LAYER_MODE_HARD_MIX,
1065 [GIMP_LAYER_MODE_GROUP_LEGACY ] = -1
1066 },
1067
1068 { [GIMP_LAYER_MODE_GROUP_DEFAULT] = GIMP_LAYER_MODE_EXCLUSION,
1069 [GIMP_LAYER_MODE_GROUP_LEGACY ] = -1
1070 },
1071
1072 { [GIMP_LAYER_MODE_GROUP_DEFAULT] = GIMP_LAYER_MODE_LINEAR_BURN,
1073 [GIMP_LAYER_MODE_GROUP_LEGACY ] = -1
1074 },
1075
1076 { [GIMP_LAYER_MODE_GROUP_DEFAULT] = GIMP_LAYER_MODE_LUMA_DARKEN_ONLY,
1077 [GIMP_LAYER_MODE_GROUP_LEGACY ] = -1
1078 },
1079
1080 { [GIMP_LAYER_MODE_GROUP_DEFAULT] = GIMP_LAYER_MODE_LUMA_LIGHTEN_ONLY,
1081 [GIMP_LAYER_MODE_GROUP_LEGACY ] = -1
1082 },
1083
1084 { [GIMP_LAYER_MODE_GROUP_DEFAULT] = GIMP_LAYER_MODE_LUMINANCE,
1085 [GIMP_LAYER_MODE_GROUP_LEGACY ] = -1
1086 },
1087
1088 { [GIMP_LAYER_MODE_GROUP_DEFAULT] = GIMP_LAYER_MODE_ERASE,
1089 [GIMP_LAYER_MODE_GROUP_LEGACY ] = -1
1090 },
1091
1092 { [GIMP_LAYER_MODE_GROUP_DEFAULT] = GIMP_LAYER_MODE_MERGE,
1093 [GIMP_LAYER_MODE_GROUP_LEGACY ] = -1
1094 },
1095
1096 { [GIMP_LAYER_MODE_GROUP_DEFAULT] = GIMP_LAYER_MODE_SPLIT,
1097 [GIMP_LAYER_MODE_GROUP_LEGACY ] = -1
1098 },
1099
1100 { [GIMP_LAYER_MODE_GROUP_DEFAULT] = GIMP_LAYER_MODE_PASS_THROUGH,
1101 [GIMP_LAYER_MODE_GROUP_LEGACY ] = -1,
1102 },
1103
1104 { [GIMP_LAYER_MODE_GROUP_DEFAULT] = GIMP_LAYER_MODE_REPLACE,
1105 [GIMP_LAYER_MODE_GROUP_LEGACY ] = -1
1106 },
1107
1108 { [GIMP_LAYER_MODE_GROUP_DEFAULT] = GIMP_LAYER_MODE_ANTI_ERASE,
1109 [GIMP_LAYER_MODE_GROUP_LEGACY ] = -1
1110 }
1111 };
1112
1113
1114 /* public functions */
1115
1116 void
gimp_layer_modes_init(void)1117 gimp_layer_modes_init (void)
1118 {
1119 gint i;
1120
1121 for (i = 0; i < G_N_ELEMENTS (layer_mode_infos); i++)
1122 {
1123 gimp_assert ((GimpLayerMode) i == layer_mode_infos[i].layer_mode);
1124 }
1125 }
1126
1127 static const GimpLayerModeInfo *
gimp_layer_mode_info(GimpLayerMode mode)1128 gimp_layer_mode_info (GimpLayerMode mode)
1129 {
1130 g_return_val_if_fail (mode >= 0 && mode < G_N_ELEMENTS (layer_mode_infos),
1131 &layer_mode_infos[0]);
1132
1133 return &layer_mode_infos[mode];
1134 }
1135
1136 gboolean
gimp_layer_mode_is_legacy(GimpLayerMode mode)1137 gimp_layer_mode_is_legacy (GimpLayerMode mode)
1138 {
1139 const GimpLayerModeInfo *info = gimp_layer_mode_info (mode);
1140
1141 if (! info)
1142 return FALSE;
1143
1144 return (info->flags & GIMP_LAYER_MODE_FLAG_LEGACY) != 0;
1145 }
1146
1147 gboolean
gimp_layer_mode_is_blend_space_mutable(GimpLayerMode mode)1148 gimp_layer_mode_is_blend_space_mutable (GimpLayerMode mode)
1149 {
1150 const GimpLayerModeInfo *info = gimp_layer_mode_info (mode);
1151
1152 if (! info)
1153 return FALSE;
1154
1155 return (info->flags & GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE) == 0;
1156 }
1157
1158 gboolean
gimp_layer_mode_is_composite_space_mutable(GimpLayerMode mode)1159 gimp_layer_mode_is_composite_space_mutable (GimpLayerMode mode)
1160 {
1161 const GimpLayerModeInfo *info = gimp_layer_mode_info (mode);
1162
1163 if (! info)
1164 return FALSE;
1165
1166 return (info->flags & GIMP_LAYER_MODE_FLAG_COMPOSITE_SPACE_IMMUTABLE) == 0;
1167 }
1168
1169 gboolean
gimp_layer_mode_is_composite_mode_mutable(GimpLayerMode mode)1170 gimp_layer_mode_is_composite_mode_mutable (GimpLayerMode mode)
1171 {
1172 const GimpLayerModeInfo *info = gimp_layer_mode_info (mode);
1173
1174 if (! info)
1175 return FALSE;
1176
1177 return (info->flags & GIMP_LAYER_MODE_FLAG_COMPOSITE_MODE_IMMUTABLE) == 0;
1178 }
1179
1180 gboolean
gimp_layer_mode_is_subtractive(GimpLayerMode mode)1181 gimp_layer_mode_is_subtractive (GimpLayerMode mode)
1182 {
1183 const GimpLayerModeInfo *info = gimp_layer_mode_info (mode);
1184
1185 if (! info)
1186 return FALSE;
1187
1188 return (info->flags & GIMP_LAYER_MODE_FLAG_SUBTRACTIVE) != 0;
1189 }
1190
1191 gboolean
gimp_layer_mode_is_alpha_only(GimpLayerMode mode)1192 gimp_layer_mode_is_alpha_only (GimpLayerMode mode)
1193 {
1194 const GimpLayerModeInfo *info = gimp_layer_mode_info (mode);
1195
1196 if (! info)
1197 return FALSE;
1198
1199 return (info->flags & GIMP_LAYER_MODE_FLAG_ALPHA_ONLY) != 0;
1200 }
1201
1202 gboolean
gimp_layer_mode_is_trivial(GimpLayerMode mode)1203 gimp_layer_mode_is_trivial (GimpLayerMode mode)
1204 {
1205 const GimpLayerModeInfo *info = gimp_layer_mode_info (mode);
1206
1207 if (! info)
1208 return FALSE;
1209
1210 return (info->flags & GIMP_LAYER_MODE_FLAG_TRIVIAL) != 0;
1211 }
1212
1213 GimpLayerColorSpace
gimp_layer_mode_get_blend_space(GimpLayerMode mode)1214 gimp_layer_mode_get_blend_space (GimpLayerMode mode)
1215 {
1216 const GimpLayerModeInfo *info = gimp_layer_mode_info (mode);
1217
1218 if (! info)
1219 return GIMP_LAYER_COLOR_SPACE_RGB_LINEAR;
1220
1221 return info->blend_space;
1222 }
1223
1224 GimpLayerColorSpace
gimp_layer_mode_get_composite_space(GimpLayerMode mode)1225 gimp_layer_mode_get_composite_space (GimpLayerMode mode)
1226 {
1227 const GimpLayerModeInfo *info = gimp_layer_mode_info (mode);
1228
1229 if (! info)
1230 return GIMP_LAYER_COLOR_SPACE_RGB_LINEAR;
1231
1232 return info->composite_space;
1233 }
1234
1235 GimpLayerCompositeMode
gimp_layer_mode_get_composite_mode(GimpLayerMode mode)1236 gimp_layer_mode_get_composite_mode (GimpLayerMode mode)
1237 {
1238 const GimpLayerModeInfo *info = gimp_layer_mode_info (mode);
1239
1240 if (! info)
1241 return GIMP_LAYER_COMPOSITE_UNION;
1242
1243 return info->composite_mode;
1244 }
1245
1246 GimpLayerCompositeMode
gimp_layer_mode_get_paint_composite_mode(GimpLayerMode mode)1247 gimp_layer_mode_get_paint_composite_mode (GimpLayerMode mode)
1248 {
1249 const GimpLayerModeInfo *info = gimp_layer_mode_info (mode);
1250
1251 if (! info)
1252 return GIMP_LAYER_COMPOSITE_UNION;
1253
1254 return info->paint_composite_mode;
1255 }
1256
1257 const gchar *
gimp_layer_mode_get_operation(GimpLayerMode mode)1258 gimp_layer_mode_get_operation (GimpLayerMode mode)
1259 {
1260 const GimpLayerModeInfo *info = gimp_layer_mode_info (mode);
1261
1262 if (! info)
1263 return "gimp:layer-mode";
1264
1265 return info->op_name;
1266 }
1267
1268 GimpLayerModeFunc
gimp_layer_mode_get_function(GimpLayerMode mode)1269 gimp_layer_mode_get_function (GimpLayerMode mode)
1270 {
1271 const GimpLayerModeInfo *info = gimp_layer_mode_info (mode);
1272 static GimpLayerModeFunc funcs[G_N_ELEMENTS (layer_mode_infos)];
1273
1274 if (! info)
1275 info = layer_mode_infos;
1276
1277 mode = info - layer_mode_infos;
1278
1279 if (! funcs[mode])
1280 {
1281 GeglNode *node;
1282 GeglOperation *operation;
1283
1284 node = gegl_node_new_child (NULL,
1285 "operation", info->op_name,
1286 NULL);
1287
1288 operation = gegl_node_get_gegl_operation (node);
1289
1290 funcs[mode] = GIMP_OPERATION_LAYER_MODE_GET_CLASS (operation)->process;
1291
1292 g_object_unref (node);
1293 }
1294
1295 return funcs[mode];
1296 }
1297
1298 GimpLayerModeBlendFunc
gimp_layer_mode_get_blend_function(GimpLayerMode mode)1299 gimp_layer_mode_get_blend_function (GimpLayerMode mode)
1300 {
1301 const GimpLayerModeInfo *info = gimp_layer_mode_info (mode);
1302
1303 if (! info)
1304 return NULL;
1305
1306 return info->blend_function;
1307 }
1308
1309 GimpLayerModeContext
gimp_layer_mode_get_context(GimpLayerMode mode)1310 gimp_layer_mode_get_context (GimpLayerMode mode)
1311 {
1312 const GimpLayerModeInfo *info = gimp_layer_mode_info (mode);
1313
1314 if (! info)
1315 return 0;
1316
1317 return info->context;
1318 }
1319
1320 GimpLayerMode *
gimp_layer_mode_get_context_array(GimpLayerMode mode,GimpLayerModeContext context,gint * n_modes)1321 gimp_layer_mode_get_context_array (GimpLayerMode mode,
1322 GimpLayerModeContext context,
1323 gint *n_modes)
1324 {
1325 GimpLayerModeGroup group;
1326 const GimpLayerMode *group_modes;
1327 gint n_group_modes;
1328 GimpLayerMode *array;
1329 gint i;
1330
1331 group = gimp_layer_mode_get_group (mode);
1332
1333 group_modes = gimp_layer_mode_get_group_array (group, &n_group_modes);
1334
1335 array = g_new0 (GimpLayerMode, n_group_modes);
1336 *n_modes = 0;
1337
1338 for (i = 0; i < n_group_modes; i++)
1339 {
1340 if (group_modes[i] != GIMP_LAYER_MODE_SEPARATOR &&
1341 (gimp_layer_mode_get_context (group_modes[i]) & context))
1342 {
1343 array[*n_modes] = group_modes[i];
1344 (*n_modes)++;
1345 }
1346 }
1347
1348 return array;
1349 }
1350
1351 static gboolean
is_mode_in_array(const GimpLayerMode * modes,gint n_modes,GimpLayerMode mode)1352 is_mode_in_array (const GimpLayerMode *modes,
1353 gint n_modes,
1354 GimpLayerMode mode)
1355 {
1356 gint i;
1357
1358 for (i = 0; i < n_modes; i++)
1359 {
1360 if (modes[i] == mode)
1361 return TRUE;
1362 }
1363
1364 return FALSE;
1365 }
1366
1367 GimpLayerModeGroup
gimp_layer_mode_get_group(GimpLayerMode mode)1368 gimp_layer_mode_get_group (GimpLayerMode mode)
1369 {
1370 if (is_mode_in_array (layer_mode_group_default,
1371 G_N_ELEMENTS (layer_mode_group_default), mode))
1372 {
1373 return GIMP_LAYER_MODE_GROUP_DEFAULT;
1374 }
1375 else if (is_mode_in_array (layer_mode_group_legacy,
1376 G_N_ELEMENTS (layer_mode_group_legacy), mode))
1377 {
1378 return GIMP_LAYER_MODE_GROUP_LEGACY;
1379 }
1380
1381 return GIMP_LAYER_MODE_GROUP_DEFAULT;
1382 }
1383
1384 const GimpLayerMode *
gimp_layer_mode_get_group_array(GimpLayerModeGroup group,gint * n_modes)1385 gimp_layer_mode_get_group_array (GimpLayerModeGroup group,
1386 gint *n_modes)
1387 {
1388 g_return_val_if_fail (n_modes != NULL, NULL);
1389
1390 switch (group)
1391 {
1392 case GIMP_LAYER_MODE_GROUP_DEFAULT:
1393 *n_modes = G_N_ELEMENTS (layer_mode_group_default);
1394 return layer_mode_group_default;
1395
1396 case GIMP_LAYER_MODE_GROUP_LEGACY:
1397 *n_modes = G_N_ELEMENTS (layer_mode_group_legacy);
1398 return layer_mode_group_legacy;
1399
1400 default:
1401 g_return_val_if_reached (NULL);
1402 }
1403 }
1404
1405 gboolean
gimp_layer_mode_get_for_group(GimpLayerMode old_mode,GimpLayerModeGroup new_group,GimpLayerMode * new_mode)1406 gimp_layer_mode_get_for_group (GimpLayerMode old_mode,
1407 GimpLayerModeGroup new_group,
1408 GimpLayerMode *new_mode)
1409 {
1410 gint i;
1411
1412 g_return_val_if_fail (new_mode != NULL, FALSE);
1413
1414 for (i = 0; i < G_N_ELEMENTS (layer_mode_groups); i++)
1415 {
1416 if (is_mode_in_array (layer_mode_groups[i], 2, old_mode))
1417 {
1418 *new_mode = layer_mode_groups[i][new_group];
1419
1420 if (*new_mode != -1)
1421 return TRUE;
1422
1423 return FALSE;
1424 }
1425 }
1426
1427 *new_mode = -1;
1428
1429 return FALSE;
1430 }
1431
1432 const Babl *
gimp_layer_mode_get_format(GimpLayerMode mode,GimpLayerColorSpace blend_space,GimpLayerColorSpace composite_space,GimpLayerCompositeMode composite_mode,const Babl * preferred_format)1433 gimp_layer_mode_get_format (GimpLayerMode mode,
1434 GimpLayerColorSpace blend_space,
1435 GimpLayerColorSpace composite_space,
1436 GimpLayerCompositeMode composite_mode,
1437 const Babl *preferred_format)
1438 {
1439 GimpLayerCompositeRegion composite_region;
1440
1441 /* for now, all modes perform i/o in the composite space. */
1442 (void) mode;
1443 (void) blend_space;
1444
1445 if (composite_space == GIMP_LAYER_COLOR_SPACE_AUTO)
1446 composite_space = gimp_layer_mode_get_composite_space (mode);
1447
1448 if (composite_mode == GIMP_LAYER_COMPOSITE_AUTO)
1449 composite_mode = gimp_layer_mode_get_composite_mode (mode);
1450
1451 composite_region = gimp_layer_mode_get_included_region (mode, composite_mode);
1452
1453 if (gimp_layer_mode_is_alpha_only (mode))
1454 {
1455 if (composite_region != GIMP_LAYER_COMPOSITE_REGION_UNION)
1456 {
1457 /* alpha-only layer modes don't combine colors in non-union composite
1458 * modes, hence we can disregard the composite space.
1459 */
1460 composite_space = GIMP_LAYER_COLOR_SPACE_AUTO;
1461 }
1462 }
1463 else if (gimp_layer_mode_is_trivial (mode))
1464 {
1465 if (! (composite_region & GIMP_LAYER_COMPOSITE_REGION_DESTINATION))
1466 {
1467 /* trivial layer modes don't combine colors when only the source
1468 * region is included, hence we can disregard the composite space.
1469 */
1470 composite_space = GIMP_LAYER_COLOR_SPACE_AUTO;
1471 }
1472 }
1473
1474 switch (composite_space)
1475 {
1476 case GIMP_LAYER_COLOR_SPACE_AUTO:
1477 /* compositing is color-space agnostic. return a format that has a fast
1478 * conversion path to/from the preferred format.
1479 */
1480 if (! preferred_format || gimp_babl_format_get_linear (preferred_format))
1481 return babl_format ("RGBA float");
1482 else
1483 return babl_format ("R'G'B'A float");
1484
1485 case GIMP_LAYER_COLOR_SPACE_RGB_LINEAR:
1486 return babl_format ("RGBA float");
1487
1488 case GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL:
1489 return babl_format ("R'G'B'A float");
1490
1491 case GIMP_LAYER_COLOR_SPACE_LAB:
1492 return babl_format ("CIE Lab alpha float");
1493 }
1494
1495 g_return_val_if_reached (babl_format ("RGBA float"));
1496 }
1497
1498 GimpLayerCompositeRegion
gimp_layer_mode_get_included_region(GimpLayerMode mode,GimpLayerCompositeMode composite_mode)1499 gimp_layer_mode_get_included_region (GimpLayerMode mode,
1500 GimpLayerCompositeMode composite_mode)
1501 {
1502 if (composite_mode == GIMP_LAYER_COMPOSITE_AUTO)
1503 composite_mode = gimp_layer_mode_get_composite_mode (mode);
1504
1505 switch (composite_mode)
1506 {
1507 case GIMP_LAYER_COMPOSITE_UNION:
1508 return GIMP_LAYER_COMPOSITE_REGION_UNION;
1509
1510 case GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP:
1511 return GIMP_LAYER_COMPOSITE_REGION_DESTINATION;
1512
1513 case GIMP_LAYER_COMPOSITE_CLIP_TO_LAYER:
1514 return GIMP_LAYER_COMPOSITE_REGION_SOURCE;
1515
1516 case GIMP_LAYER_COMPOSITE_INTERSECTION:
1517 return GIMP_LAYER_COMPOSITE_REGION_INTERSECTION;
1518
1519 default:
1520 g_return_val_if_reached (GIMP_LAYER_COMPOSITE_REGION_INTERSECTION);
1521 }
1522 }
1523