Compare commits
76 Commits
3.89.2
...
no-init-args
| Author | SHA1 | Date | |
|---|---|---|---|
| 1ae7240932 | |||
| a3e2fc2df6 | |||
| deed306e5a | |||
| 9cc64449a8 | |||
| 72877343fd | |||
| 8a816dbc19 | |||
| 002d616ca4 | |||
| 3ea1b37aff | |||
| 1d6435db48 | |||
| 5b411031ba | |||
| 68b39a4727 | |||
| a5f8a74ec1 | |||
| 293248c1d3 | |||
| af917c4ade | |||
| c0c44c7b9c | |||
| 573ceb0340 | |||
| d7e867aa95 | |||
| 3c8518dce3 | |||
| 599cc995f3 | |||
| 5017c3be65 | |||
| 3a79b17309 | |||
| c7083a5d37 | |||
| 2a7171534e | |||
| 71bbd8881f | |||
| 5d10174031 | |||
| 476cadc7f8 | |||
| 78582dd5e9 | |||
| eacf725778 | |||
| c99b46c46d | |||
| 5878f9d8af | |||
| b30225e67c | |||
| 16a9a82021 | |||
| aa0ec774bf | |||
| 81c487b841 | |||
| 18b65a2378 | |||
| b11b7dfb1a | |||
| 2bca24c455 | |||
| 1d84555729 | |||
| 89d38ae93f | |||
| 23d10df6c6 | |||
| 2750bb5e87 | |||
| 6cc08d60ef | |||
| b97e4e8631 | |||
| a36e5ceea7 | |||
| 513a8c46af | |||
| a0f65d16bc | |||
| b901572d86 | |||
| c412a717f1 | |||
| 677c5bdedf | |||
| af6e7cc169 | |||
| 4bb0c70c11 | |||
| 4e866ec06b | |||
| 5e089c4345 | |||
| 087ea8e531 | |||
| 08f9a6078b | |||
| adcde3034e | |||
| 786d3a013e | |||
| b0d5224de5 | |||
| 6c56793147 | |||
| d58799ff7a | |||
| be8c999fe8 | |||
| 2d2209859e | |||
| 373e08d6d4 | |||
| 98086014d8 | |||
| d2622d93ad | |||
| df5e12fc1d | |||
| 814b66e1a8 | |||
| b4ac7ffed4 | |||
| 735846cc82 | |||
| 91c71b10e6 | |||
| c88d279416 | |||
| 3a38bc9bf7 | |||
| 5fa1733944 | |||
| 0efeaf9508 | |||
| f1825f5eff | |||
| 23edff1606 |
@@ -12,6 +12,7 @@ gsk_renderer_unrealize
|
||||
gsk_renderer_begin_draw_frame
|
||||
gsk_renderer_end_draw_frame
|
||||
gsk_renderer_render
|
||||
gsk_renderer_render_texture
|
||||
<SUBSECTION Standard>
|
||||
GSK_IS_RENDERER
|
||||
GSK_RENDERER
|
||||
@@ -29,9 +30,15 @@ gsk_render_node_unref
|
||||
GskRenderNodeType
|
||||
gsk_render_node_get_node_type
|
||||
gsk_render_node_draw
|
||||
GskSerializationError
|
||||
gsk_render_node_serialize
|
||||
gsk_render_node_deserialize
|
||||
gsk_render_node_write_to_file
|
||||
GskScalingFilter
|
||||
gsk_render_node_set_scaling_filters
|
||||
gsk_render_node_set_name
|
||||
gsk_render_node_get_name
|
||||
gsk_render_node_get_bounds
|
||||
gsk_color_node_new
|
||||
gsk_linear_gradient_node_new
|
||||
gsk_repeating_linear_gradient_node_new
|
||||
@@ -66,6 +73,26 @@ GskRenderNode
|
||||
GskRenderNodeClass
|
||||
gsk_render_node_get_type
|
||||
GSK_TYPE_BLEND_MODE
|
||||
<SUBSECTION Standard>
|
||||
gsk_serialization_error_quark
|
||||
GSK_SERIALIZATION_ERROR
|
||||
GSK_TYPE_SERIALIZATION_ERROR
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>GskTexture</FILE>
|
||||
gsk_texture_ref
|
||||
gsk_texture_unref
|
||||
gsk_texture_new_for_data
|
||||
gsk_texture_new_for_pixbuf
|
||||
gsk_texture_get_width
|
||||
gsk_texture_get_height
|
||||
gsk_texture_download
|
||||
<SUBSECTION Standard>
|
||||
GskTexture
|
||||
gsk_texture_get_type
|
||||
GSK_TYPE_TEXTURE
|
||||
GSK_IS_TEXTURE
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
|
||||
@@ -4052,7 +4052,7 @@ gtk_cell_area_has_renderer
|
||||
gtk_cell_area_foreach
|
||||
gtk_cell_area_foreach_alloc
|
||||
gtk_cell_area_event
|
||||
gtk_cell_area_render
|
||||
gtk_cell_area_snapshot
|
||||
gtk_cell_area_get_cell_allocation
|
||||
gtk_cell_area_get_cell_at_position
|
||||
gtk_cell_area_create_context
|
||||
@@ -4170,7 +4170,7 @@ GtkCellRendererClass
|
||||
gtk_cell_renderer_class_set_accessible_type
|
||||
gtk_cell_renderer_get_aligned_area
|
||||
gtk_cell_renderer_get_size
|
||||
gtk_cell_renderer_render
|
||||
gtk_cell_renderer_snapshot
|
||||
gtk_cell_renderer_activate
|
||||
gtk_cell_renderer_start_editing
|
||||
gtk_cell_renderer_stop_editing
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@ main (int argc,
|
||||
GObject *window;
|
||||
GObject *button;
|
||||
|
||||
gtk_init (&argc, &argv);
|
||||
gtk_init ();
|
||||
|
||||
/* Construct a GtkBuilder instance and load our UI description */
|
||||
builder = gtk_builder_new ();
|
||||
|
||||
@@ -173,93 +173,7 @@ static const GDebugKey gdk_debug_keys[] = {
|
||||
{ "opengl", GDK_DEBUG_OPENGL },
|
||||
{ "vulkan", GDK_DEBUG_VULKAN }
|
||||
};
|
||||
|
||||
static gboolean
|
||||
gdk_arg_debug_cb (const char *key, const char *value, gpointer user_data, GError **error)
|
||||
{
|
||||
guint debug_value = g_parse_debug_string (value,
|
||||
(GDebugKey *) gdk_debug_keys,
|
||||
G_N_ELEMENTS (gdk_debug_keys));
|
||||
|
||||
if (debug_value == 0 && value != NULL && strcmp (value, "") != 0)
|
||||
{
|
||||
g_set_error (error,
|
||||
G_OPTION_ERROR, G_OPTION_ERROR_FAILED,
|
||||
_("Error parsing option --gdk-debug"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
_gdk_debug_flags |= debug_value;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_arg_no_debug_cb (const char *key, const char *value, gpointer user_data, GError **error)
|
||||
{
|
||||
guint debug_value = g_parse_debug_string (value,
|
||||
(GDebugKey *) gdk_debug_keys,
|
||||
G_N_ELEMENTS (gdk_debug_keys));
|
||||
|
||||
if (debug_value == 0 && value != NULL && strcmp (value, "") != 0)
|
||||
{
|
||||
g_set_error (error,
|
||||
G_OPTION_ERROR, G_OPTION_ERROR_FAILED,
|
||||
_("Error parsing option --gdk-no-debug"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
_gdk_debug_flags &= ~debug_value;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
#endif /* G_ENABLE_DEBUG */
|
||||
|
||||
static gboolean
|
||||
gdk_arg_class_cb (const char *key, const char *value, gpointer user_data, GError **error)
|
||||
{
|
||||
gdk_set_program_class (value);
|
||||
gdk_progclass_overridden = TRUE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_arg_name_cb (const char *key, const char *value, gpointer user_data, GError **error)
|
||||
{
|
||||
g_set_prgname (value);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static const GOptionEntry gdk_args[] = {
|
||||
{ "class", 0, 0, G_OPTION_ARG_CALLBACK, gdk_arg_class_cb,
|
||||
/* Description of --class=CLASS in --help output */ N_("Program class as used by the window manager"),
|
||||
/* Placeholder in --class=CLASS in --help output */ N_("CLASS") },
|
||||
{ "name", 0, 0, G_OPTION_ARG_CALLBACK, gdk_arg_name_cb,
|
||||
/* Description of --name=NAME in --help output */ N_("Program name as used by the window manager"),
|
||||
/* Placeholder in --name=NAME in --help output */ N_("NAME") },
|
||||
#ifndef G_OS_WIN32
|
||||
{ "display", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_STRING, &_gdk_display_name,
|
||||
/* Description of --display=DISPLAY in --help output */ N_("X display to use"),
|
||||
/* Placeholder in --display=DISPLAY in --help output */ N_("DISPLAY") },
|
||||
#endif
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
{ "gdk-debug", 0, 0, G_OPTION_ARG_CALLBACK, gdk_arg_debug_cb,
|
||||
/* Description of --gdk-debug=FLAGS in --help output */ N_("GDK debugging flags to set"),
|
||||
/* Placeholder in --gdk-debug=FLAGS in --help output */ N_("FLAGS") },
|
||||
{ "gdk-no-debug", 0, 0, G_OPTION_ARG_CALLBACK, gdk_arg_no_debug_cb,
|
||||
/* Description of --gdk-no-debug=FLAGS in --help output */ N_("GDK debugging flags to unset"),
|
||||
/* Placeholder in --gdk-no-debug=FLAGS in --help output */ N_("FLAGS") },
|
||||
#endif
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
void
|
||||
gdk_add_option_entries (GOptionGroup *group)
|
||||
{
|
||||
g_option_group_add_entries (group, gdk_args);
|
||||
}
|
||||
|
||||
static gpointer
|
||||
register_resources (gpointer dummy G_GNUC_UNUSED)
|
||||
@@ -328,53 +242,6 @@ gdk_pre_parse (void)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_parse_args:
|
||||
* @argc: the number of command line arguments.
|
||||
* @argv: (inout) (array length=argc): the array of command line arguments.
|
||||
*
|
||||
* Parse command line arguments, and store for future
|
||||
* use by calls to gdk_display_open().
|
||||
*
|
||||
* Any arguments used by GDK are removed from the array and @argc and @argv are
|
||||
* updated accordingly.
|
||||
*
|
||||
* You shouldn’t call this function explicitly if you are using
|
||||
* gtk_init(), gtk_init_check(), gdk_init(), or gdk_init_check().
|
||||
*
|
||||
* Since: 2.2
|
||||
**/
|
||||
void
|
||||
gdk_parse_args (int *argc,
|
||||
char ***argv)
|
||||
{
|
||||
GOptionContext *option_context;
|
||||
GOptionGroup *option_group;
|
||||
GError *error = NULL;
|
||||
|
||||
if (gdk_initialized)
|
||||
return;
|
||||
|
||||
gdk_pre_parse ();
|
||||
|
||||
option_context = g_option_context_new (NULL);
|
||||
g_option_context_set_ignore_unknown_options (option_context, TRUE);
|
||||
g_option_context_set_help_enabled (option_context, FALSE);
|
||||
option_group = g_option_group_new (NULL, NULL, NULL, NULL, NULL);
|
||||
g_option_context_set_main_group (option_context, option_group);
|
||||
|
||||
g_option_group_add_entries (option_group, gdk_args);
|
||||
|
||||
if (!g_option_context_parse (option_context, argc, argv, &error))
|
||||
{
|
||||
g_warning ("%s", error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
g_option_context_free (option_context);
|
||||
|
||||
GDK_NOTE (MISC, g_message ("progname: \"%s\"", g_get_prgname ()));
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_get_display_arg_name:
|
||||
*
|
||||
@@ -424,60 +291,6 @@ gdk_display_open_default (void)
|
||||
return display;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_init_check:
|
||||
* @argc: (inout): the number of command line arguments.
|
||||
* @argv: (array length=argc) (inout): the array of command line arguments.
|
||||
*
|
||||
* Initializes the GDK library and connects to the windowing system,
|
||||
* returning %TRUE on success.
|
||||
*
|
||||
* Any arguments used by GDK are removed from the array and @argc and @argv
|
||||
* are updated accordingly.
|
||||
*
|
||||
* GTK+ initializes GDK in gtk_init() and so this function is not usually
|
||||
* needed by GTK+ applications.
|
||||
*
|
||||
* Returns: %TRUE if initialization succeeded.
|
||||
*/
|
||||
gboolean
|
||||
gdk_init_check (int *argc,
|
||||
char ***argv)
|
||||
{
|
||||
gdk_parse_args (argc, argv);
|
||||
|
||||
return gdk_display_open_default () != NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gdk_init:
|
||||
* @argc: (inout): the number of command line arguments.
|
||||
* @argv: (array length=argc) (inout): the array of command line arguments.
|
||||
*
|
||||
* Initializes the GDK library and connects to the windowing system.
|
||||
* If initialization fails, a warning message is output and the application
|
||||
* terminates with a call to `exit(1)`.
|
||||
*
|
||||
* Any arguments used by GDK are removed from the array and @argc and @argv
|
||||
* are updated accordingly.
|
||||
*
|
||||
* GTK+ initializes GDK in gtk_init() and so this function is not usually
|
||||
* needed by GTK+ applications.
|
||||
*/
|
||||
void
|
||||
gdk_init (int *argc, char ***argv)
|
||||
{
|
||||
if (!gdk_init_check (argc, argv))
|
||||
{
|
||||
const char *display_name = gdk_get_display_arg_name ();
|
||||
g_warning ("cannot open display: %s", display_name ? display_name : "");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* SECTION:threads
|
||||
* @Short_description: Functions for using GDK in multi-threaded programs
|
||||
|
||||
+3
-1
@@ -151,7 +151,7 @@ gdk_cairo_region (cairo_t *cr,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
gdk_cairo_surface_paint_pixbuf (cairo_surface_t *surface,
|
||||
const GdkPixbuf *pixbuf)
|
||||
{
|
||||
@@ -198,7 +198,9 @@ gdk_cairo_surface_paint_pixbuf (cairo_surface_t *surface,
|
||||
q[0] = p[2];
|
||||
q[1] = p[1];
|
||||
q[2] = p[0];
|
||||
q[3] = 0xFF;
|
||||
#else
|
||||
q[0] = 0xFF;
|
||||
q[1] = p[0];
|
||||
q[2] = p[1];
|
||||
q[3] = p[2];
|
||||
|
||||
@@ -343,6 +343,9 @@ void gdk_gl_texture_quads (GdkGLContext *paint_context,
|
||||
GdkTexturedQuad *quads,
|
||||
gboolean flip_colors);
|
||||
|
||||
void gdk_cairo_surface_paint_pixbuf (cairo_surface_t *surface,
|
||||
const GdkPixbuf *pixbuf);
|
||||
|
||||
void gdk_cairo_surface_mark_as_direct (cairo_surface_t *surface,
|
||||
GdkWindow *window);
|
||||
cairo_region_t *gdk_cairo_region_from_clip (cairo_t *cr);
|
||||
|
||||
@@ -40,16 +40,6 @@ G_BEGIN_DECLS
|
||||
|
||||
#define GDK_PRIORITY_EVENTS (G_PRIORITY_DEFAULT)
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_parse_args (gint *argc,
|
||||
gchar ***argv);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_init (gint *argc,
|
||||
gchar ***argv);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gdk_init_check (gint *argc,
|
||||
gchar ***argv);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
const gchar * gdk_get_program_class (void);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
|
||||
+34
-1
@@ -41,6 +41,7 @@ struct _GdkVulkanContextPrivate {
|
||||
|
||||
guint n_images;
|
||||
VkImage *images;
|
||||
cairo_region_t **regions;
|
||||
#endif
|
||||
|
||||
guint32 draw_index;
|
||||
@@ -127,7 +128,13 @@ gdk_vulkan_context_dispose (GObject *gobject)
|
||||
GdkVulkanContextPrivate *priv = gdk_vulkan_context_get_instance_private (context);
|
||||
GdkDisplay *display;
|
||||
VkDevice device;
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < priv->n_images; i++)
|
||||
{
|
||||
cairo_region_destroy (priv->regions[i]);
|
||||
}
|
||||
g_clear_pointer (&priv->regions, g_free);
|
||||
g_clear_pointer (&priv->images, g_free);
|
||||
priv->n_images = 0;
|
||||
|
||||
@@ -176,6 +183,7 @@ gdk_vulkan_context_check_swapchain (GdkVulkanContext *context,
|
||||
VkSwapchainKHR new_swapchain;
|
||||
VkResult res;
|
||||
VkDevice device;
|
||||
guint i;
|
||||
|
||||
if (gdk_window_get_width (window) == priv->swapchain_width &&
|
||||
gdk_window_get_height (window) == priv->swapchain_height)
|
||||
@@ -239,6 +247,11 @@ gdk_vulkan_context_check_swapchain (GdkVulkanContext *context,
|
||||
vkDestroySwapchainKHR (device,
|
||||
priv->swapchain,
|
||||
NULL);
|
||||
for (i = 0; i < priv->n_images; i++)
|
||||
{
|
||||
cairo_region_destroy (priv->regions[i]);
|
||||
}
|
||||
g_clear_pointer (&priv->regions, g_free);
|
||||
g_clear_pointer (&priv->images, g_free);
|
||||
priv->n_images = 0;
|
||||
}
|
||||
@@ -258,6 +271,15 @@ gdk_vulkan_context_check_swapchain (GdkVulkanContext *context,
|
||||
priv->swapchain,
|
||||
&priv->n_images,
|
||||
priv->images);
|
||||
priv->regions = g_new (cairo_region_t *, priv->n_images);
|
||||
for (i = 0; i < priv->n_images; i++)
|
||||
{
|
||||
priv->regions[i] = cairo_region_create_rectangle (&(cairo_rectangle_int_t) {
|
||||
0, 0,
|
||||
gdk_window_get_width (window),
|
||||
gdk_window_get_height (window),
|
||||
});
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -281,6 +303,7 @@ gdk_vulkan_context_begin_frame (GdkDrawContext *draw_context,
|
||||
GdkVulkanContext *context = GDK_VULKAN_CONTEXT (draw_context);
|
||||
GdkVulkanContextPrivate *priv = gdk_vulkan_context_get_instance_private (context);
|
||||
GError *error = NULL;
|
||||
guint i;
|
||||
|
||||
if (!gdk_vulkan_context_check_swapchain (context, &error))
|
||||
{
|
||||
@@ -289,12 +312,19 @@ gdk_vulkan_context_begin_frame (GdkDrawContext *draw_context,
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < priv->n_images; i++)
|
||||
{
|
||||
cairo_region_union (priv->regions[i], region);
|
||||
}
|
||||
|
||||
GDK_VK_CHECK (vkAcquireNextImageKHR, gdk_vulkan_context_get_device (context),
|
||||
priv->swapchain,
|
||||
UINT64_MAX,
|
||||
priv->draw_semaphore,
|
||||
VK_NULL_HANDLE,
|
||||
&priv->draw_index);
|
||||
|
||||
cairo_region_union (region, priv->regions[priv->draw_index]);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -320,6 +350,9 @@ gdk_vulkan_context_end_frame (GdkDrawContext *draw_context,
|
||||
priv->draw_index
|
||||
},
|
||||
});
|
||||
|
||||
cairo_region_destroy (priv->regions[priv->draw_index]);
|
||||
priv->regions[priv->draw_index] = cairo_region_create ();
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -404,7 +437,7 @@ gdk_vulkan_context_real_init (GInitable *initable,
|
||||
&n_formats, formats);
|
||||
for (i = 0; i < n_formats; i++)
|
||||
{
|
||||
if (formats[i].format == VK_FORMAT_B8G8R8A8_SRGB)
|
||||
if (formats[i].format == VK_FORMAT_B8G8R8A8_UNORM)
|
||||
break;
|
||||
}
|
||||
if (i == n_formats)
|
||||
|
||||
@@ -26,8 +26,10 @@ if HAVE_VULKAN
|
||||
gsk_private_vulkan_source_h = \
|
||||
gskvulkanblendpipelineprivate.h \
|
||||
gskvulkanbufferprivate.h \
|
||||
gskvulkanclipprivate.h \
|
||||
gskvulkancolorpipelineprivate.h \
|
||||
gskvulkancommandpoolprivate.h \
|
||||
gskvulkanlineargradientpipelineprivate.h \
|
||||
gskvulkanimageprivate.h \
|
||||
gskvulkanmemoryprivate.h \
|
||||
gskvulkanpipelineprivate.h \
|
||||
@@ -39,8 +41,10 @@ gsk_private_vulkan_source_h = \
|
||||
gsk_private_vulkan_source_c = \
|
||||
gskvulkanblendpipeline.c \
|
||||
gskvulkanbuffer.c \
|
||||
gskvulkanclip.c \
|
||||
gskvulkancolorpipeline.c \
|
||||
gskvulkancommandpool.c \
|
||||
gskvulkanlineargradientpipeline.c \
|
||||
gskvulkanimage.c \
|
||||
gskvulkanmemory.c \
|
||||
gskvulkanpipeline.c \
|
||||
|
||||
+61
-34
@@ -18,8 +18,6 @@ struct _GskCairoRenderer
|
||||
{
|
||||
GskRenderer parent_instance;
|
||||
|
||||
graphene_rect_t viewport;
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
ProfileTimers profile_timers;
|
||||
#endif
|
||||
@@ -47,44 +45,16 @@ gsk_cairo_renderer_unrealize (GskRenderer *renderer)
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_cairo_renderer_render (GskRenderer *renderer,
|
||||
GskRenderNode *root)
|
||||
gsk_cairo_renderer_do_render (GskRenderer *renderer,
|
||||
cairo_t *cr,
|
||||
GskRenderNode *root)
|
||||
{
|
||||
GskCairoRenderer *self = GSK_CAIRO_RENDERER (renderer);
|
||||
GdkDrawingContext *context = gsk_renderer_get_drawing_context (renderer);
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
GskCairoRenderer *self = GSK_CAIRO_RENDERER (renderer);
|
||||
GskProfiler *profiler;
|
||||
gint64 cpu_time;
|
||||
#endif
|
||||
|
||||
cairo_t *cr;
|
||||
|
||||
cr = gdk_drawing_context_get_cairo_context (context);
|
||||
|
||||
g_return_if_fail (cr != NULL);
|
||||
|
||||
gsk_renderer_get_viewport (renderer, &self->viewport);
|
||||
|
||||
cairo_save (cr);
|
||||
cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
|
||||
cairo_set_source_rgba (cr, 0, 0, 0, 0);
|
||||
cairo_paint (cr);
|
||||
cairo_restore (cr);
|
||||
|
||||
if (GSK_RENDER_MODE_CHECK (GEOMETRY))
|
||||
{
|
||||
cairo_save (cr);
|
||||
cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
|
||||
cairo_rectangle (cr,
|
||||
self->viewport.origin.x,
|
||||
self->viewport.origin.y,
|
||||
self->viewport.size.width,
|
||||
self->viewport.size.height);
|
||||
cairo_set_source_rgba (cr, 0, 0, 0.85, 0.5);
|
||||
cairo_stroke (cr);
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
profiler = gsk_renderer_get_profiler (renderer);
|
||||
gsk_profiler_timer_begin (profiler, self->profile_timers.cpu_time);
|
||||
@@ -100,6 +70,62 @@ gsk_cairo_renderer_render (GskRenderer *renderer,
|
||||
#endif
|
||||
}
|
||||
|
||||
static GskTexture *
|
||||
gsk_cairo_renderer_render_texture (GskRenderer *renderer,
|
||||
GskRenderNode *root,
|
||||
const graphene_rect_t *viewport)
|
||||
{
|
||||
GskTexture *texture;
|
||||
cairo_surface_t *surface;
|
||||
cairo_t *cr;
|
||||
|
||||
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, ceil (viewport->size.width), ceil (viewport->size.height));
|
||||
cr = cairo_create (surface);
|
||||
|
||||
cairo_translate (cr, - viewport->origin.x, - viewport->origin.y);
|
||||
|
||||
gsk_cairo_renderer_do_render (renderer, cr, root);
|
||||
|
||||
cairo_destroy (cr);
|
||||
|
||||
texture = gsk_texture_new_for_surface (surface);
|
||||
cairo_surface_destroy (surface);
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_cairo_renderer_render (GskRenderer *renderer,
|
||||
GskRenderNode *root)
|
||||
{
|
||||
GdkDrawingContext *context = gsk_renderer_get_drawing_context (renderer);
|
||||
graphene_rect_t viewport;
|
||||
|
||||
cairo_t *cr;
|
||||
|
||||
cr = gdk_drawing_context_get_cairo_context (context);
|
||||
|
||||
g_return_if_fail (cr != NULL);
|
||||
|
||||
gsk_renderer_get_viewport (renderer, &viewport);
|
||||
|
||||
if (GSK_RENDER_MODE_CHECK (GEOMETRY))
|
||||
{
|
||||
cairo_save (cr);
|
||||
cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
|
||||
cairo_rectangle (cr,
|
||||
viewport.origin.x,
|
||||
viewport.origin.y,
|
||||
viewport.size.width,
|
||||
viewport.size.height);
|
||||
cairo_set_source_rgba (cr, 0, 0, 0.85, 0.5);
|
||||
cairo_stroke (cr);
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
gsk_cairo_renderer_do_render (renderer, cr, root);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_cairo_renderer_class_init (GskCairoRendererClass *klass)
|
||||
{
|
||||
@@ -108,6 +134,7 @@ gsk_cairo_renderer_class_init (GskCairoRendererClass *klass)
|
||||
renderer_class->realize = gsk_cairo_renderer_realize;
|
||||
renderer_class->unrealize = gsk_cairo_renderer_unrealize;
|
||||
renderer_class->render = gsk_cairo_renderer_render;
|
||||
renderer_class->render_texture = gsk_cairo_renderer_render_texture;
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
+3
-1
@@ -9,7 +9,8 @@ static const GDebugKey gsk_debug_keys[] = {
|
||||
{ "shaders", GSK_DEBUG_SHADERS },
|
||||
{ "transforms", GSK_DEBUG_TRANSFORMS },
|
||||
{ "surface", GSK_DEBUG_SURFACE },
|
||||
{ "vulkan", GSK_DEBUG_VULKAN }
|
||||
{ "vulkan", GSK_DEBUG_VULKAN },
|
||||
{ "fallback", GSK_DEBUG_FALLBACK }
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -17,6 +18,7 @@ static const GDebugKey gsk_rendering_keys[] = {
|
||||
{ "geometry", GSK_RENDERING_MODE_GEOMETRY },
|
||||
{ "shaders", GSK_RENDERING_MODE_SHADERS },
|
||||
{ "sync", GSK_RENDERING_MODE_SYNC },
|
||||
{ "full-redraw", GSK_RENDERING_MODE_FULL_REDRAW},
|
||||
{ "staging-image", GSK_RENDERING_MODE_STAGING_IMAGE },
|
||||
{ "staging-buffer", GSK_RENDERING_MODE_STAGING_BUFFER }
|
||||
};
|
||||
|
||||
@@ -13,15 +13,17 @@ typedef enum {
|
||||
GSK_DEBUG_SHADERS = 1 << 4,
|
||||
GSK_DEBUG_TRANSFORMS = 1 << 5,
|
||||
GSK_DEBUG_SURFACE = 1 << 6,
|
||||
GSK_DEBUG_VULKAN = 1 << 7
|
||||
GSK_DEBUG_VULKAN = 1 << 7,
|
||||
GSK_DEBUG_FALLBACK = 1 << 8
|
||||
} GskDebugFlags;
|
||||
|
||||
typedef enum {
|
||||
GSK_RENDERING_MODE_GEOMETRY = 1 << 0,
|
||||
GSK_RENDERING_MODE_SHADERS = 1 << 1,
|
||||
GSK_RENDERING_MODE_SYNC = 1 << 2,
|
||||
GSK_RENDERING_MODE_STAGING_IMAGE = 1 << 3,
|
||||
GSK_RENDERING_MODE_STAGING_BUFFER = 1 << 4
|
||||
GSK_RENDERING_MODE_FULL_REDRAW = 1 << 3,
|
||||
GSK_RENDERING_MODE_STAGING_IMAGE = 1 << 4,
|
||||
GSK_RENDERING_MODE_STAGING_BUFFER = 1 << 5
|
||||
} GskRenderingMode;
|
||||
|
||||
gboolean gsk_check_debug_flags (GskDebugFlags flags);
|
||||
|
||||
@@ -152,4 +152,21 @@ typedef enum {
|
||||
GSK_CORNER_BOTTOM_LEFT
|
||||
} GskCorner;
|
||||
|
||||
/**
|
||||
* GskSerializationError:
|
||||
* @GSK_SERIALIZATION_UNSUPPORTED_FORMAT: The format can not be
|
||||
* identified
|
||||
* @GSK_SERIALIZATION_UNSUPPORTED_VERSION: The version of the data
|
||||
* is not understood
|
||||
* @GSK_SERIALIZATION_INVALID_DATA: The given data may not exist in
|
||||
* a proper serialization
|
||||
*
|
||||
* Errors that can happen during (de)serialization.
|
||||
*/
|
||||
typedef enum {
|
||||
GSK_SERIALIZATION_UNSUPPORTED_FORMAT,
|
||||
GSK_SERIALIZATION_UNSUPPORTED_VERSION,
|
||||
GSK_SERIALIZATION_INVALID_DATA
|
||||
} GskSerializationError;
|
||||
|
||||
#endif /* __GSK_TYPES_H__ */
|
||||
|
||||
+1
-1
@@ -462,7 +462,7 @@ gsk_gl_driver_get_texture_for_texture (GskGLDriver *driver,
|
||||
if (gsk_texture_set_render_data (texture, driver, t, gsk_gl_driver_release_texture))
|
||||
t->user = texture;
|
||||
|
||||
surface = gsk_texture_download (texture);
|
||||
surface = gsk_texture_download_surface (texture);
|
||||
gsk_gl_driver_bind_source_texture (driver, t->texture_id);
|
||||
gsk_gl_driver_init_texture_with_surface (driver,
|
||||
t->texture_id,
|
||||
|
||||
+92
-26
@@ -102,6 +102,7 @@ struct _GskGLRenderer
|
||||
|
||||
guint frame_buffer;
|
||||
guint depth_stencil_buffer;
|
||||
guint texture_id;
|
||||
|
||||
GQuark uniforms[N_UNIFORMS];
|
||||
GQuark attributes[N_ATTRIBUTES];
|
||||
@@ -154,6 +155,17 @@ gsk_gl_renderer_create_buffers (GskGLRenderer *self,
|
||||
|
||||
GSK_NOTE (OPENGL, g_print ("Creating buffers (w:%d, h:%d, scale:%d)\n", width, height, scale_factor));
|
||||
|
||||
if (self->texture_id == 0)
|
||||
{
|
||||
self->texture_id = gsk_gl_driver_create_texture (self->gl_driver,
|
||||
width * scale_factor,
|
||||
height * scale_factor);
|
||||
gsk_gl_driver_bind_source_texture (self->gl_driver, self->texture_id);
|
||||
gsk_gl_driver_init_texture_empty (self->gl_driver, self->texture_id);
|
||||
}
|
||||
|
||||
gsk_gl_driver_create_render_target (self->gl_driver, self->texture_id, TRUE, TRUE);
|
||||
|
||||
self->has_buffers = TRUE;
|
||||
}
|
||||
|
||||
@@ -170,6 +182,12 @@ gsk_gl_renderer_destroy_buffers (GskGLRenderer *self)
|
||||
|
||||
gdk_gl_context_make_current (self->gl_context);
|
||||
|
||||
if (self->texture_id != 0)
|
||||
{
|
||||
gsk_gl_driver_destroy_texture (self->gl_driver, self->texture_id);
|
||||
self->texture_id = 0;
|
||||
}
|
||||
|
||||
self->has_buffers = FALSE;
|
||||
}
|
||||
|
||||
@@ -603,7 +621,6 @@ gsk_gl_renderer_add_render_item (GskGLRenderer *self,
|
||||
GskRenderNode *node,
|
||||
RenderItem *parent)
|
||||
{
|
||||
graphene_rect_t viewport;
|
||||
RenderItem item;
|
||||
RenderItem *ritem = NULL;
|
||||
int program_id;
|
||||
@@ -611,8 +628,6 @@ gsk_gl_renderer_add_render_item (GskGLRenderer *self,
|
||||
|
||||
memset (&item, 0, sizeof (RenderItem));
|
||||
|
||||
gsk_renderer_get_viewport (GSK_RENDERER (self), &viewport);
|
||||
|
||||
scale_factor = gsk_renderer_get_scale_factor (GSK_RENDERER (self));
|
||||
if (scale_factor < 1)
|
||||
scale_factor = 1;
|
||||
@@ -685,7 +700,7 @@ gsk_gl_renderer_add_render_item (GskGLRenderer *self,
|
||||
}
|
||||
else
|
||||
{
|
||||
item.render_data.render_target_id = 0;
|
||||
item.render_data.render_target_id = self->texture_id;
|
||||
item.children = NULL;
|
||||
}
|
||||
|
||||
@@ -908,47 +923,37 @@ gsk_gl_renderer_setup_render_mode (GskGLRenderer *self)
|
||||
#define ORTHO_FAR_PLANE 10000
|
||||
|
||||
static void
|
||||
gsk_gl_renderer_render (GskRenderer *renderer,
|
||||
GskRenderNode *root)
|
||||
gsk_gl_renderer_do_render (GskRenderer *renderer,
|
||||
GskRenderNode *root,
|
||||
const graphene_rect_t *viewport,
|
||||
int scale_factor)
|
||||
{
|
||||
GskGLRenderer *self = GSK_GL_RENDERER (renderer);
|
||||
graphene_matrix_t modelview, projection;
|
||||
graphene_rect_t viewport;
|
||||
guint i;
|
||||
int scale_factor;
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
GskProfiler *profiler;
|
||||
gint64 gpu_time, cpu_time;
|
||||
#endif
|
||||
|
||||
if (self->gl_context == NULL)
|
||||
return;
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
profiler = gsk_renderer_get_profiler (renderer);
|
||||
#endif
|
||||
|
||||
gdk_gl_context_make_current (self->gl_context);
|
||||
|
||||
gsk_renderer_get_viewport (renderer, &viewport);
|
||||
scale_factor = gsk_renderer_get_scale_factor (renderer);
|
||||
|
||||
gsk_gl_driver_begin_frame (self->gl_driver);
|
||||
gsk_gl_renderer_create_buffers (self, viewport.size.width, viewport.size.height, scale_factor);
|
||||
gsk_gl_driver_end_frame (self->gl_driver);
|
||||
|
||||
/* Set up the modelview and projection matrices to fit our viewport */
|
||||
graphene_matrix_init_scale (&modelview, scale_factor, scale_factor, 1.0);
|
||||
graphene_matrix_init_ortho (&projection,
|
||||
0, viewport.size.width * scale_factor,
|
||||
viewport.size.height * scale_factor, 0,
|
||||
viewport->origin.x,
|
||||
viewport->origin.x + viewport->size.width * scale_factor,
|
||||
viewport->origin.y + viewport->size.height * scale_factor,
|
||||
viewport->origin.y,
|
||||
ORTHO_NEAR_PLANE,
|
||||
ORTHO_FAR_PLANE);
|
||||
|
||||
gsk_gl_renderer_update_frustum (self, &modelview, &projection);
|
||||
|
||||
if (!gsk_gl_renderer_validate_tree (self, root, &projection))
|
||||
goto out;
|
||||
return;
|
||||
|
||||
gsk_gl_driver_begin_frame (self->gl_driver);
|
||||
|
||||
@@ -958,8 +963,8 @@ gsk_gl_renderer_render (GskRenderer *renderer,
|
||||
#endif
|
||||
|
||||
/* Ensure that the viewport is up to date */
|
||||
if (gsk_gl_driver_bind_render_target (self->gl_driver, 0))
|
||||
gsk_gl_renderer_resize_viewport (self, &viewport, scale_factor);
|
||||
if (gsk_gl_driver_bind_render_target (self->gl_driver, self->texture_id))
|
||||
gsk_gl_renderer_resize_viewport (self, viewport, scale_factor);
|
||||
|
||||
gsk_gl_renderer_setup_render_mode (self);
|
||||
|
||||
@@ -993,8 +998,68 @@ gsk_gl_renderer_render (GskRenderer *renderer,
|
||||
|
||||
gsk_profiler_push_samples (profiler);
|
||||
#endif
|
||||
}
|
||||
|
||||
static GskTexture *
|
||||
gsk_gl_renderer_render_texture (GskRenderer *renderer,
|
||||
GskRenderNode *root,
|
||||
const graphene_rect_t *viewport)
|
||||
{
|
||||
GskGLRenderer *self = GSK_GL_RENDERER (renderer);
|
||||
GskTexture *texture;
|
||||
cairo_surface_t *surface;
|
||||
cairo_t *cr;
|
||||
|
||||
g_return_val_if_fail (self->gl_context != NULL, NULL);
|
||||
|
||||
self->render_mode = RENDER_FULL;
|
||||
|
||||
gdk_gl_context_make_current (self->gl_context);
|
||||
|
||||
gsk_gl_driver_begin_frame (self->gl_driver);
|
||||
gsk_gl_renderer_create_buffers (self, ceilf (viewport->size.width), ceilf (viewport->size.height), 1);
|
||||
gsk_gl_driver_end_frame (self->gl_driver);
|
||||
|
||||
gsk_gl_renderer_do_render (renderer, root, viewport, 1);
|
||||
|
||||
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
|
||||
ceilf (viewport->size.width),
|
||||
ceilf (viewport->size.height));
|
||||
cr = cairo_create (surface);
|
||||
gdk_cairo_draw_from_gl (cr,
|
||||
gsk_renderer_get_window (renderer),
|
||||
self->texture_id,
|
||||
GL_TEXTURE,
|
||||
1.0,
|
||||
0, 0,
|
||||
viewport->size.width,
|
||||
viewport->size.height);
|
||||
cairo_destroy (cr);
|
||||
|
||||
texture = gsk_texture_new_for_surface (surface);
|
||||
cairo_surface_destroy (surface);
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gl_renderer_render (GskRenderer *renderer,
|
||||
GskRenderNode *root)
|
||||
{
|
||||
GskGLRenderer *self = GSK_GL_RENDERER (renderer);
|
||||
graphene_rect_t viewport;
|
||||
int scale_factor;
|
||||
|
||||
if (self->gl_context == NULL)
|
||||
return;
|
||||
|
||||
gdk_gl_context_make_current (self->gl_context);
|
||||
|
||||
gsk_renderer_get_viewport (renderer, &viewport);
|
||||
scale_factor = gsk_renderer_get_scale_factor (renderer);
|
||||
|
||||
gsk_gl_renderer_do_render (renderer, root, &viewport, scale_factor);
|
||||
|
||||
out:
|
||||
gdk_gl_context_make_current (self->gl_context);
|
||||
gsk_gl_renderer_clear_tree (self);
|
||||
gsk_gl_renderer_destroy_buffers (self);
|
||||
@@ -1012,6 +1077,7 @@ gsk_gl_renderer_class_init (GskGLRendererClass *klass)
|
||||
renderer_class->unrealize = gsk_gl_renderer_unrealize;
|
||||
renderer_class->begin_draw_frame = gsk_gl_renderer_begin_draw_frame;
|
||||
renderer_class->render = gsk_gl_renderer_render;
|
||||
renderer_class->render_texture = gsk_gl_renderer_render_texture;
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
+97
-1
@@ -113,6 +113,15 @@ gsk_renderer_real_unrealize (GskRenderer *self)
|
||||
GSK_RENDERER_WARN_NOT_IMPLEMENTED_METHOD (self, unrealize);
|
||||
}
|
||||
|
||||
static GskTexture *
|
||||
gsk_renderer_real_render_texture (GskRenderer *self,
|
||||
GskRenderNode *root,
|
||||
const graphene_rect_t *viewport)
|
||||
{
|
||||
GSK_RENDERER_WARN_NOT_IMPLEMENTED_METHOD (self, render_texture);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static GdkDrawingContext *
|
||||
gsk_renderer_real_begin_draw_frame (GskRenderer *self,
|
||||
const cairo_region_t *region)
|
||||
@@ -259,6 +268,7 @@ gsk_renderer_class_init (GskRendererClass *klass)
|
||||
klass->begin_draw_frame = gsk_renderer_real_begin_draw_frame;
|
||||
klass->end_draw_frame = gsk_renderer_real_end_draw_frame;
|
||||
klass->render = gsk_renderer_real_render;
|
||||
klass->render_texture = gsk_renderer_real_render_texture;
|
||||
klass->create_cairo_surface = gsk_renderer_real_create_cairo_surface;
|
||||
|
||||
gobject_class->constructed = gsk_renderer_constructed;
|
||||
@@ -606,6 +616,75 @@ gsk_renderer_unrealize (GskRenderer *renderer)
|
||||
priv->is_realized = FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_renderer_render_texture:
|
||||
* @renderer: a realized #GdkRenderer
|
||||
* @root: a #GskRenderNode
|
||||
* @viewport: (allow-none): the section to draw or %NULL to use @root's bounds
|
||||
*
|
||||
* Renders the scene graph, described by a tree of #GskRenderNode instances,
|
||||
* to a #GskTexture.
|
||||
*
|
||||
* The @renderer will acquire a reference on the #GskRenderNode tree while
|
||||
* the rendering is in progress, and will make the tree immutable.
|
||||
*
|
||||
* If you want to apply any transformations to @root, you should put it into a
|
||||
* transform node and pass that node instead.
|
||||
*
|
||||
* Returns: (transfer full): a #GskTexture with the rendered contents of @root.
|
||||
*
|
||||
* Since: 3.90
|
||||
*/
|
||||
GskTexture *
|
||||
gsk_renderer_render_texture (GskRenderer *renderer,
|
||||
GskRenderNode *root,
|
||||
const graphene_rect_t *viewport)
|
||||
{
|
||||
GskRendererPrivate *priv = gsk_renderer_get_instance_private (renderer);
|
||||
graphene_rect_t real_viewport;
|
||||
GskTexture *texture;
|
||||
|
||||
g_return_val_if_fail (GSK_IS_RENDERER (renderer), NULL);
|
||||
g_return_val_if_fail (priv->is_realized, NULL);
|
||||
g_return_val_if_fail (GSK_IS_RENDER_NODE (root), NULL);
|
||||
g_return_val_if_fail (priv->root_node == NULL, NULL);
|
||||
|
||||
priv->root_node = gsk_render_node_ref (root);
|
||||
|
||||
if (viewport == NULL)
|
||||
{
|
||||
gsk_render_node_get_bounds (root, &real_viewport);
|
||||
viewport = &real_viewport;
|
||||
}
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
gsk_profiler_reset (priv->profiler);
|
||||
#endif
|
||||
|
||||
texture = GSK_RENDERER_GET_CLASS (renderer)->render_texture (renderer, root, viewport);
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GSK_DEBUG_CHECK (RENDERER))
|
||||
{
|
||||
GString *buf = g_string_new ("*** Texture stats ***\n\n");
|
||||
|
||||
gsk_profiler_append_counters (priv->profiler, buf);
|
||||
g_string_append_c (buf, '\n');
|
||||
|
||||
gsk_profiler_append_timers (priv->profiler, buf);
|
||||
g_string_append_c (buf, '\n');
|
||||
|
||||
g_print ("%s\n***\n\n", buf->str);
|
||||
|
||||
g_string_free (buf, TRUE);
|
||||
}
|
||||
#endif
|
||||
|
||||
g_clear_pointer (&priv->root_node, gsk_render_node_unref);
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_renderer_render:
|
||||
* @renderer: a #GskRenderer
|
||||
@@ -837,7 +916,24 @@ gsk_renderer_begin_draw_frame (GskRenderer *renderer,
|
||||
g_return_val_if_fail (region != NULL, NULL);
|
||||
g_return_val_if_fail (priv->drawing_context == NULL, NULL);
|
||||
|
||||
priv->drawing_context = GSK_RENDERER_GET_CLASS (renderer)->begin_draw_frame (renderer, region);
|
||||
if (GSK_RENDER_MODE_CHECK (FULL_REDRAW))
|
||||
{
|
||||
cairo_region_t *full_window;
|
||||
|
||||
full_window = cairo_region_create_rectangle (&(GdkRectangle) {
|
||||
0, 0,
|
||||
gdk_window_get_width (priv->window),
|
||||
gdk_window_get_height (priv->window)
|
||||
});
|
||||
|
||||
priv->drawing_context = GSK_RENDERER_GET_CLASS (renderer)->begin_draw_frame (renderer, full_window);
|
||||
|
||||
cairo_region_destroy (full_window);
|
||||
}
|
||||
else
|
||||
{
|
||||
priv->drawing_context = GSK_RENDERER_GET_CLASS (renderer)->begin_draw_frame (renderer, region);
|
||||
}
|
||||
|
||||
return priv->drawing_context;
|
||||
}
|
||||
|
||||
+3
-6
@@ -53,9 +53,6 @@ void gsk_renderer_set_scale_factor (GskRenderer
|
||||
GDK_AVAILABLE_IN_3_90
|
||||
int gsk_renderer_get_scale_factor (GskRenderer *renderer);
|
||||
GDK_AVAILABLE_IN_3_90
|
||||
void gsk_renderer_set_window (GskRenderer *renderer,
|
||||
GdkWindow *window);
|
||||
GDK_AVAILABLE_IN_3_90
|
||||
GdkWindow * gsk_renderer_get_window (GskRenderer *renderer);
|
||||
|
||||
GDK_AVAILABLE_IN_3_90
|
||||
@@ -69,9 +66,9 @@ GDK_AVAILABLE_IN_3_90
|
||||
void gsk_renderer_unrealize (GskRenderer *renderer);
|
||||
|
||||
GDK_AVAILABLE_IN_3_90
|
||||
GskRenderer * gsk_renderer_create_fallback (GskRenderer *renderer,
|
||||
const graphene_rect_t *viewport,
|
||||
cairo_t *cr);
|
||||
GskTexture * gsk_renderer_render_texture (GskRenderer *renderer,
|
||||
GskRenderNode *root,
|
||||
const graphene_rect_t *viewport);
|
||||
|
||||
GDK_AVAILABLE_IN_3_90
|
||||
GdkDrawingContext * gsk_renderer_begin_draw_frame (GskRenderer *renderer,
|
||||
|
||||
@@ -42,6 +42,9 @@ struct _GskRendererClass
|
||||
GError **error);
|
||||
void (* unrealize) (GskRenderer *renderer);
|
||||
|
||||
GskTexture * (* render_texture) (GskRenderer *renderer,
|
||||
GskRenderNode *root,
|
||||
const graphene_rect_t *viewport);
|
||||
GdkDrawingContext * (* begin_draw_frame) (GskRenderer *renderer,
|
||||
const cairo_region_t *region);
|
||||
void (* end_draw_frame) (GskRenderer *renderer,
|
||||
|
||||
@@ -65,6 +65,8 @@ G_DEFINE_BOXED_TYPE (GskRenderNode, gsk_render_node,
|
||||
gsk_render_node_ref,
|
||||
gsk_render_node_unref)
|
||||
|
||||
G_DEFINE_QUARK (gsk-serialization-error-quark, gsk_serialization_error)
|
||||
|
||||
static void
|
||||
gsk_render_node_finalize (GskRenderNode *self)
|
||||
{
|
||||
@@ -253,6 +255,7 @@ gsk_render_node_draw (GskRenderNode *node,
|
||||
{
|
||||
g_return_if_fail (GSK_IS_RENDER_NODE (node));
|
||||
g_return_if_fail (cr != NULL);
|
||||
g_return_if_fail (cairo_status (cr) == CAIRO_STATUS_SUCCESS);
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
@@ -283,6 +286,137 @@ gsk_render_node_draw (GskRenderNode *node,
|
||||
}
|
||||
|
||||
cairo_restore (cr);
|
||||
|
||||
if (cairo_status (cr))
|
||||
{
|
||||
g_warning ("drawing failure for render node %s '%s': %s",
|
||||
node->node_class->type_name,
|
||||
gsk_render_node_get_name (node),
|
||||
cairo_status_to_string (cairo_status (cr)));
|
||||
}
|
||||
}
|
||||
|
||||
#define GSK_RENDER_NODE_SERIALIZATION_VERSION 0
|
||||
#define GSK_RENDER_NODE_SERIALIZATION_ID "GskRenderNode"
|
||||
|
||||
/**
|
||||
* gsk_render_node_serialize:
|
||||
* @node: a #GskRenderNode
|
||||
*
|
||||
* Serializes the @node for later deserialization via
|
||||
* gsk_render_node_deserialize(). No guarantees are made about the format
|
||||
* used other than that the same version of GTK+ will be able to deserialize
|
||||
* the result of a call to gsk_render_node_serialize() and
|
||||
* gsk_render_node_deserialize() will correctly reject files it cannot open
|
||||
* that were created with previous versions of GTK+.
|
||||
*
|
||||
* The intended use of this functions is testing, benchmarking and debugging.
|
||||
* The format is not meant as a permanent storage format.
|
||||
*
|
||||
* Returns: a #GBytes representing the node.
|
||||
**/
|
||||
GBytes *
|
||||
gsk_render_node_serialize (GskRenderNode *node)
|
||||
{
|
||||
GVariant *node_variant, *variant;
|
||||
GBytes *result;
|
||||
|
||||
node_variant = gsk_render_node_serialize_node (node);
|
||||
|
||||
variant = g_variant_new ("(suuv)",
|
||||
GSK_RENDER_NODE_SERIALIZATION_ID,
|
||||
(guint32) GSK_RENDER_NODE_SERIALIZATION_VERSION,
|
||||
(guint32) gsk_render_node_get_node_type (node),
|
||||
node_variant);
|
||||
|
||||
result = g_variant_get_data_as_bytes (variant);
|
||||
g_variant_unref (variant);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_render_node_write_to_file:
|
||||
* @node: a #GskRenderNode
|
||||
* @filename: the file to save it to.
|
||||
* @error: Return location for a potential error
|
||||
*
|
||||
* This function is equivalent to calling gsk_render_node_serialize()
|
||||
* followed by g_file_set_contents(). See those two functions for details
|
||||
* on the arguments.
|
||||
*
|
||||
* It is mostly intended for use inside a debugger to quickly dump a render
|
||||
* node to a file for later inspection.
|
||||
*
|
||||
* Returns: %TRUE if saving was successful
|
||||
**/
|
||||
gboolean
|
||||
gsk_render_node_write_to_file (GskRenderNode *node,
|
||||
const char *filename,
|
||||
GError **error)
|
||||
{
|
||||
GBytes *bytes;
|
||||
gboolean result;
|
||||
|
||||
g_return_val_if_fail (GSK_IS_RENDER_NODE (node), FALSE);
|
||||
g_return_val_if_fail (filename != NULL, FALSE);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
||||
|
||||
bytes = gsk_render_node_serialize (node);
|
||||
result = g_file_set_contents (filename,
|
||||
g_bytes_get_data (bytes, NULL),
|
||||
g_bytes_get_size (bytes),
|
||||
error);
|
||||
g_bytes_unref (bytes);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_render_node_deserialize:
|
||||
* @bytes: the bytes containing the data
|
||||
* @error: (allow-none): location to store error or %NULL
|
||||
*
|
||||
* Loads data previously created via gsk_render_node_serialize(). For a
|
||||
* discussion of the supported format, see that function.
|
||||
*
|
||||
* Returns: (nullable) (transfer full): a new #GskRenderNode or %NULL on
|
||||
* error.
|
||||
**/
|
||||
GskRenderNode *
|
||||
gsk_render_node_deserialize (GBytes *bytes,
|
||||
GError **error)
|
||||
{
|
||||
char *id_string;
|
||||
guint32 version, node_type;
|
||||
GVariant *variant, *node_variant;
|
||||
GskRenderNode *node = NULL;
|
||||
|
||||
variant = g_variant_new_from_bytes (G_VARIANT_TYPE ("(suuv)"), bytes, FALSE);
|
||||
|
||||
g_variant_get (variant, "(suuv)", &id_string, &version, &node_type, &node_variant);
|
||||
|
||||
if (!g_str_equal (id_string, GSK_RENDER_NODE_SERIALIZATION_ID))
|
||||
{
|
||||
g_set_error (error, GSK_SERIALIZATION_ERROR, GSK_SERIALIZATION_UNSUPPORTED_FORMAT,
|
||||
"Data not in GskRenderNode serialization format.");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (version != GSK_RENDER_NODE_SERIALIZATION_VERSION)
|
||||
{
|
||||
g_set_error (error, GSK_SERIALIZATION_ERROR, GSK_SERIALIZATION_UNSUPPORTED_VERSION,
|
||||
"Format version %u not supported.", version);
|
||||
goto out;
|
||||
}
|
||||
|
||||
node = gsk_render_node_deserialize_node (node_type, node_variant, error);
|
||||
|
||||
out:
|
||||
g_free (id_string);
|
||||
g_variant_unref (node_variant);
|
||||
g_variant_unref (variant);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
+20
-2
@@ -32,6 +32,8 @@ G_BEGIN_DECLS
|
||||
|
||||
#define GSK_IS_RENDER_NODE(obj) ((obj) != NULL)
|
||||
|
||||
#define GSK_SERIALIZATION_ERROR (gsk_serialization_error_quark ())
|
||||
|
||||
typedef struct _GskRenderNode GskRenderNode;
|
||||
typedef struct _GskColorStop GskColorStop;
|
||||
typedef struct _GskShadow GskShadow;
|
||||
@@ -47,12 +49,14 @@ struct _GskShadow
|
||||
GdkRGBA color;
|
||||
float dx;
|
||||
float dy;
|
||||
float spread;
|
||||
float radius;
|
||||
};
|
||||
|
||||
GDK_AVAILABLE_IN_3_90
|
||||
GType gsk_render_node_get_type (void) G_GNUC_CONST;
|
||||
GType gsk_render_node_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GDK_AVAILABLE_IN_3_90
|
||||
GQuark gsk_serialization_error_quark (void);
|
||||
|
||||
GDK_AVAILABLE_IN_3_90
|
||||
GskRenderNode * gsk_render_node_ref (GskRenderNode *node);
|
||||
@@ -167,10 +171,24 @@ void gsk_render_node_set_name (GskRenderNode *
|
||||
const char *name);
|
||||
GDK_AVAILABLE_IN_3_90
|
||||
const char * gsk_render_node_get_name (GskRenderNode *node);
|
||||
GDK_AVAILABLE_IN_3_90
|
||||
void gsk_render_node_get_bounds (GskRenderNode *node,
|
||||
graphene_rect_t *frame);
|
||||
|
||||
GDK_AVAILABLE_IN_3_90
|
||||
void gsk_render_node_draw (GskRenderNode *node,
|
||||
cairo_t *cr);
|
||||
|
||||
GDK_AVAILABLE_IN_3_90
|
||||
GBytes * gsk_render_node_serialize (GskRenderNode *node);
|
||||
GDK_AVAILABLE_IN_3_90
|
||||
gboolean gsk_render_node_write_to_file (GskRenderNode *node,
|
||||
const char *filename,
|
||||
GError **error);
|
||||
GDK_AVAILABLE_IN_3_90
|
||||
GskRenderNode * gsk_render_node_deserialize (GBytes *bytes,
|
||||
GError **error);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSK_RENDER_NODE_H__ */
|
||||
|
||||
+1019
-2
File diff suppressed because it is too large
Load Diff
@@ -34,18 +34,28 @@ struct _GskRenderNodeClass
|
||||
void (* finalize) (GskRenderNode *node);
|
||||
void (* draw) (GskRenderNode *node,
|
||||
cairo_t *cr);
|
||||
GVariant * (* serialize) (GskRenderNode *node);
|
||||
GskRenderNode * (* deserialize) (GVariant *variant,
|
||||
GError **error);
|
||||
};
|
||||
|
||||
GskRenderNode *gsk_render_node_new (const GskRenderNodeClass *node_class, gsize extra_size);
|
||||
|
||||
void gsk_render_node_get_bounds (GskRenderNode *node,
|
||||
graphene_rect_t *frame);
|
||||
GVariant * gsk_render_node_serialize_node (GskRenderNode *node);
|
||||
GskRenderNode * gsk_render_node_deserialize_node (GskRenderNodeType type, GVariant *variant, GError **error);
|
||||
|
||||
double gsk_opacity_node_get_opacity (GskRenderNode *node);
|
||||
|
||||
const graphene_point_t * gsk_linear_gradient_node_peek_start (GskRenderNode *node);
|
||||
const graphene_point_t * gsk_linear_gradient_node_peek_end (GskRenderNode *node);
|
||||
const gsize gsk_linear_gradient_node_get_n_color_stops (GskRenderNode *node);
|
||||
const GskColorStop * gsk_linear_gradient_node_peek_color_stops (GskRenderNode *node);
|
||||
|
||||
const GskRoundedRect * gsk_border_node_peek_outline (GskRenderNode *node);
|
||||
float gsk_border_node_get_width (GskRenderNode *node, guint i);
|
||||
const GdkRGBA * gsk_border_node_peek_color (GskRenderNode *node, guint i);
|
||||
|
||||
GskRenderNode *gsk_cairo_node_new_for_surface (const graphene_rect_t *bounds, cairo_surface_t *surface);
|
||||
cairo_surface_t *gsk_cairo_node_get_surface (GskRenderNode *node);
|
||||
|
||||
GskTexture *gsk_texture_node_get_texture (GskRenderNode *node);
|
||||
|
||||
@@ -277,6 +277,21 @@ gsk_rounded_rect_shrink (GskRoundedRect *self,
|
||||
return self;
|
||||
}
|
||||
|
||||
/* XXX: Fina a better name */
|
||||
gboolean
|
||||
gsk_rounded_rect_is_circular (const GskRoundedRect *self)
|
||||
{
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
if (self->corner[i].width != self->corner[i].height)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_rounded_rect_is_rectilinear:
|
||||
* @self: the #GskRoundedRect to check
|
||||
@@ -486,3 +501,33 @@ gsk_rounded_rect_path (const GskRoundedRect *self,
|
||||
cairo_close_path (cr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Converts to the format we use in our shaders:
|
||||
* vec4 rect;
|
||||
* vec4 corner_widths;
|
||||
* vec4 corner_heights;
|
||||
* rect is (x, y, width, height), the corners are the same
|
||||
* order as in the rounded rect.
|
||||
*
|
||||
* This is so that shaders can use just the first vec4 for
|
||||
* rectilinear rects, the 2nd vec4 for circular rects and
|
||||
* only look at the last vec4 if they have to.
|
||||
*/
|
||||
void
|
||||
gsk_rounded_rect_to_float (const GskRoundedRect *self,
|
||||
float rect[12])
|
||||
{
|
||||
guint i;
|
||||
|
||||
rect[0] = self->bounds.origin.x;
|
||||
rect[1] = self->bounds.origin.y;
|
||||
rect[2] = self->bounds.size.width;
|
||||
rect[3] = self->bounds.size.height;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
rect[4 + i] = self->corner[i].width;
|
||||
rect[8 + i] = self->corner[i].height;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,8 +7,12 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
gboolean gsk_rounded_rect_is_circular (const GskRoundedRect *self);
|
||||
|
||||
void gsk_rounded_rect_path (const GskRoundedRect *self,
|
||||
cairo_t *cr);
|
||||
void gsk_rounded_rect_to_float (const GskRoundedRect *self,
|
||||
float rect[12]);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
+101
-6
@@ -37,6 +37,8 @@
|
||||
#include "gskdebugprivate.h"
|
||||
#include "gskrenderer.h"
|
||||
|
||||
#include "gdk/gdkinternals.h"
|
||||
|
||||
/**
|
||||
* GskTexture: (ref-func gsk_texture_ref) (unref-func gsk_texture_unref)
|
||||
*
|
||||
@@ -135,18 +137,43 @@ gsk_texture_cairo_finalize (GskTexture *texture)
|
||||
}
|
||||
|
||||
static cairo_surface_t *
|
||||
gsk_texture_cairo_download (GskTexture *texture)
|
||||
gsk_texture_cairo_download_surface (GskTexture *texture)
|
||||
{
|
||||
GskCairoTexture *cairo = (GskCairoTexture *) texture;
|
||||
|
||||
return cairo_surface_reference (cairo->surface);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_texture_cairo_download (GskTexture *texture,
|
||||
guchar *data,
|
||||
gsize stride)
|
||||
{
|
||||
GskCairoTexture *cairo = (GskCairoTexture *) texture;
|
||||
cairo_surface_t *surface;
|
||||
cairo_t *cr;
|
||||
|
||||
surface = cairo_image_surface_create_for_data (data,
|
||||
CAIRO_FORMAT_ARGB32,
|
||||
texture->width, texture->height,
|
||||
stride);
|
||||
cr = cairo_create (surface);
|
||||
|
||||
cairo_set_source_surface (cr, cairo->surface, 0, 0);
|
||||
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
|
||||
cairo_paint (cr);
|
||||
|
||||
cairo_destroy (cr);
|
||||
cairo_surface_finish (surface);
|
||||
cairo_surface_destroy (surface);
|
||||
}
|
||||
|
||||
static const GskTextureClass GSK_TEXTURE_CLASS_CAIRO = {
|
||||
"cairo",
|
||||
sizeof (GskCairoTexture),
|
||||
gsk_texture_cairo_finalize,
|
||||
gsk_texture_cairo_download
|
||||
gsk_texture_cairo_download,
|
||||
gsk_texture_cairo_download_surface
|
||||
};
|
||||
|
||||
GskTexture *
|
||||
@@ -208,8 +235,25 @@ gsk_texture_pixbuf_finalize (GskTexture *texture)
|
||||
g_object_unref (pixbuf->pixbuf);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_texture_pixbuf_download (GskTexture *texture,
|
||||
guchar *data,
|
||||
gsize stride)
|
||||
{
|
||||
GskPixbufTexture *pixbuf = (GskPixbufTexture *) texture;
|
||||
cairo_surface_t *surface;
|
||||
|
||||
surface = cairo_image_surface_create_for_data (data,
|
||||
CAIRO_FORMAT_ARGB32,
|
||||
texture->width, texture->height,
|
||||
stride);
|
||||
gdk_cairo_surface_paint_pixbuf (surface, pixbuf->pixbuf);
|
||||
cairo_surface_finish (surface);
|
||||
cairo_surface_destroy (surface);
|
||||
}
|
||||
|
||||
static cairo_surface_t *
|
||||
gsk_texture_pixbuf_download (GskTexture *texture)
|
||||
gsk_texture_pixbuf_download_surface (GskTexture *texture)
|
||||
{
|
||||
GskPixbufTexture *pixbuf = (GskPixbufTexture *) texture;
|
||||
|
||||
@@ -220,7 +264,8 @@ static const GskTextureClass GSK_TEXTURE_CLASS_PIXBUF = {
|
||||
"pixbuf",
|
||||
sizeof (GskPixbufTexture),
|
||||
gsk_texture_pixbuf_finalize,
|
||||
gsk_texture_pixbuf_download
|
||||
gsk_texture_pixbuf_download,
|
||||
gsk_texture_pixbuf_download_surface
|
||||
};
|
||||
|
||||
GskTexture *
|
||||
@@ -276,9 +321,59 @@ gsk_texture_get_height (GskTexture *texture)
|
||||
}
|
||||
|
||||
cairo_surface_t *
|
||||
gsk_texture_download (GskTexture *texture)
|
||||
gsk_texture_download_surface (GskTexture *texture)
|
||||
{
|
||||
return texture->klass->download (texture);
|
||||
cairo_surface_t *surface;
|
||||
|
||||
if (texture->klass->download_surface)
|
||||
return texture->klass->download_surface (texture);
|
||||
|
||||
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
|
||||
texture->width, texture->height);
|
||||
gsk_texture_download (texture,
|
||||
cairo_image_surface_get_data (surface),
|
||||
cairo_image_surface_get_stride (surface));
|
||||
cairo_surface_mark_dirty (surface);
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_texture_download:
|
||||
* @texture: a #GskTexture
|
||||
* @data: pointer to enough memory to be filled with the
|
||||
* downloaded data of @texture
|
||||
* @stride: rowstride in bytes
|
||||
*
|
||||
* Downloads the @texture into local memory. This may be
|
||||
* an expensive operation, as the actual texture data may
|
||||
* reside on a GPU or on a remote display server.
|
||||
*
|
||||
* The data format of the downloaded data is equivalent to
|
||||
* %CAIRO_FORMAT_ARGB32, so every downloaded pixel requires
|
||||
* 4 bytes of memory.
|
||||
*
|
||||
* Downloading a texture into a Cairo image surface:
|
||||
* |[<!-- language="C" -->
|
||||
* surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
|
||||
* gsk_texture_get_width (texture),
|
||||
* gsk_texture_get_height (texture));
|
||||
* gsk_texture_download (texture,
|
||||
* cairo_image_surface_get_data (surface),
|
||||
* cairo_image_surface_get_stride (surface));
|
||||
* cairo_surface_mark_dirty (surface);
|
||||
* ]|
|
||||
**/
|
||||
void
|
||||
gsk_texture_download (GskTexture *texture,
|
||||
guchar *data,
|
||||
gsize stride)
|
||||
{
|
||||
g_return_if_fail (GSK_IS_TEXTURE (texture));
|
||||
g_return_if_fail (data != NULL);
|
||||
g_return_if_fail (stride >= gsk_texture_get_width (texture) * 4);
|
||||
|
||||
return texture->klass->download (texture, data, stride);
|
||||
}
|
||||
|
||||
gboolean
|
||||
|
||||
@@ -52,6 +52,11 @@ int gsk_texture_get_width (GskTexture
|
||||
GDK_AVAILABLE_IN_3_90
|
||||
int gsk_texture_get_height (GskTexture *texture);
|
||||
|
||||
GDK_AVAILABLE_IN_3_90
|
||||
void gsk_texture_download (GskTexture *texture,
|
||||
guchar *data,
|
||||
gsize stride);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSK_TEXTURE_H__ */
|
||||
|
||||
@@ -30,14 +30,17 @@ struct _GskTextureClass {
|
||||
gsize size;
|
||||
|
||||
void (* finalize) (GskTexture *texture);
|
||||
cairo_surface_t * (* download) (GskTexture *texture);
|
||||
void (* download) (GskTexture *texture,
|
||||
guchar *data,
|
||||
gsize stride);
|
||||
cairo_surface_t * (* download_surface) (GskTexture *texture);
|
||||
};
|
||||
|
||||
gpointer gsk_texture_new (const GskTextureClass *klass,
|
||||
int width,
|
||||
int height);
|
||||
GskTexture * gsk_texture_new_for_surface (cairo_surface_t *surface);
|
||||
cairo_surface_t * gsk_texture_download (GskTexture *texture);
|
||||
cairo_surface_t * gsk_texture_download_surface (GskTexture *texture);
|
||||
|
||||
gboolean gsk_texture_set_render_data (GskTexture *self,
|
||||
gpointer key,
|
||||
|
||||
@@ -71,6 +71,12 @@ gsk_vulkan_buffer_new_staging (GdkVulkanContext *context,
|
||||
return gsk_vulkan_buffer_new_internal (context, size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
|
||||
}
|
||||
|
||||
GskVulkanBuffer *
|
||||
gsk_vulkan_buffer_new_download (GdkVulkanContext *context,
|
||||
gsize size)
|
||||
{
|
||||
return gsk_vulkan_buffer_new_internal (context, size, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
|
||||
}
|
||||
void
|
||||
gsk_vulkan_buffer_free (GskVulkanBuffer *self)
|
||||
{
|
||||
|
||||
@@ -11,6 +11,8 @@ GskVulkanBuffer * gsk_vulkan_buffer_new (GdkVulk
|
||||
gsize size);
|
||||
GskVulkanBuffer * gsk_vulkan_buffer_new_staging (GdkVulkanContext *context,
|
||||
gsize size);
|
||||
GskVulkanBuffer * gsk_vulkan_buffer_new_download (GdkVulkanContext *context,
|
||||
gsize size);
|
||||
void gsk_vulkan_buffer_free (GskVulkanBuffer *buffer);
|
||||
|
||||
VkBuffer gsk_vulkan_buffer_get_buffer (GskVulkanBuffer *self);
|
||||
|
||||
@@ -0,0 +1,179 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "gskvulkanclipprivate.h"
|
||||
|
||||
#include "gskroundedrectprivate.h"
|
||||
|
||||
void
|
||||
gsk_vulkan_clip_init_empty (GskVulkanClip *clip,
|
||||
const graphene_rect_t *rect)
|
||||
{
|
||||
clip->type = GSK_VULKAN_CLIP_NONE;
|
||||
gsk_rounded_rect_init_from_rect (&clip->rect, rect, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_vulkan_clip_init_copy (GskVulkanClip *self,
|
||||
const GskVulkanClip *src)
|
||||
{
|
||||
self->type = src->type;
|
||||
gsk_rounded_rect_init_copy (&self->rect, &src->rect);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gsk_vulkan_clip_intersect_rect (GskVulkanClip *dest,
|
||||
const GskVulkanClip *src,
|
||||
const graphene_rect_t *rect)
|
||||
{
|
||||
if (graphene_rect_contains_rect (rect, &src->rect.bounds))
|
||||
{
|
||||
gsk_vulkan_clip_init_copy (dest, src);
|
||||
return TRUE;
|
||||
}
|
||||
if (!graphene_rect_intersection (rect, &src->rect.bounds, NULL))
|
||||
{
|
||||
dest->type = GSK_VULKAN_CLIP_ALL_CLIPPED;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
switch (src->type)
|
||||
{
|
||||
case GSK_VULKAN_CLIP_ALL_CLIPPED:
|
||||
dest->type = GSK_VULKAN_CLIP_ALL_CLIPPED;
|
||||
break;
|
||||
|
||||
case GSK_VULKAN_CLIP_NONE:
|
||||
gsk_vulkan_clip_init_copy (dest, src);
|
||||
if (graphene_rect_intersection (&dest->rect.bounds, rect, &dest->rect.bounds))
|
||||
dest->type = GSK_VULKAN_CLIP_RECT;
|
||||
else
|
||||
dest->type = GSK_VULKAN_CLIP_ALL_CLIPPED;
|
||||
break;
|
||||
|
||||
case GSK_VULKAN_CLIP_RECT:
|
||||
gsk_vulkan_clip_init_copy (dest, src);
|
||||
if (!graphene_rect_intersection (&dest->rect.bounds, rect, &dest->rect.bounds))
|
||||
dest->type = GSK_VULKAN_CLIP_ALL_CLIPPED;
|
||||
break;
|
||||
|
||||
case GSK_VULKAN_CLIP_ROUNDED_CIRCULAR:
|
||||
case GSK_VULKAN_CLIP_ROUNDED:
|
||||
if (gsk_rounded_rect_contains_rect (&src->rect, rect))
|
||||
{
|
||||
dest->type = GSK_VULKAN_CLIP_RECT;
|
||||
gsk_rounded_rect_init_from_rect (&dest->rect, rect, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* some points of rect are inside src's rounded rect,
|
||||
* some are outside. */
|
||||
/* XXX: If the 2 rects don't intersect on rounded corners,
|
||||
* we could actually compute a new clip here.
|
||||
*/
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gsk_vulkan_clip_intersect_rounded_rect (GskVulkanClip *dest,
|
||||
const GskVulkanClip *src,
|
||||
const GskRoundedRect *rounded)
|
||||
{
|
||||
if (gsk_rounded_rect_contains_rect (rounded, &src->rect.bounds))
|
||||
{
|
||||
gsk_vulkan_clip_init_copy (dest, src);
|
||||
return TRUE;
|
||||
}
|
||||
if (!graphene_rect_intersection (&rounded->bounds, &src->rect.bounds, NULL))
|
||||
{
|
||||
dest->type = GSK_VULKAN_CLIP_ALL_CLIPPED;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
switch (src->type)
|
||||
{
|
||||
case GSK_VULKAN_CLIP_ALL_CLIPPED:
|
||||
dest->type = GSK_VULKAN_CLIP_ALL_CLIPPED;
|
||||
break;
|
||||
|
||||
case GSK_VULKAN_CLIP_NONE:
|
||||
dest->type = gsk_rounded_rect_is_circular (&dest->rect) ? GSK_VULKAN_CLIP_ROUNDED_CIRCULAR : GSK_VULKAN_CLIP_ROUNDED;
|
||||
gsk_rounded_rect_init_copy (&dest->rect, rounded);
|
||||
break;
|
||||
|
||||
case GSK_VULKAN_CLIP_RECT:
|
||||
if (graphene_rect_contains_rect (&src->rect.bounds, &rounded->bounds))
|
||||
{
|
||||
dest->type = gsk_rounded_rect_is_circular (&dest->rect) ? GSK_VULKAN_CLIP_ROUNDED_CIRCULAR : GSK_VULKAN_CLIP_ROUNDED;
|
||||
gsk_rounded_rect_init_copy (&dest->rect, rounded);
|
||||
return TRUE;
|
||||
}
|
||||
/* some points of rect are inside src's rounded rect,
|
||||
* some are outside. */
|
||||
/* XXX: If the 2 rects don't intersect on rounded corners,
|
||||
* we could actually compute a new clip here.
|
||||
*/
|
||||
return FALSE;
|
||||
|
||||
case GSK_VULKAN_CLIP_ROUNDED_CIRCULAR:
|
||||
case GSK_VULKAN_CLIP_ROUNDED:
|
||||
/* XXX: improve */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gsk_vulkan_clip_transform (GskVulkanClip *dest,
|
||||
const GskVulkanClip *src,
|
||||
const graphene_matrix_t *transform,
|
||||
const graphene_rect_t *viewport)
|
||||
{
|
||||
switch (dest->type)
|
||||
{
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
return FALSE;
|
||||
|
||||
case GSK_VULKAN_CLIP_ALL_CLIPPED:
|
||||
gsk_vulkan_clip_init_copy (dest, src);
|
||||
return TRUE;
|
||||
|
||||
case GSK_VULKAN_CLIP_NONE:
|
||||
gsk_vulkan_clip_init_empty (dest, viewport);
|
||||
return TRUE;
|
||||
|
||||
case GSK_VULKAN_CLIP_RECT:
|
||||
case GSK_VULKAN_CLIP_ROUNDED_CIRCULAR:
|
||||
case GSK_VULKAN_CLIP_ROUNDED:
|
||||
/* FIXME: Handle 2D operations, in particular transform and scale */
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
gsk_vulkan_clip_contains_rect (const GskVulkanClip *self,
|
||||
const graphene_rect_t *rect)
|
||||
{
|
||||
switch (self->type)
|
||||
{
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
case GSK_VULKAN_CLIP_ALL_CLIPPED:
|
||||
return FALSE;
|
||||
|
||||
case GSK_VULKAN_CLIP_NONE:
|
||||
return TRUE;
|
||||
|
||||
case GSK_VULKAN_CLIP_RECT:
|
||||
return graphene_rect_contains_rect (&self->rect.bounds, rect);
|
||||
|
||||
case GSK_VULKAN_CLIP_ROUNDED_CIRCULAR:
|
||||
case GSK_VULKAN_CLIP_ROUNDED:
|
||||
return gsk_rounded_rect_contains_rect (&self->rect, rect);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
#ifndef __GSK_VULKAN_CLIP_PRIVATE_H__
|
||||
#define __GSK_VULKAN_CLIP_PRIVATE_H__
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
#include <graphene.h>
|
||||
#include <gsk/gskroundedrect.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef enum {
|
||||
/* The whole area is clipped, no drawing is necessary.
|
||||
* This can't be handled by return values because for return
|
||||
* values we return if clips could even be computed.
|
||||
*/
|
||||
GSK_VULKAN_CLIP_ALL_CLIPPED,
|
||||
/* No clipping is necesary, but the clip rect is set
|
||||
* to the actual bounds of the underlying framebuffer
|
||||
*/
|
||||
GSK_VULKAN_CLIP_NONE,
|
||||
/* The clip is a rectangular area */
|
||||
GSK_VULKAN_CLIP_RECT,
|
||||
/* The clip is a rounded rectangle, and for every corner
|
||||
* corner.width == corner.height is true
|
||||
*/
|
||||
GSK_VULKAN_CLIP_ROUNDED_CIRCULAR,
|
||||
/* The clip is a rounded rectangle */
|
||||
GSK_VULKAN_CLIP_ROUNDED
|
||||
} GskVulkanClipComplexity;
|
||||
|
||||
typedef struct _GskVulkanClip GskVulkanClip;
|
||||
|
||||
struct _GskVulkanClip
|
||||
{
|
||||
GskVulkanClipComplexity type;
|
||||
GskRoundedRect rect;
|
||||
};
|
||||
|
||||
void gsk_vulkan_clip_init_empty (GskVulkanClip *clip,
|
||||
const graphene_rect_t *rect);
|
||||
|
||||
gboolean gsk_vulkan_clip_intersect_rect (GskVulkanClip *dest,
|
||||
const GskVulkanClip *src,
|
||||
const graphene_rect_t *rect) G_GNUC_WARN_UNUSED_RESULT;
|
||||
gboolean gsk_vulkan_clip_intersect_rounded_rect (GskVulkanClip *dest,
|
||||
const GskVulkanClip *src,
|
||||
const GskRoundedRect *rounded) G_GNUC_WARN_UNUSED_RESULT;
|
||||
gboolean gsk_vulkan_clip_transform (GskVulkanClip *dest,
|
||||
const GskVulkanClip *src,
|
||||
const graphene_matrix_t*transform,
|
||||
const graphene_rect_t *viewport) G_GNUC_WARN_UNUSED_RESULT;
|
||||
|
||||
gboolean gsk_vulkan_clip_contains_rect (const GskVulkanClip *self,
|
||||
const graphene_rect_t *rect) G_GNUC_WARN_UNUSED_RESULT;
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSK_VULKAN_CLIP_PRIVATE_H__ */
|
||||
@@ -101,9 +101,9 @@ gsk_vulkan_color_pipeline_collect_vertex_data (GskVulkanColorPipeline *pipeline,
|
||||
instance->rect[1] = rect->origin.y;
|
||||
instance->rect[2] = rect->size.width;
|
||||
instance->rect[3] = rect->size.height;
|
||||
instance->color[0] = pow (color->red, 2.2);
|
||||
instance->color[1] = pow (color->green, 2.2);
|
||||
instance->color[2] = pow (color->blue, 2.2);
|
||||
instance->color[0] = color->red;
|
||||
instance->color[1] = color->green;
|
||||
instance->color[2] = color->blue;
|
||||
instance->color[3] = color->alpha;
|
||||
}
|
||||
|
||||
|
||||
@@ -83,10 +83,12 @@ gsk_vulkan_command_pool_submit_buffer (GskVulkanCommandPool *self,
|
||||
1,
|
||||
&(VkSubmitInfo) {
|
||||
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
|
||||
#if 0
|
||||
.waitSemaphoreCount = 1,
|
||||
.pWaitSemaphores = (VkSemaphore[1]) {
|
||||
gdk_vulkan_context_get_draw_semaphore (self->vulkan)
|
||||
},
|
||||
#endif
|
||||
.pWaitDstStageMask = (VkPipelineStageFlags []) {
|
||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
},
|
||||
@@ -94,10 +96,12 @@ gsk_vulkan_command_pool_submit_buffer (GskVulkanCommandPool *self,
|
||||
.pCommandBuffers = (VkCommandBuffer[1]) {
|
||||
command_buffer
|
||||
},
|
||||
#if 0
|
||||
.signalSemaphoreCount = 1,
|
||||
.pSignalSemaphores = (VkSemaphore[1]) {
|
||||
gdk_vulkan_context_get_draw_semaphore (self->vulkan)
|
||||
}
|
||||
#endif
|
||||
},
|
||||
fence);
|
||||
}
|
||||
|
||||
+90
-5
@@ -167,7 +167,7 @@ gsk_vulkan_image_new (GdkVulkanContext *context,
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
|
||||
.flags = 0,
|
||||
.imageType = VK_IMAGE_TYPE_2D,
|
||||
.format = VK_FORMAT_B8G8R8A8_SRGB,
|
||||
.format = VK_FORMAT_B8G8R8A8_UNORM,
|
||||
.extent = { width, height, 1 },
|
||||
.mipLevels = 1,
|
||||
.arrayLayers = 1,
|
||||
@@ -359,7 +359,7 @@ gsk_vulkan_image_new_from_data_via_staging_buffer (GskVulkanUploader *uploader,
|
||||
|
||||
uploader->staging_buffer_free_list = g_slist_prepend (uploader->staging_buffer_free_list, staging);
|
||||
|
||||
gsk_vulkan_image_ensure_view (self, VK_FORMAT_B8G8R8A8_SRGB);
|
||||
gsk_vulkan_image_ensure_view (self, VK_FORMAT_B8G8R8A8_UNORM);
|
||||
|
||||
return self;
|
||||
}
|
||||
@@ -478,7 +478,7 @@ gsk_vulkan_image_new_from_data_via_staging_image (GskVulkanUploader *uploader,
|
||||
|
||||
uploader->staging_image_free_list = g_slist_prepend (uploader->staging_image_free_list, staging);
|
||||
|
||||
gsk_vulkan_image_ensure_view (self, VK_FORMAT_B8G8R8A8_SRGB);
|
||||
gsk_vulkan_image_ensure_view (self, VK_FORMAT_B8G8R8A8_UNORM);
|
||||
|
||||
return self;
|
||||
}
|
||||
@@ -521,7 +521,7 @@ gsk_vulkan_image_new_from_data_directly (GskVulkanUploader *uploader,
|
||||
}
|
||||
});
|
||||
|
||||
gsk_vulkan_image_ensure_view (self, VK_FORMAT_B8G8R8A8_SRGB);
|
||||
gsk_vulkan_image_ensure_view (self, VK_FORMAT_B8G8R8A8_UNORM);
|
||||
|
||||
return self;
|
||||
}
|
||||
@@ -557,11 +557,96 @@ gsk_vulkan_image_new_for_swapchain (GdkVulkanContext *context,
|
||||
self->height = height;
|
||||
self->vk_image = image;
|
||||
|
||||
gsk_vulkan_image_ensure_view (self, VK_FORMAT_B8G8R8A8_SRGB);
|
||||
gsk_vulkan_image_ensure_view (self, VK_FORMAT_B8G8R8A8_UNORM);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
GskVulkanImage *
|
||||
gsk_vulkan_image_new_for_framebuffer (GdkVulkanContext *context,
|
||||
gsize width,
|
||||
gsize height)
|
||||
{
|
||||
GskVulkanImage *self;
|
||||
|
||||
|
||||
self = gsk_vulkan_image_new (context,
|
||||
width,
|
||||
height,
|
||||
VK_IMAGE_TILING_OPTIMAL,
|
||||
VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
|
||||
|
||||
gsk_vulkan_image_ensure_view (self, VK_FORMAT_B8G8R8A8_UNORM);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
GskTexture *
|
||||
gsk_vulkan_image_download (GskVulkanImage *self,
|
||||
GskVulkanUploader *uploader)
|
||||
{
|
||||
GskVulkanBuffer *buffer;
|
||||
GskTexture *texture;
|
||||
guchar *mem;
|
||||
|
||||
gsk_vulkan_uploader_add_image_barrier (uploader,
|
||||
FALSE,
|
||||
&(VkImageMemoryBarrier) {
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
||||
.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT,
|
||||
.oldLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
|
||||
.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.image = self->vk_image,
|
||||
.subresourceRange = {
|
||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
.baseMipLevel = 0,
|
||||
.levelCount = 1,
|
||||
.baseArrayLayer = 0,
|
||||
.layerCount = 1
|
||||
}
|
||||
});
|
||||
|
||||
buffer = gsk_vulkan_buffer_new_download (self->vulkan, self->width * self->height * 4);
|
||||
|
||||
vkCmdCopyImageToBuffer (gsk_vulkan_uploader_get_copy_buffer (uploader),
|
||||
self->vk_image,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
gsk_vulkan_buffer_get_buffer (buffer),
|
||||
1,
|
||||
(VkBufferImageCopy[1]) {
|
||||
{
|
||||
.bufferOffset = 0,
|
||||
.imageSubresource = {
|
||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
.mipLevel = 0,
|
||||
.baseArrayLayer = 0,
|
||||
.layerCount = 1
|
||||
},
|
||||
.imageOffset = { 0, 0, 0 },
|
||||
.imageExtent = {
|
||||
.width = self->width,
|
||||
.height = self->height,
|
||||
.depth = 1
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
gsk_vulkan_uploader_upload (uploader);
|
||||
|
||||
GSK_VK_CHECK (vkQueueWaitIdle, gdk_vulkan_context_get_queue (self->vulkan));
|
||||
|
||||
mem = gsk_vulkan_buffer_map (buffer);
|
||||
texture = gsk_texture_new_for_data (mem, self->width, self->height, self->width * 4);
|
||||
gsk_vulkan_buffer_unmap (buffer);
|
||||
gsk_vulkan_buffer_free (buffer);
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
void
|
||||
gsk_vulkan_image_finalize (GObject *object)
|
||||
{
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
#include "gsk/gsktexture.h"
|
||||
#include "gsk/gskvulkancommandpoolprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
@@ -30,6 +31,12 @@ GskVulkanImage * gsk_vulkan_image_new_from_data (GskVulk
|
||||
gsize width,
|
||||
gsize height,
|
||||
gsize stride);
|
||||
GskVulkanImage * gsk_vulkan_image_new_for_framebuffer (GdkVulkanContext *context,
|
||||
gsize width,
|
||||
gsize height);
|
||||
|
||||
GskTexture * gsk_vulkan_image_download (GskVulkanImage *self,
|
||||
GskVulkanUploader *uploader);
|
||||
|
||||
gsize gsk_vulkan_image_get_width (GskVulkanImage *self);
|
||||
gsize gsk_vulkan_image_get_height (GskVulkanImage *self);
|
||||
|
||||
@@ -0,0 +1,224 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "gskvulkanlineargradientpipelineprivate.h"
|
||||
|
||||
struct _GskVulkanLinearGradientPipeline
|
||||
{
|
||||
GObject parent_instance;
|
||||
};
|
||||
|
||||
typedef struct _GskVulkanLinearGradientInstance GskVulkanLinearGradientInstance;
|
||||
|
||||
struct _GskVulkanLinearGradientInstance
|
||||
{
|
||||
float rect[4];
|
||||
float start[2];
|
||||
float end[2];
|
||||
gint32 repeating;
|
||||
gint32 stop_count;
|
||||
float offsets[GSK_VULKAN_LINEAR_GRADIENT_PIPELINE_MAX_COLOR_STOPS];
|
||||
float colors[GSK_VULKAN_LINEAR_GRADIENT_PIPELINE_MAX_COLOR_STOPS][4];
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GskVulkanLinearGradientPipeline, gsk_vulkan_linear_gradient_pipeline, GSK_TYPE_VULKAN_PIPELINE)
|
||||
|
||||
static const VkPipelineVertexInputStateCreateInfo *
|
||||
gsk_vulkan_linear_gradient_pipeline_get_input_state_create_info (GskVulkanPipeline *self)
|
||||
{
|
||||
static const VkVertexInputBindingDescription vertexBindingDescriptions[] = {
|
||||
{
|
||||
.binding = 0,
|
||||
.stride = sizeof (GskVulkanLinearGradientInstance),
|
||||
.inputRate = VK_VERTEX_INPUT_RATE_INSTANCE
|
||||
}
|
||||
};
|
||||
static const VkVertexInputAttributeDescription vertexInputAttributeDescription[] = {
|
||||
{
|
||||
.location = 0,
|
||||
.binding = 0,
|
||||
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
|
||||
.offset = 0,
|
||||
},
|
||||
{
|
||||
.location = 1,
|
||||
.binding = 0,
|
||||
.format = VK_FORMAT_R32G32_SFLOAT,
|
||||
.offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, start),
|
||||
},
|
||||
{
|
||||
.location = 2,
|
||||
.binding = 0,
|
||||
.format = VK_FORMAT_R32G32_SFLOAT,
|
||||
.offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, end),
|
||||
},
|
||||
{
|
||||
.location = 3,
|
||||
.binding = 0,
|
||||
.format = VK_FORMAT_R32_SINT,
|
||||
.offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, repeating),
|
||||
},
|
||||
{
|
||||
.location = 4,
|
||||
.binding = 0,
|
||||
.format = VK_FORMAT_R32_SINT,
|
||||
.offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, stop_count),
|
||||
},
|
||||
{
|
||||
.location = 5,
|
||||
.binding = 0,
|
||||
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
|
||||
.offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, offsets),
|
||||
},
|
||||
{
|
||||
.location = 6,
|
||||
.binding = 0,
|
||||
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
|
||||
.offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, offsets) + sizeof (float) * 4,
|
||||
},
|
||||
{
|
||||
.location = 7,
|
||||
.binding = 0,
|
||||
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
|
||||
.offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, colors[0]),
|
||||
},
|
||||
{
|
||||
.location = 8,
|
||||
.binding = 0,
|
||||
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
|
||||
.offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, colors[1]),
|
||||
},
|
||||
{
|
||||
.location = 9,
|
||||
.binding = 0,
|
||||
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
|
||||
.offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, colors[2]),
|
||||
},
|
||||
{
|
||||
.location = 10,
|
||||
.binding = 0,
|
||||
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
|
||||
.offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, colors[3]),
|
||||
},
|
||||
{
|
||||
.location = 11,
|
||||
.binding = 0,
|
||||
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
|
||||
.offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, colors[4]),
|
||||
},
|
||||
{
|
||||
.location = 12,
|
||||
.binding = 0,
|
||||
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
|
||||
.offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, colors[5]),
|
||||
},
|
||||
{
|
||||
.location = 13,
|
||||
.binding = 0,
|
||||
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
|
||||
.offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, colors[6]),
|
||||
},
|
||||
{
|
||||
.location = 14,
|
||||
.binding = 0,
|
||||
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
|
||||
.offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, colors[7]),
|
||||
}
|
||||
};
|
||||
static const VkPipelineVertexInputStateCreateInfo info = {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
|
||||
.vertexBindingDescriptionCount = G_N_ELEMENTS (vertexBindingDescriptions),
|
||||
.pVertexBindingDescriptions = vertexBindingDescriptions,
|
||||
.vertexAttributeDescriptionCount = G_N_ELEMENTS (vertexInputAttributeDescription),
|
||||
.pVertexAttributeDescriptions = vertexInputAttributeDescription
|
||||
};
|
||||
|
||||
return &info;
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_vulkan_linear_gradient_pipeline_finalize (GObject *gobject)
|
||||
{
|
||||
//GskVulkanLinearGradientPipeline *self = GSK_VULKAN_LINEAR_GRADIENT_PIPELINE (gobject);
|
||||
|
||||
G_OBJECT_CLASS (gsk_vulkan_linear_gradient_pipeline_parent_class)->finalize (gobject);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_vulkan_linear_gradient_pipeline_class_init (GskVulkanLinearGradientPipelineClass *klass)
|
||||
{
|
||||
GskVulkanPipelineClass *pipeline_class = GSK_VULKAN_PIPELINE_CLASS (klass);
|
||||
|
||||
G_OBJECT_CLASS (klass)->finalize = gsk_vulkan_linear_gradient_pipeline_finalize;
|
||||
|
||||
pipeline_class->get_input_state_create_info = gsk_vulkan_linear_gradient_pipeline_get_input_state_create_info;
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_vulkan_linear_gradient_pipeline_init (GskVulkanLinearGradientPipeline *self)
|
||||
{
|
||||
}
|
||||
|
||||
GskVulkanPipeline *
|
||||
gsk_vulkan_linear_gradient_pipeline_new (GskVulkanPipelineLayout *layout,
|
||||
const char *shader_name,
|
||||
VkRenderPass render_pass)
|
||||
{
|
||||
return gsk_vulkan_pipeline_new (GSK_TYPE_VULKAN_LINEAR_GRADIENT_PIPELINE, layout, shader_name, render_pass);
|
||||
}
|
||||
|
||||
gsize
|
||||
gsk_vulkan_linear_gradient_pipeline_count_vertex_data (GskVulkanLinearGradientPipeline *pipeline)
|
||||
{
|
||||
return sizeof (GskVulkanLinearGradientInstance);
|
||||
}
|
||||
|
||||
void
|
||||
gsk_vulkan_linear_gradient_pipeline_collect_vertex_data (GskVulkanLinearGradientPipeline *pipeline,
|
||||
guchar *data,
|
||||
const graphene_rect_t *rect,
|
||||
const graphene_point_t *start,
|
||||
const graphene_point_t *end,
|
||||
gboolean repeating,
|
||||
gsize n_stops,
|
||||
const GskColorStop *stops)
|
||||
{
|
||||
GskVulkanLinearGradientInstance *instance = (GskVulkanLinearGradientInstance *) data;
|
||||
gsize i;
|
||||
|
||||
if (n_stops > GSK_VULKAN_LINEAR_GRADIENT_PIPELINE_MAX_COLOR_STOPS)
|
||||
{
|
||||
g_warning ("Only %u color stops supported.", GSK_VULKAN_LINEAR_GRADIENT_PIPELINE_MAX_COLOR_STOPS);
|
||||
n_stops = GSK_VULKAN_LINEAR_GRADIENT_PIPELINE_MAX_COLOR_STOPS;
|
||||
}
|
||||
instance->rect[0] = rect->origin.x;
|
||||
instance->rect[1] = rect->origin.y;
|
||||
instance->rect[2] = rect->size.width;
|
||||
instance->rect[3] = rect->size.height;
|
||||
instance->start[0] = start->x;
|
||||
instance->start[1] = start->y;
|
||||
instance->end[0] = end->x;
|
||||
instance->end[1] = end->y;
|
||||
instance->repeating = repeating;
|
||||
instance->stop_count = n_stops;
|
||||
for (i = 0; i < n_stops; i++)
|
||||
{
|
||||
instance->offsets[i] = stops[i].offset;
|
||||
instance->colors[i][0] = stops[i].color.red;
|
||||
instance->colors[i][1] = stops[i].color.green;
|
||||
instance->colors[i][2] = stops[i].color.blue;
|
||||
instance->colors[i][3] = stops[i].color.alpha;
|
||||
}
|
||||
}
|
||||
|
||||
gsize
|
||||
gsk_vulkan_linear_gradient_pipeline_draw (GskVulkanLinearGradientPipeline *pipeline,
|
||||
VkCommandBuffer command_buffer,
|
||||
gsize offset,
|
||||
gsize n_commands)
|
||||
{
|
||||
vkCmdDraw (command_buffer,
|
||||
6, n_commands,
|
||||
0, offset);
|
||||
|
||||
return n_commands;
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
#ifndef __GSK_VULKAN_LINEAR_GRADIENT_PIPELINE_PRIVATE_H__
|
||||
#define __GSK_VULKAN_LINEAR_GRADIENT_PIPELINE_PRIVATE_H__
|
||||
|
||||
#include <graphene.h>
|
||||
|
||||
#include "gskvulkanpipelineprivate.h"
|
||||
#include "gskrendernode.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GSK_VULKAN_LINEAR_GRADIENT_PIPELINE_MAX_COLOR_STOPS 8
|
||||
|
||||
typedef struct _GskVulkanLinearGradientPipelineLayout GskVulkanLinearGradientPipelineLayout;
|
||||
|
||||
#define GSK_TYPE_VULKAN_LINEAR_GRADIENT_PIPELINE (gsk_vulkan_linear_gradient_pipeline_get_type ())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (GskVulkanLinearGradientPipeline, gsk_vulkan_linear_gradient_pipeline, GSK, VULKAN_LINEAR_GRADIENT_PIPELINE, GskVulkanPipeline)
|
||||
|
||||
GskVulkanPipeline * gsk_vulkan_linear_gradient_pipeline_new (GskVulkanPipelineLayout * layout,
|
||||
const char *shader_name,
|
||||
VkRenderPass render_pass);
|
||||
|
||||
gsize gsk_vulkan_linear_gradient_pipeline_count_vertex_data
|
||||
(GskVulkanLinearGradientPipeline*pipeline);
|
||||
void gsk_vulkan_linear_gradient_pipeline_collect_vertex_data
|
||||
(GskVulkanLinearGradientPipeline*pipeline,
|
||||
guchar *data,
|
||||
const graphene_rect_t *rect,
|
||||
const graphene_point_t *start,
|
||||
const graphene_point_t *end,
|
||||
gboolean repeating,
|
||||
gsize n_stops,
|
||||
const GskColorStop *stops);
|
||||
gsize gsk_vulkan_linear_gradient_pipeline_draw (GskVulkanLinearGradientPipeline*pipeline,
|
||||
VkCommandBuffer command_buffer,
|
||||
gsize offset,
|
||||
gsize n_commands);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSK_VULKAN_LINEAR_GRADIENT_PIPELINE_PRIVATE_H__ */
|
||||
@@ -2,13 +2,15 @@
|
||||
|
||||
#include "gskvulkanpushconstantsprivate.h"
|
||||
|
||||
#include <math.h>
|
||||
#include "gskroundedrectprivate.h"
|
||||
|
||||
void
|
||||
gsk_vulkan_push_constants_init (GskVulkanPushConstants *constants,
|
||||
const graphene_matrix_t *mvp)
|
||||
const graphene_matrix_t *mvp,
|
||||
const graphene_rect_t *viewport)
|
||||
{
|
||||
gsk_vulkan_push_constants_set_mvp (constants, mvp);
|
||||
graphene_matrix_init_from_matrix (&constants->mvp, mvp);
|
||||
gsk_vulkan_clip_init_empty (&constants->clip, viewport);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -18,35 +20,67 @@ gsk_vulkan_push_constants_init_copy (GskVulkanPushConstants *self,
|
||||
*self = *src;
|
||||
}
|
||||
|
||||
void
|
||||
gsk_vulkan_push_constants_set_mvp (GskVulkanPushConstants *self,
|
||||
const graphene_matrix_t *mvp)
|
||||
gboolean
|
||||
gsk_vulkan_push_constants_transform (GskVulkanPushConstants *self,
|
||||
const GskVulkanPushConstants *src,
|
||||
const graphene_matrix_t *transform,
|
||||
const graphene_rect_t *viewport)
|
||||
|
||||
{
|
||||
graphene_matrix_to_float (mvp, self->vertex.mvp);
|
||||
if (!gsk_vulkan_clip_transform (&self->clip, &src->clip, transform, viewport))
|
||||
return FALSE;
|
||||
|
||||
graphene_matrix_multiply (transform, &src->mvp, &self->mvp);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gsk_vulkan_push_constants_intersect_rect (GskVulkanPushConstants *self,
|
||||
const GskVulkanPushConstants *src,
|
||||
const graphene_rect_t *rect)
|
||||
{
|
||||
if (!gsk_vulkan_clip_intersect_rect (&self->clip, &src->clip, rect))
|
||||
return FALSE;
|
||||
|
||||
graphene_matrix_init_from_matrix (&self->mvp, &src->mvp);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gsk_vulkan_push_constants_intersect_rounded (GskVulkanPushConstants *self,
|
||||
const GskVulkanPushConstants *src,
|
||||
const GskRoundedRect *rect)
|
||||
{
|
||||
if (!gsk_vulkan_clip_intersect_rounded_rect (&self->clip, &src->clip, rect))
|
||||
return FALSE;
|
||||
|
||||
graphene_matrix_init_from_matrix (&self->mvp, &src->mvp);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_vulkan_push_constants_wire_init (GskVulkanPushConstantsWire *wire,
|
||||
const GskVulkanPushConstants *self)
|
||||
{
|
||||
graphene_matrix_to_float (&self->mvp, wire->vertex.mvp);
|
||||
gsk_rounded_rect_to_float (&self->clip.rect, wire->vertex.clip);
|
||||
}
|
||||
|
||||
void
|
||||
gsk_vulkan_push_constants_multiply_mvp (GskVulkanPushConstants *self,
|
||||
const graphene_matrix_t *transform)
|
||||
gsk_vulkan_push_constants_push_vertex (const GskVulkanPushConstants *self,
|
||||
VkCommandBuffer command_buffer,
|
||||
VkPipelineLayout pipeline_layout)
|
||||
{
|
||||
graphene_matrix_t old_mvp, new_mvp;
|
||||
GskVulkanPushConstantsWire wire;
|
||||
|
||||
graphene_matrix_init_from_float (&old_mvp, self->vertex.mvp);
|
||||
graphene_matrix_multiply (transform, &old_mvp, &new_mvp);
|
||||
gsk_vulkan_push_constants_set_mvp (self, &new_mvp);
|
||||
}
|
||||
gsk_vulkan_push_constants_wire_init (&wire, self);
|
||||
|
||||
void
|
||||
gsk_vulkan_push_constants_push_vertex (GskVulkanPushConstants *self,
|
||||
VkCommandBuffer command_buffer,
|
||||
VkPipelineLayout pipeline_layout)
|
||||
{
|
||||
vkCmdPushConstants (command_buffer,
|
||||
pipeline_layout,
|
||||
VK_SHADER_STAGE_VERTEX_BIT,
|
||||
G_STRUCT_OFFSET (GskVulkanPushConstants, vertex),
|
||||
sizeof (self->vertex),
|
||||
&self->vertex);
|
||||
G_STRUCT_OFFSET (GskVulkanPushConstantsWire, vertex),
|
||||
sizeof (wire.vertex),
|
||||
&wire.vertex);
|
||||
}
|
||||
|
||||
#if 0
|
||||
@@ -76,8 +110,8 @@ gst_vulkan_push_constants_get_ranges (void)
|
||||
static const VkPushConstantRange ranges[2] = {
|
||||
{
|
||||
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT,
|
||||
.offset = G_STRUCT_OFFSET (GskVulkanPushConstants, vertex),
|
||||
.size = sizeof (((GskVulkanPushConstants *) 0)->vertex)
|
||||
.offset = G_STRUCT_OFFSET (GskVulkanPushConstantsWire, vertex),
|
||||
.size = sizeof (((GskVulkanPushConstantsWire *) 0)->vertex)
|
||||
#if 0
|
||||
},
|
||||
{
|
||||
|
||||
@@ -3,15 +3,24 @@
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
#include <graphene.h>
|
||||
#include <gsk/gskvulkanclipprivate.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GskVulkanPushConstants GskVulkanPushConstants;
|
||||
typedef struct _GskVulkanPushConstantsWire GskVulkanPushConstantsWire;
|
||||
|
||||
struct _GskVulkanPushConstants
|
||||
{
|
||||
graphene_matrix_t mvp;
|
||||
GskVulkanClip clip;
|
||||
};
|
||||
|
||||
struct _GskVulkanPushConstantsWire
|
||||
{
|
||||
struct {
|
||||
float mvp[16];
|
||||
float clip[12];
|
||||
} vertex;
|
||||
#if 0
|
||||
struct {
|
||||
@@ -24,16 +33,23 @@ const VkPushConstantRange *
|
||||
uint32_t gst_vulkan_push_constants_get_range_count (void) G_GNUC_PURE;
|
||||
|
||||
void gsk_vulkan_push_constants_init (GskVulkanPushConstants *constants,
|
||||
const graphene_matrix_t *mvp);
|
||||
const graphene_matrix_t *mvp,
|
||||
const graphene_rect_t *viewport);
|
||||
void gsk_vulkan_push_constants_init_copy (GskVulkanPushConstants *self,
|
||||
const GskVulkanPushConstants *src);
|
||||
|
||||
void gsk_vulkan_push_constants_set_mvp (GskVulkanPushConstants *self,
|
||||
const graphene_matrix_t *mvp);
|
||||
void gsk_vulkan_push_constants_multiply_mvp (GskVulkanPushConstants *self,
|
||||
const graphene_matrix_t *transform);
|
||||
gboolean gsk_vulkan_push_constants_transform (GskVulkanPushConstants *self,
|
||||
const GskVulkanPushConstants *src,
|
||||
const graphene_matrix_t *transform,
|
||||
const graphene_rect_t *viewport);
|
||||
gboolean gsk_vulkan_push_constants_intersect_rect (GskVulkanPushConstants *self,
|
||||
const GskVulkanPushConstants *src,
|
||||
const graphene_rect_t *rect);
|
||||
gboolean gsk_vulkan_push_constants_intersect_rounded (GskVulkanPushConstants *self,
|
||||
const GskVulkanPushConstants *src,
|
||||
const GskRoundedRect *rect);
|
||||
|
||||
void gsk_vulkan_push_constants_push_vertex (GskVulkanPushConstants *self,
|
||||
void gsk_vulkan_push_constants_push_vertex (const GskVulkanPushConstants *self,
|
||||
VkCommandBuffer command_buffer,
|
||||
VkPipelineLayout pipeline_layout);
|
||||
|
||||
|
||||
+92
-49
@@ -10,6 +10,7 @@
|
||||
|
||||
#include "gskvulkanblendpipelineprivate.h"
|
||||
#include "gskvulkancolorpipelineprivate.h"
|
||||
#include "gskvulkanlineargradientpipelineprivate.h"
|
||||
|
||||
#define ORTHO_NEAR_PLANE -10000
|
||||
#define ORTHO_FAR_PLANE 10000
|
||||
@@ -24,8 +25,8 @@ struct _GskVulkanRender
|
||||
|
||||
graphene_matrix_t mvp;
|
||||
int scale_factor;
|
||||
VkExtent2D size;
|
||||
VkRect2D scissor;
|
||||
VkRect2D viewport;
|
||||
cairo_region_t *clip;
|
||||
|
||||
GHashTable *framebuffers;
|
||||
GskVulkanCommandPool *command_pool;
|
||||
@@ -48,29 +49,40 @@ struct _GskVulkanRender
|
||||
};
|
||||
|
||||
static void
|
||||
gsk_vulkan_render_compute_mvp (GskVulkanRender *self)
|
||||
gsk_vulkan_render_setup (GskVulkanRender *self,
|
||||
GskVulkanImage *target,
|
||||
const graphene_rect_t *rect)
|
||||
{
|
||||
GdkWindow *window = gsk_renderer_get_window (self->renderer);
|
||||
graphene_matrix_t modelview, projection;
|
||||
cairo_rectangle_int_t extents;
|
||||
|
||||
cairo_region_get_extents (gdk_drawing_context_get_clip (gsk_renderer_get_drawing_context (self->renderer)),
|
||||
&extents);
|
||||
self->target = g_object_ref (target);
|
||||
|
||||
self->scale_factor = gsk_renderer_get_scale_factor (self->renderer);
|
||||
self->size.width = gdk_window_get_width (window) * self->scale_factor;
|
||||
self->size.height = gdk_window_get_height (window) * self->scale_factor;
|
||||
self->scissor.offset.x = extents.x * self->scale_factor;
|
||||
self->scissor.offset.y = extents.y * self->scale_factor;
|
||||
self->scissor.extent.width = extents.width * self->scale_factor;
|
||||
self->scissor.extent.height = extents.height * self->scale_factor;
|
||||
if (rect)
|
||||
{
|
||||
self->viewport = (VkRect2D) { { rect->origin.x, rect->origin.y }, { rect->size.width, rect->size.height } };
|
||||
self->scale_factor = 1;
|
||||
self->clip = cairo_region_create_rectangle (&(cairo_rectangle_int_t) {
|
||||
0, 0,
|
||||
gsk_vulkan_image_get_width (target), gsk_vulkan_image_get_height (target)
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
self->scale_factor = gsk_renderer_get_scale_factor (self->renderer);
|
||||
self->viewport.offset = (VkOffset2D) { 0, 0 };
|
||||
self->viewport.extent.width = gdk_window_get_width (window) * self->scale_factor;
|
||||
self->viewport.extent.height = gdk_window_get_height (window) * self->scale_factor;
|
||||
self->clip = gdk_drawing_context_get_clip (gsk_renderer_get_drawing_context (self->renderer));
|
||||
}
|
||||
|
||||
graphene_matrix_init_scale (&modelview, self->scale_factor, self->scale_factor, 1.0);
|
||||
graphene_matrix_init_ortho (&projection,
|
||||
0, self->size.width,
|
||||
0, self->size.height,
|
||||
self->viewport.offset.x, self->viewport.offset.x + self->viewport.extent.width,
|
||||
self->viewport.offset.y, self->viewport.offset.y + self->viewport.extent.height,
|
||||
ORTHO_NEAR_PLANE,
|
||||
ORTHO_FAR_PLANE);
|
||||
|
||||
graphene_matrix_multiply (&modelview, &projection, &self->mvp);
|
||||
}
|
||||
|
||||
@@ -231,7 +243,14 @@ gsk_vulkan_render_add_node (GskVulkanRender *self,
|
||||
|
||||
self->render_passes = g_slist_prepend (self->render_passes, pass);
|
||||
|
||||
gsk_vulkan_render_pass_add (pass, self, &self->mvp, node);
|
||||
gsk_vulkan_render_pass_add (pass,
|
||||
self,
|
||||
&self->mvp,
|
||||
&GRAPHENE_RECT_INIT (
|
||||
self->viewport.offset.x, self->viewport.offset.y,
|
||||
self->viewport.extent.width, self->viewport.extent.height
|
||||
),
|
||||
node);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -295,7 +314,12 @@ gsk_vulkan_render_get_pipeline (GskVulkanRender *self,
|
||||
GskVulkanPipeline * (* create_func) (GskVulkanPipelineLayout *layout, const char *name, VkRenderPass render_pass);
|
||||
} pipeline_info[GSK_VULKAN_N_PIPELINES] = {
|
||||
{ "blit", gsk_vulkan_blend_pipeline_new },
|
||||
{ "color", gsk_vulkan_color_pipeline_new }
|
||||
{ "color", gsk_vulkan_color_pipeline_new },
|
||||
{ "color-clip", gsk_vulkan_color_pipeline_new },
|
||||
{ "color-clip-rounded", gsk_vulkan_color_pipeline_new },
|
||||
{ "linear", gsk_vulkan_linear_gradient_pipeline_new },
|
||||
{ "linear-clip", gsk_vulkan_linear_gradient_pipeline_new },
|
||||
{ "linear-clip-rounded", gsk_vulkan_linear_gradient_pipeline_new }
|
||||
};
|
||||
|
||||
g_return_val_if_fail (type < GSK_VULKAN_N_PIPELINES, NULL);
|
||||
@@ -439,6 +463,7 @@ gsk_vulkan_render_draw (GskVulkanRender *self,
|
||||
GskVulkanBuffer *buffer;
|
||||
VkCommandBuffer command_buffer;
|
||||
GSList *l;
|
||||
guint i;
|
||||
|
||||
gsk_vulkan_render_prepare_descriptor_sets (self, sampler);
|
||||
|
||||
@@ -452,39 +477,49 @@ gsk_vulkan_render_draw (GskVulkanRender *self,
|
||||
&(VkViewport) {
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
.width = self->size.width,
|
||||
.height = self->size.height,
|
||||
.width = self->viewport.extent.width,
|
||||
.height = self->viewport.extent.height,
|
||||
.minDepth = 0,
|
||||
.maxDepth = 1
|
||||
});
|
||||
|
||||
vkCmdSetScissor (command_buffer,
|
||||
0,
|
||||
1,
|
||||
&self->scissor);
|
||||
|
||||
vkCmdBeginRenderPass (command_buffer,
|
||||
&(VkRenderPassBeginInfo) {
|
||||
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
|
||||
.renderPass = self->render_pass,
|
||||
.framebuffer = gsk_vulkan_render_get_framebuffer (self, self->target),
|
||||
.renderArea = {
|
||||
{ 0, 0 },
|
||||
{ self->size.width, self->size.height }
|
||||
},
|
||||
.clearValueCount = 1,
|
||||
.pClearValues = (VkClearValue [1]) {
|
||||
{ .color = { .float32 = { 0.f, 0.f, 0.f, 0.f } } }
|
||||
}
|
||||
},
|
||||
VK_SUBPASS_CONTENTS_INLINE);
|
||||
|
||||
for (l = self->render_passes; l; l = l->next)
|
||||
for (i = 0; i < cairo_region_num_rectangles (self->clip); i++)
|
||||
{
|
||||
gsk_vulkan_render_pass_draw (l->data, self, buffer, self->layout, command_buffer);
|
||||
}
|
||||
cairo_rectangle_int_t rect;
|
||||
|
||||
vkCmdEndRenderPass (command_buffer);
|
||||
cairo_region_get_rectangle (self->clip, i, &rect);
|
||||
|
||||
vkCmdSetScissor (command_buffer,
|
||||
0,
|
||||
1,
|
||||
&(VkRect2D) {
|
||||
{ rect.x * self->scale_factor, rect.y * self->scale_factor },
|
||||
{ rect.width * self->scale_factor, rect.height * self->scale_factor }
|
||||
});
|
||||
|
||||
vkCmdBeginRenderPass (command_buffer,
|
||||
&(VkRenderPassBeginInfo) {
|
||||
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
|
||||
.renderPass = self->render_pass,
|
||||
.framebuffer = gsk_vulkan_render_get_framebuffer (self, self->target),
|
||||
.renderArea = {
|
||||
{ rect.x * self->scale_factor, rect.y * self->scale_factor },
|
||||
{ rect.width * self->scale_factor, rect.height * self->scale_factor }
|
||||
},
|
||||
.clearValueCount = 1,
|
||||
.pClearValues = (VkClearValue [1]) {
|
||||
{ .color = { .float32 = { 0.f, 0.f, 0.f, 0.f } } }
|
||||
}
|
||||
},
|
||||
VK_SUBPASS_CONTENTS_INLINE);
|
||||
|
||||
for (l = self->render_passes; l; l = l->next)
|
||||
{
|
||||
gsk_vulkan_render_pass_draw (l->data, self, buffer, self->layout, command_buffer);
|
||||
}
|
||||
|
||||
vkCmdEndRenderPass (command_buffer);
|
||||
}
|
||||
|
||||
gsk_vulkan_command_pool_submit_buffer (self->command_pool, command_buffer, self->fence);
|
||||
|
||||
@@ -500,6 +535,14 @@ gsk_vulkan_render_draw (GskVulkanRender *self,
|
||||
}
|
||||
}
|
||||
|
||||
GskTexture *
|
||||
gsk_vulkan_render_download_target (GskVulkanRender *self)
|
||||
{
|
||||
gsk_vulkan_uploader_reset (self->uploader);
|
||||
|
||||
return gsk_vulkan_image_download (self->target, self->uploader);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_vulkan_render_cleanup (GskVulkanRender *self)
|
||||
{
|
||||
@@ -527,6 +570,7 @@ gsk_vulkan_render_cleanup (GskVulkanRender *self)
|
||||
g_slist_free_full (self->cleanup_images, g_object_unref);
|
||||
self->cleanup_images = NULL;
|
||||
|
||||
g_clear_pointer (&self->clip, cairo_region_destroy);
|
||||
g_clear_object (&self->target);
|
||||
}
|
||||
|
||||
@@ -589,14 +633,13 @@ gsk_vulkan_render_is_busy (GskVulkanRender *self)
|
||||
}
|
||||
|
||||
void
|
||||
gsk_vulkan_render_reset (GskVulkanRender *self,
|
||||
GskVulkanImage *target)
|
||||
gsk_vulkan_render_reset (GskVulkanRender *self,
|
||||
GskVulkanImage *target,
|
||||
const graphene_rect_t *rect)
|
||||
{
|
||||
gsk_vulkan_render_cleanup (self);
|
||||
|
||||
self->target = g_object_ref (target);
|
||||
|
||||
gsk_vulkan_render_compute_mvp (self);
|
||||
gsk_vulkan_render_setup (self, target, rect);
|
||||
}
|
||||
|
||||
GskRenderer *
|
||||
|
||||
+53
-16
@@ -170,6 +170,54 @@ gsk_vulkan_renderer_unrealize (GskRenderer *renderer)
|
||||
g_clear_object (&self->vulkan);
|
||||
}
|
||||
|
||||
static GskTexture *
|
||||
gsk_vulkan_renderer_render_texture (GskRenderer *renderer,
|
||||
GskRenderNode *root,
|
||||
const graphene_rect_t *viewport)
|
||||
{
|
||||
GskVulkanRenderer *self = GSK_VULKAN_RENDERER (renderer);
|
||||
GskVulkanRender *render;
|
||||
GskVulkanImage *image;
|
||||
GskTexture *texture;
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
GskProfiler *profiler;
|
||||
gint64 cpu_time;
|
||||
#endif
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
profiler = gsk_renderer_get_profiler (renderer);
|
||||
gsk_profiler_timer_begin (profiler, self->profile_timers.cpu_time);
|
||||
#endif
|
||||
|
||||
render = gsk_vulkan_render_new (renderer, self->vulkan);
|
||||
|
||||
image = gsk_vulkan_image_new_for_framebuffer (self->vulkan,
|
||||
ceil (viewport->size.width),
|
||||
ceil (viewport->size.height));
|
||||
|
||||
gsk_vulkan_render_reset (render, image, viewport);
|
||||
|
||||
gsk_vulkan_render_add_node (render, root);
|
||||
|
||||
gsk_vulkan_render_upload (render);
|
||||
|
||||
gsk_vulkan_render_draw (render, self->sampler);
|
||||
|
||||
texture = gsk_vulkan_render_download_target (render);
|
||||
|
||||
g_object_unref (image);
|
||||
gsk_vulkan_render_free (render);
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
cpu_time = gsk_profiler_timer_end (profiler, self->profile_timers.cpu_time);
|
||||
gsk_profiler_timer_set (profiler, self->profile_timers.cpu_time, cpu_time);
|
||||
|
||||
gsk_profiler_push_samples (profiler);
|
||||
#endif
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_vulkan_renderer_render (GskRenderer *renderer,
|
||||
GskRenderNode *root)
|
||||
@@ -188,7 +236,7 @@ gsk_vulkan_renderer_render (GskRenderer *renderer,
|
||||
|
||||
render = self->render;
|
||||
|
||||
gsk_vulkan_render_reset (render, self->targets[gdk_vulkan_context_get_draw_index (self->vulkan)]);
|
||||
gsk_vulkan_render_reset (render, self->targets[gdk_vulkan_context_get_draw_index (self->vulkan)], NULL);
|
||||
|
||||
gsk_vulkan_render_add_node (render, root);
|
||||
|
||||
@@ -209,23 +257,11 @@ gsk_vulkan_renderer_begin_draw_frame (GskRenderer *renderer,
|
||||
const cairo_region_t *region)
|
||||
{
|
||||
GskVulkanRenderer *self = GSK_VULKAN_RENDERER (renderer);
|
||||
cairo_region_t *whole_window;
|
||||
GdkDrawingContext *result;
|
||||
GdkWindow *window;
|
||||
|
||||
window = gsk_renderer_get_window (renderer);
|
||||
|
||||
whole_window = cairo_region_create_rectangle (&(GdkRectangle) {
|
||||
0, 0,
|
||||
gdk_window_get_width (window),
|
||||
gdk_window_get_height (window)
|
||||
});
|
||||
|
||||
result = gdk_window_begin_draw_frame (window,
|
||||
result = gdk_window_begin_draw_frame (gsk_renderer_get_window (renderer),
|
||||
GDK_DRAW_CONTEXT (self->vulkan),
|
||||
whole_window);
|
||||
|
||||
cairo_region_destroy (whole_window);
|
||||
region);
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -238,6 +274,7 @@ gsk_vulkan_renderer_class_init (GskVulkanRendererClass *klass)
|
||||
renderer_class->realize = gsk_vulkan_renderer_realize;
|
||||
renderer_class->unrealize = gsk_vulkan_renderer_unrealize;
|
||||
renderer_class->render = gsk_vulkan_renderer_render;
|
||||
renderer_class->render_texture = gsk_vulkan_renderer_render_texture;
|
||||
renderer_class->begin_draw_frame = gsk_vulkan_renderer_begin_draw_frame;
|
||||
}
|
||||
|
||||
@@ -281,7 +318,7 @@ gsk_vulkan_renderer_ref_texture_image (GskVulkanRenderer *self,
|
||||
if (data)
|
||||
return g_object_ref (data->image);
|
||||
|
||||
surface = gsk_texture_download (texture);
|
||||
surface = gsk_texture_download_surface (texture);
|
||||
image = gsk_vulkan_image_new_from_data (uploader,
|
||||
cairo_image_surface_get_data (surface),
|
||||
cairo_image_surface_get_width (surface),
|
||||
|
||||
+218
-28
@@ -2,11 +2,15 @@
|
||||
|
||||
#include "gskvulkanrenderpassprivate.h"
|
||||
|
||||
#include "gskvulkanblendpipelineprivate.h"
|
||||
#include "gskvulkancolorpipelineprivate.h"
|
||||
#include "gskvulkanimageprivate.h"
|
||||
#include "gskdebugprivate.h"
|
||||
#include "gskrendernodeprivate.h"
|
||||
#include "gskrenderer.h"
|
||||
#include "gskroundedrectprivate.h"
|
||||
#include "gskvulkanblendpipelineprivate.h"
|
||||
#include "gskvulkanclipprivate.h"
|
||||
#include "gskvulkancolorpipelineprivate.h"
|
||||
#include "gskvulkanlineargradientpipelineprivate.h"
|
||||
#include "gskvulkanimageprivate.h"
|
||||
#include "gskvulkanpushconstantsprivate.h"
|
||||
#include "gskvulkanrendererprivate.h"
|
||||
|
||||
@@ -17,9 +21,12 @@ typedef struct _GskVulkanOpPushConstants GskVulkanOpPushConstants;
|
||||
typedef enum {
|
||||
/* GskVulkanOpRender */
|
||||
GSK_VULKAN_OP_FALLBACK,
|
||||
GSK_VULKAN_OP_FALLBACK_CLIP,
|
||||
GSK_VULKAN_OP_FALLBACK_ROUNDED_CLIP,
|
||||
GSK_VULKAN_OP_SURFACE,
|
||||
GSK_VULKAN_OP_TEXTURE,
|
||||
GSK_VULKAN_OP_COLOR,
|
||||
GSK_VULKAN_OP_LINEAR_GRADIENT,
|
||||
/* GskVulkanOpPushConstants */
|
||||
GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS
|
||||
} GskVulkanOpType;
|
||||
@@ -29,6 +36,7 @@ struct _GskVulkanOpRender
|
||||
GskVulkanOpType type;
|
||||
GskRenderNode *node; /* node that's the source of this op */
|
||||
GskVulkanPipeline *pipeline; /* pipeline to use */
|
||||
GskRoundedRect clip; /* clip rect (or random memory if not relevant) */
|
||||
GskVulkanImage *source; /* source image to render */
|
||||
gsize vertex_offset; /* offset into vertex buffer */
|
||||
gsize vertex_count; /* number of vertices */
|
||||
@@ -77,6 +85,11 @@ gsk_vulkan_render_pass_free (GskVulkanRenderPass *self)
|
||||
g_slice_free (GskVulkanRenderPass, self);
|
||||
}
|
||||
|
||||
#define FALLBACK(...) G_STMT_START { \
|
||||
GSK_NOTE (FALLBACK, g_print (__VA_ARGS__)); \
|
||||
goto fallback; \
|
||||
}G_STMT_END
|
||||
|
||||
void
|
||||
gsk_vulkan_render_pass_add_node (GskVulkanRenderPass *self,
|
||||
GskVulkanRender *render,
|
||||
@@ -87,39 +100,66 @@ gsk_vulkan_render_pass_add_node (GskVulkanRenderPass *self,
|
||||
.type = GSK_VULKAN_OP_FALLBACK,
|
||||
.render.node = node
|
||||
};
|
||||
GskVulkanPipelineType pipeline_type;
|
||||
|
||||
switch (gsk_render_node_get_node_type (node))
|
||||
{
|
||||
case GSK_NOT_A_RENDER_NODE:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
|
||||
return;
|
||||
default:
|
||||
op.type = GSK_VULKAN_OP_FALLBACK;
|
||||
op.render.pipeline = gsk_vulkan_render_get_pipeline (render, GSK_VULKAN_PIPELINE_BLIT);
|
||||
g_array_append_val (self->render_ops, op);
|
||||
break;
|
||||
FALLBACK ("Unsupported node '%s'\n", node->node_class->type_name);
|
||||
|
||||
case GSK_CAIRO_NODE:
|
||||
if (gsk_cairo_node_get_surface (node) != NULL)
|
||||
{
|
||||
op.type = GSK_VULKAN_OP_SURFACE;
|
||||
op.render.pipeline = gsk_vulkan_render_get_pipeline (render, GSK_VULKAN_PIPELINE_BLIT);
|
||||
g_array_append_val (self->render_ops, op);
|
||||
}
|
||||
break;
|
||||
if (gsk_cairo_node_get_surface (node) == NULL)
|
||||
return;
|
||||
if (!gsk_vulkan_clip_contains_rect (&constants->clip, &node->bounds))
|
||||
FALLBACK ("Cairo nodes can't deal with clip type %u\n", constants->clip.type);
|
||||
op.type = GSK_VULKAN_OP_SURFACE;
|
||||
op.render.pipeline = gsk_vulkan_render_get_pipeline (render, GSK_VULKAN_PIPELINE_BLIT);
|
||||
g_array_append_val (self->render_ops, op);
|
||||
return;
|
||||
|
||||
case GSK_TEXTURE_NODE:
|
||||
if (!gsk_vulkan_clip_contains_rect (&constants->clip, &node->bounds))
|
||||
FALLBACK ("Texture nodes can't deal with clip type %u\n", constants->clip.type);
|
||||
op.type = GSK_VULKAN_OP_TEXTURE;
|
||||
op.render.pipeline = gsk_vulkan_render_get_pipeline (render, GSK_VULKAN_PIPELINE_BLIT);
|
||||
g_array_append_val (self->render_ops, op);
|
||||
break;
|
||||
return;
|
||||
|
||||
case GSK_COLOR_NODE:
|
||||
if (gsk_vulkan_clip_contains_rect (&constants->clip, &node->bounds))
|
||||
pipeline_type = GSK_VULKAN_PIPELINE_COLOR;
|
||||
else if (constants->clip.type == GSK_VULKAN_CLIP_RECT)
|
||||
pipeline_type = GSK_VULKAN_PIPELINE_COLOR_CLIP;
|
||||
else if (constants->clip.type == GSK_VULKAN_CLIP_ROUNDED_CIRCULAR)
|
||||
pipeline_type = GSK_VULKAN_PIPELINE_COLOR_CLIP_ROUNDED;
|
||||
else
|
||||
FALLBACK ("Color nodes can't deal with clip type %u\n", constants->clip.type);
|
||||
op.type = GSK_VULKAN_OP_COLOR;
|
||||
op.render.pipeline = gsk_vulkan_render_get_pipeline (render, GSK_VULKAN_PIPELINE_COLOR);
|
||||
op.render.pipeline = gsk_vulkan_render_get_pipeline (render, pipeline_type);
|
||||
g_array_append_val (self->render_ops, op);
|
||||
break;
|
||||
return;
|
||||
|
||||
case GSK_LINEAR_GRADIENT_NODE:
|
||||
case GSK_REPEATING_LINEAR_GRADIENT_NODE:
|
||||
if (gsk_linear_gradient_node_get_n_color_stops (node) > GSK_VULKAN_LINEAR_GRADIENT_PIPELINE_MAX_COLOR_STOPS)
|
||||
FALLBACK ("Linear gradient with %zu color stops, hardcoded limit is %u\n",
|
||||
gsk_linear_gradient_node_get_n_color_stops (node),
|
||||
GSK_VULKAN_LINEAR_GRADIENT_PIPELINE_MAX_COLOR_STOPS);
|
||||
if (gsk_vulkan_clip_contains_rect (&constants->clip, &node->bounds))
|
||||
pipeline_type = GSK_VULKAN_PIPELINE_LINEAR_GRADIENT;
|
||||
else if (constants->clip.type == GSK_VULKAN_CLIP_RECT)
|
||||
pipeline_type = GSK_VULKAN_PIPELINE_LINEAR_GRADIENT_CLIP;
|
||||
else if (constants->clip.type == GSK_VULKAN_CLIP_ROUNDED_CIRCULAR)
|
||||
pipeline_type = GSK_VULKAN_PIPELINE_LINEAR_GRADIENT_CLIP_ROUNDED;
|
||||
else
|
||||
FALLBACK ("Linear gradient nodes can't deal with clip type %u\n", constants->clip.type);
|
||||
op.type = GSK_VULKAN_OP_LINEAR_GRADIENT;
|
||||
op.render.pipeline = gsk_vulkan_render_get_pipeline (render, pipeline_type);
|
||||
g_array_append_val (self->render_ops, op);
|
||||
return;
|
||||
|
||||
case GSK_CONTAINER_NODE:
|
||||
{
|
||||
@@ -130,36 +170,107 @@ gsk_vulkan_render_pass_add_node (GskVulkanRenderPass *self,
|
||||
gsk_vulkan_render_pass_add_node (self, render, constants, gsk_container_node_get_child (node, i));
|
||||
}
|
||||
}
|
||||
break;
|
||||
return;
|
||||
|
||||
case GSK_TRANSFORM_NODE:
|
||||
{
|
||||
graphene_matrix_t transform;
|
||||
GskRenderNode *child;
|
||||
|
||||
#if 0
|
||||
if (!gsk_vulkan_clip_contains_rect (clip, &node->bounds))
|
||||
FALLBACK ("Transform nodes can't deal with clip type %u\n", clip->type);
|
||||
#endif
|
||||
|
||||
gsk_transform_node_get_transform (node, &transform);
|
||||
child = gsk_transform_node_get_child (node);
|
||||
if (!gsk_vulkan_push_constants_transform (&op.constants.constants, constants, &transform, &child->bounds))
|
||||
FALLBACK ("Transform nodes can't deal with clip type %u\n", constants->clip.type);
|
||||
op.type = GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS;
|
||||
gsk_vulkan_push_constants_init_copy (&op.constants.constants, constants);
|
||||
gsk_vulkan_push_constants_multiply_mvp (&op.constants.constants, &transform);
|
||||
g_array_append_val (self->render_ops, op);
|
||||
|
||||
gsk_vulkan_render_pass_add_node (self, render, &op.constants.constants, gsk_transform_node_get_child (node));
|
||||
gsk_vulkan_render_pass_add_node (self, render, &op.constants.constants, child);
|
||||
gsk_vulkan_push_constants_init_copy (&op.constants.constants, constants);
|
||||
g_array_append_val (self->render_ops, op);
|
||||
}
|
||||
break;
|
||||
return;
|
||||
|
||||
case GSK_CLIP_NODE:
|
||||
{
|
||||
if (!gsk_vulkan_push_constants_intersect_rect (&op.constants.constants, constants, gsk_clip_node_peek_clip (node)))
|
||||
FALLBACK ("Failed to find intersection between clip of type %u and rectangle\n", constants->clip.type);
|
||||
if (&op.constants.constants.clip.type == GSK_VULKAN_CLIP_ALL_CLIPPED)
|
||||
return;
|
||||
|
||||
op.type = GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS;
|
||||
g_array_append_val (self->render_ops, op);
|
||||
|
||||
gsk_vulkan_render_pass_add_node (self, render, &op.constants.constants, gsk_clip_node_get_child (node));
|
||||
|
||||
gsk_vulkan_push_constants_init_copy (&op.constants.constants, constants);
|
||||
g_array_append_val (self->render_ops, op);
|
||||
}
|
||||
return;
|
||||
|
||||
case GSK_ROUNDED_CLIP_NODE:
|
||||
{
|
||||
if (!gsk_vulkan_push_constants_intersect_rounded (&op.constants.constants,
|
||||
constants,
|
||||
gsk_rounded_clip_node_peek_clip (node)))
|
||||
FALLBACK ("Failed to find intersection between clip of type %u and rounded rectangle\n", constants->clip.type);
|
||||
if (&op.constants.constants.clip.type == GSK_VULKAN_CLIP_ALL_CLIPPED)
|
||||
return;
|
||||
|
||||
op.type = GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS;
|
||||
g_array_append_val (self->render_ops, op);
|
||||
|
||||
gsk_vulkan_render_pass_add_node (self, render, &op.constants.constants, gsk_rounded_clip_node_get_child (node));
|
||||
|
||||
gsk_vulkan_push_constants_init_copy (&op.constants.constants, constants);
|
||||
g_array_append_val (self->render_ops, op);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
g_assert_not_reached ();
|
||||
return;
|
||||
|
||||
fallback:
|
||||
switch (constants->clip.type)
|
||||
{
|
||||
case GSK_VULKAN_CLIP_NONE:
|
||||
op.type = GSK_VULKAN_OP_FALLBACK;
|
||||
break;
|
||||
case GSK_VULKAN_CLIP_RECT:
|
||||
op.type = GSK_VULKAN_OP_FALLBACK_CLIP;
|
||||
gsk_rounded_rect_init_copy (&op.render.clip, &constants->clip.rect);
|
||||
break;
|
||||
case GSK_VULKAN_CLIP_ROUNDED_CIRCULAR:
|
||||
case GSK_VULKAN_CLIP_ROUNDED:
|
||||
op.type = GSK_VULKAN_OP_FALLBACK_ROUNDED_CLIP;
|
||||
gsk_rounded_rect_init_copy (&op.render.clip, &constants->clip.rect);
|
||||
break;
|
||||
case GSK_VULKAN_CLIP_ALL_CLIPPED:
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
return;
|
||||
}
|
||||
op.render.pipeline = gsk_vulkan_render_get_pipeline (render, GSK_VULKAN_PIPELINE_BLIT);
|
||||
g_array_append_val (self->render_ops, op);
|
||||
}
|
||||
#undef FALLBACK
|
||||
|
||||
void
|
||||
gsk_vulkan_render_pass_add (GskVulkanRenderPass *self,
|
||||
GskVulkanRender *render,
|
||||
const graphene_matrix_t *mvp,
|
||||
const graphene_rect_t *viewport,
|
||||
GskRenderNode *node)
|
||||
{
|
||||
GskVulkanOp op = { 0, };
|
||||
|
||||
op.type = GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS;
|
||||
gsk_vulkan_push_constants_init (&op.constants.constants, mvp);
|
||||
gsk_vulkan_push_constants_init (&op.constants.constants, mvp, viewport);
|
||||
g_array_append_val (self->render_ops, op);
|
||||
|
||||
gsk_vulkan_render_pass_add_node (self, render, &op.constants.constants, node);
|
||||
@@ -177,12 +288,30 @@ gsk_vulkan_render_pass_upload_fallback (GskVulkanRenderPass *self,
|
||||
|
||||
node = op->node;
|
||||
|
||||
/* XXX: We could intersect bounds with clip bounds here */
|
||||
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
|
||||
ceil (node->bounds.size.width),
|
||||
ceil (node->bounds.size.height));
|
||||
cr = cairo_create (surface);
|
||||
cairo_translate (cr, -node->bounds.origin.x, -node->bounds.origin.y);
|
||||
|
||||
if (op->type == GSK_VULKAN_OP_FALLBACK_CLIP)
|
||||
{
|
||||
cairo_rectangle (cr,
|
||||
op->clip.bounds.origin.x, op->clip.bounds.origin.y,
|
||||
op->clip.bounds.size.width, op->clip.bounds.size.height);
|
||||
cairo_clip (cr);
|
||||
}
|
||||
else if (op->type == GSK_VULKAN_OP_FALLBACK_ROUNDED_CLIP)
|
||||
{
|
||||
gsk_rounded_rect_path (&op->clip, cr);
|
||||
cairo_clip (cr);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_assert (op->type == GSK_VULKAN_OP_FALLBACK);
|
||||
}
|
||||
|
||||
gsk_render_node_draw (node, cr);
|
||||
|
||||
cairo_destroy (cr);
|
||||
@@ -213,6 +342,8 @@ gsk_vulkan_render_pass_upload (GskVulkanRenderPass *self,
|
||||
switch (op->type)
|
||||
{
|
||||
case GSK_VULKAN_OP_FALLBACK:
|
||||
case GSK_VULKAN_OP_FALLBACK_CLIP:
|
||||
case GSK_VULKAN_OP_FALLBACK_ROUNDED_CLIP:
|
||||
gsk_vulkan_render_pass_upload_fallback (self, &op->render, render, uploader);
|
||||
break;
|
||||
|
||||
@@ -240,6 +371,7 @@ gsk_vulkan_render_pass_upload (GskVulkanRenderPass *self,
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
case GSK_VULKAN_OP_COLOR:
|
||||
case GSK_VULKAN_OP_LINEAR_GRADIENT:
|
||||
case GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS:
|
||||
break;
|
||||
}
|
||||
@@ -261,6 +393,8 @@ gsk_vulkan_render_pass_count_vertex_data (GskVulkanRenderPass *self)
|
||||
switch (op->type)
|
||||
{
|
||||
case GSK_VULKAN_OP_FALLBACK:
|
||||
case GSK_VULKAN_OP_FALLBACK_CLIP:
|
||||
case GSK_VULKAN_OP_FALLBACK_ROUNDED_CLIP:
|
||||
case GSK_VULKAN_OP_SURFACE:
|
||||
case GSK_VULKAN_OP_TEXTURE:
|
||||
op->render.vertex_count = gsk_vulkan_blend_pipeline_count_vertex_data (GSK_VULKAN_BLEND_PIPELINE (op->render.pipeline));
|
||||
@@ -272,6 +406,11 @@ gsk_vulkan_render_pass_count_vertex_data (GskVulkanRenderPass *self)
|
||||
n_bytes += op->render.vertex_count;
|
||||
break;
|
||||
|
||||
case GSK_VULKAN_OP_LINEAR_GRADIENT:
|
||||
op->render.vertex_count = gsk_vulkan_linear_gradient_pipeline_count_vertex_data (GSK_VULKAN_LINEAR_GRADIENT_PIPELINE (op->render.pipeline));
|
||||
n_bytes += op->render.vertex_count;
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
case GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS:
|
||||
@@ -300,6 +439,8 @@ gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self,
|
||||
switch (op->type)
|
||||
{
|
||||
case GSK_VULKAN_OP_FALLBACK:
|
||||
case GSK_VULKAN_OP_FALLBACK_CLIP:
|
||||
case GSK_VULKAN_OP_FALLBACK_ROUNDED_CLIP:
|
||||
case GSK_VULKAN_OP_SURFACE:
|
||||
case GSK_VULKAN_OP_TEXTURE:
|
||||
{
|
||||
@@ -322,6 +463,21 @@ gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self,
|
||||
}
|
||||
break;
|
||||
|
||||
case GSK_VULKAN_OP_LINEAR_GRADIENT:
|
||||
{
|
||||
op->render.vertex_offset = offset + n_bytes;
|
||||
gsk_vulkan_linear_gradient_pipeline_collect_vertex_data (GSK_VULKAN_LINEAR_GRADIENT_PIPELINE (op->render.pipeline),
|
||||
data + n_bytes + offset,
|
||||
&op->render.node->bounds,
|
||||
gsk_linear_gradient_node_peek_start (op->render.node),
|
||||
gsk_linear_gradient_node_peek_end (op->render.node),
|
||||
gsk_render_node_get_node_type (op->render.node) == GSK_REPEATING_LINEAR_GRADIENT_NODE,
|
||||
gsk_linear_gradient_node_get_n_color_stops (op->render.node),
|
||||
gsk_linear_gradient_node_peek_color_stops (op->render.node));
|
||||
n_bytes += op->render.vertex_count;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
case GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS:
|
||||
@@ -348,6 +504,8 @@ gsk_vulkan_render_pass_reserve_descriptor_sets (GskVulkanRenderPass *self,
|
||||
switch (op->type)
|
||||
{
|
||||
case GSK_VULKAN_OP_FALLBACK:
|
||||
case GSK_VULKAN_OP_FALLBACK_CLIP:
|
||||
case GSK_VULKAN_OP_FALLBACK_ROUNDED_CLIP:
|
||||
case GSK_VULKAN_OP_SURFACE:
|
||||
case GSK_VULKAN_OP_TEXTURE:
|
||||
op->render.descriptor_set_index = gsk_vulkan_render_reserve_descriptor_set (render, op->render.source);
|
||||
@@ -356,6 +514,7 @@ gsk_vulkan_render_pass_reserve_descriptor_sets (GskVulkanRenderPass *self,
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
case GSK_VULKAN_OP_COLOR:
|
||||
case GSK_VULKAN_OP_LINEAR_GRADIENT:
|
||||
case GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS:
|
||||
break;
|
||||
}
|
||||
@@ -372,15 +531,18 @@ gsk_vulkan_render_pass_draw (GskVulkanRenderPass *self,
|
||||
GskVulkanPipeline *current_pipeline = NULL;
|
||||
gsize current_draw_index = 0;
|
||||
GskVulkanOp *op;
|
||||
guint i;
|
||||
guint i, step;
|
||||
|
||||
for (i = 0; i < self->render_ops->len; i++)
|
||||
for (i = 0; i < self->render_ops->len; i += step)
|
||||
{
|
||||
op = &g_array_index (self->render_ops, GskVulkanOp, i);
|
||||
step = 1;
|
||||
|
||||
switch (op->type)
|
||||
{
|
||||
case GSK_VULKAN_OP_FALLBACK:
|
||||
case GSK_VULKAN_OP_FALLBACK_CLIP:
|
||||
case GSK_VULKAN_OP_FALLBACK_ROUNDED_CLIP:
|
||||
case GSK_VULKAN_OP_SURFACE:
|
||||
case GSK_VULKAN_OP_TEXTURE:
|
||||
if (current_pipeline != op->render.pipeline)
|
||||
@@ -432,9 +594,37 @@ gsk_vulkan_render_pass_draw (GskVulkanRenderPass *self,
|
||||
current_draw_index = 0;
|
||||
}
|
||||
|
||||
for (step = 1; step + i < self->render_ops->len; step++)
|
||||
{
|
||||
GskVulkanOp *cmp = &g_array_index (self->render_ops, GskVulkanOp, i + step);
|
||||
if (cmp->type != GSK_VULKAN_OP_COLOR ||
|
||||
cmp->render.pipeline != current_pipeline)
|
||||
break;
|
||||
}
|
||||
current_draw_index += gsk_vulkan_color_pipeline_draw (GSK_VULKAN_COLOR_PIPELINE (current_pipeline),
|
||||
command_buffer,
|
||||
current_draw_index, 1);
|
||||
current_draw_index, step);
|
||||
break;
|
||||
|
||||
case GSK_VULKAN_OP_LINEAR_GRADIENT:
|
||||
if (current_pipeline != op->render.pipeline)
|
||||
{
|
||||
current_pipeline = op->render.pipeline;
|
||||
vkCmdBindPipeline (command_buffer,
|
||||
VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
gsk_vulkan_pipeline_get_pipeline (current_pipeline));
|
||||
vkCmdBindVertexBuffers (command_buffer,
|
||||
0,
|
||||
1,
|
||||
(VkBuffer[1]) {
|
||||
gsk_vulkan_buffer_get_buffer (vertex_buffer)
|
||||
},
|
||||
(VkDeviceSize[1]) { op->render.vertex_offset });
|
||||
current_draw_index = 0;
|
||||
}
|
||||
current_draw_index += gsk_vulkan_linear_gradient_pipeline_draw (GSK_VULKAN_LINEAR_GRADIENT_PIPELINE (current_pipeline),
|
||||
command_buffer,
|
||||
current_draw_index, 1);
|
||||
break;
|
||||
|
||||
case GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS:
|
||||
|
||||
@@ -17,6 +17,7 @@ void gsk_vulkan_render_pass_free (GskVulk
|
||||
void gsk_vulkan_render_pass_add (GskVulkanRenderPass *self,
|
||||
GskVulkanRender *render,
|
||||
const graphene_matrix_t*mvp,
|
||||
const graphene_rect_t *viewport,
|
||||
GskRenderNode *node);
|
||||
|
||||
void gsk_vulkan_render_pass_upload (GskVulkanRenderPass *self,
|
||||
|
||||
@@ -12,6 +12,11 @@ G_BEGIN_DECLS
|
||||
typedef enum {
|
||||
GSK_VULKAN_PIPELINE_BLIT,
|
||||
GSK_VULKAN_PIPELINE_COLOR,
|
||||
GSK_VULKAN_PIPELINE_COLOR_CLIP,
|
||||
GSK_VULKAN_PIPELINE_COLOR_CLIP_ROUNDED,
|
||||
GSK_VULKAN_PIPELINE_LINEAR_GRADIENT,
|
||||
GSK_VULKAN_PIPELINE_LINEAR_GRADIENT_CLIP,
|
||||
GSK_VULKAN_PIPELINE_LINEAR_GRADIENT_CLIP_ROUNDED,
|
||||
/* add more */
|
||||
GSK_VULKAN_N_PIPELINES
|
||||
} GskVulkanPipelineType;
|
||||
@@ -24,7 +29,8 @@ void gsk_vulkan_render_free (GskVulk
|
||||
|
||||
gboolean gsk_vulkan_render_is_busy (GskVulkanRender *self);
|
||||
void gsk_vulkan_render_reset (GskVulkanRender *self,
|
||||
GskVulkanImage *target);
|
||||
GskVulkanImage *target,
|
||||
const graphene_rect_t *rect);
|
||||
|
||||
GskRenderer * gsk_vulkan_render_get_renderer (GskVulkanRender *self);
|
||||
|
||||
@@ -47,6 +53,8 @@ void gsk_vulkan_render_draw (GskVulk
|
||||
|
||||
void gsk_vulkan_render_submit (GskVulkanRender *self);
|
||||
|
||||
GskTexture * gsk_vulkan_render_download_target (GskVulkanRender *self);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSK_VULKAN_RENDER_PRIVATE_H__ */
|
||||
|
||||
@@ -5,6 +5,9 @@ layout(location = 1) in vec2 inTexCoord;
|
||||
|
||||
layout(push_constant) uniform PushConstants {
|
||||
mat4 mvp;
|
||||
vec4 clip_bounds;
|
||||
vec4 clip_widths;
|
||||
vec4 clip_heights;
|
||||
} push;
|
||||
|
||||
layout(location = 0) out vec2 outTexCoord;
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,56 @@
|
||||
#version 420 core
|
||||
|
||||
layout(location = 0) in vec2 inPos;
|
||||
layout(location = 1) in vec4 inColor;
|
||||
layout(location = 2) in vec4 inClipBounds;
|
||||
layout(location = 3) in vec4 inClipWidths;
|
||||
|
||||
layout(location = 0) out vec4 color;
|
||||
|
||||
struct RoundedRect {
|
||||
vec4 bounds;
|
||||
vec4 corners;
|
||||
};
|
||||
|
||||
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
float clip(vec2 pos, RoundedRect r) {
|
||||
vec2 ref_tl = r.bounds.xy + vec2( r.corners.x, r.corners.x);
|
||||
vec2 ref_tr = r.bounds.zy + vec2(-r.corners.y, r.corners.y);
|
||||
vec2 ref_br = r.bounds.zw + vec2(-r.corners.z, -r.corners.z);
|
||||
vec2 ref_bl = r.bounds.xw + vec2( r.corners.w, -r.corners.w);
|
||||
|
||||
float d_tl = distance(pos, ref_tl);
|
||||
float d_tr = distance(pos, ref_tr);
|
||||
float d_br = distance(pos, ref_br);
|
||||
float d_bl = distance(pos, ref_bl);
|
||||
|
||||
float pixels_per_fragment = length(fwidth(pos.xy));
|
||||
float nudge = 0.5 * pixels_per_fragment;
|
||||
vec4 distances = vec4(d_tl, d_tr, d_br, d_bl) - r.corners + nudge;
|
||||
|
||||
bvec4 is_out = bvec4(pos.x < ref_tl.x && pos.y < ref_tl.y,
|
||||
pos.x > ref_tr.x && pos.y < ref_tr.y,
|
||||
pos.x > ref_br.x && pos.y > ref_br.y,
|
||||
pos.x < ref_bl.x && pos.y > ref_bl.y);
|
||||
|
||||
float distance_from_border = dot(vec4(is_out),
|
||||
max(vec4(0.0, 0.0, 0.0, 0.0), distances));
|
||||
|
||||
// Move the distance back into pixels.
|
||||
distance_from_border /= pixels_per_fragment;
|
||||
// Apply a more gradual fade out to transparent.
|
||||
//distance_from_border -= 0.5;
|
||||
|
||||
return 1.0 - smoothstep(0.0, 1.0, distance_from_border);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
RoundedRect r = RoundedRect(vec4(inClipBounds.xy, inClipBounds.xy + inClipBounds.zw), inClipWidths);
|
||||
|
||||
color = vec4(inColor.rgb * inColor.a, inColor.a) * clip (inPos, r);
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,36 @@
|
||||
#version 420 core
|
||||
|
||||
layout(location = 0) in vec4 inRect;
|
||||
layout(location = 1) in vec4 inColor;
|
||||
|
||||
layout(push_constant) uniform PushConstants {
|
||||
mat4 mvp;
|
||||
vec4 clip_bounds;
|
||||
vec4 clip_widths;
|
||||
vec4 clip_heights;
|
||||
} push;
|
||||
|
||||
layout(location = 0) out vec2 outPos;
|
||||
layout(location = 1) out flat vec4 outColor;
|
||||
layout(location = 2) out flat vec4 outClipBounds;
|
||||
layout(location = 3) out flat vec4 outClipWidths;
|
||||
|
||||
out gl_PerVertex {
|
||||
vec4 gl_Position;
|
||||
};
|
||||
|
||||
vec2 offsets[6] = { vec2(0.0, 0.0),
|
||||
vec2(1.0, 0.0),
|
||||
vec2(0.0, 1.0),
|
||||
vec2(0.0, 1.0),
|
||||
vec2(1.0, 0.0),
|
||||
vec2(1.0, 1.0) };
|
||||
|
||||
void main() {
|
||||
vec2 pos = inRect.xy + inRect.zw * offsets[gl_VertexIndex];
|
||||
gl_Position = push.mvp * vec4 (pos, 0.0, 1.0);
|
||||
outPos = pos;
|
||||
outColor = inColor;
|
||||
outClipBounds = push.clip_bounds;
|
||||
outClipWidths = push.clip_widths;
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,10 @@
|
||||
#version 420 core
|
||||
|
||||
layout(location = 0) in vec4 inColor;
|
||||
|
||||
layout(location = 0) out vec4 color;
|
||||
|
||||
void main()
|
||||
{
|
||||
color = vec4(inColor.rgb * inColor.a, inColor.a);
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,42 @@
|
||||
#version 420 core
|
||||
|
||||
layout(location = 0) in vec4 inRect;
|
||||
layout(location = 1) in vec4 inColor;
|
||||
|
||||
layout(push_constant) uniform PushConstants {
|
||||
mat4 mvp;
|
||||
vec4 clip_bounds;
|
||||
vec4 clip_widths;
|
||||
vec4 clip_heights;
|
||||
} push;
|
||||
|
||||
out gl_PerVertex {
|
||||
vec4 gl_Position;
|
||||
};
|
||||
|
||||
layout(location = 0) out vec4 outColor;
|
||||
|
||||
vec2 offsets[6] = { vec2(0.0, 0.0),
|
||||
vec2(1.0, 0.0),
|
||||
vec2(0.0, 1.0),
|
||||
vec2(0.0, 1.0),
|
||||
vec2(1.0, 0.0),
|
||||
vec2(1.0, 1.0) };
|
||||
|
||||
vec4 intersect(vec4 a, vec4 b)
|
||||
{
|
||||
a = vec4(a.xy, a.xy + a.zw);
|
||||
b = vec4(b.xy, b.xy + b.zw);
|
||||
vec4 result = vec4(max(a.xy, b.xy), min(a.zw, b.zw));
|
||||
if (any (greaterThanEqual (result.xy, result.zw)))
|
||||
return vec4(0.0,0.0,0.0,0.0);
|
||||
return vec4(result.xy, result.zw - result.xy);
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec4 rect = intersect(inRect, push.clip_bounds);
|
||||
|
||||
vec2 pos = rect.xy + rect.zw * offsets[gl_VertexIndex];
|
||||
gl_Position = push.mvp * vec4 (pos, 0.0, 1.0);
|
||||
outColor = inColor;
|
||||
}
|
||||
Binary file not shown.
@@ -6,5 +6,5 @@ layout(location = 0) out vec4 color;
|
||||
|
||||
void main()
|
||||
{
|
||||
color = inColor;
|
||||
color = vec4(inColor.rgb * inColor.a, inColor.a);
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -5,6 +5,9 @@ layout(location = 1) in vec4 inColor;
|
||||
|
||||
layout(push_constant) uniform PushConstants {
|
||||
mat4 mvp;
|
||||
vec4 clip_bounds;
|
||||
vec4 clip_widths;
|
||||
vec4 clip_heights;
|
||||
} push;
|
||||
|
||||
layout(location = 0) out vec4 outColor;
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,78 @@
|
||||
#version 420 core
|
||||
|
||||
struct ColorStop {
|
||||
float offset;
|
||||
vec4 color;
|
||||
};
|
||||
|
||||
struct RoundedRect {
|
||||
vec4 bounds;
|
||||
vec4 corners;
|
||||
};
|
||||
|
||||
layout(location = 0) in vec2 inPos;
|
||||
layout(location = 1) in float inGradientPos;
|
||||
layout(location = 2) in flat int inRepeating;
|
||||
layout(location = 3) in flat int inStopCount;
|
||||
layout(location = 4) in flat vec4 inClipBounds;
|
||||
layout(location = 5) in flat vec4 inClipWidths;
|
||||
layout(location = 6) in flat ColorStop inStops[8];
|
||||
|
||||
layout(location = 0) out vec4 outColor;
|
||||
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
float clip(vec2 pos, RoundedRect r) {
|
||||
vec2 ref_tl = r.bounds.xy + vec2( r.corners.x, r.corners.x);
|
||||
vec2 ref_tr = r.bounds.zy + vec2(-r.corners.y, r.corners.y);
|
||||
vec2 ref_br = r.bounds.zw + vec2(-r.corners.z, -r.corners.z);
|
||||
vec2 ref_bl = r.bounds.xw + vec2( r.corners.w, -r.corners.w);
|
||||
|
||||
float d_tl = distance(pos, ref_tl);
|
||||
float d_tr = distance(pos, ref_tr);
|
||||
float d_br = distance(pos, ref_br);
|
||||
float d_bl = distance(pos, ref_bl);
|
||||
|
||||
float pixels_per_fragment = length(fwidth(pos.xy));
|
||||
float nudge = 0.5 * pixels_per_fragment;
|
||||
vec4 distances = vec4(d_tl, d_tr, d_br, d_bl) - r.corners + nudge;
|
||||
|
||||
bvec4 is_out = bvec4(pos.x < ref_tl.x && pos.y < ref_tl.y,
|
||||
pos.x > ref_tr.x && pos.y < ref_tr.y,
|
||||
pos.x > ref_br.x && pos.y > ref_br.y,
|
||||
pos.x < ref_bl.x && pos.y > ref_bl.y);
|
||||
|
||||
float distance_from_border = dot(vec4(is_out),
|
||||
max(vec4(0.0, 0.0, 0.0, 0.0), distances));
|
||||
|
||||
// Move the distance back into pixels.
|
||||
distance_from_border /= pixels_per_fragment;
|
||||
// Apply a more gradual fade out to transparent.
|
||||
//distance_from_border -= 0.5;
|
||||
|
||||
return 1.0 - smoothstep(0.0, 1.0, distance_from_border);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
RoundedRect r = RoundedRect(vec4(inClipBounds.xy, inClipBounds.xy + inClipBounds.zw), inClipWidths);
|
||||
|
||||
float pos;
|
||||
if (inRepeating != 0)
|
||||
pos = fract (inGradientPos);
|
||||
else
|
||||
pos = clamp (inGradientPos, 0, 1);
|
||||
|
||||
vec4 color = inStops[0].color;
|
||||
int n = clamp (inStopCount, 2, 8);
|
||||
for (int i = 1; i < n; i++)
|
||||
{
|
||||
if (inStops[i].offset > inStops[i-1].offset)
|
||||
color = mix (color, inStops[i].color, clamp((pos - inStops[i-1].offset) / (inStops[i].offset - inStops[i-1].offset), 0, 1));
|
||||
}
|
||||
|
||||
//outColor = vec4(pos, pos, pos, 1.0);
|
||||
outColor = color * clip (inPos, r);
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,84 @@
|
||||
#version 420 core
|
||||
|
||||
struct ColorStop {
|
||||
float offset;
|
||||
vec4 color;
|
||||
};
|
||||
|
||||
layout(location = 0) in vec4 inRect;
|
||||
layout(location = 1) in vec2 inStart;
|
||||
layout(location = 2) in vec2 inEnd;
|
||||
layout(location = 3) in int inRepeating;
|
||||
layout(location = 4) in int inStopCount;
|
||||
layout(location = 5) in vec4 inOffsets0;
|
||||
layout(location = 6) in vec4 inOffsets1;
|
||||
layout(location = 7) in vec4 inColors0;
|
||||
layout(location = 8) in vec4 inColors1;
|
||||
layout(location = 9) in vec4 inColors2;
|
||||
layout(location = 10) in vec4 inColors3;
|
||||
layout(location = 11) in vec4 inColors4;
|
||||
layout(location = 12) in vec4 inColors5;
|
||||
layout(location = 13) in vec4 inColors6;
|
||||
layout(location = 14) in vec4 inColors7;
|
||||
|
||||
layout(push_constant) uniform PushConstants {
|
||||
mat4 mvp;
|
||||
vec4 clip_bounds;
|
||||
vec4 clip_widths;
|
||||
vec4 clip_heights;
|
||||
} push;
|
||||
|
||||
layout(location = 0) out vec2 outPos;
|
||||
layout(location = 1) out float outGradientPos;
|
||||
layout(location = 2) out flat int outRepeating;
|
||||
layout(location = 3) out flat int outStopCount;
|
||||
layout(location = 4) out flat vec4 outClipBounds;
|
||||
layout(location = 5) out flat vec4 outClipWidths;
|
||||
layout(location = 6) out flat ColorStop outStops[8];
|
||||
|
||||
out gl_PerVertex {
|
||||
vec4 gl_Position;
|
||||
};
|
||||
|
||||
vec2 offsets[6] = { vec2(0.0, 0.0),
|
||||
vec2(1.0, 0.0),
|
||||
vec2(0.0, 1.0),
|
||||
vec2(0.0, 1.0),
|
||||
vec2(1.0, 0.0),
|
||||
vec2(1.0, 1.0) };
|
||||
|
||||
float
|
||||
get_gradient_pos (vec2 pos)
|
||||
{
|
||||
pos = pos - inStart;
|
||||
vec2 grad = inEnd - inStart;
|
||||
|
||||
return dot (pos, grad) / dot (grad, grad);
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec2 pos = inRect.xy + inRect.zw * offsets[gl_VertexIndex];
|
||||
gl_Position = push.mvp * vec4 (pos, 0.0, 1.0);
|
||||
outPos = pos;
|
||||
outGradientPos = get_gradient_pos (pos);
|
||||
outClipBounds = push.clip_bounds;
|
||||
outClipWidths = push.clip_widths;
|
||||
outRepeating = inRepeating;
|
||||
outStopCount = inStopCount;
|
||||
outStops[0].offset = inOffsets0[0];
|
||||
outStops[0].color = inColors0 * vec4(inColors0.aaa, 1.0);
|
||||
outStops[1].offset = inOffsets0[1];
|
||||
outStops[1].color = inColors1 * vec4(inColors1.aaa, 1.0);
|
||||
outStops[2].offset = inOffsets0[2];
|
||||
outStops[2].color = inColors2 * vec4(inColors2.aaa, 1.0);
|
||||
outStops[3].offset = inOffsets0[3];
|
||||
outStops[3].color = inColors3 * vec4(inColors3.aaa, 1.0);
|
||||
outStops[4].offset = inOffsets1[0];
|
||||
outStops[4].color = inColors4 * vec4(inColors4.aaa, 1.0);
|
||||
outStops[5].offset = inOffsets1[1];
|
||||
outStops[5].color = inColors5 * vec4(inColors5.aaa, 1.0);
|
||||
outStops[6].offset = inOffsets1[2];
|
||||
outStops[6].color = inColors6 * vec4(inColors6.aaa, 1.0);
|
||||
outStops[7].offset = inOffsets1[3];
|
||||
outStops[7].color = inColors7 * vec4(inColors7.aaa, 1.0);
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,33 @@
|
||||
#version 420 core
|
||||
|
||||
struct ColorStop {
|
||||
float offset;
|
||||
vec4 color;
|
||||
};
|
||||
|
||||
layout(location = 0) in float inGradientPos;
|
||||
layout(location = 1) in flat int inRepeating;
|
||||
layout(location = 2) in flat int inStopCount;
|
||||
layout(location = 3) in flat ColorStop inStops[8];
|
||||
|
||||
layout(location = 0) out vec4 outColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
float pos;
|
||||
if (inRepeating != 0)
|
||||
pos = fract (inGradientPos);
|
||||
else
|
||||
pos = clamp (inGradientPos, 0, 1);
|
||||
|
||||
vec4 color = inStops[0].color;
|
||||
int n = clamp (inStopCount, 2, 8);
|
||||
for (int i = 1; i < n; i++)
|
||||
{
|
||||
if (inStops[i].offset > inStops[i-1].offset)
|
||||
color = mix (color, inStops[i].color, clamp((pos - inStops[i-1].offset) / (inStops[i].offset - inStops[i-1].offset), 0, 1));
|
||||
}
|
||||
|
||||
//outColor = vec4(pos, pos, pos, 1.0);
|
||||
outColor = color;
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,78 @@
|
||||
#version 420 core
|
||||
|
||||
struct ColorStop {
|
||||
float offset;
|
||||
vec4 color;
|
||||
};
|
||||
|
||||
layout(location = 0) in vec4 inRect;
|
||||
layout(location = 1) in vec2 inStart;
|
||||
layout(location = 2) in vec2 inEnd;
|
||||
layout(location = 3) in int inRepeating;
|
||||
layout(location = 4) in int inStopCount;
|
||||
layout(location = 5) in vec4 inOffsets0;
|
||||
layout(location = 6) in vec4 inOffsets1;
|
||||
layout(location = 7) in vec4 inColors0;
|
||||
layout(location = 8) in vec4 inColors1;
|
||||
layout(location = 9) in vec4 inColors2;
|
||||
layout(location = 10) in vec4 inColors3;
|
||||
layout(location = 11) in vec4 inColors4;
|
||||
layout(location = 12) in vec4 inColors5;
|
||||
layout(location = 13) in vec4 inColors6;
|
||||
layout(location = 14) in vec4 inColors7;
|
||||
|
||||
layout(push_constant) uniform PushConstants {
|
||||
mat4 mvp;
|
||||
vec4 clip_bounds;
|
||||
vec4 clip_widths;
|
||||
vec4 clip_heights;
|
||||
} push;
|
||||
|
||||
layout(location = 0) out float outGradientPos;
|
||||
layout(location = 1) out flat int outRepeating;
|
||||
layout(location = 2) out flat int outStopCount;
|
||||
layout(location = 3) out flat ColorStop outStops[8];
|
||||
|
||||
out gl_PerVertex {
|
||||
vec4 gl_Position;
|
||||
};
|
||||
|
||||
vec2 offsets[6] = { vec2(0.0, 0.0),
|
||||
vec2(1.0, 0.0),
|
||||
vec2(0.0, 1.0),
|
||||
vec2(0.0, 1.0),
|
||||
vec2(1.0, 0.0),
|
||||
vec2(1.0, 1.0) };
|
||||
|
||||
float
|
||||
get_gradient_pos (vec2 pos)
|
||||
{
|
||||
pos = pos - inStart;
|
||||
vec2 grad = inEnd - inStart;
|
||||
|
||||
return dot (pos, grad) / dot (grad, grad);
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec2 pos = inRect.xy + inRect.zw * offsets[gl_VertexIndex];
|
||||
gl_Position = push.mvp * vec4 (pos, 0.0, 1.0);
|
||||
outGradientPos = get_gradient_pos (pos);
|
||||
outRepeating = inRepeating;
|
||||
outStopCount = inStopCount;
|
||||
outStops[0].offset = inOffsets0[0];
|
||||
outStops[0].color = inColors0 * vec4(inColors0.aaa, 1.0);
|
||||
outStops[1].offset = inOffsets0[1];
|
||||
outStops[1].color = inColors1 * vec4(inColors1.aaa, 1.0);
|
||||
outStops[2].offset = inOffsets0[2];
|
||||
outStops[2].color = inColors2 * vec4(inColors2.aaa, 1.0);
|
||||
outStops[3].offset = inOffsets0[3];
|
||||
outStops[3].color = inColors3 * vec4(inColors3.aaa, 1.0);
|
||||
outStops[4].offset = inOffsets1[0];
|
||||
outStops[4].color = inColors4 * vec4(inColors4.aaa, 1.0);
|
||||
outStops[5].offset = inOffsets1[1];
|
||||
outStops[5].color = inColors5 * vec4(inColors5.aaa, 1.0);
|
||||
outStops[6].offset = inOffsets1[2];
|
||||
outStops[6].color = inColors6 * vec4(inColors6.aaa, 1.0);
|
||||
outStops[7].offset = inOffsets1[3];
|
||||
outStops[7].color = inColors7 * vec4(inColors7.aaa, 1.0);
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,33 @@
|
||||
#version 420 core
|
||||
|
||||
struct ColorStop {
|
||||
float offset;
|
||||
vec4 color;
|
||||
};
|
||||
|
||||
layout(location = 0) in float inGradientPos;
|
||||
layout(location = 1) in flat int inRepeating;
|
||||
layout(location = 2) in flat int inStopCount;
|
||||
layout(location = 3) in flat ColorStop inStops[8];
|
||||
|
||||
layout(location = 0) out vec4 outColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
float pos;
|
||||
if (inRepeating != 0)
|
||||
pos = fract (inGradientPos);
|
||||
else
|
||||
pos = clamp (inGradientPos, 0, 1);
|
||||
|
||||
vec4 color = inStops[0].color;
|
||||
int n = clamp (inStopCount, 2, 8);
|
||||
for (int i = 1; i < n; i++)
|
||||
{
|
||||
if (inStops[i].offset > inStops[i-1].offset)
|
||||
color = mix (color, inStops[i].color, clamp((pos - inStops[i-1].offset) / (inStops[i].offset - inStops[i-1].offset), 0, 1));
|
||||
}
|
||||
|
||||
//outColor = vec4(pos, pos, pos, 1.0);
|
||||
outColor = color;
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,89 @@
|
||||
#version 420 core
|
||||
|
||||
struct ColorStop {
|
||||
float offset;
|
||||
vec4 color;
|
||||
};
|
||||
|
||||
layout(location = 0) in vec4 inRect;
|
||||
layout(location = 1) in vec2 inStart;
|
||||
layout(location = 2) in vec2 inEnd;
|
||||
layout(location = 3) in int inRepeating;
|
||||
layout(location = 4) in int inStopCount;
|
||||
layout(location = 5) in vec4 inOffsets0;
|
||||
layout(location = 6) in vec4 inOffsets1;
|
||||
layout(location = 7) in vec4 inColors0;
|
||||
layout(location = 8) in vec4 inColors1;
|
||||
layout(location = 9) in vec4 inColors2;
|
||||
layout(location = 10) in vec4 inColors3;
|
||||
layout(location = 11) in vec4 inColors4;
|
||||
layout(location = 12) in vec4 inColors5;
|
||||
layout(location = 13) in vec4 inColors6;
|
||||
layout(location = 14) in vec4 inColors7;
|
||||
|
||||
layout(push_constant) uniform PushConstants {
|
||||
mat4 mvp;
|
||||
vec4 clip_bounds;
|
||||
vec4 clip_widths;
|
||||
vec4 clip_heights;
|
||||
} push;
|
||||
|
||||
layout(location = 0) out float outGradientPos;
|
||||
layout(location = 1) out flat int outRepeating;
|
||||
layout(location = 2) out flat int outStopCount;
|
||||
layout(location = 3) out flat ColorStop outStops[8];
|
||||
|
||||
out gl_PerVertex {
|
||||
vec4 gl_Position;
|
||||
};
|
||||
|
||||
vec2 offsets[6] = { vec2(0.0, 0.0),
|
||||
vec2(1.0, 0.0),
|
||||
vec2(0.0, 1.0),
|
||||
vec2(0.0, 1.0),
|
||||
vec2(1.0, 0.0),
|
||||
vec2(1.0, 1.0) };
|
||||
|
||||
vec4 intersect(vec4 a, vec4 b)
|
||||
{
|
||||
a = vec4(a.xy, a.xy + a.zw);
|
||||
b = vec4(b.xy, b.xy + b.zw);
|
||||
vec4 result = vec4(max(a.xy, b.xy), min(a.zw, b.zw));
|
||||
if (any (greaterThanEqual (result.xy, result.zw)))
|
||||
return vec4(0.0,0.0,0.0,0.0);
|
||||
return vec4(result.xy, result.zw - result.xy);
|
||||
}
|
||||
|
||||
float
|
||||
get_gradient_pos (vec2 pos)
|
||||
{
|
||||
pos = pos - inStart;
|
||||
vec2 grad = inEnd - inStart;
|
||||
|
||||
return dot (pos, grad) / dot (grad, grad);
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec4 rect = intersect(inRect, push.clip_bounds);
|
||||
vec2 pos = rect.xy + rect.zw * offsets[gl_VertexIndex];
|
||||
gl_Position = push.mvp * vec4 (pos, 0.0, 1.0);
|
||||
outGradientPos = get_gradient_pos (pos);
|
||||
outRepeating = inRepeating;
|
||||
outStopCount = inStopCount;
|
||||
outStops[0].offset = inOffsets0[0];
|
||||
outStops[0].color = inColors0 * vec4(inColors0.aaa, 1.0);
|
||||
outStops[1].offset = inOffsets0[1];
|
||||
outStops[1].color = inColors1 * vec4(inColors1.aaa, 1.0);
|
||||
outStops[2].offset = inOffsets0[2];
|
||||
outStops[2].color = inColors2 * vec4(inColors2.aaa, 1.0);
|
||||
outStops[3].offset = inOffsets0[3];
|
||||
outStops[3].color = inColors3 * vec4(inColors3.aaa, 1.0);
|
||||
outStops[4].offset = inOffsets1[0];
|
||||
outStops[4].color = inColors4 * vec4(inColors4.aaa, 1.0);
|
||||
outStops[5].offset = inOffsets1[1];
|
||||
outStops[5].color = inColors5 * vec4(inColors5.aaa, 1.0);
|
||||
outStops[6].offset = inOffsets1[2];
|
||||
outStops[6].color = inColors6 * vec4(inColors6.aaa, 1.0);
|
||||
outStops[7].offset = inOffsets1[3];
|
||||
outStops[7].color = inColors7 * vec4(inColors7.aaa, 1.0);
|
||||
}
|
||||
Binary file not shown.
@@ -1071,7 +1071,7 @@ main (int argc, const char *argv[])
|
||||
{
|
||||
g_set_prgname ("gtk-builder-tool");
|
||||
|
||||
gtk_init (NULL, NULL);
|
||||
gtk_init ();
|
||||
|
||||
gtk_test_register_all_types ();
|
||||
|
||||
|
||||
+1
-3
@@ -79,8 +79,6 @@ main (int argc, char *argv[])
|
||||
"optionally passing one or more URIs as arguments.");
|
||||
g_option_context_set_summary (context, summary);
|
||||
g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
|
||||
g_option_context_add_group (context, gtk_get_option_group (FALSE));
|
||||
|
||||
g_option_context_parse (context, &argc, &argv, &error);
|
||||
|
||||
g_option_context_free (context);
|
||||
@@ -116,7 +114,7 @@ main (int argc, char *argv[])
|
||||
}
|
||||
|
||||
|
||||
gtk_init (&argc, &argv);
|
||||
gtk_init ();
|
||||
|
||||
app_name = *args;
|
||||
#ifdef G_OS_UNIX
|
||||
|
||||
@@ -30,7 +30,7 @@ main (int argc, char **argv)
|
||||
int max_prop_name_length = 0;
|
||||
gchar *pattern = NULL;
|
||||
|
||||
gtk_init (&argc, &argv);
|
||||
gtk_init ();
|
||||
|
||||
if (argc > 1)
|
||||
pattern = argv[1];
|
||||
|
||||
@@ -290,7 +290,7 @@ gtk_application_startup (GApplication *g_application)
|
||||
|
||||
gtk_action_muxer_insert (application->priv->muxer, "app", G_ACTION_GROUP (application));
|
||||
|
||||
gtk_init (NULL, NULL);
|
||||
gtk_init ();
|
||||
|
||||
application->priv->impl = gtk_application_impl_new (application, gdk_display_get_default ());
|
||||
gtk_application_impl_startup (application->priv->impl, application->priv->register_session);
|
||||
@@ -327,8 +327,6 @@ gtk_application_local_command_line (GApplication *application,
|
||||
gchar ***arguments,
|
||||
gint *exit_status)
|
||||
{
|
||||
g_application_add_option_group (application, gtk_get_option_group (FALSE));
|
||||
|
||||
return G_APPLICATION_CLASS (gtk_application_parent_class)->local_command_line (application, arguments, exit_status);
|
||||
}
|
||||
|
||||
|
||||
+59
-53
@@ -481,8 +481,9 @@ gtk_box_size_allocate_no_center (GtkWidget *widget,
|
||||
|
||||
GtkPackType packing;
|
||||
|
||||
gint size;
|
||||
gint extra;
|
||||
gint extra_space;
|
||||
gint children_minimum_size = 0;
|
||||
gint size_given_to_child;
|
||||
gint n_extra_widgets = 0; /* Number of widgets that receive 1 extra px */
|
||||
gint x = 0, y = 0, i;
|
||||
gint child_size;
|
||||
@@ -500,9 +501,9 @@ gtk_box_size_allocate_no_center (GtkWidget *widget,
|
||||
spacing = get_spacing (box);
|
||||
|
||||
if (private->orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
size = allocation->width - (nvis_children - 1) * spacing;
|
||||
extra_space = allocation->width - (nvis_children - 1) * spacing;
|
||||
else
|
||||
size = allocation->height - (nvis_children - 1) * spacing;
|
||||
extra_space = allocation->height - (nvis_children - 1) * spacing;
|
||||
|
||||
have_baseline = FALSE;
|
||||
minimum_above = natural_above = 0;
|
||||
@@ -541,7 +542,7 @@ gtk_box_size_allocate_no_center (GtkWidget *widget,
|
||||
(private->orientation == GTK_ORIENTATION_HORIZONTAL) ? "height" : "width",
|
||||
(private->orientation == GTK_ORIENTATION_HORIZONTAL) ? allocation->height : allocation->width);
|
||||
|
||||
size -= sizes[i].minimum_size;
|
||||
children_minimum_size += sizes[i].minimum_size;
|
||||
|
||||
sizes[i].data = child;
|
||||
|
||||
@@ -550,32 +551,32 @@ gtk_box_size_allocate_no_center (GtkWidget *widget,
|
||||
|
||||
if (private->homogeneous)
|
||||
{
|
||||
/* If were homogenous we still need to run the above loop to get the
|
||||
* minimum sizes for children that are not going to fill
|
||||
/* We still need to run the above loop to populate the minimum sizes for
|
||||
* children that aren't going to fill.
|
||||
*/
|
||||
if (private->orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
size = allocation->width - (nvis_children - 1) * get_spacing (box);
|
||||
else
|
||||
size = allocation->height - (nvis_children - 1) * get_spacing (box);
|
||||
|
||||
extra = size / nvis_children;
|
||||
n_extra_widgets = size % nvis_children;
|
||||
size_given_to_child = extra_space / nvis_children;
|
||||
n_extra_widgets = extra_space % nvis_children;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Bring children up to size first */
|
||||
size = gtk_distribute_natural_allocation (MAX (0, size), nvis_children, sizes);
|
||||
extra_space -= children_minimum_size;
|
||||
extra_space = MAX (0, extra_space);
|
||||
extra_space = gtk_distribute_natural_allocation (extra_space, nvis_children, sizes);
|
||||
|
||||
/* Calculate space which hasn't distributed yet,
|
||||
* and is available for expanding children.
|
||||
*/
|
||||
if (nexpand_children > 0)
|
||||
{
|
||||
extra = size / nexpand_children;
|
||||
n_extra_widgets = size % nexpand_children;
|
||||
size_given_to_child = extra_space / nexpand_children;
|
||||
n_extra_widgets = extra_space % nexpand_children;
|
||||
}
|
||||
else
|
||||
extra = 0;
|
||||
{
|
||||
size_given_to_child = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate child sizes. */
|
||||
@@ -603,7 +604,7 @@ gtk_box_size_allocate_no_center (GtkWidget *widget,
|
||||
/* Assign the child's size. */
|
||||
if (private->homogeneous)
|
||||
{
|
||||
child_size = extra;
|
||||
child_size = size_given_to_child;
|
||||
|
||||
if (n_extra_widgets > 0)
|
||||
{
|
||||
@@ -617,7 +618,7 @@ gtk_box_size_allocate_no_center (GtkWidget *widget,
|
||||
|
||||
if (child->expand || gtk_widget_compute_expand (child->widget, private->orientation))
|
||||
{
|
||||
child_size += extra;
|
||||
child_size += size_given_to_child;
|
||||
|
||||
if (n_extra_widgets > 0)
|
||||
{
|
||||
@@ -815,7 +816,7 @@ gtk_box_size_allocate_with_center (GtkWidget *widget,
|
||||
GtkPackType packing;
|
||||
gint min_size[2];
|
||||
gint nat_size[2];
|
||||
gint extra[2];
|
||||
gint size_given_to_child[2];
|
||||
gint n_extra_widgets[2];
|
||||
gint x = 0, y = 0, i;
|
||||
gint child_size;
|
||||
@@ -895,30 +896,34 @@ gtk_box_size_allocate_with_center (GtkWidget *widget,
|
||||
|
||||
if (priv->homogeneous)
|
||||
{
|
||||
extra[0] = ((box_size - center_size) / 2 - nvis[0] * spacing) / nvis[0];
|
||||
extra[1] = ((box_size - center_size) / 2 - nvis[1] * spacing) / nvis[1];
|
||||
extra[0] = MIN (extra[0], extra[1]);
|
||||
size_given_to_child[0] = ((box_size - center_size) / 2 - nvis[0] * spacing) / nvis[0];
|
||||
size_given_to_child[1] = ((box_size - center_size) / 2 - nvis[1] * spacing) / nvis[1];
|
||||
size_given_to_child[0] = MIN (size_given_to_child[0], size_given_to_child[1]);
|
||||
n_extra_widgets[0] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (packing = GTK_PACK_START; packing <= GTK_PACK_END; packing++)
|
||||
{
|
||||
gint s;
|
||||
gint extra_space;
|
||||
/* Distribute the remainder naturally on each side */
|
||||
s = MIN ((box_size - center_size) / 2 - min_size[packing], box_size - center_size - min_size[0] - min_size[1]);
|
||||
s = gtk_distribute_natural_allocation (MAX (0, s), nvis[packing], sizes[packing]);
|
||||
extra_space = MIN ((box_size - center_size) / 2 - min_size[packing],
|
||||
box_size - center_size - min_size[0] - min_size[1]);
|
||||
extra_space = MAX (0, extra_space);
|
||||
extra_space = gtk_distribute_natural_allocation (extra_space, nvis[packing], sizes[packing]);
|
||||
|
||||
/* Calculate space which hasn't distributed yet,
|
||||
* and is available for expanding children.
|
||||
*/
|
||||
if (nexp[packing] > 0)
|
||||
{
|
||||
extra[packing] = s / nexp[packing];
|
||||
n_extra_widgets[packing] = s % nexp[packing];
|
||||
size_given_to_child[packing] = extra_space / nexp[packing];
|
||||
n_extra_widgets[packing] = extra_space % nexp[packing];
|
||||
}
|
||||
else
|
||||
{
|
||||
size_given_to_child[packing] = 0;
|
||||
}
|
||||
else
|
||||
extra[packing] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -944,7 +949,7 @@ gtk_box_size_allocate_with_center (GtkWidget *widget,
|
||||
/* Assign the child's size. */
|
||||
if (priv->homogeneous)
|
||||
{
|
||||
child_size = extra[0];
|
||||
child_size = size_given_to_child[0];
|
||||
|
||||
if (n_extra_widgets[0] > 0)
|
||||
{
|
||||
@@ -958,7 +963,7 @@ gtk_box_size_allocate_with_center (GtkWidget *widget,
|
||||
|
||||
if (child->expand || gtk_widget_compute_expand (child->widget, priv->orientation))
|
||||
{
|
||||
child_size += extra[packing];
|
||||
child_size += size_given_to_child[packing];
|
||||
|
||||
if (n_extra_widgets[packing] > 0)
|
||||
{
|
||||
@@ -1679,7 +1684,7 @@ gtk_box_compute_size_for_opposing_orientation (GtkBox *box,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline)
|
||||
{
|
||||
GtkBoxPrivate *private = box->priv;
|
||||
GtkBoxPrivate *private = box->priv;
|
||||
GtkBoxChild *child;
|
||||
GList *children;
|
||||
gint nvis_children;
|
||||
@@ -1690,7 +1695,8 @@ gtk_box_compute_size_for_opposing_orientation (GtkBox *box,
|
||||
gint computed_minimum_baseline = -1, computed_natural_baseline = -1;
|
||||
GtkRequestedSize *sizes;
|
||||
GtkPackType packing;
|
||||
gint size, extra, i;
|
||||
gint extra_space, size_given_to_child, i;
|
||||
gint children_minimum_size = 0;
|
||||
gint child_size, child_minimum, child_natural;
|
||||
gint child_minimum_baseline, child_natural_baseline;
|
||||
gint n_extra_widgets = 0;
|
||||
@@ -1704,7 +1710,7 @@ gtk_box_compute_size_for_opposing_orientation (GtkBox *box,
|
||||
|
||||
spacing = get_spacing (box);
|
||||
sizes = g_newa (GtkRequestedSize, nvis_children);
|
||||
size = avail_size - (nvis_children - 1) * spacing;
|
||||
extra_space = avail_size - (nvis_children - 1) * spacing;
|
||||
|
||||
/* Retrieve desired size for visible children */
|
||||
for (i = 0, children = private->children; children; children = children->next)
|
||||
@@ -1733,7 +1739,7 @@ gtk_box_compute_size_for_opposing_orientation (GtkBox *box,
|
||||
sizes[i].natural_size,
|
||||
sizes[i].minimum_size);
|
||||
|
||||
size -= sizes[i].minimum_size;
|
||||
children_minimum_size += sizes[i].minimum_size;
|
||||
|
||||
sizes[i].data = child;
|
||||
|
||||
@@ -1743,28 +1749,32 @@ gtk_box_compute_size_for_opposing_orientation (GtkBox *box,
|
||||
|
||||
if (private->homogeneous)
|
||||
{
|
||||
/* If were homogenous we still need to run the above loop to get the
|
||||
* minimum sizes for children that are not going to fill
|
||||
/* We still need to run the above loop to populate the minimum sizes for
|
||||
* children that aren't going to fill.
|
||||
*/
|
||||
size = avail_size - (nvis_children - 1) * spacing;
|
||||
extra = size / nvis_children;
|
||||
n_extra_widgets = size % nvis_children;
|
||||
|
||||
size_given_to_child = extra_space / nvis_children;
|
||||
n_extra_widgets = extra_space % nvis_children;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Bring children up to size first */
|
||||
size = gtk_distribute_natural_allocation (MAX (0, size), nvis_children, sizes);
|
||||
extra_space -= children_minimum_size;
|
||||
extra_space = MAX (0, extra_space);
|
||||
extra_space = gtk_distribute_natural_allocation (extra_space, nvis_children, sizes);
|
||||
|
||||
/* Calculate space which hasn't distributed yet,
|
||||
* and is available for expanding children.
|
||||
*/
|
||||
if (nexpand_children > 0)
|
||||
{
|
||||
extra = size / nexpand_children;
|
||||
n_extra_widgets = size % nexpand_children;
|
||||
size_given_to_child = extra_space / nexpand_children;
|
||||
n_extra_widgets = extra_space % nexpand_children;
|
||||
}
|
||||
else
|
||||
extra = 0;
|
||||
{
|
||||
size_given_to_child = 0;
|
||||
}
|
||||
}
|
||||
|
||||
have_baseline = FALSE;
|
||||
@@ -1795,7 +1805,7 @@ gtk_box_compute_size_for_opposing_orientation (GtkBox *box,
|
||||
/* Assign the child's size. */
|
||||
if (private->homogeneous)
|
||||
{
|
||||
child_size = extra;
|
||||
child_size = size_given_to_child;
|
||||
|
||||
if (n_extra_widgets > 0)
|
||||
{
|
||||
@@ -1809,7 +1819,7 @@ gtk_box_compute_size_for_opposing_orientation (GtkBox *box,
|
||||
|
||||
if (child->expand || gtk_widget_compute_expand (child->widget, private->orientation))
|
||||
{
|
||||
child_size += extra;
|
||||
child_size += size_given_to_child;
|
||||
|
||||
if (n_extra_widgets > 0)
|
||||
{
|
||||
@@ -1820,13 +1830,9 @@ gtk_box_compute_size_for_opposing_orientation (GtkBox *box,
|
||||
}
|
||||
|
||||
if (child->fill)
|
||||
{
|
||||
child_size = MAX (1, child_size);
|
||||
}
|
||||
child_size = MAX (1, child_size);
|
||||
else
|
||||
{
|
||||
child_size = sizes[i].minimum_size;
|
||||
}
|
||||
child_size = sizes[i].minimum_size;
|
||||
|
||||
|
||||
child_minimum_baseline = child_natural_baseline = -1;
|
||||
|
||||
+108
-115
@@ -79,7 +79,9 @@
|
||||
#include "gtkmarshalers.h"
|
||||
#include "gtktooltip.h"
|
||||
#include "gtkprivate.h"
|
||||
#include "gtkrender.h"
|
||||
#include "gtkrendericonprivate.h"
|
||||
#include "gtksnapshot.h"
|
||||
#include "gtkstylecontextprivate.h"
|
||||
|
||||
#define TIMEOUT_INITIAL 500
|
||||
#define TIMEOUT_REPEAT 50
|
||||
@@ -270,8 +272,8 @@ static void gtk_calendar_measure (GtkWidget *widget,
|
||||
int *natural_baseline);
|
||||
static void gtk_calendar_size_allocate (GtkWidget *widget,
|
||||
GtkAllocation *allocation);
|
||||
static gboolean gtk_calendar_draw (GtkWidget *widget,
|
||||
cairo_t *cr);
|
||||
static void gtk_calendar_snapshot (GtkWidget *widget,
|
||||
GtkSnapshot *snapshot);
|
||||
static gboolean gtk_calendar_button_press (GtkWidget *widget,
|
||||
GdkEventButton *event);
|
||||
static gboolean gtk_calendar_button_release (GtkWidget *widget,
|
||||
@@ -365,7 +367,7 @@ gtk_calendar_class_init (GtkCalendarClass *class)
|
||||
widget_class->unrealize = gtk_calendar_unrealize;
|
||||
widget_class->map = gtk_calendar_map;
|
||||
widget_class->unmap = gtk_calendar_unmap;
|
||||
widget_class->draw = gtk_calendar_draw;
|
||||
widget_class->snapshot = gtk_calendar_snapshot;
|
||||
widget_class->measure = gtk_calendar_measure;
|
||||
widget_class->size_allocate = gtk_calendar_size_allocate;
|
||||
widget_class->button_press_event = gtk_calendar_button_press;
|
||||
@@ -2132,7 +2134,8 @@ gtk_calendar_size_allocate (GtkWidget *widget,
|
||||
****************************************/
|
||||
|
||||
static void
|
||||
calendar_paint_header (GtkCalendar *calendar, cairo_t *cr)
|
||||
calendar_snapshot_header (GtkCalendar *calendar,
|
||||
GtkSnapshot *snapshot)
|
||||
{
|
||||
GtkWidget *widget = GTK_WIDGET (calendar);
|
||||
GtkCalendarPrivate *priv = calendar->priv;
|
||||
@@ -2155,8 +2158,7 @@ calendar_paint_header (GtkCalendar *calendar, cairo_t *cr)
|
||||
get_component_paddings (calendar, &padding, NULL, NULL, NULL);
|
||||
context = gtk_widget_get_style_context (widget);
|
||||
|
||||
cairo_save (cr);
|
||||
cairo_translate (cr, padding.left, padding.top);
|
||||
gtk_snapshot_translate_2d (snapshot, padding.left, padding.top);
|
||||
|
||||
if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
|
||||
year_left = priv->year_before;
|
||||
@@ -2178,8 +2180,8 @@ calendar_paint_header (GtkCalendar *calendar, cairo_t *cr)
|
||||
gtk_style_context_set_state (context, state);
|
||||
gtk_style_context_add_class (context, GTK_STYLE_CLASS_HEADER);
|
||||
|
||||
gtk_render_background (context, cr, 0, 0, header_width, priv->header_h);
|
||||
gtk_render_frame (context, cr, 0, 0, header_width, priv->header_h);
|
||||
gtk_snapshot_render_background (snapshot, context, 0, 0, header_width, priv->header_h);
|
||||
gtk_snapshot_render_frame (snapshot, context, 0, 0, header_width, priv->header_h);
|
||||
|
||||
tmp_time = 1; /* Jan 1 1970, 00:00:01 UTC */
|
||||
tm = gmtime (&tmp_time);
|
||||
@@ -2220,7 +2222,7 @@ calendar_paint_header (GtkCalendar *calendar, cairo_t *cr)
|
||||
x = header_width - (3 + priv->arrow_width + max_year_width
|
||||
- (max_year_width - logical_rect.width)/2);
|
||||
|
||||
gtk_render_layout (context, cr, x, y, layout);
|
||||
gtk_snapshot_render_layout (snapshot, context, x, y, layout);
|
||||
|
||||
/* Draw month */
|
||||
g_snprintf (buffer, sizeof (buffer), "%s", default_monthname[priv->month]);
|
||||
@@ -2240,16 +2242,16 @@ calendar_paint_header (GtkCalendar *calendar, cairo_t *cr)
|
||||
else
|
||||
x = 3 + priv->arrow_width + (max_month_width - logical_rect.width)/2;
|
||||
|
||||
gtk_render_layout (context, cr, x, y, layout);
|
||||
gtk_snapshot_render_layout (snapshot, context, x, y, layout);
|
||||
g_object_unref (layout);
|
||||
|
||||
gtk_style_context_restore (context);
|
||||
cairo_restore (cr);
|
||||
gtk_snapshot_translate_2d (snapshot, -padding.left, -padding.top);
|
||||
}
|
||||
|
||||
static void
|
||||
calendar_paint_day_names (GtkCalendar *calendar,
|
||||
cairo_t *cr)
|
||||
calendar_snapshot_day_names (GtkCalendar *calendar,
|
||||
GtkSnapshot *snapshot)
|
||||
{
|
||||
GtkWidget *widget = GTK_WIDGET (calendar);
|
||||
GtkCalendarPrivate *priv = calendar->priv;
|
||||
@@ -2270,11 +2272,9 @@ calendar_paint_day_names (GtkCalendar *calendar,
|
||||
get_component_paddings (calendar, &padding, NULL, &day_name_padding, NULL);
|
||||
context = gtk_widget_get_style_context (widget);
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
cairo_translate (cr,
|
||||
padding.left + inner_border,
|
||||
priv->header_h + padding.top + inner_border);
|
||||
gtk_snapshot_translate_2d (snapshot,
|
||||
padding.left + inner_border,
|
||||
priv->header_h + padding.top + inner_border);
|
||||
|
||||
gtk_widget_get_allocation (widget, &allocation);
|
||||
|
||||
@@ -2294,17 +2294,17 @@ calendar_paint_day_names (GtkCalendar *calendar,
|
||||
gtk_style_context_set_state (context, state);
|
||||
gtk_style_context_add_class (context, GTK_STYLE_CLASS_HIGHLIGHT);
|
||||
|
||||
gtk_render_background (context, cr,
|
||||
CALENDAR_MARGIN, CALENDAR_MARGIN,
|
||||
cal_width - CALENDAR_MARGIN * 2,
|
||||
priv->day_name_h - CALENDAR_MARGIN);
|
||||
gtk_snapshot_render_background (snapshot, context,
|
||||
CALENDAR_MARGIN, CALENDAR_MARGIN,
|
||||
cal_width - CALENDAR_MARGIN * 2,
|
||||
priv->day_name_h - CALENDAR_MARGIN);
|
||||
|
||||
if (priv->display_flags & GTK_CALENDAR_SHOW_WEEK_NUMBERS)
|
||||
gtk_render_background (context, cr,
|
||||
CALENDAR_MARGIN,
|
||||
priv->day_name_h - calendar_ysep,
|
||||
priv->week_width - calendar_ysep - CALENDAR_MARGIN,
|
||||
calendar_ysep);
|
||||
gtk_snapshot_render_background (snapshot, context,
|
||||
CALENDAR_MARGIN,
|
||||
priv->day_name_h - calendar_ysep,
|
||||
priv->week_width - calendar_ysep - CALENDAR_MARGIN,
|
||||
calendar_ysep);
|
||||
|
||||
/*
|
||||
* Write the labels
|
||||
@@ -2323,26 +2323,28 @@ calendar_paint_day_names (GtkCalendar *calendar,
|
||||
pango_layout_set_text (layout, buffer, -1);
|
||||
pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
|
||||
|
||||
gtk_render_layout (context, cr,
|
||||
(CALENDAR_MARGIN +
|
||||
+ (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR ?
|
||||
(priv->week_width + (priv->week_width ? calendar_xsep : 0))
|
||||
: 0)
|
||||
+ day_wid_sep * i
|
||||
+ (day_width - logical_rect.width)/2),
|
||||
CALENDAR_MARGIN + day_name_padding.top + logical_rect.y,
|
||||
layout);
|
||||
gtk_snapshot_render_layout (snapshot, context,
|
||||
(CALENDAR_MARGIN +
|
||||
+ (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR ?
|
||||
(priv->week_width + (priv->week_width ? calendar_xsep : 0))
|
||||
: 0)
|
||||
+ day_wid_sep * i
|
||||
+ (day_width - logical_rect.width)/2),
|
||||
CALENDAR_MARGIN + day_name_padding.top + logical_rect.y,
|
||||
layout);
|
||||
}
|
||||
|
||||
g_object_unref (layout);
|
||||
|
||||
gtk_style_context_restore (context);
|
||||
cairo_restore (cr);
|
||||
gtk_snapshot_translate_2d (snapshot,
|
||||
- (padding.left + inner_border),
|
||||
- (priv->header_h + padding.top + inner_border));
|
||||
}
|
||||
|
||||
static void
|
||||
calendar_paint_week_numbers (GtkCalendar *calendar,
|
||||
cairo_t *cr)
|
||||
calendar_snapshot_week_numbers (GtkCalendar *calendar,
|
||||
GtkSnapshot *snapshot)
|
||||
{
|
||||
GtkWidget *widget = GTK_WIDGET (calendar);
|
||||
GtkCalendarPrivate *priv = calendar->priv;
|
||||
@@ -2361,8 +2363,6 @@ calendar_paint_week_numbers (GtkCalendar *calendar,
|
||||
get_component_paddings (calendar, &padding, NULL, NULL, &week_padding);
|
||||
context = gtk_widget_get_style_context (widget);
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
y = priv->header_h + priv->day_name_h + (padding.top + inner_border);
|
||||
if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
|
||||
x = padding.left + inner_border;
|
||||
@@ -2378,16 +2378,16 @@ calendar_paint_week_numbers (GtkCalendar *calendar,
|
||||
gtk_style_context_add_class (context, GTK_STYLE_CLASS_HIGHLIGHT);
|
||||
|
||||
if (priv->display_flags & GTK_CALENDAR_SHOW_DAY_NAMES)
|
||||
gtk_render_background (context, cr,
|
||||
x + CALENDAR_MARGIN, y,
|
||||
priv->week_width - CALENDAR_MARGIN,
|
||||
priv->main_h - CALENDAR_MARGIN);
|
||||
gtk_snapshot_render_background (snapshot, context,
|
||||
x + CALENDAR_MARGIN, y,
|
||||
priv->week_width - CALENDAR_MARGIN,
|
||||
priv->main_h - CALENDAR_MARGIN);
|
||||
else
|
||||
gtk_render_background (context, cr,
|
||||
x + CALENDAR_MARGIN,
|
||||
y + CALENDAR_MARGIN,
|
||||
priv->week_width - CALENDAR_MARGIN,
|
||||
priv->main_h - 2 * CALENDAR_MARGIN);
|
||||
gtk_snapshot_render_background (snapshot, context,
|
||||
x + CALENDAR_MARGIN,
|
||||
y + CALENDAR_MARGIN,
|
||||
priv->week_width - CALENDAR_MARGIN,
|
||||
priv->main_h - 2 * CALENDAR_MARGIN);
|
||||
|
||||
/*
|
||||
* Write the labels
|
||||
@@ -2438,13 +2438,12 @@ calendar_paint_week_numbers (GtkCalendar *calendar,
|
||||
- logical_rect.width
|
||||
- calendar_xsep - week_padding.right);
|
||||
|
||||
gtk_render_layout (context, cr, x_loc, y_loc, layout);
|
||||
gtk_snapshot_render_layout (snapshot, context, x_loc, y_loc, layout);
|
||||
}
|
||||
|
||||
g_object_unref (layout);
|
||||
|
||||
gtk_style_context_restore (context);
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2496,10 +2495,10 @@ is_color_attribute (PangoAttribute *attribute,
|
||||
}
|
||||
|
||||
static void
|
||||
calendar_paint_day (GtkCalendar *calendar,
|
||||
cairo_t *cr,
|
||||
gint row,
|
||||
gint col)
|
||||
calendar_snapshot_day (GtkCalendar *calendar,
|
||||
GtkSnapshot *snapshot,
|
||||
gint row,
|
||||
gint col)
|
||||
{
|
||||
GtkWidget *widget = GTK_WIDGET (calendar);
|
||||
GtkCalendarPrivate *priv = calendar->priv;
|
||||
@@ -2544,9 +2543,9 @@ calendar_paint_day (GtkCalendar *calendar,
|
||||
state |= GTK_STATE_FLAG_SELECTED;
|
||||
|
||||
gtk_style_context_set_state (context, state);
|
||||
gtk_render_background (context, cr,
|
||||
day_rect.x, day_rect.y,
|
||||
day_rect.width, day_rect.height);
|
||||
gtk_snapshot_render_background (snapshot, context,
|
||||
day_rect.x, day_rect.y,
|
||||
day_rect.width, day_rect.height);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2575,11 +2574,11 @@ calendar_paint_day (GtkCalendar *calendar,
|
||||
x_loc = day_rect.x + (day_rect.width - logical_rect.width) / 2;
|
||||
y_loc = day_rect.y;
|
||||
|
||||
gtk_render_layout (context, cr, x_loc, y_loc, layout);
|
||||
gtk_snapshot_render_layout (snapshot, context, x_loc, y_loc, layout);
|
||||
|
||||
if (priv->day_month[row][col] == MONTH_CURRENT &&
|
||||
(priv->marked_date[day-1] || (detail && !show_details)))
|
||||
gtk_render_layout (context, cr, x_loc - 1, y_loc, layout);
|
||||
gtk_snapshot_render_layout (snapshot, context, x_loc - 1, y_loc, layout);
|
||||
|
||||
y_loc += priv->max_day_char_descent;
|
||||
|
||||
@@ -2587,17 +2586,15 @@ calendar_paint_day (GtkCalendar *calendar,
|
||||
{
|
||||
GdkRGBA color;
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
gtk_style_context_get_color (context, &color);
|
||||
gdk_cairo_set_source_rgba (cr, &color);
|
||||
|
||||
cairo_set_line_width (cr, 1);
|
||||
cairo_move_to (cr, day_rect.x + 2, y_loc + 0.5);
|
||||
cairo_line_to (cr, day_rect.x + day_rect.width - 2, y_loc + 0.5);
|
||||
cairo_stroke (cr);
|
||||
|
||||
cairo_restore (cr);
|
||||
gtk_snapshot_append_color_node (snapshot,
|
||||
&color,
|
||||
&GRAPHENE_RECT_INIT (
|
||||
day_rect.x + 2, y_loc,
|
||||
day_rect.width - 2, 1
|
||||
),
|
||||
"CalendarDetailSeparator");
|
||||
|
||||
y_loc += 2;
|
||||
}
|
||||
@@ -2631,15 +2628,14 @@ calendar_paint_day (GtkCalendar *calendar,
|
||||
pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END);
|
||||
}
|
||||
|
||||
cairo_move_to (cr, day_rect.x, y_loc);
|
||||
pango_cairo_show_layout (cr, layout);
|
||||
gtk_snapshot_render_layout (snapshot, context, day_rect.x, y_loc, layout);
|
||||
}
|
||||
|
||||
if (gtk_widget_has_visible_focus (widget) &&
|
||||
priv->focus_row == row && priv->focus_col == col)
|
||||
gtk_render_focus (context, cr,
|
||||
day_rect.x, day_rect.y,
|
||||
day_rect.width, day_rect.height);
|
||||
gtk_snapshot_render_focus (snapshot, context,
|
||||
day_rect.x, day_rect.y,
|
||||
day_rect.width, day_rect.height);
|
||||
|
||||
if (overflow)
|
||||
priv->detail_overflow[row] |= (1 << col);
|
||||
@@ -2652,18 +2648,14 @@ calendar_paint_day (GtkCalendar *calendar,
|
||||
}
|
||||
|
||||
static void
|
||||
calendar_paint_main (GtkCalendar *calendar,
|
||||
cairo_t *cr)
|
||||
calendar_snapshot_main (GtkCalendar *calendar,
|
||||
GtkSnapshot *snapshot)
|
||||
{
|
||||
gint row, col;
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
for (col = 0; col < 7; col++)
|
||||
for (row = 0; row < 6; row++)
|
||||
calendar_paint_day (calendar, cr, row, col);
|
||||
|
||||
cairo_restore (cr);
|
||||
calendar_snapshot_day (calendar, snapshot, row, col);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2688,24 +2680,22 @@ calendar_invalidate_arrow (GtkCalendar *calendar,
|
||||
}
|
||||
|
||||
static void
|
||||
calendar_paint_arrow (GtkCalendar *calendar,
|
||||
cairo_t *cr,
|
||||
guint arrow)
|
||||
calendar_snapshot_arrow (GtkCalendar *calendar,
|
||||
GtkSnapshot *snapshot,
|
||||
guint arrow)
|
||||
{
|
||||
GtkWidget *widget = GTK_WIDGET (calendar);
|
||||
GtkCalendarPrivate *priv = calendar->priv;
|
||||
GtkCssImageBuiltinType image_type;
|
||||
GtkStyleContext *context;
|
||||
GtkStateFlags state;
|
||||
GdkRectangle rect;
|
||||
gdouble angle;
|
||||
|
||||
if (!priv->arrow_win[arrow])
|
||||
return;
|
||||
|
||||
calendar_arrow_rectangle (calendar, arrow, &rect);
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
context = gtk_widget_get_style_context (widget);
|
||||
state = gtk_widget_get_state_flags (widget);
|
||||
|
||||
@@ -2718,27 +2708,32 @@ calendar_paint_arrow (GtkCalendar *calendar,
|
||||
gtk_style_context_set_state (context, state);
|
||||
gtk_style_context_add_class (context, GTK_STYLE_CLASS_BUTTON);
|
||||
|
||||
gtk_render_background (context, cr,
|
||||
rect.x, rect.y,
|
||||
rect.width, rect.height);
|
||||
gtk_snapshot_render_background (snapshot, context,
|
||||
rect.x, rect.y,
|
||||
rect.width, rect.height);
|
||||
|
||||
if (arrow == ARROW_MONTH_LEFT || arrow == ARROW_YEAR_LEFT)
|
||||
angle = 3 * (G_PI / 2);
|
||||
image_type = GTK_CSS_IMAGE_BUILTIN_ARROW_LEFT;
|
||||
else
|
||||
angle = G_PI / 2;
|
||||
image_type = GTK_CSS_IMAGE_BUILTIN_ARROW_RIGHT;
|
||||
|
||||
gtk_render_arrow (context, cr, angle,
|
||||
rect.x + (rect.width - 8) / 2,
|
||||
rect.y + (rect.height - 8) / 2,
|
||||
8);
|
||||
gtk_snapshot_translate_2d (snapshot,
|
||||
rect.x + (rect.width - 8) / 2,
|
||||
rect.y + (rect.height - 8) / 2);
|
||||
gtk_css_style_snapshot_icon (gtk_style_context_lookup_style (context),
|
||||
snapshot,
|
||||
8, 8,
|
||||
image_type);
|
||||
gtk_snapshot_translate_2d (snapshot,
|
||||
- rect.x - (rect.width - 8) / 2,
|
||||
- rect.y - (rect.height - 8) / 2);
|
||||
|
||||
gtk_style_context_restore (context);
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_calendar_draw (GtkWidget *widget,
|
||||
cairo_t *cr)
|
||||
static void
|
||||
gtk_calendar_snapshot (GtkWidget *widget,
|
||||
GtkSnapshot *snapshot)
|
||||
{
|
||||
GtkCalendar *calendar = GTK_CALENDAR (widget);
|
||||
GtkCalendarPrivate *priv = calendar->priv;
|
||||
@@ -2750,31 +2745,29 @@ gtk_calendar_draw (GtkWidget *widget,
|
||||
gtk_style_context_save (context);
|
||||
gtk_style_context_add_class (context, GTK_STYLE_CLASS_VIEW);
|
||||
|
||||
gtk_render_background (context, cr, 0, 0,
|
||||
gtk_widget_get_allocated_width (widget),
|
||||
gtk_widget_get_allocated_height (widget));
|
||||
gtk_render_frame (context, cr, 0, 0,
|
||||
gtk_widget_get_allocated_width (widget),
|
||||
gtk_widget_get_allocated_height (widget));
|
||||
gtk_snapshot_render_background (snapshot, context, 0, 0,
|
||||
gtk_widget_get_allocated_width (widget),
|
||||
gtk_widget_get_allocated_height (widget));
|
||||
gtk_snapshot_render_frame (snapshot, context, 0, 0,
|
||||
gtk_widget_get_allocated_width (widget),
|
||||
gtk_widget_get_allocated_height (widget));
|
||||
|
||||
gtk_style_context_restore (context);
|
||||
|
||||
calendar_paint_main (calendar, cr);
|
||||
calendar_snapshot_main (calendar, snapshot);
|
||||
|
||||
if (priv->display_flags & GTK_CALENDAR_SHOW_HEADING)
|
||||
{
|
||||
calendar_paint_header (calendar, cr);
|
||||
calendar_snapshot_header (calendar, snapshot);
|
||||
for (i = 0; i < 4; i++)
|
||||
calendar_paint_arrow (calendar, cr, i);
|
||||
calendar_snapshot_arrow (calendar, snapshot, i);
|
||||
}
|
||||
|
||||
if (priv->display_flags & GTK_CALENDAR_SHOW_DAY_NAMES)
|
||||
calendar_paint_day_names (calendar, cr);
|
||||
calendar_snapshot_day_names (calendar, snapshot);
|
||||
|
||||
if (priv->display_flags & GTK_CALENDAR_SHOW_WEEK_NUMBERS)
|
||||
calendar_paint_week_numbers (calendar, cr);
|
||||
|
||||
return FALSE;
|
||||
calendar_snapshot_week_numbers (calendar, snapshot);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+31
-84
@@ -390,10 +390,10 @@ static gint gtk_cell_area_real_event (GtkCellArea
|
||||
GdkEvent *event,
|
||||
const GdkRectangle *cell_area,
|
||||
GtkCellRendererState flags);
|
||||
static void gtk_cell_area_real_render (GtkCellArea *area,
|
||||
static void gtk_cell_area_real_snapshot (GtkCellArea *area,
|
||||
GtkCellAreaContext *context,
|
||||
GtkWidget *widget,
|
||||
cairo_t *cr,
|
||||
GtkSnapshot *snapshot,
|
||||
const GdkRectangle *background_area,
|
||||
const GdkRectangle *cell_area,
|
||||
GtkCellRendererState flags,
|
||||
@@ -487,7 +487,7 @@ typedef struct {
|
||||
typedef struct {
|
||||
GtkCellArea *area;
|
||||
GtkWidget *widget;
|
||||
cairo_t *cr;
|
||||
GtkSnapshot *snapshot;
|
||||
GdkRectangle focus_rect;
|
||||
GtkCellRendererState render_flags;
|
||||
guint paint_focus : 1;
|
||||
@@ -653,7 +653,7 @@ gtk_cell_area_class_init (GtkCellAreaClass *class)
|
||||
class->foreach = gtk_cell_area_real_foreach;
|
||||
class->foreach_alloc = gtk_cell_area_real_foreach_alloc;
|
||||
class->event = gtk_cell_area_real_event;
|
||||
class->render = gtk_cell_area_real_render;
|
||||
class->snapshot = gtk_cell_area_real_snapshot;
|
||||
class->apply_attributes = gtk_cell_area_real_apply_attributes;
|
||||
|
||||
/* geometry */
|
||||
@@ -1110,10 +1110,10 @@ gtk_cell_area_real_event (GtkCellArea *area,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
render_cell (GtkCellRenderer *renderer,
|
||||
const GdkRectangle *cell_area,
|
||||
const GdkRectangle *cell_background,
|
||||
CellRenderData *data)
|
||||
snapshot_cell (GtkCellRenderer *renderer,
|
||||
const GdkRectangle *cell_area,
|
||||
const GdkRectangle *cell_background,
|
||||
CellRenderData *data)
|
||||
{
|
||||
GtkCellRenderer *focus_cell;
|
||||
GtkCellRendererState flags;
|
||||
@@ -1145,27 +1145,27 @@ render_cell (GtkCellRenderer *renderer,
|
||||
}
|
||||
}
|
||||
|
||||
gtk_cell_renderer_render (renderer, data->cr, data->widget,
|
||||
cell_background, &inner_area, flags);
|
||||
gtk_cell_renderer_snapshot (renderer, data->snapshot, data->widget,
|
||||
cell_background, &inner_area, flags);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_cell_area_real_render (GtkCellArea *area,
|
||||
GtkCellAreaContext *context,
|
||||
GtkWidget *widget,
|
||||
cairo_t *cr,
|
||||
const GdkRectangle *background_area,
|
||||
const GdkRectangle *cell_area,
|
||||
GtkCellRendererState flags,
|
||||
gboolean paint_focus)
|
||||
gtk_cell_area_real_snapshot (GtkCellArea *area,
|
||||
GtkCellAreaContext *context,
|
||||
GtkWidget *widget,
|
||||
GtkSnapshot *snapshot,
|
||||
const GdkRectangle *background_area,
|
||||
const GdkRectangle *cell_area,
|
||||
GtkCellRendererState flags,
|
||||
gboolean paint_focus)
|
||||
{
|
||||
CellRenderData render_data =
|
||||
{
|
||||
area,
|
||||
widget,
|
||||
cr,
|
||||
snapshot,
|
||||
{ 0, },
|
||||
flags,
|
||||
paint_focus,
|
||||
@@ -1188,7 +1188,7 @@ gtk_cell_area_real_render (GtkCellArea *area,
|
||||
render_data.focus_all = TRUE;
|
||||
|
||||
gtk_cell_area_foreach_alloc (area, context, widget, cell_area, background_area,
|
||||
(GtkCellAllocCallback)render_cell, &render_data);
|
||||
(GtkCellAllocCallback) snapshot_cell, &render_data);
|
||||
|
||||
if (render_data.paint_focus &&
|
||||
render_data.focus_rect.width != 0 &&
|
||||
@@ -1203,17 +1203,11 @@ gtk_cell_area_real_render (GtkCellArea *area,
|
||||
renderer_state = gtk_cell_renderer_get_state (NULL, widget, flags);
|
||||
gtk_style_context_set_state (style_context, renderer_state);
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
gdk_cairo_rectangle (cr, background_area);
|
||||
cairo_clip (cr);
|
||||
|
||||
gtk_render_focus (style_context, cr,
|
||||
render_data.focus_rect.x, render_data.focus_rect.y,
|
||||
render_data.focus_rect.width, render_data.focus_rect.height);
|
||||
gtk_snapshot_render_focus (snapshot, style_context,
|
||||
render_data.focus_rect.x, render_data.focus_rect.y,
|
||||
render_data.focus_rect.width, render_data.focus_rect.height);
|
||||
|
||||
gtk_style_context_restore (style_context);
|
||||
cairo_restore (cr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1804,50 +1798,6 @@ gtk_cell_area_event (GtkCellArea *area,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_cell_area_render:
|
||||
* @area: a #GtkCellArea
|
||||
* @context: the #GtkCellAreaContext for this row of data.
|
||||
* @widget: the #GtkWidget that @area is rendering to
|
||||
* @cr: the #cairo_t to render with
|
||||
* @background_area: the @widget relative coordinates for @area’s background
|
||||
* @cell_area: the @widget relative coordinates for @area
|
||||
* @flags: the #GtkCellRendererState for @area in this row.
|
||||
* @paint_focus: whether @area should paint focus on focused cells for focused rows or not.
|
||||
*
|
||||
* Renders @area’s cells according to @area’s layout onto @widget at
|
||||
* the given coordinates.
|
||||
*
|
||||
* Since: 3.0
|
||||
*/
|
||||
void
|
||||
gtk_cell_area_render (GtkCellArea *area,
|
||||
GtkCellAreaContext *context,
|
||||
GtkWidget *widget,
|
||||
cairo_t *cr,
|
||||
const GdkRectangle *background_area,
|
||||
const GdkRectangle *cell_area,
|
||||
GtkCellRendererState flags,
|
||||
gboolean paint_focus)
|
||||
{
|
||||
GtkCellAreaClass *class;
|
||||
|
||||
g_return_if_fail (GTK_IS_CELL_AREA (area));
|
||||
g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
|
||||
g_return_if_fail (GTK_IS_WIDGET (widget));
|
||||
g_return_if_fail (cr != NULL);
|
||||
g_return_if_fail (background_area != NULL);
|
||||
g_return_if_fail (cell_area != NULL);
|
||||
|
||||
class = GTK_CELL_AREA_GET_CLASS (area);
|
||||
|
||||
if (class->render)
|
||||
class->render (area, context, widget, cr, background_area, cell_area, flags, paint_focus);
|
||||
else
|
||||
g_warning ("GtkCellAreaClass::render not implemented for '%s'",
|
||||
g_type_name (G_TYPE_FROM_INSTANCE (area)));
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_cell_area_snapshot:
|
||||
* @area: a #GtkCellArea
|
||||
@@ -1874,7 +1824,7 @@ gtk_cell_area_snapshot (GtkCellArea *area,
|
||||
GtkCellRendererState flags,
|
||||
gboolean paint_focus)
|
||||
{
|
||||
cairo_t *cr;
|
||||
GtkCellAreaClass *class;
|
||||
|
||||
g_return_if_fail (GTK_IS_CELL_AREA (area));
|
||||
g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
|
||||
@@ -1883,16 +1833,13 @@ gtk_cell_area_snapshot (GtkCellArea *area,
|
||||
g_return_if_fail (background_area != NULL);
|
||||
g_return_if_fail (cell_area != NULL);
|
||||
|
||||
cr = gtk_snapshot_append_cairo_node (snapshot,
|
||||
&GRAPHENE_RECT_INIT (
|
||||
background_area->x,
|
||||
background_area->y,
|
||||
background_area->width,
|
||||
background_area->height
|
||||
),
|
||||
"CellArea<%s>", G_OBJECT_TYPE_NAME (area));
|
||||
gtk_cell_area_render (area, context, widget, cr, background_area, cell_area, flags, paint_focus);
|
||||
cairo_destroy (cr);
|
||||
class = GTK_CELL_AREA_GET_CLASS (area);
|
||||
|
||||
if (class->snapshot)
|
||||
class->snapshot (area, context, widget, snapshot, background_area, cell_area, flags, paint_focus);
|
||||
else
|
||||
g_warning ("GtkCellAreaClass::snapshot not implemented for '%s'",
|
||||
g_type_name (G_TYPE_FROM_INSTANCE (area)));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
||||
+3
-12
@@ -112,7 +112,7 @@ struct _GtkCellArea
|
||||
* @event: Handle an event in the area, this is generally used to activate
|
||||
* a cell at the event location for button events but can also be used
|
||||
* to generically pass events to #GtkWidgets drawn onto the area.
|
||||
* @render: Actually render the area’s cells to the specified rectangle,
|
||||
* @snapshot: Actually snapshot the area’s cells to the specified rectangle,
|
||||
* @background_area should be correctly distributed to the cells
|
||||
* corresponding background areas.
|
||||
* @apply_attributes: Apply the cell attributes to the cells. This is
|
||||
@@ -198,10 +198,10 @@ struct _GtkCellAreaClass
|
||||
GdkEvent *event,
|
||||
const GdkRectangle *cell_area,
|
||||
GtkCellRendererState flags);
|
||||
void (* render) (GtkCellArea *area,
|
||||
void (* snapshot) (GtkCellArea *area,
|
||||
GtkCellAreaContext *context,
|
||||
GtkWidget *widget,
|
||||
cairo_t *cr,
|
||||
GtkSnapshot *snapshot,
|
||||
const GdkRectangle *background_area,
|
||||
const GdkRectangle *cell_area,
|
||||
GtkCellRendererState flags,
|
||||
@@ -308,15 +308,6 @@ gint gtk_cell_area_event (GtkCellArea
|
||||
GdkEvent *event,
|
||||
const GdkRectangle *cell_area,
|
||||
GtkCellRendererState flags);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_cell_area_render (GtkCellArea *area,
|
||||
GtkCellAreaContext *context,
|
||||
GtkWidget *widget,
|
||||
cairo_t *cr,
|
||||
const GdkRectangle *background_area,
|
||||
const GdkRectangle *cell_area,
|
||||
GtkCellRendererState flags,
|
||||
gboolean paint_focus);
|
||||
GDK_AVAILABLE_IN_3_90
|
||||
void gtk_cell_area_snapshot (GtkCellArea *area,
|
||||
GtkCellAreaContext *context,
|
||||
|
||||
+35
-27
@@ -43,7 +43,7 @@
|
||||
* CellRenderer keep any permanent state around. Instead, any state is set
|
||||
* just prior to use using #GObjects property system. Then, the
|
||||
* cell is measured using gtk_cell_renderer_get_size(). Finally, the cell
|
||||
* is rendered in the correct location using gtk_cell_renderer_render().
|
||||
* is rendered in the correct location using gtk_cell_renderer_snapshot().
|
||||
*
|
||||
* There are a number of rules that must be followed when writing a new
|
||||
* #GtkCellRenderer. First and foremost, it’s important that a certain set
|
||||
@@ -202,7 +202,7 @@ gtk_cell_renderer_class_init (GtkCellRendererClass *class)
|
||||
object_class->get_property = gtk_cell_renderer_get_property;
|
||||
object_class->set_property = gtk_cell_renderer_set_property;
|
||||
|
||||
class->render = NULL;
|
||||
class->snapshot = NULL;
|
||||
class->get_size = NULL;
|
||||
class->get_request_mode = gtk_cell_renderer_real_get_request_mode;
|
||||
class->get_preferred_width = gtk_cell_renderer_real_get_preferred_width;
|
||||
@@ -680,7 +680,7 @@ set_cell_bg_color (GtkCellRenderer *cell,
|
||||
*
|
||||
* Obtains the width and height needed to render the cell. Used by view
|
||||
* widgets to determine the appropriate size for the cell_area passed to
|
||||
* gtk_cell_renderer_render(). If @cell_area is not %NULL, fills in the
|
||||
* gtk_cell_renderer_snapshot(). If @cell_area is not %NULL, fills in the
|
||||
* x and y offsets (if set) of the cell relative to this location.
|
||||
*
|
||||
* Please note that the values set in @width and @height, as well as those
|
||||
@@ -716,9 +716,9 @@ gtk_cell_renderer_get_size (GtkCellRenderer *cell,
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_cell_renderer_render:
|
||||
* gtk_cell_renderer_snapshot:
|
||||
* @cell: a #GtkCellRenderer
|
||||
* @cr: a cairo context to draw to
|
||||
* @snapshot: a #GtkSnapshot to draw to
|
||||
* @widget: the widget owning @window
|
||||
* @background_area: entire cell area (including tree expanders and maybe
|
||||
* padding on the sides)
|
||||
@@ -732,14 +732,16 @@ gtk_cell_renderer_get_size (GtkCellRenderer *cell,
|
||||
* blank space around the cell, and also the area containing the tree expander;
|
||||
* so the @background_area rectangles for all cells tile to cover the entire
|
||||
* @window.
|
||||
*
|
||||
* Since: 3.90
|
||||
**/
|
||||
void
|
||||
gtk_cell_renderer_render (GtkCellRenderer *cell,
|
||||
cairo_t *cr,
|
||||
GtkWidget *widget,
|
||||
const GdkRectangle *background_area,
|
||||
const GdkRectangle *cell_area,
|
||||
GtkCellRendererState flags)
|
||||
gtk_cell_renderer_snapshot (GtkCellRenderer *cell,
|
||||
GtkSnapshot *snapshot,
|
||||
GtkWidget *widget,
|
||||
const GdkRectangle *background_area,
|
||||
const GdkRectangle *cell_area,
|
||||
GtkCellRendererState flags)
|
||||
{
|
||||
gboolean selected = FALSE;
|
||||
GtkCellRendererPrivate *priv = cell->priv;
|
||||
@@ -747,22 +749,28 @@ gtk_cell_renderer_render (GtkCellRenderer *cell,
|
||||
GtkStateFlags state;
|
||||
|
||||
g_return_if_fail (GTK_IS_CELL_RENDERER (cell));
|
||||
g_return_if_fail (GTK_CELL_RENDERER_GET_CLASS (cell)->render != NULL);
|
||||
g_return_if_fail (cr != NULL);
|
||||
g_return_if_fail (GTK_CELL_RENDERER_GET_CLASS (cell)->snapshot != NULL);
|
||||
g_return_if_fail (snapshot != NULL);
|
||||
|
||||
selected = (flags & GTK_CELL_RENDERER_SELECTED) == GTK_CELL_RENDERER_SELECTED;
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
if (priv->cell_background_set && !selected)
|
||||
{
|
||||
gdk_cairo_rectangle (cr, background_area);
|
||||
gdk_cairo_set_source_rgba (cr, &priv->cell_background);
|
||||
cairo_fill (cr);
|
||||
gtk_snapshot_append_color_node (snapshot,
|
||||
&priv->cell_background,
|
||||
&GRAPHENE_RECT_INIT (
|
||||
background_area->x, background_area->y,
|
||||
background_area->width, background_area->height
|
||||
),
|
||||
"CellBackground");
|
||||
}
|
||||
|
||||
gdk_cairo_rectangle (cr, background_area);
|
||||
cairo_clip (cr);
|
||||
gtk_snapshot_push_clip (snapshot,
|
||||
&GRAPHENE_RECT_INIT (
|
||||
background_area->x, background_area->y,
|
||||
background_area->width, background_area->height
|
||||
),
|
||||
"CellClip");
|
||||
|
||||
context = gtk_widget_get_style_context (widget);
|
||||
|
||||
@@ -772,14 +780,14 @@ gtk_cell_renderer_render (GtkCellRenderer *cell,
|
||||
state = gtk_cell_renderer_get_state (cell, widget, flags);
|
||||
gtk_style_context_set_state (context, state);
|
||||
|
||||
GTK_CELL_RENDERER_GET_CLASS (cell)->render (cell,
|
||||
cr,
|
||||
widget,
|
||||
background_area,
|
||||
cell_area,
|
||||
flags);
|
||||
GTK_CELL_RENDERER_GET_CLASS (cell)->snapshot (cell,
|
||||
snapshot,
|
||||
widget,
|
||||
background_area,
|
||||
cell_area,
|
||||
flags);
|
||||
gtk_style_context_restore (context);
|
||||
cairo_restore (cr);
|
||||
gtk_snapshot_pop_and_append (snapshot);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -100,7 +100,7 @@ struct _GtkCellRenderer
|
||||
* @get_preferred_width_for_height: Called to get a renderer’s natural width for height.
|
||||
* @get_aligned_area: Called to get the aligned area used by @cell inside @cell_area.
|
||||
* @get_size: Called to get the width and height needed to render the cell. Deprecated: 3.0.
|
||||
* @render: Called to render the content of the #GtkCellRenderer.
|
||||
* @snapshot: Called to snapshot the content of the #GtkCellRenderer.
|
||||
* @activate: Called to activate the content of the #GtkCellRenderer.
|
||||
* @start_editing: Called to initiate editing the content of the #GtkCellRenderer.
|
||||
* @editing_canceled: Signal gets emitted when the user cancels the process of editing a cell.
|
||||
@@ -145,8 +145,8 @@ struct _GtkCellRendererClass
|
||||
gint *y_offset,
|
||||
gint *width,
|
||||
gint *height);
|
||||
void (* render) (GtkCellRenderer *cell,
|
||||
cairo_t *cr,
|
||||
void (* snapshot) (GtkCellRenderer *cell,
|
||||
GtkSnapshot *snapshot,
|
||||
GtkWidget *widget,
|
||||
const GdkRectangle *background_area,
|
||||
const GdkRectangle *cell_area,
|
||||
@@ -229,9 +229,9 @@ void gtk_cell_renderer_get_size (GtkCellRenderer *cell,
|
||||
gint *y_offset,
|
||||
gint *width,
|
||||
gint *height);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_cell_renderer_render (GtkCellRenderer *cell,
|
||||
cairo_t *cr,
|
||||
GDK_AVAILABLE_IN_3_90
|
||||
void gtk_cell_renderer_snapshot (GtkCellRenderer *cell,
|
||||
GtkSnapshot *snapshot,
|
||||
GtkWidget *widget,
|
||||
const GdkRectangle *background_area,
|
||||
const GdkRectangle *cell_area,
|
||||
|
||||
+13
-12
@@ -62,8 +62,8 @@ static void gtk_cell_renderer_pixbuf_get_size (GtkCellRenderer *cel
|
||||
gint *y_offset,
|
||||
gint *width,
|
||||
gint *height);
|
||||
static void gtk_cell_renderer_pixbuf_render (GtkCellRenderer *cell,
|
||||
cairo_t *cr,
|
||||
static void gtk_cell_renderer_pixbuf_snapshot (GtkCellRenderer *cell,
|
||||
GtkSnapshot *snapshot,
|
||||
GtkWidget *widget,
|
||||
const GdkRectangle *background_area,
|
||||
const GdkRectangle *cell_area,
|
||||
@@ -138,7 +138,7 @@ gtk_cell_renderer_pixbuf_class_init (GtkCellRendererPixbufClass *class)
|
||||
object_class->set_property = gtk_cell_renderer_pixbuf_set_property;
|
||||
|
||||
cell_class->get_size = gtk_cell_renderer_pixbuf_get_size;
|
||||
cell_class->render = gtk_cell_renderer_pixbuf_render;
|
||||
cell_class->snapshot = gtk_cell_renderer_pixbuf_snapshot;
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_PIXBUF,
|
||||
@@ -482,12 +482,12 @@ gtk_cell_renderer_pixbuf_get_size (GtkCellRenderer *cell,
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_cell_renderer_pixbuf_render (GtkCellRenderer *cell,
|
||||
cairo_t *cr,
|
||||
GtkWidget *widget,
|
||||
const GdkRectangle *background_area,
|
||||
const GdkRectangle *cell_area,
|
||||
GtkCellRendererState flags)
|
||||
gtk_cell_renderer_pixbuf_snapshot (GtkCellRenderer *cell,
|
||||
GtkSnapshot *snapshot,
|
||||
GtkWidget *widget,
|
||||
const GdkRectangle *background_area,
|
||||
const GdkRectangle *cell_area,
|
||||
GtkCellRendererState flags)
|
||||
|
||||
{
|
||||
GtkCellRendererPixbuf *cellpixbuf = (GtkCellRendererPixbuf *) cell;
|
||||
@@ -541,9 +541,10 @@ gtk_cell_renderer_pixbuf_render (GtkCellRenderer *cell,
|
||||
if (icon_helper == NULL)
|
||||
icon_helper = create_icon_helper (cellpixbuf, widget);
|
||||
|
||||
_gtk_icon_helper_draw (icon_helper,
|
||||
cr,
|
||||
pix_rect.x, pix_rect.y);
|
||||
gtk_snapshot_translate_2d (snapshot, pix_rect.x, pix_rect.y);
|
||||
gtk_icon_helper_snapshot (icon_helper, snapshot);
|
||||
gtk_snapshot_translate_2d (snapshot, - pix_rect.x, - pix_rect.y);
|
||||
|
||||
g_object_unref (icon_helper);
|
||||
|
||||
gtk_style_context_restore (context);
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
#include "gtkintl.h"
|
||||
#include "gtkorientable.h"
|
||||
#include "gtkprivate.h"
|
||||
#include "gtkrender.h"
|
||||
#include "gtksnapshot.h"
|
||||
|
||||
|
||||
/**
|
||||
@@ -99,8 +99,8 @@ static void gtk_cell_renderer_progress_get_size (GtkCellRenderer *ce
|
||||
gint *y_offset,
|
||||
gint *width,
|
||||
gint *height);
|
||||
static void gtk_cell_renderer_progress_render (GtkCellRenderer *cell,
|
||||
cairo_t *cr,
|
||||
static void gtk_cell_renderer_progress_snapshot (GtkCellRenderer *cell,
|
||||
GtkSnapshot *snapshot,
|
||||
GtkWidget *widget,
|
||||
const GdkRectangle *background_area,
|
||||
const GdkRectangle *cell_area,
|
||||
@@ -122,7 +122,7 @@ gtk_cell_renderer_progress_class_init (GtkCellRendererProgressClass *klass)
|
||||
object_class->set_property = gtk_cell_renderer_progress_set_property;
|
||||
|
||||
cell_class->get_size = gtk_cell_renderer_progress_get_size;
|
||||
cell_class->render = gtk_cell_renderer_progress_render;
|
||||
cell_class->snapshot = gtk_cell_renderer_progress_snapshot;
|
||||
|
||||
/**
|
||||
* GtkCellRendererProgress:value:
|
||||
@@ -544,12 +544,12 @@ get_bar_position (gint start,
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_cell_renderer_progress_render (GtkCellRenderer *cell,
|
||||
cairo_t *cr,
|
||||
GtkWidget *widget,
|
||||
const GdkRectangle *background_area,
|
||||
const GdkRectangle *cell_area,
|
||||
GtkCellRendererState flags)
|
||||
gtk_cell_renderer_progress_snapshot (GtkCellRenderer *cell,
|
||||
GtkSnapshot *snapshot,
|
||||
GtkWidget *widget,
|
||||
const GdkRectangle *background_area,
|
||||
const GdkRectangle *cell_area,
|
||||
GtkCellRendererState flags)
|
||||
{
|
||||
GtkCellRendererProgress *cellprogress = GTK_CELL_RENDERER_PROGRESS (cell);
|
||||
GtkCellRendererProgressPrivate *priv= cellprogress->priv;
|
||||
@@ -574,8 +574,8 @@ gtk_cell_renderer_progress_render (GtkCellRenderer *cell,
|
||||
gtk_style_context_save (context);
|
||||
gtk_style_context_add_class (context, GTK_STYLE_CLASS_TROUGH);
|
||||
|
||||
gtk_render_background (context, cr, x, y, w, h);
|
||||
gtk_render_frame (context, cr, x, y, w, h);
|
||||
gtk_snapshot_render_background (snapshot, context, x, y, w, h);
|
||||
gtk_snapshot_render_frame (snapshot, context, x, y, w, h);
|
||||
|
||||
gtk_style_context_get_padding (context, &padding);
|
||||
|
||||
@@ -632,8 +632,8 @@ gtk_cell_renderer_progress_render (GtkCellRenderer *cell,
|
||||
gtk_style_context_save (context);
|
||||
gtk_style_context_add_class (context, GTK_STYLE_CLASS_PROGRESSBAR);
|
||||
|
||||
gtk_render_background (context, cr, clip.x, clip.y, clip.width, clip.height);
|
||||
gtk_render_frame (context, cr, clip.x, clip.y, clip.width, clip.height);
|
||||
gtk_snapshot_render_background (snapshot, context, clip.x, clip.y, clip.width, clip.height);
|
||||
gtk_snapshot_render_frame (snapshot, context, clip.x, clip.y, clip.width, clip.height);
|
||||
|
||||
gtk_style_context_restore (context);
|
||||
}
|
||||
@@ -656,19 +656,22 @@ gtk_cell_renderer_progress_render (GtkCellRenderer *cell,
|
||||
y_pos = y + padding.top + priv->text_yalign *
|
||||
(h - padding.top - padding.bottom - logical_rect.height);
|
||||
|
||||
cairo_save (cr);
|
||||
gdk_cairo_rectangle (cr, &clip);
|
||||
cairo_clip (cr);
|
||||
gtk_snapshot_push_clip (snapshot,
|
||||
&GRAPHENE_RECT_INIT(
|
||||
clip.x, clip.y,
|
||||
clip.width, clip.height
|
||||
),
|
||||
"CellProgressClip");
|
||||
|
||||
gtk_style_context_save (context);
|
||||
gtk_style_context_add_class (context, GTK_STYLE_CLASS_PROGRESSBAR);
|
||||
|
||||
gtk_render_layout (context, cr,
|
||||
x_pos, y_pos,
|
||||
layout);
|
||||
gtk_snapshot_render_layout (snapshot, context,
|
||||
x_pos, y_pos,
|
||||
layout);
|
||||
|
||||
gtk_style_context_restore (context);
|
||||
cairo_restore (cr);
|
||||
gtk_snapshot_pop_and_append (snapshot);
|
||||
|
||||
gtk_style_context_save (context);
|
||||
gtk_style_context_add_class (context, GTK_STYLE_CLASS_TROUGH);
|
||||
@@ -686,15 +689,18 @@ gtk_cell_renderer_progress_render (GtkCellRenderer *cell,
|
||||
clip.height = bar_position - y;
|
||||
}
|
||||
|
||||
cairo_save (cr);
|
||||
gdk_cairo_rectangle (cr, &clip);
|
||||
cairo_clip (cr);
|
||||
gtk_snapshot_push_clip (snapshot,
|
||||
&GRAPHENE_RECT_INIT(
|
||||
clip.x, clip.y,
|
||||
clip.width, clip.height
|
||||
),
|
||||
"CellTroughClip");
|
||||
|
||||
gtk_render_layout (context, cr,
|
||||
x_pos, y_pos,
|
||||
layout);
|
||||
gtk_snapshot_render_layout (snapshot, context,
|
||||
x_pos, y_pos,
|
||||
layout);
|
||||
|
||||
cairo_restore (cr);
|
||||
gtk_snapshot_pop_and_append (snapshot);
|
||||
}
|
||||
|
||||
if (bar_position + bar_size < start + full_size)
|
||||
@@ -710,15 +716,18 @@ gtk_cell_renderer_progress_render (GtkCellRenderer *cell,
|
||||
clip.height = y + h - (bar_position + bar_size);
|
||||
}
|
||||
|
||||
cairo_save (cr);
|
||||
gdk_cairo_rectangle (cr, &clip);
|
||||
cairo_clip (cr);
|
||||
gtk_snapshot_push_clip (snapshot,
|
||||
&GRAPHENE_RECT_INIT(
|
||||
clip.x, clip.y,
|
||||
clip.width, clip.height
|
||||
),
|
||||
"CellTroughClip");
|
||||
|
||||
gtk_render_layout (context, cr,
|
||||
x_pos, y_pos,
|
||||
layout);
|
||||
gtk_snapshot_render_layout (snapshot, context,
|
||||
x_pos, y_pos,
|
||||
layout);
|
||||
|
||||
cairo_restore (cr);
|
||||
gtk_snapshot_pop_and_append (snapshot);
|
||||
}
|
||||
|
||||
gtk_style_context_restore (context);
|
||||
|
||||
@@ -31,15 +31,11 @@
|
||||
#include "gtkicontheme.h"
|
||||
#include "gtkintl.h"
|
||||
#include "gtksettings.h"
|
||||
#include "gtksnapshot.h"
|
||||
#include "gtktypebuiltins.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#undef GDK_DEPRECATED
|
||||
#undef GDK_DEPRECATED_FOR
|
||||
#define GDK_DEPRECATED
|
||||
#define GDK_DEPRECATED_FOR(f)
|
||||
|
||||
/**
|
||||
* SECTION:gtkcellrendererspinner
|
||||
* @Short_description: Renders a spinning animation in a cell
|
||||
@@ -90,8 +86,8 @@ static void gtk_cell_renderer_spinner_get_size (GtkCellRenderer *cell,
|
||||
gint *y_offset,
|
||||
gint *width,
|
||||
gint *height);
|
||||
static void gtk_cell_renderer_spinner_render (GtkCellRenderer *cell,
|
||||
cairo_t *cr,
|
||||
static void gtk_cell_renderer_spinner_snapshot (GtkCellRenderer *cell,
|
||||
GtkSnapshot *snapshot,
|
||||
GtkWidget *widget,
|
||||
const GdkRectangle *background_area,
|
||||
const GdkRectangle *cell_area,
|
||||
@@ -109,7 +105,7 @@ gtk_cell_renderer_spinner_class_init (GtkCellRendererSpinnerClass *klass)
|
||||
object_class->set_property = gtk_cell_renderer_spinner_set_property;
|
||||
|
||||
cell_class->get_size = gtk_cell_renderer_spinner_get_size;
|
||||
cell_class->render = gtk_cell_renderer_spinner_render;
|
||||
cell_class->snapshot = gtk_cell_renderer_spinner_snapshot;
|
||||
|
||||
/* GtkCellRendererSpinner:active:
|
||||
*
|
||||
@@ -388,18 +384,19 @@ gtk_paint_spinner (GtkStyleContext *context,
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_cell_renderer_spinner_render (GtkCellRenderer *cellr,
|
||||
cairo_t *cr,
|
||||
GtkWidget *widget,
|
||||
const GdkRectangle *background_area,
|
||||
const GdkRectangle *cell_area,
|
||||
GtkCellRendererState flags)
|
||||
gtk_cell_renderer_spinner_snapshot (GtkCellRenderer *cellr,
|
||||
GtkSnapshot *snapshot,
|
||||
GtkWidget *widget,
|
||||
const GdkRectangle *background_area,
|
||||
const GdkRectangle *cell_area,
|
||||
GtkCellRendererState flags)
|
||||
{
|
||||
GtkCellRendererSpinner *cell = GTK_CELL_RENDERER_SPINNER (cellr);
|
||||
GtkCellRendererSpinnerPrivate *priv = cell->priv;
|
||||
GdkRectangle pix_rect;
|
||||
GdkRectangle draw_rect;
|
||||
gint xpad, ypad;
|
||||
cairo_t *cr;
|
||||
|
||||
if (!priv->active)
|
||||
return;
|
||||
@@ -420,10 +417,12 @@ gtk_cell_renderer_spinner_render (GtkCellRenderer *cellr,
|
||||
if (!gdk_rectangle_intersect (cell_area, &pix_rect, &draw_rect))
|
||||
return;
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
gdk_cairo_rectangle (cr, cell_area);
|
||||
cairo_clip (cr);
|
||||
cr = gtk_snapshot_append_cairo_node (snapshot,
|
||||
&GRAPHENE_RECT_INIT (
|
||||
cell_area->x, cell_area->y,
|
||||
cell_area->width, cell_area->height
|
||||
),
|
||||
"CellSpinner");
|
||||
|
||||
gtk_paint_spinner (gtk_widget_get_style_context (widget),
|
||||
cr,
|
||||
@@ -431,5 +430,5 @@ gtk_cell_renderer_spinner_render (GtkCellRenderer *cellr,
|
||||
draw_rect.x, draw_rect.y,
|
||||
draw_rect.width, draw_rect.height);
|
||||
|
||||
cairo_restore (cr);
|
||||
cairo_destroy (cr);
|
||||
}
|
||||
|
||||
+27
-21
@@ -55,8 +55,8 @@ static void gtk_cell_renderer_text_set_property (GObject *obje
|
||||
guint param_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static void gtk_cell_renderer_text_render (GtkCellRenderer *cell,
|
||||
cairo_t *cr,
|
||||
static void gtk_cell_renderer_text_snapshot (GtkCellRenderer *cell,
|
||||
GtkSnapshot *snapshot,
|
||||
GtkWidget *widget,
|
||||
const GdkRectangle *background_area,
|
||||
const GdkRectangle *cell_area,
|
||||
@@ -241,7 +241,7 @@ gtk_cell_renderer_text_class_init (GtkCellRendererTextClass *class)
|
||||
object_class->get_property = gtk_cell_renderer_text_get_property;
|
||||
object_class->set_property = gtk_cell_renderer_text_set_property;
|
||||
|
||||
cell_class->render = gtk_cell_renderer_text_render;
|
||||
cell_class->snapshot = gtk_cell_renderer_text_snapshot;
|
||||
cell_class->start_editing = gtk_cell_renderer_text_start_editing;
|
||||
cell_class->get_preferred_width = gtk_cell_renderer_text_get_preferred_width;
|
||||
cell_class->get_preferred_height = gtk_cell_renderer_text_get_preferred_height;
|
||||
@@ -1712,12 +1712,12 @@ get_size (GtkCellRenderer *cell,
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_cell_renderer_text_render (GtkCellRenderer *cell,
|
||||
cairo_t *cr,
|
||||
GtkWidget *widget,
|
||||
const GdkRectangle *background_area,
|
||||
const GdkRectangle *cell_area,
|
||||
GtkCellRendererState flags)
|
||||
gtk_cell_renderer_text_snapshot (GtkCellRenderer *cell,
|
||||
GtkSnapshot *snapshot,
|
||||
GtkWidget *widget,
|
||||
const GdkRectangle *background_area,
|
||||
const GdkRectangle *cell_area,
|
||||
GtkCellRendererState flags)
|
||||
|
||||
{
|
||||
GtkCellRendererText *celltext = GTK_CELL_RENDERER_TEXT (cell);
|
||||
@@ -1735,9 +1735,13 @@ gtk_cell_renderer_text_render (GtkCellRenderer *cell,
|
||||
|
||||
if (priv->background_set && (flags & GTK_CELL_RENDERER_SELECTED) == 0)
|
||||
{
|
||||
gdk_cairo_rectangle (cr, background_area);
|
||||
gdk_cairo_set_source_rgba (cr, &priv->background);
|
||||
cairo_fill (cr);
|
||||
gtk_snapshot_append_color_node (snapshot,
|
||||
&priv->background,
|
||||
&GRAPHENE_RECT_INIT(
|
||||
background_area->x, background_area->y,
|
||||
background_area->width, background_area->height
|
||||
),
|
||||
"CellTextBackground");
|
||||
}
|
||||
|
||||
gtk_cell_renderer_get_padding (cell, &xpad, &ypad);
|
||||
@@ -1751,17 +1755,19 @@ gtk_cell_renderer_text_render (GtkCellRenderer *cell,
|
||||
pango_layout_get_pixel_extents (layout, NULL, &rect);
|
||||
x_offset = x_offset - rect.x;
|
||||
|
||||
cairo_save (cr);
|
||||
gtk_snapshot_push_clip (snapshot,
|
||||
&GRAPHENE_RECT_INIT(
|
||||
cell_area->x, cell_area->y,
|
||||
cell_area->width, cell_area->height
|
||||
),
|
||||
"CellTextClip");
|
||||
|
||||
gdk_cairo_rectangle (cr, cell_area);
|
||||
cairo_clip (cr);
|
||||
gtk_snapshot_render_layout (snapshot, context,
|
||||
cell_area->x + x_offset + xpad,
|
||||
cell_area->y + y_offset + ypad,
|
||||
layout);
|
||||
|
||||
gtk_render_layout (context, cr,
|
||||
cell_area->x + x_offset + xpad,
|
||||
cell_area->y + y_offset + ypad,
|
||||
layout);
|
||||
|
||||
cairo_restore (cr);
|
||||
gtk_snapshot_pop_and_append (snapshot);
|
||||
|
||||
g_object_unref (layout);
|
||||
}
|
||||
|
||||
+46
-32
@@ -21,6 +21,7 @@
|
||||
#include "gtkintl.h"
|
||||
#include "gtkmarshalers.h"
|
||||
#include "gtkprivate.h"
|
||||
#include "gtkrendericonprivate.h"
|
||||
#include "gtkstylecontextprivate.h"
|
||||
#include "gtktreeprivate.h"
|
||||
#include "a11y/gtkbooleancellaccessible.h"
|
||||
@@ -53,8 +54,8 @@ static void gtk_cell_renderer_toggle_get_size (GtkCellRenderer *cel
|
||||
gint *y_offset,
|
||||
gint *width,
|
||||
gint *height);
|
||||
static void gtk_cell_renderer_toggle_render (GtkCellRenderer *cell,
|
||||
cairo_t *cr,
|
||||
static void gtk_cell_renderer_toggle_snapshot (GtkCellRenderer *cell,
|
||||
GtkSnapshot *snapshot,
|
||||
GtkWidget *widget,
|
||||
const GdkRectangle *background_area,
|
||||
const GdkRectangle *cell_area,
|
||||
@@ -125,7 +126,7 @@ gtk_cell_renderer_toggle_class_init (GtkCellRendererToggleClass *class)
|
||||
object_class->set_property = gtk_cell_renderer_toggle_set_property;
|
||||
|
||||
cell_class->get_size = gtk_cell_renderer_toggle_get_size;
|
||||
cell_class->render = gtk_cell_renderer_toggle_render;
|
||||
cell_class->snapshot = gtk_cell_renderer_toggle_snapshot;
|
||||
cell_class->activate = gtk_cell_renderer_toggle_activate;
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
@@ -373,12 +374,12 @@ gtk_cell_renderer_toggle_get_size (GtkCellRenderer *cell,
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_cell_renderer_toggle_render (GtkCellRenderer *cell,
|
||||
cairo_t *cr,
|
||||
GtkWidget *widget,
|
||||
const GdkRectangle *background_area,
|
||||
const GdkRectangle *cell_area,
|
||||
GtkCellRendererState flags)
|
||||
gtk_cell_renderer_toggle_snapshot (GtkCellRenderer *cell,
|
||||
GtkSnapshot *snapshot,
|
||||
GtkWidget *widget,
|
||||
const GdkRectangle *background_area,
|
||||
const GdkRectangle *cell_area,
|
||||
GtkCellRendererState flags)
|
||||
{
|
||||
GtkCellRendererToggle *celltoggle = GTK_CELL_RENDERER_TOGGLE (cell);
|
||||
GtkCellRendererTogglePrivate *priv = celltoggle->priv;
|
||||
@@ -388,6 +389,7 @@ gtk_cell_renderer_toggle_render (GtkCellRenderer *cell,
|
||||
gint xpad, ypad;
|
||||
GtkStateFlags state;
|
||||
GtkBorder padding, border;
|
||||
GtkCssImageBuiltinType image_type;
|
||||
|
||||
context = gtk_widget_get_style_context (widget);
|
||||
gtk_cell_renderer_toggle_get_size (cell, widget, cell_area,
|
||||
@@ -413,45 +415,57 @@ gtk_cell_renderer_toggle_render (GtkCellRenderer *cell,
|
||||
if (priv->active)
|
||||
state |= GTK_STATE_FLAG_CHECKED;
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
gdk_cairo_rectangle (cr, cell_area);
|
||||
cairo_clip (cr);
|
||||
gtk_snapshot_push_clip (snapshot,
|
||||
&GRAPHENE_RECT_INIT (
|
||||
cell_area->x, cell_area->y,
|
||||
cell_area->width, cell_area->height
|
||||
),
|
||||
"CellToggleClip");
|
||||
|
||||
context = gtk_cell_renderer_toggle_save_context (cell, widget);
|
||||
gtk_style_context_set_state (context, state);
|
||||
|
||||
gtk_render_background (context, cr,
|
||||
cell_area->x + x_offset + xpad,
|
||||
cell_area->y + y_offset + ypad,
|
||||
width, height);
|
||||
gtk_render_frame (context, cr,
|
||||
cell_area->x + x_offset + xpad,
|
||||
cell_area->y + y_offset + ypad,
|
||||
width, height);
|
||||
gtk_snapshot_render_background (snapshot, context,
|
||||
cell_area->x + x_offset + xpad,
|
||||
cell_area->y + y_offset + ypad,
|
||||
width, height);
|
||||
gtk_snapshot_render_frame (snapshot, context,
|
||||
cell_area->x + x_offset + xpad,
|
||||
cell_area->y + y_offset + ypad,
|
||||
width, height);
|
||||
|
||||
gtk_style_context_get_padding (context, &padding);
|
||||
gtk_style_context_get_border (context, &border);
|
||||
|
||||
if (priv->radio)
|
||||
{
|
||||
gtk_render_option (context, cr,
|
||||
cell_area->x + x_offset + xpad + padding.left + border.left,
|
||||
cell_area->y + y_offset + ypad + padding.top + border.top,
|
||||
width - padding.left - padding.right - border.left - border.right,
|
||||
height - padding.top - padding.bottom - border.top - border.bottom);
|
||||
if (state & GTK_STATE_FLAG_INCONSISTENT)
|
||||
image_type = GTK_CSS_IMAGE_BUILTIN_OPTION_INCONSISTENT;
|
||||
else if (state & GTK_STATE_FLAG_CHECKED)
|
||||
image_type = GTK_CSS_IMAGE_BUILTIN_OPTION;
|
||||
else
|
||||
image_type = GTK_CSS_IMAGE_BUILTIN_NONE;
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_render_check (context, cr,
|
||||
cell_area->x + x_offset + xpad + padding.left + border.left,
|
||||
cell_area->y + y_offset + ypad + padding.top + border.top,
|
||||
width - padding.left - padding.right - border.left - border.right,
|
||||
height - padding.top - padding.bottom - border.top - border.bottom);
|
||||
if (state & GTK_STATE_FLAG_INCONSISTENT)
|
||||
image_type = GTK_CSS_IMAGE_BUILTIN_CHECK_INCONSISTENT;
|
||||
else if (state & GTK_STATE_FLAG_CHECKED)
|
||||
image_type = GTK_CSS_IMAGE_BUILTIN_CHECK;
|
||||
else
|
||||
image_type = GTK_CSS_IMAGE_BUILTIN_NONE;
|
||||
}
|
||||
|
||||
gtk_snapshot_translate_2d (snapshot,
|
||||
cell_area->x + x_offset + xpad + padding.left + border.left,
|
||||
cell_area->y + y_offset + ypad + padding.top + border.top);
|
||||
gtk_css_style_snapshot_icon (gtk_style_context_lookup_style (context), snapshot,
|
||||
width - padding.left - padding.right - border.left - border.right,
|
||||
height - padding.top - padding.bottom - border.top - border.bottom,
|
||||
image_type);
|
||||
|
||||
gtk_style_context_restore (context);
|
||||
cairo_restore (cr);
|
||||
gtk_snapshot_pop_and_append (snapshot);
|
||||
}
|
||||
|
||||
static gint
|
||||
|
||||
+17
-1
@@ -134,7 +134,7 @@ gtk_css_image_linear_snapshot (GtkCssImage *image,
|
||||
double height)
|
||||
{
|
||||
GtkCssImageLinear *linear = GTK_CSS_IMAGE_LINEAR (image);
|
||||
GskColorStop stops[linear->stops->len];
|
||||
GskColorStop *stops;
|
||||
GskRenderNode *node;
|
||||
double off_x, off_y; /* snapshot offset */
|
||||
double angle; /* actual angle of the gradiant line in degrees */
|
||||
@@ -181,8 +181,23 @@ gtk_css_image_linear_snapshot (GtkCssImage *image,
|
||||
length = sqrt (x * x + y * y);
|
||||
gtk_css_image_linear_get_start_end (linear, length, &start, &end);
|
||||
|
||||
if (start == end)
|
||||
{
|
||||
/* repeating gradients with all color stops sharing the same offset
|
||||
* get the color of the last color stop */
|
||||
GtkCssImageLinearColorStop *stop = &g_array_index (linear->stops, GtkCssImageLinearColorStop, linear->stops->len - 1);
|
||||
|
||||
gtk_snapshot_append_color_node (snapshot,
|
||||
_gtk_css_rgba_value_get_rgba (stop->color),
|
||||
&GRAPHENE_RECT_INIT (0, 0, width, height),
|
||||
"RepeatingLinearGradient<degenerate>");
|
||||
return;
|
||||
}
|
||||
|
||||
offset = start;
|
||||
last = -1;
|
||||
stops = g_newa (GskColorStop, linear->stops->len);
|
||||
|
||||
for (i = 0; i < linear->stops->len; i++)
|
||||
{
|
||||
GtkCssImageLinearColorStop *stop;
|
||||
@@ -238,6 +253,7 @@ gtk_css_image_linear_snapshot (GtkCssImage *image,
|
||||
stops,
|
||||
linear->stops->len);
|
||||
}
|
||||
|
||||
name = g_strdup_printf ("%sLinearGradient<%ustops>", linear->repeating ? "Repeating" : "", linear->stops->len);
|
||||
gsk_render_node_set_name (node, name);
|
||||
g_free (name);
|
||||
|
||||
@@ -631,7 +631,6 @@ gtk_css_shadow_value_get_shadow (const GtkCssValue *value,
|
||||
shadow->color = *_gtk_css_rgba_value_get_rgba (value->color);
|
||||
shadow->dx = _gtk_css_number_value_get (value->hoffset, 0);
|
||||
shadow->dy = _gtk_css_number_value_get (value->voffset, 0);
|
||||
shadow->spread = _gtk_css_number_value_get (value->spread, 0);
|
||||
shadow->radius = _gtk_css_number_value_get (value->radius, 0);
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -873,13 +873,13 @@ gtk_icon_helper_snapshot (GtkIconHelper *self,
|
||||
GtkCssStyle *style;
|
||||
GskTexture *texture;
|
||||
|
||||
style = gtk_css_node_get_style (gtk_css_gadget_get_node (GTK_CSS_GADGET (self)));
|
||||
|
||||
gtk_icon_helper_ensure_texture (self);
|
||||
texture = self->priv->texture;
|
||||
if (texture == NULL)
|
||||
return;
|
||||
|
||||
style = gtk_css_node_get_style (gtk_css_gadget_get_node (GTK_CSS_GADGET (self)));
|
||||
|
||||
gtk_css_style_snapshot_icon_texture (style,
|
||||
snapshot,
|
||||
texture,
|
||||
|
||||
+21
-313
@@ -396,62 +396,6 @@ gtk_disable_setlocale (void)
|
||||
#endif
|
||||
|
||||
static GString *gtk_modules_string = NULL;
|
||||
static gboolean g_fatal_warnings = FALSE;
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
static gboolean
|
||||
gtk_arg_debug_cb (const char *key, const char *value, gpointer user_data)
|
||||
{
|
||||
debug_flags[0].flags |= g_parse_debug_string (value,
|
||||
gtk_debug_keys,
|
||||
G_N_ELEMENTS (gtk_debug_keys));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_arg_no_debug_cb (const char *key, const char *value, gpointer user_data)
|
||||
{
|
||||
debug_flags[0].flags &= ~g_parse_debug_string (value,
|
||||
gtk_debug_keys,
|
||||
G_N_ELEMENTS (gtk_debug_keys));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
#endif /* G_ENABLE_DEBUG */
|
||||
|
||||
static gboolean
|
||||
gtk_arg_module_cb (const char *key, const char *value, gpointer user_data)
|
||||
{
|
||||
if (value && *value)
|
||||
{
|
||||
if (gtk_modules_string)
|
||||
g_string_append_c (gtk_modules_string, G_SEARCHPATH_SEPARATOR);
|
||||
else
|
||||
gtk_modules_string = g_string_new (NULL);
|
||||
|
||||
g_string_append (gtk_modules_string, value);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static const GOptionEntry gtk_args[] = {
|
||||
{ "gtk-module", 0, 0, G_OPTION_ARG_CALLBACK, gtk_arg_module_cb,
|
||||
/* Description of --gtk-module=MODULES in --help output */ N_("Load additional GTK+ modules"),
|
||||
/* Placeholder in --gtk-module=MODULES in --help output */ N_("MODULES") },
|
||||
{ "g-fatal-warnings", 0, 0, G_OPTION_ARG_NONE, &g_fatal_warnings,
|
||||
/* Description of --g-fatal-warnings in --help output */ N_("Make all warnings fatal"), NULL },
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
{ "gtk-debug", 0, 0, G_OPTION_ARG_CALLBACK, gtk_arg_debug_cb,
|
||||
/* Description of --gtk-debug=FLAGS in --help output */ N_("GTK+ debugging flags to set"),
|
||||
/* Placeholder in --gtk-debug=FLAGS in --help output */ N_("FLAGS") },
|
||||
{ "gtk-no-debug", 0, 0, G_OPTION_ARG_CALLBACK, gtk_arg_no_debug_cb,
|
||||
/* Description of --gtk-no-debug=FLAGS in --help output */ N_("GTK+ debugging flags to unset"),
|
||||
/* Placeholder in --gtk-no-debug=FLAGS in --help output */ N_("FLAGS") },
|
||||
#endif
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
|
||||
@@ -617,12 +561,11 @@ setlocale_initialization (void)
|
||||
}
|
||||
|
||||
static void
|
||||
do_pre_parse_initialization (int *argc,
|
||||
char ***argv)
|
||||
do_pre_parse_initialization (void)
|
||||
{
|
||||
const gchar *env_string;
|
||||
double slowdown;
|
||||
|
||||
|
||||
if (pre_initialized)
|
||||
return;
|
||||
|
||||
@@ -680,7 +623,7 @@ gettext_initialization (void)
|
||||
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
|
||||
bind_textdomain_codeset (GETTEXT_PACKAGE "-properties", "UTF-8");
|
||||
# endif
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -691,8 +634,7 @@ default_display_notify_cb (GdkDisplayManager *dm)
|
||||
}
|
||||
|
||||
static void
|
||||
do_post_parse_initialization (int *argc,
|
||||
char ***argv)
|
||||
do_post_parse_initialization (void)
|
||||
{
|
||||
GdkDisplayManager *display_manager;
|
||||
|
||||
@@ -705,15 +647,6 @@ do_post_parse_initialization (int *argc,
|
||||
signal (SIGPIPE, SIG_IGN);
|
||||
#endif
|
||||
|
||||
if (g_fatal_warnings)
|
||||
{
|
||||
GLogLevelFlags fatal_mask;
|
||||
|
||||
fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK);
|
||||
fatal_mask |= G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL;
|
||||
g_log_set_always_fatal (fatal_mask);
|
||||
}
|
||||
|
||||
if (debug_flags[0].flags & GTK_DEBUG_UPDATES)
|
||||
gtk_debug_updates_set_enabled (TRUE);
|
||||
|
||||
@@ -727,12 +660,12 @@ do_post_parse_initialization (int *argc,
|
||||
|
||||
if (gtk_modules_string)
|
||||
{
|
||||
_gtk_modules_init (argc, argv, gtk_modules_string->str);
|
||||
_gtk_modules_init (NULL, NULL, gtk_modules_string->str);
|
||||
g_string_free (gtk_modules_string, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
_gtk_modules_init (argc, argv, NULL);
|
||||
_gtk_modules_init (NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
display_manager = gdk_display_manager_get ();
|
||||
@@ -744,52 +677,6 @@ do_post_parse_initialization (int *argc,
|
||||
NULL);
|
||||
}
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gboolean open_default_display;
|
||||
} OptionGroupInfo;
|
||||
|
||||
static gboolean
|
||||
pre_parse_hook (GOptionContext *context,
|
||||
GOptionGroup *group,
|
||||
gpointer data,
|
||||
GError **error)
|
||||
{
|
||||
do_pre_parse_initialization (NULL, NULL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
post_parse_hook (GOptionContext *context,
|
||||
GOptionGroup *group,
|
||||
gpointer data,
|
||||
GError **error)
|
||||
{
|
||||
OptionGroupInfo *info = data;
|
||||
|
||||
|
||||
do_post_parse_initialization (NULL, NULL);
|
||||
|
||||
if (info->open_default_display)
|
||||
{
|
||||
if (gdk_display_open_default () == NULL)
|
||||
{
|
||||
const char *display_name = gdk_get_display_arg_name ();
|
||||
g_set_error (error,
|
||||
G_OPTION_ERROR,
|
||||
G_OPTION_ERROR_FAILED,
|
||||
_("Cannot open display: %s"),
|
||||
display_name ? display_name : "" );
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
guint
|
||||
gtk_get_display_debug_flags (GdkDisplay *display)
|
||||
{
|
||||
@@ -861,179 +748,12 @@ gtk_simulate_touchscreen (void)
|
||||
return test_touchscreen > 0 || (gtk_get_debug_flags () & GTK_DEBUG_TOUCHSCREEN) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_get_option_group:
|
||||
* @open_default_display: whether to open the default display
|
||||
* when parsing the commandline arguments
|
||||
*
|
||||
* Returns a #GOptionGroup for the commandline arguments recognized
|
||||
* by GTK+ and GDK.
|
||||
*
|
||||
* You should add this group to your #GOptionContext
|
||||
* with g_option_context_add_group(), if you are using
|
||||
* g_option_context_parse() to parse your commandline arguments.
|
||||
*
|
||||
* Returns: (transfer full): a #GOptionGroup for the commandline
|
||||
* arguments recognized by GTK+
|
||||
*
|
||||
* Since: 2.6
|
||||
*/
|
||||
GOptionGroup *
|
||||
gtk_get_option_group (gboolean open_default_display)
|
||||
{
|
||||
GOptionGroup *group;
|
||||
OptionGroupInfo *info;
|
||||
|
||||
gettext_initialization ();
|
||||
|
||||
info = g_new0 (OptionGroupInfo, 1);
|
||||
info->open_default_display = open_default_display;
|
||||
|
||||
group = g_option_group_new ("gtk", _("GTK+ Options"), _("Show GTK+ Options"), info, g_free);
|
||||
g_option_group_set_parse_hooks (group, pre_parse_hook, post_parse_hook);
|
||||
|
||||
gdk_add_option_entries (group);
|
||||
g_option_group_add_entries (group, gtk_args);
|
||||
g_option_group_set_translation_domain (group, GETTEXT_PACKAGE);
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_init_with_args:
|
||||
* @argc: (inout): Address of the `argc` parameter of
|
||||
* your main() function (or 0 if @argv is %NULL). This will be changed if
|
||||
* any arguments were handled.
|
||||
* @argv: (array length=argc) (inout) (allow-none): Address of the
|
||||
* `argv` parameter of main(), or %NULL. Any options
|
||||
* understood by GTK+ are stripped before return.
|
||||
* @parameter_string: (allow-none): a string which is displayed in
|
||||
* the first line of `--help` output, after
|
||||
* `programname [OPTION...]`
|
||||
* @entries: (array zero-terminated=1): a %NULL-terminated array
|
||||
* of #GOptionEntrys describing the options of your program
|
||||
* @translation_domain: (nullable): a translation domain to use for translating
|
||||
* the `--help` output for the options in @entries
|
||||
* and the @parameter_string with gettext(), or %NULL
|
||||
* @error: a return location for errors
|
||||
*
|
||||
* This function does the same work as gtk_init_check().
|
||||
* Additionally, it allows you to add your own commandline options,
|
||||
* and it automatically generates nicely formatted
|
||||
* `--help` output. Note that your program will
|
||||
* be terminated after writing out the help output.
|
||||
*
|
||||
* Returns: %TRUE if the windowing system has been successfully
|
||||
* initialized, %FALSE otherwise
|
||||
*
|
||||
* Since: 2.6
|
||||
*/
|
||||
gboolean
|
||||
gtk_init_with_args (gint *argc,
|
||||
gchar ***argv,
|
||||
const gchar *parameter_string,
|
||||
const GOptionEntry *entries,
|
||||
const gchar *translation_domain,
|
||||
GError **error)
|
||||
{
|
||||
GOptionContext *context;
|
||||
GOptionGroup *gtk_group;
|
||||
gboolean retval;
|
||||
|
||||
if (gtk_initialized)
|
||||
goto done;
|
||||
|
||||
gettext_initialization ();
|
||||
|
||||
if (!check_setugid ())
|
||||
return FALSE;
|
||||
|
||||
gtk_group = gtk_get_option_group (FALSE);
|
||||
|
||||
context = g_option_context_new (parameter_string);
|
||||
g_option_context_add_group (context, gtk_group);
|
||||
g_option_context_set_translation_domain (context, translation_domain);
|
||||
|
||||
if (entries)
|
||||
g_option_context_add_main_entries (context, entries, translation_domain);
|
||||
retval = g_option_context_parse (context, argc, argv, error);
|
||||
|
||||
g_option_context_free (context);
|
||||
|
||||
if (!retval)
|
||||
return FALSE;
|
||||
|
||||
done:
|
||||
return gdk_display_open_default () != NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gtk_parse_args:
|
||||
* @argc: (inout): a pointer to the number of command line arguments
|
||||
* @argv: (array length=argc) (inout): a pointer to the array of
|
||||
* command line arguments
|
||||
*
|
||||
* Parses command line arguments, and initializes global
|
||||
* attributes of GTK+, but does not actually open a connection
|
||||
* to a display. (See gdk_display_open(), gdk_get_display_arg_name())
|
||||
*
|
||||
* Any arguments used by GTK+ or GDK are removed from the array and
|
||||
* @argc and @argv are updated accordingly.
|
||||
*
|
||||
* There is no need to call this function explicitly if you are using
|
||||
* gtk_init(), or gtk_init_check().
|
||||
*
|
||||
* Note that many aspects of GTK+ require a display connection to
|
||||
* function, so this way of initializing GTK+ is really only useful
|
||||
* for specialized use cases.
|
||||
*
|
||||
* Returns: %TRUE if initialization succeeded, otherwise %FALSE
|
||||
*/
|
||||
gboolean
|
||||
gtk_parse_args (int *argc,
|
||||
char ***argv)
|
||||
{
|
||||
GOptionContext *option_context;
|
||||
GOptionGroup *gtk_group;
|
||||
GError *error = NULL;
|
||||
|
||||
if (gtk_initialized)
|
||||
return TRUE;
|
||||
|
||||
gettext_initialization ();
|
||||
|
||||
if (!check_setugid ())
|
||||
return FALSE;
|
||||
|
||||
option_context = g_option_context_new (NULL);
|
||||
g_option_context_set_ignore_unknown_options (option_context, TRUE);
|
||||
g_option_context_set_help_enabled (option_context, FALSE);
|
||||
gtk_group = gtk_get_option_group (FALSE);
|
||||
g_option_context_set_main_group (option_context, gtk_group);
|
||||
if (!g_option_context_parse (option_context, argc, argv, &error))
|
||||
{
|
||||
g_warning ("%s", error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
g_option_context_free (option_context);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#ifdef G_PLATFORM_WIN32
|
||||
#undef gtk_init_check
|
||||
#endif
|
||||
|
||||
/**
|
||||
* gtk_init_check:
|
||||
* @argc: (inout): Address of the `argc` parameter of
|
||||
* your main() function (or 0 if @argv is %NULL). This will be changed if
|
||||
* any arguments were handled.
|
||||
* @argv: (array length=argc) (inout) (allow-none): Address of the
|
||||
* `argv` parameter of main(), or %NULL. Any options
|
||||
* understood by GTK+ are stripped before return.
|
||||
*
|
||||
* This function does the same work as gtk_init() with only a single
|
||||
* change: It does not terminate the program if the windowing system
|
||||
@@ -1047,14 +767,21 @@ gtk_parse_args (int *argc,
|
||||
* initialized, %FALSE otherwise
|
||||
*/
|
||||
gboolean
|
||||
gtk_init_check (int *argc,
|
||||
char ***argv)
|
||||
gtk_init_check (void)
|
||||
{
|
||||
gboolean ret;
|
||||
|
||||
if (!gtk_parse_args (argc, argv))
|
||||
if (gtk_initialized)
|
||||
return TRUE;
|
||||
|
||||
gettext_initialization ();
|
||||
|
||||
if (!check_setugid ())
|
||||
return FALSE;
|
||||
|
||||
do_pre_parse_initialization ();
|
||||
do_post_parse_initialization ();
|
||||
|
||||
ret = gdk_display_open_default () != NULL;
|
||||
|
||||
if (gtk_get_debug_flags () & GTK_DEBUG_INTERACTIVE)
|
||||
@@ -1069,32 +796,13 @@ gtk_init_check (int *argc,
|
||||
|
||||
/**
|
||||
* gtk_init:
|
||||
* @argc: (inout): Address of the `argc` parameter of
|
||||
* your main() function (or 0 if @argv is %NULL). This will be changed if
|
||||
* any arguments were handled.
|
||||
* @argv: (array length=argc) (inout) (allow-none): Address of the
|
||||
* `argv` parameter of main(), or %NULL. Any options
|
||||
* understood by GTK+ are stripped before return.
|
||||
*
|
||||
* Call this function before using any other GTK+ functions in your GUI
|
||||
* applications. It will initialize everything needed to operate the
|
||||
* toolkit and parses some standard command line options.
|
||||
*
|
||||
* Although you are expected to pass the @argc, @argv parameters from main() to
|
||||
* this function, it is possible to pass %NULL if @argv is not available or
|
||||
* commandline handling is not required.
|
||||
*
|
||||
* @argc and @argv are adjusted accordingly so your own code will
|
||||
* never see those standard arguments.
|
||||
*
|
||||
* Note that there are some alternative ways to initialize GTK+:
|
||||
* if you are calling gtk_parse_args(), gtk_init_check(),
|
||||
* gtk_init_with_args() or g_option_context_parse() with
|
||||
* the option group returned by gtk_get_option_group(),
|
||||
* you don’t have to call gtk_init().
|
||||
*
|
||||
* And if you are using #GtkApplication, you don't have to call any of the
|
||||
* initialization functions either; the #GtkApplication::startup handler
|
||||
* If you are using #GtkApplication, you don't have to call gtk_init()
|
||||
* or gtk_init_check(); the #GtkApplication::startup handler
|
||||
* does it for you.
|
||||
*
|
||||
* This function will terminate your program if it was unable to
|
||||
@@ -1110,13 +818,13 @@ gtk_init_check (int *argc,
|
||||
* similar things.
|
||||
*/
|
||||
void
|
||||
gtk_init (int *argc, char ***argv)
|
||||
gtk_init (void)
|
||||
{
|
||||
if (!gtk_init_check (argc, argv))
|
||||
if (!gtk_init_check ())
|
||||
{
|
||||
const char *display_name_arg = gdk_get_display_arg_name ();
|
||||
if (display_name_arg == NULL)
|
||||
display_name_arg = getenv("DISPLAY");
|
||||
display_name_arg = getenv ("DISPLAY");
|
||||
g_warning ("cannot open display: %s", display_name_arg ? display_name_arg : "");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
+2
-19
@@ -73,27 +73,10 @@ const gchar* gtk_check_version (guint required_major,
|
||||
*/
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_parse_args (int *argc,
|
||||
char ***argv);
|
||||
void gtk_init (void);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_init (int *argc,
|
||||
char ***argv);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_init_check (int *argc,
|
||||
char ***argv);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_init_with_args (gint *argc,
|
||||
gchar ***argv,
|
||||
const gchar *parameter_string,
|
||||
const GOptionEntry *entries,
|
||||
const gchar *translation_domain,
|
||||
GError **error);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GOptionGroup *gtk_get_option_group (gboolean open_default_display);
|
||||
gboolean gtk_init_check (void);
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
|
||||
|
||||
+1
-1
@@ -96,7 +96,7 @@ gtk_test_init (int *argcp,
|
||||
*/
|
||||
gdk_disable_multidevice ();
|
||||
|
||||
gtk_init (argcp, argvp);
|
||||
gtk_init ();
|
||||
}
|
||||
|
||||
static GSList*
|
||||
|
||||
@@ -126,8 +126,8 @@ gboolean _gtk_tree_view_column_is_blank_at_pos (GtkTreeViewColumn *co
|
||||
gint x,
|
||||
gint y);
|
||||
|
||||
void _gtk_tree_view_column_cell_render (GtkTreeViewColumn *tree_column,
|
||||
cairo_t *cr,
|
||||
void gtk_tree_view_column_cell_snapshot (GtkTreeViewColumn *tree_column,
|
||||
GtkSnapshot *snapshot,
|
||||
const GdkRectangle *background_area,
|
||||
const GdkRectangle *cell_area,
|
||||
guint flags,
|
||||
|
||||
+254
-191
@@ -50,9 +50,11 @@
|
||||
#include "gtkstylecontextprivate.h"
|
||||
#include "gtkcssstylepropertyprivate.h"
|
||||
#include "gtkcssrgbavalueprivate.h"
|
||||
#include "gtkrendericonprivate.h"
|
||||
#include "gtktypebuiltins.h"
|
||||
#include "gtkmain.h"
|
||||
#include "gtksettingsprivate.h"
|
||||
#include "gtksnapshotprivate.h"
|
||||
#include "gtkwidgetpath.h"
|
||||
#include "a11y/gtktreeviewaccessibleprivate.h"
|
||||
|
||||
@@ -596,8 +598,8 @@ static void gtk_tree_view_measure (GtkWidget *widget,
|
||||
int *natural_baseline);
|
||||
static void gtk_tree_view_size_allocate (GtkWidget *widget,
|
||||
GtkAllocation *allocation);
|
||||
static gboolean gtk_tree_view_draw (GtkWidget *widget,
|
||||
cairo_t *cr);
|
||||
static void gtk_tree_view_snapshot (GtkWidget *widget,
|
||||
GtkSnapshot *snapshot);
|
||||
static gboolean gtk_tree_view_key_press (GtkWidget *widget,
|
||||
GdkEventKey *event);
|
||||
static gboolean gtk_tree_view_key_release (GtkWidget *widget,
|
||||
@@ -733,8 +735,8 @@ static void gtk_tree_view_queue_draw_path (GtkTreeView
|
||||
static void gtk_tree_view_queue_draw_arrow (GtkTreeView *tree_view,
|
||||
GtkRBTree *tree,
|
||||
GtkRBNode *node);
|
||||
static void gtk_tree_view_draw_arrow (GtkTreeView *tree_view,
|
||||
cairo_t *cr,
|
||||
static void gtk_tree_view_snapshot_arrow (GtkTreeView *tree_view,
|
||||
GtkSnapshot *snapshot,
|
||||
GtkRBTree *tree,
|
||||
GtkRBNode *node);
|
||||
static void gtk_tree_view_get_arrow_xrange (GtkTreeView *tree_view,
|
||||
@@ -978,7 +980,7 @@ gtk_tree_view_class_init (GtkTreeViewClass *class)
|
||||
widget_class->measure = gtk_tree_view_measure;
|
||||
widget_class->size_allocate = gtk_tree_view_size_allocate;
|
||||
widget_class->motion_notify_event = gtk_tree_view_motion;
|
||||
widget_class->draw = gtk_tree_view_draw;
|
||||
widget_class->snapshot = gtk_tree_view_snapshot;
|
||||
widget_class->key_press_event = gtk_tree_view_key_press;
|
||||
widget_class->key_release_event = gtk_tree_view_key_release;
|
||||
widget_class->enter_notify_event = gtk_tree_view_enter_notify;
|
||||
@@ -4485,8 +4487,8 @@ gtk_tree_view_update_rubber_band (GtkTreeView *tree_view)
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tree_view_paint_rubber_band (GtkTreeView *tree_view,
|
||||
cairo_t *cr)
|
||||
gtk_tree_view_snapshot_rubber_band (GtkTreeView *tree_view,
|
||||
GtkSnapshot *snapshot)
|
||||
{
|
||||
gdouble start_x, start_y, offset_x, offset_y;
|
||||
GdkRectangle rect;
|
||||
@@ -4505,8 +4507,6 @@ gtk_tree_view_paint_rubber_band (GtkTreeView *tree_view,
|
||||
bin_x = MAX (0, bin_x + offset_x);
|
||||
bin_y = MAX (0, bin_y + offset_y + tree_view->priv->dy);
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
context = gtk_widget_get_style_context (GTK_WIDGET (tree_view));
|
||||
|
||||
gtk_style_context_save_to_node (context, tree_view->priv->rubber_band_cssnode);
|
||||
@@ -4516,18 +4516,14 @@ gtk_tree_view_paint_rubber_band (GtkTreeView *tree_view,
|
||||
rect.width = ABS (tree_view->priv->press_start_x - bin_x) + 1;
|
||||
rect.height = ABS (tree_view->priv->press_start_y - bin_y) + 1;
|
||||
|
||||
gdk_cairo_rectangle (cr, &rect);
|
||||
cairo_clip (cr);
|
||||
|
||||
gtk_render_background (context, cr,
|
||||
rect.x, rect.y,
|
||||
rect.width, rect.height);
|
||||
gtk_render_frame (context, cr,
|
||||
rect.x, rect.y,
|
||||
rect.width, rect.height);
|
||||
gtk_snapshot_render_background (snapshot, context,
|
||||
rect.x, rect.y,
|
||||
rect.width, rect.height);
|
||||
gtk_snapshot_render_frame (snapshot, context,
|
||||
rect.x, rect.y,
|
||||
rect.width, rect.height);
|
||||
|
||||
gtk_style_context_restore (context);
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -4647,22 +4643,21 @@ invalidate_empty_focus (GtkTreeView *tree_view)
|
||||
* used when the tree is empty.
|
||||
*/
|
||||
static void
|
||||
draw_empty (GtkTreeView *tree_view,
|
||||
cairo_t *cr)
|
||||
snapshot_empty (GtkTreeView *tree_view,
|
||||
GtkSnapshot *snapshot)
|
||||
{
|
||||
GtkWidget *widget = GTK_WIDGET (tree_view);
|
||||
GtkStyleContext *context;
|
||||
gint width, height;
|
||||
|
||||
context = gtk_widget_get_style_context (widget);
|
||||
|
||||
width = gdk_window_get_width (tree_view->priv->bin_window);
|
||||
height = gdk_window_get_height (tree_view->priv->bin_window);
|
||||
|
||||
gtk_render_background (context, cr, 0, 0, width, height);
|
||||
|
||||
if (gtk_widget_has_visible_focus (widget))
|
||||
gtk_render_focus (context, cr, 0, 0, width, height);
|
||||
{
|
||||
gtk_snapshot_render_focus (snapshot, context,
|
||||
0, 0,
|
||||
gdk_window_get_width (tree_view->priv->bin_window),
|
||||
gdk_window_get_height (tree_view->priv->bin_window));
|
||||
}
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
@@ -4672,17 +4667,25 @@ typedef enum {
|
||||
} GtkTreeViewLineType;
|
||||
|
||||
static void
|
||||
gtk_tree_view_draw_line (GtkTreeView *tree_view,
|
||||
cairo_t *cr,
|
||||
GtkTreeViewLineType type,
|
||||
int x1,
|
||||
int y1,
|
||||
int x2,
|
||||
int y2)
|
||||
gtk_tree_view_snapshot_line (GtkTreeView *tree_view,
|
||||
GtkSnapshot *snapshot,
|
||||
GtkTreeViewLineType type,
|
||||
int x1,
|
||||
int y1,
|
||||
int x2,
|
||||
int y2)
|
||||
{
|
||||
GtkStyleContext *context;
|
||||
cairo_t *cr;
|
||||
|
||||
cairo_save (cr);
|
||||
cr = gtk_snapshot_append_cairo_node (snapshot,
|
||||
&GRAPHENE_RECT_INIT (
|
||||
MIN (x1, x2),
|
||||
MIN (y1, y2),
|
||||
ABS (x2 - x1) + 1,
|
||||
ABS (y2 - y1) + 1
|
||||
),
|
||||
"TreeViewGridLine");
|
||||
|
||||
context = gtk_widget_get_style_context (GTK_WIDGET (tree_view));
|
||||
|
||||
@@ -4733,12 +4736,12 @@ gtk_tree_view_draw_line (GtkTreeView *tree_view,
|
||||
cairo_line_to (cr, x2 + 0.5, y2 + 0.5);
|
||||
cairo_stroke (cr);
|
||||
|
||||
cairo_restore (cr);
|
||||
cairo_destroy (cr);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tree_view_draw_grid_lines (GtkTreeView *tree_view,
|
||||
cairo_t *cr)
|
||||
gtk_tree_view_snapshot_grid_lines (GtkTreeView *tree_view,
|
||||
GtkSnapshot *snapshot)
|
||||
{
|
||||
GList *list, *first, *last;
|
||||
gboolean rtl;
|
||||
@@ -4768,10 +4771,10 @@ gtk_tree_view_draw_grid_lines (GtkTreeView *tree_view,
|
||||
|
||||
current_x += gtk_tree_view_column_get_width (column);
|
||||
|
||||
gtk_tree_view_draw_line (tree_view, cr,
|
||||
GTK_TREE_VIEW_GRID_LINE,
|
||||
current_x - 1, 0,
|
||||
current_x - 1, gtk_tree_view_get_height (tree_view));
|
||||
gtk_tree_view_snapshot_line (tree_view, snapshot,
|
||||
GTK_TREE_VIEW_GRID_LINE,
|
||||
current_x - 1, 0,
|
||||
current_x - 1, gtk_tree_view_get_height (tree_view));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4781,9 +4784,9 @@ gtk_tree_view_draw_grid_lines (GtkTreeView *tree_view,
|
||||
* KEEP IN SYNC WITH gtk_tree_view_create_row_drag_icon()!
|
||||
* FIXME: It’s not...
|
||||
*/
|
||||
static gboolean
|
||||
gtk_tree_view_bin_draw (GtkWidget *widget,
|
||||
cairo_t *cr)
|
||||
static void
|
||||
gtk_tree_view_bin_snapshot (GtkWidget *widget,
|
||||
GtkSnapshot *snapshot)
|
||||
{
|
||||
GtkTreeView *tree_view = GTK_TREE_VIEW (widget);
|
||||
GtkTreePath *path;
|
||||
@@ -4818,18 +4821,13 @@ gtk_tree_view_bin_draw (GtkWidget *widget,
|
||||
|
||||
if (tree_view->priv->tree == NULL)
|
||||
{
|
||||
draw_empty (tree_view, cr);
|
||||
return TRUE;
|
||||
snapshot_empty (tree_view, snapshot);
|
||||
return;
|
||||
}
|
||||
|
||||
bin_window_width = gdk_window_get_width (tree_view->priv->bin_window);
|
||||
bin_window_height = gdk_window_get_height (tree_view->priv->bin_window);
|
||||
cairo_rectangle (cr, 0, 0, bin_window_width, bin_window_height);
|
||||
cairo_clip (cr);
|
||||
|
||||
if (!gdk_cairo_get_clip_rectangle (cr, &clip))
|
||||
return TRUE;
|
||||
|
||||
clip = (GdkRectangle) { 0, 0, bin_window_width, bin_window_height };
|
||||
new_y = TREE_WINDOW_Y_TO_RBTREE_Y (tree_view, clip.y);
|
||||
y_offset = -_gtk_rbtree_find_offset (tree_view->priv->tree, new_y, &tree, &node);
|
||||
|
||||
@@ -4838,16 +4836,16 @@ gtk_tree_view_bin_draw (GtkWidget *widget,
|
||||
gtk_style_context_save (context);
|
||||
gtk_style_context_add_class (context, GTK_STYLE_CLASS_CELL);
|
||||
|
||||
gtk_render_background (context, cr,
|
||||
0, gtk_tree_view_get_height (tree_view),
|
||||
bin_window_width,
|
||||
bin_window_height - gtk_tree_view_get_height (tree_view));
|
||||
gtk_snapshot_render_background (snapshot, context,
|
||||
0, gtk_tree_view_get_height (tree_view),
|
||||
bin_window_width,
|
||||
bin_window_height - gtk_tree_view_get_height (tree_view));
|
||||
|
||||
gtk_style_context_restore (context);
|
||||
}
|
||||
|
||||
if (node == NULL)
|
||||
return TRUE;
|
||||
return;
|
||||
|
||||
/* find the path for the node */
|
||||
path = _gtk_tree_path_new_from_rbtree (tree, node);
|
||||
@@ -5046,18 +5044,18 @@ gtk_tree_view_bin_draw (GtkWidget *widget,
|
||||
draw_focus = FALSE;
|
||||
|
||||
/* Draw background */
|
||||
gtk_render_background (context, cr,
|
||||
background_area.x,
|
||||
background_area.y,
|
||||
background_area.width,
|
||||
background_area.height);
|
||||
gtk_snapshot_render_background (snapshot, context,
|
||||
background_area.x,
|
||||
background_area.y,
|
||||
background_area.width,
|
||||
background_area.height);
|
||||
|
||||
/* Draw frame */
|
||||
gtk_render_frame (context, cr,
|
||||
background_area.x,
|
||||
background_area.y,
|
||||
background_area.width,
|
||||
background_area.height);
|
||||
gtk_snapshot_render_frame (snapshot, context,
|
||||
background_area.x,
|
||||
background_area.y,
|
||||
background_area.width,
|
||||
background_area.height);
|
||||
|
||||
if (gtk_tree_view_is_expander_column (tree_view, column))
|
||||
{
|
||||
@@ -5074,75 +5072,89 @@ gtk_tree_view_bin_draw (GtkWidget *widget,
|
||||
|
||||
if (is_separator)
|
||||
{
|
||||
GdkRGBA color;
|
||||
|
||||
gtk_style_context_save (context);
|
||||
gtk_style_context_add_class (context, GTK_STYLE_CLASS_SEPARATOR);
|
||||
|
||||
gtk_render_line (context, cr,
|
||||
cell_area.x,
|
||||
cell_area.y + cell_area.height / 2,
|
||||
cell_area.x + cell_area.width,
|
||||
cell_area.y + cell_area.height / 2);
|
||||
gtk_style_context_get_color (context, &color);
|
||||
gtk_snapshot_append_color_node (snapshot,
|
||||
&color,
|
||||
&GRAPHENE_RECT_INIT(
|
||||
cell_area.x,
|
||||
cell_area.y + cell_area.height / 2,
|
||||
cell_area.x + cell_area.width,
|
||||
1
|
||||
),
|
||||
"Separator");
|
||||
|
||||
gtk_style_context_restore (context);
|
||||
}
|
||||
else
|
||||
{
|
||||
_gtk_tree_view_column_cell_render (column,
|
||||
cr,
|
||||
&background_area,
|
||||
&cell_area,
|
||||
flags,
|
||||
draw_focus);
|
||||
gtk_tree_view_column_cell_snapshot (column,
|
||||
snapshot,
|
||||
&background_area,
|
||||
&cell_area,
|
||||
flags,
|
||||
draw_focus);
|
||||
}
|
||||
|
||||
if (gtk_tree_view_draw_expanders (tree_view)
|
||||
&& (node->flags & GTK_RBNODE_IS_PARENT) == GTK_RBNODE_IS_PARENT)
|
||||
{
|
||||
gtk_tree_view_draw_arrow (GTK_TREE_VIEW (widget),
|
||||
cr,
|
||||
tree,
|
||||
node);
|
||||
gtk_tree_view_snapshot_arrow (GTK_TREE_VIEW (widget),
|
||||
snapshot,
|
||||
tree,
|
||||
node);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (is_separator)
|
||||
{
|
||||
GdkRGBA color;
|
||||
|
||||
gtk_style_context_save (context);
|
||||
gtk_style_context_add_class (context, GTK_STYLE_CLASS_SEPARATOR);
|
||||
|
||||
gtk_render_line (context, cr,
|
||||
cell_area.x,
|
||||
cell_area.y + cell_area.height / 2,
|
||||
cell_area.x + cell_area.width,
|
||||
cell_area.y + cell_area.height / 2);
|
||||
gtk_style_context_get_color (context, &color);
|
||||
gtk_snapshot_append_color_node (snapshot,
|
||||
&color,
|
||||
&GRAPHENE_RECT_INIT(
|
||||
cell_area.x,
|
||||
cell_area.y + cell_area.height / 2,
|
||||
cell_area.x + cell_area.width,
|
||||
1
|
||||
),
|
||||
"Separator");
|
||||
|
||||
gtk_style_context_restore (context);
|
||||
}
|
||||
else
|
||||
_gtk_tree_view_column_cell_render (column,
|
||||
cr,
|
||||
&background_area,
|
||||
&cell_area,
|
||||
flags,
|
||||
draw_focus);
|
||||
gtk_tree_view_column_cell_snapshot (column,
|
||||
snapshot,
|
||||
&background_area,
|
||||
&cell_area,
|
||||
flags,
|
||||
draw_focus);
|
||||
}
|
||||
|
||||
if (draw_hgrid_lines)
|
||||
{
|
||||
if (background_area.y >= clip.y)
|
||||
gtk_tree_view_draw_line (tree_view, cr,
|
||||
GTK_TREE_VIEW_GRID_LINE,
|
||||
background_area.x, background_area.y,
|
||||
background_area.x + background_area.width,
|
||||
background_area.y);
|
||||
gtk_tree_view_snapshot_line (tree_view, snapshot,
|
||||
GTK_TREE_VIEW_GRID_LINE,
|
||||
background_area.x, background_area.y,
|
||||
background_area.x + background_area.width,
|
||||
background_area.y);
|
||||
|
||||
if (background_area.y + max_height < clip.y + clip.height)
|
||||
gtk_tree_view_draw_line (tree_view, cr,
|
||||
GTK_TREE_VIEW_GRID_LINE,
|
||||
background_area.x, background_area.y + max_height,
|
||||
background_area.x + background_area.width,
|
||||
background_area.y + max_height);
|
||||
gtk_tree_view_snapshot_line (tree_view, snapshot,
|
||||
GTK_TREE_VIEW_GRID_LINE,
|
||||
background_area.x, background_area.y + max_height,
|
||||
background_area.x + background_area.width,
|
||||
background_area.y + max_height);
|
||||
}
|
||||
|
||||
if (gtk_tree_view_is_expander_column (tree_view, column) &&
|
||||
@@ -5160,21 +5172,21 @@ gtk_tree_view_bin_draw (GtkWidget *widget,
|
||||
if ((node->flags & GTK_RBNODE_IS_PARENT) == GTK_RBNODE_IS_PARENT
|
||||
&& depth > 1)
|
||||
{
|
||||
gtk_tree_view_draw_line (tree_view, cr,
|
||||
GTK_TREE_VIEW_TREE_LINE,
|
||||
x + expander_size * (depth - 1.5) * mult,
|
||||
y1,
|
||||
x + expander_size * (depth - 1.1) * mult,
|
||||
y1);
|
||||
gtk_tree_view_snapshot_line (tree_view, snapshot,
|
||||
GTK_TREE_VIEW_TREE_LINE,
|
||||
x + expander_size * (depth - 1.5) * mult,
|
||||
y1,
|
||||
x + expander_size * (depth - 1.1) * mult,
|
||||
y1);
|
||||
}
|
||||
else if (depth > 1)
|
||||
{
|
||||
gtk_tree_view_draw_line (tree_view, cr,
|
||||
GTK_TREE_VIEW_TREE_LINE,
|
||||
x + expander_size * (depth - 1.5) * mult,
|
||||
y1,
|
||||
x + expander_size * (depth - 0.5) * mult,
|
||||
y1);
|
||||
gtk_tree_view_snapshot_line (tree_view, snapshot,
|
||||
GTK_TREE_VIEW_TREE_LINE,
|
||||
x + expander_size * (depth - 1.5) * mult,
|
||||
y1,
|
||||
x + expander_size * (depth - 0.5) * mult,
|
||||
y1);
|
||||
}
|
||||
|
||||
if (depth > 1)
|
||||
@@ -5184,19 +5196,19 @@ gtk_tree_view_bin_draw (GtkWidget *widget,
|
||||
GtkRBTree *tmp_tree;
|
||||
|
||||
if (!_gtk_rbtree_next (tree, node))
|
||||
gtk_tree_view_draw_line (tree_view, cr,
|
||||
GTK_TREE_VIEW_TREE_LINE,
|
||||
x + expander_size * (depth - 1.5) * mult,
|
||||
y0,
|
||||
x + expander_size * (depth - 1.5) * mult,
|
||||
y1);
|
||||
gtk_tree_view_snapshot_line (tree_view, snapshot,
|
||||
GTK_TREE_VIEW_TREE_LINE,
|
||||
x + expander_size * (depth - 1.5) * mult,
|
||||
y0,
|
||||
x + expander_size * (depth - 1.5) * mult,
|
||||
y1);
|
||||
else
|
||||
gtk_tree_view_draw_line (tree_view, cr,
|
||||
GTK_TREE_VIEW_TREE_LINE,
|
||||
x + expander_size * (depth - 1.5) * mult,
|
||||
y0,
|
||||
x + expander_size * (depth - 1.5) * mult,
|
||||
y2);
|
||||
gtk_tree_view_snapshot_line (tree_view, snapshot,
|
||||
GTK_TREE_VIEW_TREE_LINE,
|
||||
x + expander_size * (depth - 1.5) * mult,
|
||||
y0,
|
||||
x + expander_size * (depth - 1.5) * mult,
|
||||
y2);
|
||||
|
||||
tmp_node = tree->parent_node;
|
||||
tmp_tree = tree->parent_tree;
|
||||
@@ -5204,12 +5216,12 @@ gtk_tree_view_bin_draw (GtkWidget *widget,
|
||||
for (i = depth - 2; i > 0; i--)
|
||||
{
|
||||
if (_gtk_rbtree_next (tmp_tree, tmp_node))
|
||||
gtk_tree_view_draw_line (tree_view, cr,
|
||||
GTK_TREE_VIEW_TREE_LINE,
|
||||
x + expander_size * (i - 0.5) * mult,
|
||||
y0,
|
||||
x + expander_size * (i - 0.5) * mult,
|
||||
y2);
|
||||
gtk_tree_view_snapshot_line (tree_view, snapshot,
|
||||
GTK_TREE_VIEW_TREE_LINE,
|
||||
x + expander_size * (i - 0.5) * mult,
|
||||
y0,
|
||||
x + expander_size * (i - 0.5) * mult,
|
||||
y2);
|
||||
|
||||
tmp_node = tmp_tree->parent_node;
|
||||
tmp_tree = tmp_tree->parent_tree;
|
||||
@@ -5249,10 +5261,10 @@ gtk_tree_view_bin_draw (GtkWidget *widget,
|
||||
|
||||
_gtk_tree_view_find_node (tree_view, drag_dest_path, &drag_tree, &drag_node);
|
||||
if (drag_tree != NULL)
|
||||
gtk_render_frame (context, cr,
|
||||
0, gtk_tree_view_get_row_y_offset (tree_view, drag_tree, drag_node),
|
||||
gdk_window_get_width (tree_view->priv->bin_window),
|
||||
gtk_tree_view_get_row_height (tree_view, drag_node));
|
||||
gtk_snapshot_render_frame (snapshot, context,
|
||||
0, gtk_tree_view_get_row_y_offset (tree_view, drag_tree, drag_node),
|
||||
gdk_window_get_width (tree_view->priv->bin_window),
|
||||
gtk_tree_view_get_row_height (tree_view, drag_node));
|
||||
|
||||
gtk_style_context_restore (context);
|
||||
}
|
||||
@@ -5281,10 +5293,10 @@ gtk_tree_view_bin_draw (GtkWidget *widget,
|
||||
tmp_height = gtk_tree_view_get_row_height (tree_view, node);
|
||||
}
|
||||
|
||||
gtk_render_focus (context, cr,
|
||||
0, tmp_y,
|
||||
gdk_window_get_width (tree_view->priv->bin_window),
|
||||
tmp_height);
|
||||
gtk_snapshot_render_focus (snapshot, context,
|
||||
0, tmp_y,
|
||||
gdk_window_get_width (tree_view->priv->bin_window),
|
||||
tmp_height);
|
||||
|
||||
gtk_style_context_restore (context);
|
||||
}
|
||||
@@ -5304,7 +5316,7 @@ gtk_tree_view_bin_draw (GtkWidget *widget,
|
||||
depth++;
|
||||
|
||||
/* Sanity Check! */
|
||||
TREE_VIEW_INTERNAL_ASSERT (has_child, FALSE);
|
||||
TREE_VIEW_INTERNAL_ASSERT_VOID (has_child);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -5319,7 +5331,7 @@ gtk_tree_view_bin_draw (GtkWidget *widget,
|
||||
done = TRUE;
|
||||
|
||||
/* Sanity Check! */
|
||||
TREE_VIEW_INTERNAL_ASSERT (has_next, FALSE);
|
||||
TREE_VIEW_INTERNAL_ASSERT_VOID (has_next);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -5337,7 +5349,7 @@ gtk_tree_view_bin_draw (GtkWidget *widget,
|
||||
depth--;
|
||||
|
||||
/* Sanity check */
|
||||
TREE_VIEW_INTERNAL_ASSERT (has_parent, FALSE);
|
||||
TREE_VIEW_INTERNAL_ASSERT_VOID (has_parent);
|
||||
}
|
||||
}
|
||||
while (!done);
|
||||
@@ -5346,39 +5358,48 @@ gtk_tree_view_bin_draw (GtkWidget *widget,
|
||||
while (y_offset < clip.height);
|
||||
|
||||
done:
|
||||
gtk_tree_view_draw_grid_lines (tree_view, cr);
|
||||
gtk_tree_view_snapshot_grid_lines (tree_view, snapshot);
|
||||
|
||||
if (tree_view->priv->rubber_band_status == RUBBER_BAND_ACTIVE)
|
||||
gtk_tree_view_paint_rubber_band (tree_view, cr);
|
||||
gtk_tree_view_snapshot_rubber_band (tree_view, snapshot);
|
||||
|
||||
if (drag_dest_path)
|
||||
gtk_tree_path_free (drag_dest_path);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_tree_view_draw (GtkWidget *widget,
|
||||
cairo_t *cr)
|
||||
static void
|
||||
gtk_tree_view_snapshot (GtkWidget *widget,
|
||||
GtkSnapshot *snapshot)
|
||||
{
|
||||
GtkTreeView *tree_view = GTK_TREE_VIEW (widget);
|
||||
GtkWidget *button;
|
||||
GtkStyleContext *context;
|
||||
GList *list;
|
||||
gint width, height;
|
||||
|
||||
context = gtk_widget_get_style_context (widget);
|
||||
width = gtk_widget_get_allocated_width (widget);
|
||||
height = gtk_widget_get_allocated_height (widget);
|
||||
|
||||
gtk_render_background (context, cr,
|
||||
0, 0,
|
||||
gtk_widget_get_allocated_width (widget),
|
||||
gtk_widget_get_allocated_height (widget));
|
||||
gtk_snapshot_render_background (snapshot, context,
|
||||
0, 0,
|
||||
width, height);
|
||||
|
||||
cairo_save (cr);
|
||||
gtk_snapshot_push_clip (snapshot,
|
||||
&GRAPHENE_RECT_INIT(
|
||||
0, gtk_tree_view_get_effective_header_height (tree_view),
|
||||
width,
|
||||
height - gtk_tree_view_get_effective_header_height (tree_view)
|
||||
),
|
||||
"TreeViewContentClip");
|
||||
|
||||
gtk_cairo_transform_to_window (cr, widget, tree_view->priv->bin_window);
|
||||
gtk_tree_view_bin_draw (widget, cr);
|
||||
|
||||
cairo_restore (cr);
|
||||
gtk_snapshot_translate_2d (snapshot,
|
||||
- (gint) gtk_adjustment_get_value (tree_view->priv->hadjustment),
|
||||
gtk_tree_view_get_effective_header_height (tree_view));
|
||||
gtk_tree_view_bin_snapshot (widget, snapshot);
|
||||
gtk_snapshot_translate_2d (snapshot,
|
||||
(gint) gtk_adjustment_get_value (tree_view->priv->hadjustment),
|
||||
- gtk_tree_view_get_effective_header_height (tree_view));
|
||||
|
||||
/* We can't just chain up to Container::draw as it will try to send the
|
||||
* event to the headers, so we handle propagating it to our children
|
||||
@@ -5388,9 +5409,13 @@ gtk_tree_view_draw (GtkWidget *widget,
|
||||
{
|
||||
GtkTreeViewChild *child = list->data;
|
||||
|
||||
gtk_container_propagate_draw (GTK_CONTAINER (tree_view), child->widget, cr);
|
||||
gtk_container_snapshot_child (GTK_CONTAINER (tree_view), child->widget, snapshot);
|
||||
}
|
||||
|
||||
gtk_snapshot_pop_and_append (snapshot);
|
||||
|
||||
#if 0
|
||||
Thyis clearly does not work. priv->drag_highlight_window is potentially a toplevel...
|
||||
if (tree_view->priv->drag_highlight_window)
|
||||
{
|
||||
GdkRGBA color;
|
||||
@@ -5416,6 +5441,15 @@ gtk_tree_view_draw (GtkWidget *widget,
|
||||
}
|
||||
cairo_restore (cr);
|
||||
}
|
||||
#endif
|
||||
|
||||
gtk_snapshot_push_clip (snapshot,
|
||||
&GRAPHENE_RECT_INIT(
|
||||
0, 0,
|
||||
width,
|
||||
gtk_tree_view_get_effective_header_height (tree_view)
|
||||
),
|
||||
"TreeViewHeaderClip");
|
||||
|
||||
gtk_style_context_save (context);
|
||||
gtk_style_context_remove_class (context, GTK_STYLE_CLASS_VIEW);
|
||||
@@ -5430,21 +5464,21 @@ gtk_tree_view_draw (GtkWidget *widget,
|
||||
if (gtk_tree_view_column_get_visible (column))
|
||||
{
|
||||
button = gtk_tree_view_column_get_button (column);
|
||||
gtk_container_propagate_draw (GTK_CONTAINER (tree_view),
|
||||
button, cr);
|
||||
gtk_container_snapshot_child (GTK_CONTAINER (tree_view),
|
||||
button, snapshot);
|
||||
}
|
||||
}
|
||||
|
||||
if (tree_view->priv->drag_window)
|
||||
{
|
||||
button = gtk_tree_view_column_get_button (tree_view->priv->drag_column);
|
||||
gtk_container_propagate_draw (GTK_CONTAINER (tree_view),
|
||||
button, cr);
|
||||
gtk_container_snapshot_child (GTK_CONTAINER (tree_view),
|
||||
button, snapshot);
|
||||
}
|
||||
|
||||
gtk_style_context_restore (context);
|
||||
|
||||
return FALSE;
|
||||
gtk_snapshot_pop_and_append (snapshot);
|
||||
}
|
||||
|
||||
enum
|
||||
@@ -9962,10 +9996,10 @@ gtk_tree_view_queue_draw_path (GtkTreeView *tree_view,
|
||||
/* x and y are the mouse position
|
||||
*/
|
||||
static void
|
||||
gtk_tree_view_draw_arrow (GtkTreeView *tree_view,
|
||||
cairo_t *cr,
|
||||
GtkRBTree *tree,
|
||||
GtkRBNode *node)
|
||||
gtk_tree_view_snapshot_arrow (GtkTreeView *tree_view,
|
||||
GtkSnapshot *snapshot,
|
||||
GtkRBTree *tree,
|
||||
GtkRBNode *node)
|
||||
{
|
||||
GdkRectangle area;
|
||||
GtkStateFlags state = 0;
|
||||
@@ -9974,9 +10008,12 @@ gtk_tree_view_draw_arrow (GtkTreeView *tree_view,
|
||||
gint x_offset = 0;
|
||||
gint x2;
|
||||
GtkCellRendererState flags = 0;
|
||||
GtkCssImageBuiltinType image_type;
|
||||
gboolean rtl;
|
||||
|
||||
widget = GTK_WIDGET (tree_view);
|
||||
context = gtk_widget_get_style_context (widget);
|
||||
rtl = (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL);
|
||||
|
||||
if (! GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_PARENT))
|
||||
return;
|
||||
@@ -9998,18 +10035,27 @@ gtk_tree_view_draw_arrow (GtkTreeView *tree_view,
|
||||
state = gtk_cell_renderer_get_state (NULL, widget, flags);
|
||||
|
||||
if (node->children != NULL)
|
||||
state |= GTK_STATE_FLAG_CHECKED;
|
||||
{
|
||||
state |= GTK_STATE_FLAG_CHECKED;
|
||||
image_type = rtl ? GTK_CSS_IMAGE_BUILTIN_EXPANDER_VERTICAL_RIGHT_EXPANDED
|
||||
: GTK_CSS_IMAGE_BUILTIN_EXPANDER_VERTICAL_LEFT_EXPANDED;
|
||||
}
|
||||
else
|
||||
state &= ~(GTK_STATE_FLAG_CHECKED);
|
||||
{
|
||||
state &= ~(GTK_STATE_FLAG_CHECKED);
|
||||
image_type = rtl ? GTK_CSS_IMAGE_BUILTIN_EXPANDER_VERTICAL_RIGHT
|
||||
: GTK_CSS_IMAGE_BUILTIN_EXPANDER_VERTICAL_LEFT;
|
||||
}
|
||||
|
||||
gtk_style_context_save (context);
|
||||
|
||||
gtk_style_context_set_state (context, state);
|
||||
gtk_style_context_add_class (context, GTK_STYLE_CLASS_EXPANDER);
|
||||
|
||||
gtk_render_expander (context, cr,
|
||||
area.x, area.y,
|
||||
area.width, area.height);
|
||||
gtk_snapshot_translate_2d (snapshot, area.x, area.y);
|
||||
gtk_css_style_snapshot_icon (gtk_style_context_lookup_style (context), snapshot,
|
||||
area.width, area.height, image_type);
|
||||
gtk_snapshot_translate_2d (snapshot, -area.x, -area.y);
|
||||
|
||||
gtk_style_context_restore (context);
|
||||
}
|
||||
@@ -14101,6 +14147,8 @@ gtk_tree_view_create_row_drag_icon (GtkTreeView *tree_view,
|
||||
GList *list;
|
||||
GdkRectangle background_area;
|
||||
GtkWidget *widget;
|
||||
GtkSnapshot snapshot;
|
||||
GskRenderNode *rendernode;
|
||||
gint depth;
|
||||
/* start drawing inside the black outline */
|
||||
gint x = 1, y = 1;
|
||||
@@ -14149,11 +14197,12 @@ gtk_tree_view_create_row_drag_icon (GtkTreeView *tree_view,
|
||||
bin_window_width + 2,
|
||||
background_area.height + 2);
|
||||
|
||||
cr = cairo_create (surface);
|
||||
gtk_snapshot_init (&snapshot, NULL, NULL, "TreeView DragIcon");
|
||||
|
||||
gtk_render_background (context, cr, 0, 0,
|
||||
bin_window_width + 2,
|
||||
background_area.height + 2);
|
||||
gtk_snapshot_render_background (&snapshot, context,
|
||||
0, 0,
|
||||
bin_window_width + 2,
|
||||
background_area.height + 2);
|
||||
|
||||
rtl = gtk_widget_get_direction (GTK_WIDGET (tree_view)) == GTK_TEXT_DIR_RTL;
|
||||
|
||||
@@ -14195,29 +14244,42 @@ gtk_tree_view_create_row_drag_icon (GtkTreeView *tree_view,
|
||||
{
|
||||
if (is_separator)
|
||||
{
|
||||
GdkRGBA color;
|
||||
|
||||
gtk_style_context_save (context);
|
||||
gtk_style_context_add_class (context, GTK_STYLE_CLASS_SEPARATOR);
|
||||
|
||||
gtk_render_line (context, cr,
|
||||
cell_area.x,
|
||||
cell_area.y + cell_area.height / 2,
|
||||
cell_area.x + cell_area.width,
|
||||
cell_area.y + cell_area.height / 2);
|
||||
gtk_style_context_get_color (context, &color);
|
||||
gtk_snapshot_append_color_node (&snapshot,
|
||||
&color,
|
||||
&GRAPHENE_RECT_INIT(
|
||||
cell_area.x,
|
||||
cell_area.y + cell_area.height / 2,
|
||||
cell_area.x + cell_area.width,
|
||||
1
|
||||
),
|
||||
"Separator");
|
||||
|
||||
gtk_style_context_restore (context);
|
||||
}
|
||||
else
|
||||
{
|
||||
_gtk_tree_view_column_cell_render (column,
|
||||
cr,
|
||||
&background_area,
|
||||
&cell_area,
|
||||
0, FALSE);
|
||||
gtk_tree_view_column_cell_snapshot (column,
|
||||
&snapshot,
|
||||
&background_area,
|
||||
&cell_area,
|
||||
0, FALSE);
|
||||
}
|
||||
}
|
||||
cell_offset += gtk_tree_view_column_get_width (column);
|
||||
}
|
||||
|
||||
rendernode = gtk_snapshot_finish (&snapshot);
|
||||
|
||||
cr = cairo_create (surface);
|
||||
|
||||
gsk_render_node_draw (rendernode, cr);
|
||||
|
||||
cairo_set_source_rgb (cr, 0, 0, 0);
|
||||
cairo_rectangle (cr,
|
||||
0.5, 0.5,
|
||||
@@ -14227,6 +14289,7 @@ gtk_tree_view_create_row_drag_icon (GtkTreeView *tree_view,
|
||||
cairo_stroke (cr);
|
||||
|
||||
cairo_destroy (cr);
|
||||
gsk_render_node_unref (rendernode);
|
||||
|
||||
cairo_surface_set_device_offset (surface, 2, 2);
|
||||
|
||||
|
||||
+13
-17
@@ -2865,9 +2865,9 @@ gtk_tree_view_column_cell_get_size (GtkTreeViewColumn *tree_column,
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_tree_view_column_cell_render:
|
||||
* gtk_tree_view_column_cell_snapshot:
|
||||
* @tree_column: A #GtkTreeViewColumn.
|
||||
* @cr: cairo context to draw to
|
||||
* @snapshot: #GtkSnapshot to draw to
|
||||
* @background_area: entire cell area (including tree expanders and maybe padding on the sides)
|
||||
* @cell_area: area normally rendered by a cell renderer
|
||||
* @flags: flags that affect rendering
|
||||
@@ -2876,30 +2876,26 @@ gtk_tree_view_column_cell_get_size (GtkTreeViewColumn *tree_column,
|
||||
* #GtkTreeView.
|
||||
**/
|
||||
void
|
||||
_gtk_tree_view_column_cell_render (GtkTreeViewColumn *tree_column,
|
||||
cairo_t *cr,
|
||||
const GdkRectangle *background_area,
|
||||
const GdkRectangle *cell_area,
|
||||
guint flags,
|
||||
gboolean draw_focus)
|
||||
gtk_tree_view_column_cell_snapshot (GtkTreeViewColumn *tree_column,
|
||||
GtkSnapshot *snapshot,
|
||||
const GdkRectangle *background_area,
|
||||
const GdkRectangle *cell_area,
|
||||
guint flags,
|
||||
gboolean draw_focus)
|
||||
{
|
||||
GtkTreeViewColumnPrivate *priv;
|
||||
|
||||
g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
|
||||
g_return_if_fail (cr != NULL);
|
||||
g_return_if_fail (snapshot != NULL);
|
||||
g_return_if_fail (background_area != NULL);
|
||||
g_return_if_fail (cell_area != NULL);
|
||||
|
||||
priv = tree_column->priv;
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
gtk_cell_area_render (priv->cell_area, priv->cell_area_context,
|
||||
priv->tree_view, cr,
|
||||
background_area, cell_area, flags,
|
||||
draw_focus);
|
||||
|
||||
cairo_restore (cr);
|
||||
gtk_cell_area_snapshot (priv->cell_area, priv->cell_area_context,
|
||||
priv->tree_view, snapshot,
|
||||
background_area, cell_area, flags,
|
||||
draw_focus);
|
||||
}
|
||||
|
||||
gboolean
|
||||
|
||||
@@ -153,12 +153,12 @@ gtk_cell_renderer_graph_get_size (GtkCellRenderer *cell,
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_cell_renderer_graph_render (GtkCellRenderer *cell,
|
||||
cairo_t *cr,
|
||||
GtkWidget *widget,
|
||||
const GdkRectangle *background_area,
|
||||
const GdkRectangle *cell_area,
|
||||
GtkCellRendererState flags)
|
||||
gtk_cell_renderer_graph_snapshot (GtkCellRenderer *cell,
|
||||
GtkSnapshot *snapshot,
|
||||
GtkWidget *widget,
|
||||
const GdkRectangle *background_area,
|
||||
const GdkRectangle *cell_area,
|
||||
GtkCellRendererState flags)
|
||||
{
|
||||
GtkCellRendererGraph *graph = GTK_CELL_RENDERER_GRAPH (cell);
|
||||
GtkCellRendererGraphPrivate *priv = graph->priv;
|
||||
@@ -166,6 +166,7 @@ gtk_cell_renderer_graph_render (GtkCellRenderer *cell,
|
||||
double minimum, maximum, diff;
|
||||
double x, y, width, height;
|
||||
int xpad, ypad;
|
||||
cairo_t *cr;
|
||||
GdkRGBA color;
|
||||
guint i, n;
|
||||
|
||||
@@ -194,6 +195,13 @@ gtk_cell_renderer_graph_render (GtkCellRenderer *cell,
|
||||
context = gtk_widget_get_style_context (widget);
|
||||
gtk_style_context_get_color (context, &color);
|
||||
|
||||
cr = gtk_snapshot_append_cairo_node (snapshot,
|
||||
&GRAPHENE_RECT_INIT (
|
||||
background_area->x, background_area->y,
|
||||
background_area->width, background_area->height
|
||||
),
|
||||
"CellGraph");
|
||||
|
||||
cairo_set_line_width (cr, 1.0);
|
||||
|
||||
x = background_area->x + xpad + LINE_WIDTH / 2.0;
|
||||
@@ -226,6 +234,8 @@ gtk_cell_renderer_graph_render (GtkCellRenderer *cell,
|
||||
color.alpha *= 0.2;
|
||||
gdk_cairo_set_source_rgba (cr, &color);
|
||||
cairo_fill (cr);
|
||||
|
||||
cairo_destroy (cr);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -239,7 +249,7 @@ gtk_cell_renderer_graph_class_init (GtkCellRendererGraphClass *klass)
|
||||
object_class->set_property = gtk_cell_renderer_graph_set_property;
|
||||
|
||||
cell_class->get_size = gtk_cell_renderer_graph_get_size;
|
||||
cell_class->render = gtk_cell_renderer_graph_render;
|
||||
cell_class->snapshot = gtk_cell_renderer_graph_snapshot;
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_DATA,
|
||||
|
||||
@@ -21,8 +21,10 @@
|
||||
#include "recorder.h"
|
||||
|
||||
#include <gtk/gtkbox.h>
|
||||
#include <gtk/gtkfilechooserdialog.h>
|
||||
#include <gtk/gtklabel.h>
|
||||
#include <gtk/gtklistbox.h>
|
||||
#include <gtk/gtkmessagedialog.h>
|
||||
#include <gtk/gtktogglebutton.h>
|
||||
#include <gtk/gtktreeselection.h>
|
||||
#include <gtk/gtktreeview.h>
|
||||
@@ -43,6 +45,7 @@ struct _GtkInspectorRecorderPrivate
|
||||
GtkWidget *recordings_list;
|
||||
GtkWidget *render_node_view;
|
||||
GtkWidget *render_node_tree;
|
||||
GtkWidget *render_node_save_button;
|
||||
GtkWidget *node_property_tree;
|
||||
GtkTreeModel *render_node_properties;
|
||||
|
||||
@@ -219,14 +222,92 @@ render_node_list_selection_changed (GtkTreeSelection *selection,
|
||||
GtkTreeIter iter;
|
||||
|
||||
if (!gtk_tree_selection_get_selected (selection, NULL, &iter))
|
||||
return;
|
||||
{
|
||||
gtk_widget_set_sensitive (priv->render_node_save_button, FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
gtk_widget_set_sensitive (priv->render_node_save_button, TRUE);
|
||||
node = gtk_tree_model_render_node_get_node_from_iter (GTK_TREE_MODEL_RENDER_NODE (priv->render_node_model), &iter);
|
||||
gtk_render_node_view_set_render_node (GTK_RENDER_NODE_VIEW (priv->render_node_view), node);
|
||||
|
||||
populate_render_node_properties (GTK_LIST_STORE (priv->render_node_properties), node);
|
||||
}
|
||||
|
||||
static void
|
||||
render_node_save_response (GtkWidget *dialog,
|
||||
gint response,
|
||||
GskRenderNode *node)
|
||||
{
|
||||
gtk_widget_hide (dialog);
|
||||
|
||||
if (response == GTK_RESPONSE_ACCEPT)
|
||||
{
|
||||
GBytes *bytes = gsk_render_node_serialize (node);
|
||||
GError *error = NULL;
|
||||
|
||||
if (!g_file_replace_contents (gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog)),
|
||||
g_bytes_get_data (bytes, NULL),
|
||||
g_bytes_get_size (bytes),
|
||||
NULL,
|
||||
FALSE,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
&error))
|
||||
{
|
||||
GtkWidget *message_dialog;
|
||||
|
||||
message_dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_window_get_transient_for (GTK_WINDOW (dialog))),
|
||||
GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||
GTK_MESSAGE_INFO,
|
||||
GTK_BUTTONS_OK,
|
||||
_("Saving RenderNode failed"));
|
||||
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (message_dialog),
|
||||
"%s", error->message);
|
||||
g_signal_connect (message_dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL);
|
||||
gtk_widget_show (message_dialog);
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
g_bytes_unref (bytes);
|
||||
}
|
||||
|
||||
gtk_widget_destroy (dialog);
|
||||
}
|
||||
|
||||
static void
|
||||
render_node_save (GtkButton *button,
|
||||
GtkInspectorRecorder *recorder)
|
||||
{
|
||||
GtkInspectorRecorderPrivate *priv = gtk_inspector_recorder_get_instance_private (recorder);
|
||||
GskRenderNode *node;
|
||||
GtkTreeIter iter;
|
||||
GtkWidget *dialog;
|
||||
char *filename;
|
||||
|
||||
if (!gtk_tree_selection_get_selected (gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->render_node_tree)), NULL, &iter))
|
||||
return;
|
||||
|
||||
node = gtk_tree_model_render_node_get_node_from_iter (GTK_TREE_MODEL_RENDER_NODE (priv->render_node_model), &iter);
|
||||
|
||||
dialog = gtk_file_chooser_dialog_new ("",
|
||||
GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (recorder))),
|
||||
GTK_FILE_CHOOSER_ACTION_SAVE,
|
||||
_("_Cancel"), GTK_RESPONSE_CANCEL,
|
||||
_("_Save"), GTK_RESPONSE_ACCEPT,
|
||||
NULL);
|
||||
filename = g_strdup_printf ("%s.node", gsk_render_node_get_name (node) ? gsk_render_node_get_name (node)
|
||||
: node_type_name (gsk_render_node_get_node_type (node)));
|
||||
gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), filename);
|
||||
g_free (filename);
|
||||
gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
|
||||
gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
|
||||
gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE);
|
||||
g_signal_connect (dialog, "response", G_CALLBACK (render_node_save_response), node);
|
||||
gtk_widget_show (dialog);
|
||||
}
|
||||
|
||||
static char *
|
||||
format_timespan (gint64 timespan)
|
||||
{
|
||||
@@ -394,11 +475,13 @@ gtk_inspector_recorder_class_init (GtkInspectorRecorderClass *klass)
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorRecorder, recordings_list);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorRecorder, render_node_view);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorRecorder, render_node_tree);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorRecorder, render_node_save_button);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorRecorder, node_property_tree);
|
||||
|
||||
gtk_widget_class_bind_template_callback (widget_class, recordings_clear_all);
|
||||
gtk_widget_class_bind_template_callback (widget_class, recordings_list_row_selected);
|
||||
gtk_widget_class_bind_template_callback (widget_class, render_node_list_selection_changed);
|
||||
gtk_widget_class_bind_template_callback (widget_class, render_node_save);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -33,6 +33,18 @@
|
||||
<property name="stack">render_stack</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="render_node_save_button">
|
||||
<property name="visible">1</property>
|
||||
<property name="relief">none</property>
|
||||
<property name="sensitive">0</property>
|
||||
<property name="icon-name">document-save-as-symbolic</property>
|
||||
<signal name="clicked" handler="render_node_save"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="pack-type">end</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
|
||||
@@ -292,6 +292,7 @@ gtk/inspector/gtkstackcombo.c
|
||||
gtk/inspector/menu.c
|
||||
gtk/inspector/misc-info.c
|
||||
gtk/inspector/prop-editor.c
|
||||
gtk/inspector/recorder.c
|
||||
gtk/inspector/signals-list.c
|
||||
gtk/inspector/size-groups.c
|
||||
gtk/inspector/statistics.c
|
||||
|
||||
+259
-260
File diff suppressed because it is too large
Load Diff
@@ -306,6 +306,7 @@ gtk/inspector/object-hierarchy.ui
|
||||
gtk/inspector/object-tree.ui
|
||||
gtk/inspector/prop-editor.c
|
||||
gtk/inspector/prop-list.ui
|
||||
gtk/inspector/recorder.c
|
||||
gtk/inspector/resource-list.ui
|
||||
gtk/inspector/selector.ui
|
||||
gtk/inspector/signals-list.c
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user