mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-25 21:21:21 +00:00
Make mask nodes more versatile
Add a GskMaskMode enumeration and implement it in the GL and cairo renderers.
This commit is contained in:
parent
f1311dc053
commit
0eb791eaaa
@ -92,7 +92,7 @@ demo4_widget_snapshot (GtkWidget *widget,
|
||||
width = gtk_widget_get_width (widget);
|
||||
height = gtk_widget_get_height (widget);
|
||||
|
||||
gtk_snapshot_push_mask (snapshot);
|
||||
gtk_snapshot_push_mask (snapshot, GSK_MASK_MODE_INVERTED_ALPHA);
|
||||
gtk_snapshot_append_layout (snapshot, self->layout, &(GdkRGBA) { 0, 0, 0, 1 });
|
||||
gtk_snapshot_pop (snapshot);
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
|
||||
#include "gdkdisplay-wayland.h"
|
||||
#include "gdksurface-wayland.h"
|
||||
#include "gdksurface-wayland-private.h"
|
||||
|
||||
#include "gdkwaylanddisplay.h"
|
||||
#include "gdkwaylandglcontext.h"
|
||||
@ -60,10 +61,15 @@ gdk_wayland_gl_context_end_frame (GdkDrawContext *draw_context,
|
||||
cairo_region_t *painted)
|
||||
{
|
||||
GdkSurface *surface = gdk_draw_context_get_surface (draw_context);
|
||||
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
|
||||
int dx = impl->pending_buffer_offset_x;
|
||||
int dy = impl->pending_buffer_offset_y;
|
||||
|
||||
gdk_wayland_surface_sync (surface);
|
||||
gdk_wayland_surface_request_frame (surface);
|
||||
|
||||
wl_surface_offset (impl->display_server.wl_surface, dx, dy);
|
||||
|
||||
GDK_DRAW_CONTEXT_CLASS (gdk_wayland_gl_context_parent_class)->end_frame (draw_context, painted);
|
||||
|
||||
gdk_wayland_surface_notify_committed (surface);
|
||||
|
@ -229,7 +229,7 @@ gdk_wayland_surface_update_size (GdkSurface *surface,
|
||||
|
||||
if (impl->display_server.egl_window)
|
||||
wl_egl_window_resize (impl->display_server.egl_window, width * scale, height * scale, 0, 0);
|
||||
if (impl->display_server.wl_surface)
|
||||
if (impl->display_server.wl_surface && scale_changed)
|
||||
wl_surface_set_buffer_scale (impl->display_server.wl_surface, scale);
|
||||
|
||||
gdk_surface_invalidate_rect (surface, NULL);
|
||||
@ -588,6 +588,7 @@ gdk_wayland_surface_sync_offset (GdkSurface *surface)
|
||||
WL_SURFACE_OFFSET_SINCE_VERSION)
|
||||
return;
|
||||
|
||||
#if 0
|
||||
if (impl->pending_buffer_offset_x == 0 &&
|
||||
impl->pending_buffer_offset_y == 0)
|
||||
return;
|
||||
@ -597,6 +598,7 @@ gdk_wayland_surface_sync_offset (GdkSurface *surface)
|
||||
impl->pending_buffer_offset_y);
|
||||
impl->pending_buffer_offset_x = 0;
|
||||
impl->pending_buffer_offset_y = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -62,7 +62,8 @@ GSK_GL_DEFINE_PROGRAM (linear_gradient,
|
||||
|
||||
GSK_GL_DEFINE_PROGRAM (mask,
|
||||
GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("mask.glsl")),
|
||||
GSK_GL_ADD_UNIFORM (1, MASK_SOURCE, u_mask))
|
||||
GSK_GL_ADD_UNIFORM (1, MASK_SOURCE, u_mask)
|
||||
GSK_GL_ADD_UNIFORM (2, MASK_MODE, u_mode))
|
||||
|
||||
GSK_GL_DEFINE_PROGRAM (outset_shadow,
|
||||
GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("outset_shadow.glsl")),
|
||||
|
@ -3278,8 +3278,8 @@ gsk_gl_render_job_visit_blend_node (GskGLRenderJob *job,
|
||||
}
|
||||
|
||||
static inline void
|
||||
gsk_gl_render_job_visit_mask_node (GskGLRenderJob *job,
|
||||
const GskRenderNode *node)
|
||||
gsk_gl_render_job_visit_mask_node (GskGLRenderJob *job,
|
||||
const GskRenderNode *node)
|
||||
{
|
||||
const GskRenderNode *source = gsk_mask_node_get_source (node);
|
||||
const GskRenderNode *mask = gsk_mask_node_get_mask (node);
|
||||
@ -3293,6 +3293,7 @@ gsk_gl_render_job_visit_mask_node (GskGLRenderJob *job,
|
||||
mask_offscreen.bounds = &node->bounds;
|
||||
mask_offscreen.force_offscreen = TRUE;
|
||||
mask_offscreen.reset_clip = TRUE;
|
||||
mask_offscreen.do_not_cache = TRUE;
|
||||
|
||||
/* TODO: We create 2 textures here as big as the mask node, but both
|
||||
* nodes might be a lot smaller than that.
|
||||
@ -3323,6 +3324,9 @@ gsk_gl_render_job_visit_mask_node (GskGLRenderJob *job,
|
||||
GL_TEXTURE_2D,
|
||||
GL_TEXTURE1,
|
||||
mask_offscreen.texture_id);
|
||||
gsk_gl_program_set_uniform1i (job->current_program,
|
||||
UNIFORM_MASK_MODE, 0,
|
||||
gsk_mask_node_get_mask_mode (node));
|
||||
gsk_gl_render_job_draw_offscreen_rect (job, &node->bounds);
|
||||
gsk_gl_render_job_end_draw (job);
|
||||
}
|
||||
|
@ -10,10 +10,24 @@ void main() {
|
||||
// FRAGMENT_SHADER:
|
||||
// mask.glsl
|
||||
|
||||
uniform int u_mode;
|
||||
uniform sampler2D u_mask;
|
||||
|
||||
void main() {
|
||||
vec4 source = GskTexture(u_source, vUv);
|
||||
vec4 mask = GskTexture(u_mask, vUv);
|
||||
gskSetOutputColor(vec4 (source * mask.a));
|
||||
float mask_value;
|
||||
|
||||
if (u_mode == 0)
|
||||
mask_value = mask.a;
|
||||
else if (u_mode == 1)
|
||||
mask_value = 1 - mask.a;
|
||||
else if (u_mode == 2)
|
||||
mask_value = (0.2126 * mask.r + 0.7152 * mask.g + 0.0722 * mask.b) * mask.a;
|
||||
else if (u_mode == 3)
|
||||
mask_value = 1 - (0.2126 * mask.r + 0.7152 * mask.g + 0.0722 * mask.b) * mask.a;
|
||||
else
|
||||
mask_value = 0;
|
||||
|
||||
gskSetOutputColor(vec4 (source * mask_value));
|
||||
}
|
||||
|
@ -255,5 +255,25 @@ typedef enum
|
||||
GSK_GL_UNIFORM_TYPE_VEC4,
|
||||
} GskGLUniformType;
|
||||
|
||||
/**
|
||||
* GskMaskMode:
|
||||
* @GSK_MASK_MODE_ALPHA: Use the alpha channel of the mask
|
||||
* @GSK_MASK_MODE_INVERTED_ALPHA: Use the inverted alpha channel of the mask
|
||||
* @GSK_MASK_MODE_LUMINANCE: Use the luminance of the mask,
|
||||
* multiplied by mask alpha
|
||||
* @GSK_MASK_MODE_INVERTED_LUMINANCE: Use the inverted luminance of the mask,
|
||||
* multiplied by mask alpha
|
||||
*
|
||||
* The mask modes available for mask nodes.
|
||||
*
|
||||
* Since: 4.10
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
GSK_MASK_MODE_ALPHA,
|
||||
GSK_MASK_MODE_INVERTED_ALPHA,
|
||||
GSK_MASK_MODE_LUMINANCE,
|
||||
GSK_MASK_MODE_INVERTED_LUMINANCE
|
||||
} GskMaskMode;
|
||||
|
||||
#endif /* __GSK_TYPES_H__ */
|
||||
|
@ -535,11 +535,14 @@ GDK_AVAILABLE_IN_4_10
|
||||
GType gsk_mask_node_get_type (void) G_GNUC_CONST;
|
||||
GDK_AVAILABLE_IN_4_10
|
||||
GskRenderNode * gsk_mask_node_new (GskRenderNode *source,
|
||||
GskRenderNode *mask);
|
||||
GskRenderNode *mask,
|
||||
GskMaskMode mask_mode);
|
||||
GDK_AVAILABLE_IN_4_10
|
||||
GskRenderNode * gsk_mask_node_get_source (const GskRenderNode *node);
|
||||
GDK_AVAILABLE_IN_4_10
|
||||
GskRenderNode * gsk_mask_node_get_mask (const GskRenderNode *node);
|
||||
GDK_AVAILABLE_IN_4_10
|
||||
GskMaskMode gsk_mask_node_get_mask_mode (const GskRenderNode *node);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GType gsk_gl_shader_node_get_type (void) G_GNUC_CONST;
|
||||
|
@ -3410,29 +3410,18 @@ gsk_color_matrix_node_finalize (GskRenderNode *node)
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_color_matrix_node_draw (GskRenderNode *node,
|
||||
cairo_t *cr)
|
||||
apply_color_matrix_to_pattern (cairo_pattern_t *pattern,
|
||||
const graphene_matrix_t *color_matrix,
|
||||
const graphene_vec4_t *color_offset,
|
||||
gboolean multiply_alpha)
|
||||
{
|
||||
GskColorMatrixNode *self = (GskColorMatrixNode *) node;
|
||||
cairo_pattern_t *pattern;
|
||||
cairo_surface_t *surface, *image_surface;
|
||||
graphene_vec4_t pixel;
|
||||
guint32* pixel_data;
|
||||
guchar *data;
|
||||
gsize x, y, width, height, stride;
|
||||
float alpha;
|
||||
float alpha, orig_alpha;
|
||||
graphene_vec4_t pixel;
|
||||
guint32* pixel_data;
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
/* clip so the push_group() creates a smaller surface */
|
||||
gsk_cairo_rectangle (cr, &node->bounds);
|
||||
cairo_clip (cr);
|
||||
|
||||
cairo_push_group (cr);
|
||||
|
||||
gsk_render_node_draw (self->child, cr);
|
||||
|
||||
pattern = cairo_pop_group (cr);
|
||||
cairo_pattern_get_surface (pattern, &surface);
|
||||
image_surface = cairo_surface_map_to_image (surface, NULL);
|
||||
|
||||
@ -3446,7 +3435,7 @@ gsk_color_matrix_node_draw (GskRenderNode *node,
|
||||
pixel_data = (guint32 *) data;
|
||||
for (x = 0; x < width; x++)
|
||||
{
|
||||
alpha = ((pixel_data[x] >> 24) & 0xFF) / 255.0;
|
||||
alpha = orig_alpha = ((pixel_data[x] >> 24) & 0xFF) / 255.0;
|
||||
|
||||
if (alpha == 0)
|
||||
{
|
||||
@ -3459,12 +3448,16 @@ gsk_color_matrix_node_draw (GskRenderNode *node,
|
||||
((pixel_data[x] >> 8) & 0xFF) / (255.0 * alpha),
|
||||
( pixel_data[x] & 0xFF) / (255.0 * alpha),
|
||||
alpha);
|
||||
graphene_matrix_transform_vec4 (&self->color_matrix, &pixel, &pixel);
|
||||
graphene_matrix_transform_vec4 (color_matrix, &pixel, &pixel);
|
||||
}
|
||||
|
||||
graphene_vec4_add (&pixel, &self->color_offset, &pixel);
|
||||
graphene_vec4_add (&pixel, color_offset, &pixel);
|
||||
|
||||
alpha = graphene_vec4_get_w (&pixel);
|
||||
|
||||
if (multiply_alpha)
|
||||
alpha *= orig_alpha;
|
||||
|
||||
if (alpha > 0.0)
|
||||
{
|
||||
alpha = MIN (alpha, 1.0);
|
||||
@ -3483,6 +3476,28 @@ gsk_color_matrix_node_draw (GskRenderNode *node,
|
||||
|
||||
cairo_surface_mark_dirty (image_surface);
|
||||
cairo_surface_unmap_image (surface, image_surface);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_color_matrix_node_draw (GskRenderNode *node,
|
||||
cairo_t *cr)
|
||||
{
|
||||
GskColorMatrixNode *self = (GskColorMatrixNode *) node;
|
||||
cairo_pattern_t *pattern;
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
/* clip so the push_group() creates a smaller surface */
|
||||
gsk_cairo_rectangle (cr, &node->bounds);
|
||||
cairo_clip (cr);
|
||||
|
||||
cairo_push_group (cr);
|
||||
|
||||
gsk_render_node_draw (self->child, cr);
|
||||
|
||||
pattern = cairo_pop_group (cr);
|
||||
|
||||
apply_color_matrix_to_pattern (pattern, &self->color_matrix, &self->color_offset, FALSE);
|
||||
|
||||
cairo_set_source (cr, pattern);
|
||||
cairo_paint (cr);
|
||||
@ -5202,6 +5217,7 @@ struct _GskMaskNode
|
||||
|
||||
GskRenderNode *mask;
|
||||
GskRenderNode *source;
|
||||
GskMaskMode mask_mode;
|
||||
};
|
||||
|
||||
static void
|
||||
@ -5219,6 +5235,8 @@ gsk_mask_node_draw (GskRenderNode *node,
|
||||
{
|
||||
GskMaskNode *self = (GskMaskNode *) node;
|
||||
cairo_pattern_t *mask_pattern;
|
||||
graphene_matrix_t color_matrix;
|
||||
graphene_vec4_t color_offset;
|
||||
|
||||
cairo_push_group (cr);
|
||||
gsk_render_node_draw (self->source, cr);
|
||||
@ -5228,6 +5246,41 @@ gsk_mask_node_draw (GskRenderNode *node,
|
||||
gsk_render_node_draw (self->mask, cr);
|
||||
mask_pattern = cairo_pop_group (cr);
|
||||
|
||||
switch (self->mask_mode)
|
||||
{
|
||||
case GSK_MASK_MODE_ALPHA:
|
||||
break;
|
||||
case GSK_MASK_MODE_INVERTED_ALPHA:
|
||||
graphene_matrix_init_from_float (&color_matrix, (float[]){ 1, 0, 0, 0,
|
||||
0, 1, 0, 0,
|
||||
0, 0, 1, 0,
|
||||
0, 0, 0, -1 });
|
||||
graphene_vec4_init (&color_offset, 0, 0, 0, 1);
|
||||
apply_color_matrix_to_pattern (mask_pattern, &color_matrix, &color_offset, FALSE);
|
||||
break;
|
||||
case GSK_MASK_MODE_LUMINANCE:
|
||||
graphene_matrix_init_from_float (&color_matrix, (float[]){ 1, 0, 0, 0.2126,
|
||||
0, 1, 0, 0.7152,
|
||||
0, 0, 1, 0.0722,
|
||||
0, 0, 0, 0 });
|
||||
graphene_vec4_init (&color_offset, 0, 0, 0, 0);
|
||||
apply_color_matrix_to_pattern (mask_pattern, &color_matrix, &color_offset, TRUE);
|
||||
break;
|
||||
case GSK_MASK_MODE_INVERTED_LUMINANCE:
|
||||
graphene_matrix_init_from_float (&color_matrix, (float[]){ 1, 0, 0, -0.2126,
|
||||
0, 1, 0, -0.7152,
|
||||
0, 0, 1, -0.0722,
|
||||
0, 0, 0, 0 });
|
||||
graphene_vec4_init (&color_offset, 0, 0, 0, 1);
|
||||
apply_color_matrix_to_pattern (mask_pattern, &color_matrix, &color_offset, TRUE);
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
gsk_cairo_rectangle (cr, &node->bounds);
|
||||
cairo_clip (cr);
|
||||
|
||||
cairo_mask (cr, mask_pattern);
|
||||
}
|
||||
|
||||
@ -5245,11 +5298,15 @@ gsk_mask_node_diff (GskRenderNode *node1,
|
||||
|
||||
/**
|
||||
* gsk_mask_node_new:
|
||||
* @source: The bottom node to be drawn
|
||||
* @mask: The node to be blended onto the @bottom node
|
||||
* @source: The source node to be drawn
|
||||
* @mask: The node to be used as mask
|
||||
* @mask_mode: The mask mode to use
|
||||
*
|
||||
* Creates a `GskRenderNode` that will use @blend_mode to blend the @top
|
||||
* node onto the @bottom node.
|
||||
* Creates a `GskRenderNode` that will mask a given node by another.
|
||||
*
|
||||
* The @mask_mode determines how the 'mask values' are derived from
|
||||
* the colors of the @mask. Applying the mask consists of multiplying
|
||||
* the 'mask value' with the alpha of the source.
|
||||
*
|
||||
* Returns: (transfer full) (type GskMaskNode): A new `GskRenderNode`
|
||||
*
|
||||
@ -5257,7 +5314,8 @@ gsk_mask_node_diff (GskRenderNode *node1,
|
||||
*/
|
||||
GskRenderNode *
|
||||
gsk_mask_node_new (GskRenderNode *source,
|
||||
GskRenderNode *mask)
|
||||
GskRenderNode *mask,
|
||||
GskMaskMode mask_mode)
|
||||
{
|
||||
GskMaskNode *self;
|
||||
|
||||
@ -5267,15 +5325,18 @@ gsk_mask_node_new (GskRenderNode *source,
|
||||
self = gsk_render_node_alloc (GSK_MASK_NODE);
|
||||
self->source = gsk_render_node_ref (source);
|
||||
self->mask = gsk_render_node_ref (mask);
|
||||
self->mask_mode = mask_mode;
|
||||
|
||||
graphene_rect_union (&source->bounds, &mask->bounds, &self->render_node.bounds);
|
||||
self->render_node.bounds = source->bounds;
|
||||
|
||||
self->render_node.prefers_high_depth = gsk_render_node_prefers_high_depth (source);
|
||||
|
||||
return &self->render_node;
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_mask_node_get_source:
|
||||
* @node: (type GskBlendNode): a mask `GskRenderNode`
|
||||
* @node: (type GskMaskNode): a mask `GskRenderNode`
|
||||
*
|
||||
* Retrieves the source `GskRenderNode` child of the @node.
|
||||
*
|
||||
@ -5295,7 +5356,7 @@ gsk_mask_node_get_source (const GskRenderNode *node)
|
||||
|
||||
/**
|
||||
* gsk_mask_node_get_mask:
|
||||
* @node: (type GskBlendNode): a mask `GskRenderNode`
|
||||
* @node: (type GskMaskNode): a mask `GskRenderNode`
|
||||
*
|
||||
* Retrieves the mask `GskRenderNode` child of the @node.
|
||||
*
|
||||
@ -5313,6 +5374,24 @@ gsk_mask_node_get_mask (const GskRenderNode *node)
|
||||
return self->mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_mask_node_get_mask_mode:
|
||||
* @node: (type GskMaskNode): a blending `GskRenderNode`
|
||||
*
|
||||
* Retrieves the mask mode used by @node.
|
||||
*
|
||||
* Returns: the mask mode
|
||||
*
|
||||
* Since: 4.10
|
||||
*/
|
||||
GskMaskMode
|
||||
gsk_mask_node_get_mask_mode (const GskRenderNode *node)
|
||||
{
|
||||
const GskMaskNode *self = (const GskMaskNode *) node;
|
||||
|
||||
return self->mask_mode;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
/* {{{ GSK_DEBUG_NODE */
|
||||
|
||||
|
@ -649,6 +649,18 @@ static const struct
|
||||
{ GSK_BLEND_MODE_LUMINOSITY, "luminosity" }
|
||||
};
|
||||
|
||||
static const char *
|
||||
get_blend_mode_name (GskBlendMode mode)
|
||||
{
|
||||
for (unsigned int i = 0; i < G_N_ELEMENTS (blend_modes); i++)
|
||||
{
|
||||
if (blend_modes[i].mode == mode)
|
||||
return blend_modes[i].name;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
parse_blend_mode (GtkCssParser *parser,
|
||||
gpointer out_mode)
|
||||
@ -667,6 +679,46 @@ parse_blend_mode (GtkCssParser *parser,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static const struct
|
||||
{
|
||||
GskMaskMode mode;
|
||||
const char *name;
|
||||
} mask_modes[] = {
|
||||
{ GSK_MASK_MODE_ALPHA, "alpha" },
|
||||
{ GSK_MASK_MODE_INVERTED_ALPHA, "inverted-alpha" },
|
||||
{ GSK_MASK_MODE_LUMINANCE, "luminance" },
|
||||
};
|
||||
|
||||
static const char *
|
||||
get_mask_mode_name (GskMaskMode mode)
|
||||
{
|
||||
for (unsigned int i = 0; i < G_N_ELEMENTS (mask_modes); i++)
|
||||
{
|
||||
if (mask_modes[i].mode == mode)
|
||||
return mask_modes[i].name;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
parse_mask_mode (GtkCssParser *parser,
|
||||
gpointer out_mode)
|
||||
{
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (mask_modes); i++)
|
||||
{
|
||||
if (gtk_css_parser_try_ident (parser, mask_modes[i].name))
|
||||
{
|
||||
*(GskMaskMode *) out_mode = mask_modes[i].mode;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static PangoFont *
|
||||
font_from_string (const char *string)
|
||||
{
|
||||
@ -1381,7 +1433,9 @@ parse_mask_node (GtkCssParser *parser)
|
||||
{
|
||||
GskRenderNode *source = NULL;
|
||||
GskRenderNode *mask = NULL;
|
||||
GskMaskMode mode = GSK_MASK_MODE_ALPHA;
|
||||
const Declaration declarations[] = {
|
||||
{ "mode", parse_mask_mode, NULL, &mode },
|
||||
{ "source", parse_node, clear_node, &source },
|
||||
{ "mask", parse_node, clear_node, &mask },
|
||||
};
|
||||
@ -1393,7 +1447,7 @@ parse_mask_node (GtkCssParser *parser)
|
||||
if (mask == NULL)
|
||||
mask = gsk_color_node_new (&GDK_RGBA("AAFF00"), &GRAPHENE_RECT_INIT (0, 0, 50, 50));
|
||||
|
||||
result = gsk_mask_node_new (source, mask);
|
||||
result = gsk_mask_node_new (source, mask, mode);
|
||||
|
||||
gsk_render_node_unref (source);
|
||||
gsk_render_node_unref (mask);
|
||||
@ -3103,21 +3157,13 @@ render_node_print (Printer *p,
|
||||
case GSK_BLEND_NODE:
|
||||
{
|
||||
GskBlendMode mode = gsk_blend_node_get_blend_mode (node);
|
||||
guint i;
|
||||
|
||||
start_node (p, "blend");
|
||||
|
||||
if (mode != GSK_BLEND_MODE_DEFAULT)
|
||||
{
|
||||
_indent (p);
|
||||
for (i = 0; i < G_N_ELEMENTS (blend_modes); i++)
|
||||
{
|
||||
if (blend_modes[i].mode == mode)
|
||||
{
|
||||
g_string_append_printf (p->str, "mode: %s;\n", blend_modes[i].name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
g_string_append_printf (p->str, "mode: %s;\n", get_blend_mode_name (mode));
|
||||
}
|
||||
append_node_param (p, "bottom", gsk_blend_node_get_bottom_child (node));
|
||||
append_node_param (p, "top", gsk_blend_node_get_top_child (node));
|
||||
@ -3128,8 +3174,15 @@ render_node_print (Printer *p,
|
||||
|
||||
case GSK_MASK_NODE:
|
||||
{
|
||||
GskMaskMode mode = gsk_mask_node_get_mask_mode (node);
|
||||
|
||||
start_node (p, "mask");
|
||||
|
||||
if (mode != GSK_MASK_MODE_ALPHA)
|
||||
{
|
||||
_indent (p);
|
||||
g_string_append_printf (p->str, "mode: %s;\n", get_mask_mode_name (mode));
|
||||
}
|
||||
append_node_param (p, "source", gsk_mask_node_get_source (node));
|
||||
append_node_param (p, "mask", gsk_mask_node_get_mask (node));
|
||||
|
||||
|
@ -122,6 +122,7 @@ struct _GtkSnapshotState {
|
||||
char *message;
|
||||
} debug;
|
||||
struct {
|
||||
GskMaskMode mask_mode;
|
||||
GskRenderNode *mask_node;
|
||||
} mask;
|
||||
} data;
|
||||
@ -1258,7 +1259,7 @@ gtk_snapshot_collect_mask_source (GtkSnapshot *snapshot,
|
||||
if (source_child == NULL || mask_child == NULL)
|
||||
return NULL;
|
||||
|
||||
mask_node = gsk_mask_node_new (source_child, mask_child);
|
||||
mask_node = gsk_mask_node_new (source_child, mask_child, state->data.mask.mask_mode);
|
||||
|
||||
gsk_render_node_unref (source_child);
|
||||
gsk_render_node_unref (mask_child);
|
||||
@ -1290,9 +1291,11 @@ gtk_snapshot_collect_mask_mask (GtkSnapshot *snapshot,
|
||||
/**
|
||||
* gtk_snapshot_push_mask:
|
||||
* @snapshot: a #GtkSnapshot
|
||||
* @mask_mode: mask mode to use
|
||||
*
|
||||
* Until the first call to [method@Gtk.Snapshot.pop], the
|
||||
* mask image for the mask operation will be recorded.
|
||||
*
|
||||
* After that call, the source image will be recorded until
|
||||
* the second call to [method@Gtk.Snapshot.pop].
|
||||
*
|
||||
@ -1301,7 +1304,8 @@ gtk_snapshot_collect_mask_mask (GtkSnapshot *snapshot,
|
||||
* Since: 4.10
|
||||
*/
|
||||
void
|
||||
gtk_snapshot_push_mask (GtkSnapshot *snapshot)
|
||||
gtk_snapshot_push_mask (GtkSnapshot *snapshot,
|
||||
GskMaskMode mask_mode)
|
||||
{
|
||||
GtkSnapshotState *current_state = gtk_snapshot_get_current_state (snapshot);
|
||||
GtkSnapshotState *source_state;
|
||||
@ -1311,6 +1315,8 @@ gtk_snapshot_push_mask (GtkSnapshot *snapshot)
|
||||
gtk_snapshot_collect_mask_source,
|
||||
gtk_snapshot_clear_mask_source);
|
||||
|
||||
source_state->data.mask.mask_mode = mask_mode;
|
||||
|
||||
gtk_snapshot_push_state (snapshot,
|
||||
source_state->transform,
|
||||
gtk_snapshot_collect_mask_mask,
|
||||
|
@ -96,7 +96,8 @@ GDK_AVAILABLE_IN_ALL
|
||||
void gtk_snapshot_push_blend (GtkSnapshot *snapshot,
|
||||
GskBlendMode blend_mode);
|
||||
GDK_AVAILABLE_IN_4_10
|
||||
void gtk_snapshot_push_mask (GtkSnapshot *snapshot);
|
||||
void gtk_snapshot_push_mask (GtkSnapshot *snapshot,
|
||||
GskMaskMode mask_mode);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_snapshot_push_cross_fade (GtkSnapshot *snapshot,
|
||||
|
@ -1140,6 +1140,12 @@ populate_render_node_properties (GListStore *store,
|
||||
break;
|
||||
|
||||
case GSK_MASK_NODE:
|
||||
{
|
||||
GskMaskMode mode = gsk_mask_node_get_mask_mode (node);
|
||||
tmp = g_enum_to_string (GSK_TYPE_MASK_MODE, mode);
|
||||
add_text_row (store, "Mask mode", tmp);
|
||||
g_free (tmp);
|
||||
}
|
||||
break;
|
||||
|
||||
case GSK_BLUR_NODE:
|
||||
|
Loading…
Reference in New Issue
Block a user