Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 865cab3cc6 | |||
| bc47cc5970 |
@@ -50,7 +50,6 @@ case "${backend}" in
|
||||
--suite=gtk \
|
||||
--no-suite=failing \
|
||||
--no-suite=flaky \
|
||||
--no-suite=${backend}_failing \
|
||||
--no-suite=gsk-compare-broadway
|
||||
exit_code=$?
|
||||
|
||||
|
||||
@@ -64,8 +64,6 @@
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="short_time_label">
|
||||
<property name="hexpand">1</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="valign">baseline</property>
|
||||
<property name="label" translatable="yes">38m</property>
|
||||
<style>
|
||||
|
||||
@@ -61,10 +61,8 @@ struct _NodeEditorWindow
|
||||
GtkWidget *scale_scale;
|
||||
|
||||
GtkWidget *renderer_listbox;
|
||||
GListStore *saved_nodes;
|
||||
GListStore *renderers;
|
||||
GskRenderNode *node;
|
||||
GtkAdjustment *compare_progress;
|
||||
|
||||
GFileMonitor *file_monitor;
|
||||
|
||||
@@ -210,7 +208,7 @@ text_changed (GtkTextBuffer *buffer,
|
||||
GtkSnapshot *snapshot;
|
||||
GdkPaintable *paintable;
|
||||
graphene_rect_t bounds;
|
||||
guint i, n;
|
||||
guint i;
|
||||
|
||||
snapshot = gtk_snapshot_new ();
|
||||
gsk_render_node_get_bounds (big_node, &bounds);
|
||||
@@ -226,8 +224,6 @@ text_changed (GtkTextBuffer *buffer,
|
||||
gtk_snapshot_append_node (snapshot, self->node);
|
||||
paintable = gtk_snapshot_free_to_paintable (snapshot, &bounds.size);
|
||||
|
||||
n = g_list_model_get_n_items (G_LIST_MODEL (self->saved_nodes));
|
||||
g_list_store_splice (self->saved_nodes, MAX (n, 1) - 1, MIN (n, 1), (gpointer[1]) { paintable }, 1);
|
||||
for (i = 0; i < g_list_model_get_n_items (G_LIST_MODEL (self->renderers)); i++)
|
||||
{
|
||||
gpointer item = g_list_model_get_item (G_LIST_MODEL (self->renderers), i);
|
||||
@@ -312,17 +308,6 @@ text_changed (GtkTextBuffer *buffer,
|
||||
&start, &end);
|
||||
}
|
||||
|
||||
static void
|
||||
stash_current_node (NodeEditorWindow *self)
|
||||
{
|
||||
GdkPaintable *last;
|
||||
|
||||
last = g_list_model_get_item (G_LIST_MODEL (self->saved_nodes),
|
||||
g_list_model_get_n_items (G_LIST_MODEL (self->saved_nodes)) - 1);
|
||||
g_list_store_append (self->saved_nodes, last);
|
||||
g_object_unref (last);
|
||||
}
|
||||
|
||||
static void
|
||||
scale_changed (GObject *object,
|
||||
GParamSpec *pspec,
|
||||
@@ -392,8 +377,7 @@ text_view_query_tooltip_cb (GtkWidget *widget,
|
||||
|
||||
static gboolean
|
||||
load_bytes (NodeEditorWindow *self,
|
||||
GBytes *bytes,
|
||||
gboolean stash);
|
||||
GBytes *bytes);
|
||||
|
||||
static void
|
||||
load_error (NodeEditorWindow *self,
|
||||
@@ -411,7 +395,7 @@ load_error (NodeEditorWindow *self,
|
||||
node = gtk_snapshot_free_to_node (snapshot);
|
||||
bytes = gsk_render_node_serialize (node);
|
||||
|
||||
load_bytes (self, bytes, TRUE);
|
||||
load_bytes (self, bytes);
|
||||
|
||||
gsk_render_node_unref (node);
|
||||
g_object_unref (layout);
|
||||
@@ -419,8 +403,7 @@ load_error (NodeEditorWindow *self,
|
||||
|
||||
static gboolean
|
||||
load_bytes (NodeEditorWindow *self,
|
||||
GBytes *bytes,
|
||||
gboolean stash)
|
||||
GBytes *bytes)
|
||||
{
|
||||
if (!g_utf8_validate (g_bytes_get_data (bytes, NULL), g_bytes_get_size (bytes), NULL))
|
||||
{
|
||||
@@ -428,9 +411,6 @@ load_bytes (NodeEditorWindow *self,
|
||||
g_bytes_unref (bytes);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (stash)
|
||||
stash_current_node (self);
|
||||
|
||||
gtk_text_buffer_set_text (self->text_buffer,
|
||||
g_bytes_get_data (bytes, NULL),
|
||||
@@ -456,29 +436,7 @@ load_file_contents (NodeEditorWindow *self,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return load_bytes (self, bytes, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
saved_node_activate_cb (GtkListView *listview,
|
||||
guint pos,
|
||||
NodeEditorWindow *self)
|
||||
{
|
||||
GdkPaintable *paintable;
|
||||
GtkSnapshot *snapshot;
|
||||
GskRenderNode *node;
|
||||
GBytes *bytes;
|
||||
|
||||
paintable = g_list_model_get_item (G_LIST_MODEL (self->saved_nodes), pos);
|
||||
|
||||
snapshot = gtk_snapshot_new ();
|
||||
gdk_paintable_snapshot (paintable, snapshot, gdk_paintable_get_intrinsic_width (paintable), gdk_paintable_get_intrinsic_height (paintable));
|
||||
node = gtk_snapshot_free_to_node (snapshot);
|
||||
|
||||
bytes = gsk_render_node_serialize (node);
|
||||
load_bytes (self, bytes, TRUE);
|
||||
|
||||
g_object_unref (paintable);
|
||||
return load_bytes (self, bytes);
|
||||
}
|
||||
|
||||
static GdkContentProvider *
|
||||
@@ -507,7 +465,7 @@ on_picture_drop_read_done_cb (GObject *source,
|
||||
if (g_output_stream_splice_finish (stream, res, NULL) >= 0)
|
||||
{
|
||||
bytes = g_memory_output_stream_steal_as_bytes (G_MEMORY_OUTPUT_STREAM (stream));
|
||||
if (load_bytes (self, bytes, TRUE))
|
||||
if (load_bytes (self, bytes))
|
||||
action = GDK_ACTION_COPY;
|
||||
}
|
||||
|
||||
@@ -681,10 +639,6 @@ save_response_cb (GObject *source,
|
||||
g_object_unref (alert);
|
||||
g_error_free (error);
|
||||
}
|
||||
else
|
||||
{
|
||||
stash_current_node (self);
|
||||
}
|
||||
|
||||
g_free (text);
|
||||
g_object_unref (file);
|
||||
@@ -1103,8 +1057,6 @@ testcase_save_clicked_cb (GtkWidget *button,
|
||||
gtk_editable_set_text (GTK_EDITABLE (self->testcase_name_entry), "");
|
||||
gtk_popover_popdown (GTK_POPOVER (self->testcase_popover));
|
||||
|
||||
stash_current_node (self);
|
||||
|
||||
out:
|
||||
g_free (text);
|
||||
g_free (png_file);
|
||||
@@ -1112,147 +1064,9 @@ out:
|
||||
g_free (source_dir);
|
||||
}
|
||||
|
||||
static inline double
|
||||
double_transform (double start,
|
||||
double end,
|
||||
double progress)
|
||||
{
|
||||
return start + (end - start) * progress;
|
||||
}
|
||||
|
||||
static void
|
||||
rgba_transform (GdkRGBA *result,
|
||||
const GdkRGBA *start,
|
||||
const GdkRGBA *end,
|
||||
double progress)
|
||||
{
|
||||
result->alpha = CLAMP (double_transform (start->alpha, end->alpha, progress), 0, 1);
|
||||
|
||||
if (result->alpha <= 0.0)
|
||||
{
|
||||
result->red = result->green = result->blue = 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
result->red = CLAMP (double_transform (start->red * start->alpha, end->red * end->alpha, progress), 0, 1) / result->alpha;
|
||||
result->green = CLAMP (double_transform (start->green * start->alpha, end->green * end->alpha, progress), 0, 1) / result->alpha;
|
||||
result->blue = CLAMP (double_transform (start->blue * start->alpha, end->blue * end->alpha, progress), 0, 1) / result->alpha;
|
||||
}
|
||||
}
|
||||
|
||||
static GskRenderNode *
|
||||
render_node_transform (GskRenderNode *start,
|
||||
GskRenderNode *end,
|
||||
double progress)
|
||||
{
|
||||
GskRenderNodeType start_type, end_type;
|
||||
|
||||
start_type = gsk_render_node_get_node_type (start);
|
||||
end_type = gsk_render_node_get_node_type (end);
|
||||
|
||||
if (start_type == end_type)
|
||||
{
|
||||
switch (start_type)
|
||||
{
|
||||
case GSK_COLOR_NODE:
|
||||
{
|
||||
GdkRGBA rgba;
|
||||
graphene_rect_t start_bounds, end_bounds, bounds;
|
||||
|
||||
rgba_transform (&rgba, gsk_color_node_get_color (start), gsk_color_node_get_color (end), progress);
|
||||
gsk_render_node_get_bounds (start, &start_bounds);
|
||||
gsk_render_node_get_bounds (end, &end_bounds);
|
||||
graphene_rect_interpolate (&start_bounds, &end_bounds, progress, &bounds);
|
||||
return gsk_color_node_new (&rgba, &bounds);
|
||||
}
|
||||
|
||||
case GSK_CAIRO_NODE:
|
||||
case GSK_TEXT_NODE:
|
||||
case GSK_TEXTURE_NODE:
|
||||
case GSK_TEXTURE_SCALE_NODE:
|
||||
case GSK_LINEAR_GRADIENT_NODE:
|
||||
case GSK_REPEATING_LINEAR_GRADIENT_NODE:
|
||||
case GSK_RADIAL_GRADIENT_NODE:
|
||||
case GSK_REPEATING_RADIAL_GRADIENT_NODE:
|
||||
case GSK_CONIC_GRADIENT_NODE:
|
||||
case GSK_BORDER_NODE:
|
||||
case GSK_INSET_SHADOW_NODE:
|
||||
case GSK_OUTSET_SHADOW_NODE:
|
||||
case GSK_TRANSFORM_NODE:
|
||||
case GSK_OPACITY_NODE:
|
||||
case GSK_COLOR_MATRIX_NODE:
|
||||
case GSK_BLUR_NODE:
|
||||
case GSK_REPEAT_NODE:
|
||||
case GSK_CLIP_NODE:
|
||||
case GSK_ROUNDED_CLIP_NODE:
|
||||
case GSK_SHADOW_NODE:
|
||||
case GSK_BLEND_NODE:
|
||||
case GSK_MASK_NODE:
|
||||
case GSK_CROSS_FADE_NODE:
|
||||
case GSK_GL_SHADER_NODE:
|
||||
case GSK_CONTAINER_NODE:
|
||||
case GSK_DEBUG_NODE:
|
||||
break;
|
||||
|
||||
case GSK_NOT_A_RENDER_NODE:
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return gsk_cross_fade_node_new (start, end, progress);
|
||||
}
|
||||
|
||||
static void
|
||||
update_compare (NodeEditorWindow *self)
|
||||
{
|
||||
GdkPaintable *from, *to;
|
||||
GtkSnapshot *snapshot;
|
||||
GskRenderNode *node, *node_from, *node_to;
|
||||
GBytes *bytes;
|
||||
guint n;
|
||||
|
||||
n = g_list_model_get_n_items (G_LIST_MODEL (self->saved_nodes));
|
||||
|
||||
from = g_list_model_get_item (G_LIST_MODEL (self->saved_nodes), n - 3);
|
||||
snapshot = gtk_snapshot_new ();
|
||||
gdk_paintable_snapshot (from, snapshot, gdk_paintable_get_intrinsic_width (from), gdk_paintable_get_intrinsic_height (from));
|
||||
node_from = gtk_snapshot_free_to_node (snapshot);
|
||||
g_object_unref (from);
|
||||
|
||||
to = g_list_model_get_item (G_LIST_MODEL (self->saved_nodes), n - 2);
|
||||
snapshot = gtk_snapshot_new ();
|
||||
gdk_paintable_snapshot (to, snapshot, gdk_paintable_get_intrinsic_width (to), gdk_paintable_get_intrinsic_height (to));
|
||||
node_to = gtk_snapshot_free_to_node (snapshot);
|
||||
g_object_unref (to);
|
||||
|
||||
node = render_node_transform (node_from, node_to, gtk_adjustment_get_value (self->compare_progress));
|
||||
|
||||
bytes = gsk_render_node_serialize (node);
|
||||
load_bytes (self, bytes, FALSE);
|
||||
|
||||
gsk_render_node_unref (node);
|
||||
gsk_render_node_unref (node_to);
|
||||
gsk_render_node_unref (node_from);
|
||||
}
|
||||
|
||||
static void
|
||||
compare_toggled_cb (GtkToggleButton *button,
|
||||
GParamSpec *pspec,
|
||||
NodeEditorWindow *self)
|
||||
{
|
||||
if (!gtk_toggle_button_get_active (button))
|
||||
return;
|
||||
|
||||
stash_current_node (self);
|
||||
|
||||
update_compare (self);
|
||||
}
|
||||
|
||||
static void
|
||||
dark_mode_cb (GtkToggleButton *button,
|
||||
GParamSpec *pspec,
|
||||
dark_mode_cb (GtkToggleButton *button,
|
||||
GParamSpec *pspec,
|
||||
NodeEditorWindow *self)
|
||||
{
|
||||
g_object_set (gtk_widget_get_settings (GTK_WIDGET (self)),
|
||||
@@ -1373,7 +1187,6 @@ node_editor_window_class_init (NodeEditorWindowClass *class)
|
||||
|
||||
gtk_widget_class_bind_template_child (widget_class, NodeEditorWindow, text_view);
|
||||
gtk_widget_class_bind_template_child (widget_class, NodeEditorWindow, picture);
|
||||
gtk_widget_class_bind_template_child (widget_class, NodeEditorWindow, compare_progress);
|
||||
gtk_widget_class_bind_template_child (widget_class, NodeEditorWindow, renderer_listbox);
|
||||
gtk_widget_class_bind_template_child (widget_class, NodeEditorWindow, testcase_popover);
|
||||
gtk_widget_class_bind_template_child (widget_class, NodeEditorWindow, testcase_error_label);
|
||||
@@ -1381,21 +1194,17 @@ node_editor_window_class_init (NodeEditorWindowClass *class)
|
||||
gtk_widget_class_bind_template_child (widget_class, NodeEditorWindow, testcase_name_entry);
|
||||
gtk_widget_class_bind_template_child (widget_class, NodeEditorWindow, testcase_save_button);
|
||||
gtk_widget_class_bind_template_child (widget_class, NodeEditorWindow, scale_scale);
|
||||
gtk_widget_class_bind_template_child (widget_class, NodeEditorWindow, saved_nodes);
|
||||
|
||||
gtk_widget_class_bind_template_callback (widget_class, text_view_query_tooltip_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, saved_node_activate_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, open_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, save_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, export_image_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, clip_image_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, testcase_save_clicked_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, testcase_name_entry_changed_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, compare_toggled_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, dark_mode_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_picture_drag_prepare_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_picture_drop_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, update_compare);
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
|
||||
@@ -157,16 +157,6 @@
|
||||
<signal name="notify::active" handler="dark_mode_cb" swapped="0"/>
|
||||
</object>
|
||||
</child>
|
||||
<child type="end">
|
||||
<object class="GtkToggleButton" id="compare_button">
|
||||
<property name="focus-on-click">0</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="has-frame">0</property>
|
||||
<property name="icon-name">emblem-synchronizing-symbolic</property>
|
||||
<property name="tooltip-text" translatable="yes">Compare the last 2 items</property>
|
||||
<signal name="notify::active" handler="compare_toggled_cb" swapped="0"/>
|
||||
</object>
|
||||
</child>
|
||||
<child type="end">
|
||||
<object class="GtkScaleButton" id="scale_scale">
|
||||
<property name="focus-on-click">0</property>
|
||||
@@ -187,150 +177,78 @@
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkListView">
|
||||
<property name="orientation">horizontal</property>
|
||||
<property name="single-click-activate">1</property>
|
||||
<property name="model">
|
||||
<object class="GtkNoSelection">
|
||||
<property name="model">
|
||||
<object class="GListStore" id="saved_nodes" />
|
||||
</property>
|
||||
<object class="GtkPaned">
|
||||
<property name="shrink-start-child">false</property>
|
||||
<property name="shrink-end-child">false</property>
|
||||
<property name="position">400</property>
|
||||
<property name="start-child">
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="hscrollbar-policy">never</property>
|
||||
<property name="hexpand">1</property>
|
||||
<property name="vexpand">1</property>
|
||||
<child>
|
||||
<object class="GtkTextView" id="text_view">
|
||||
<property name="wrap-mode">word</property>
|
||||
<property name="monospace">1</property>
|
||||
<property name="top-margin">6</property>
|
||||
<property name="left-margin">6</property>
|
||||
<property name="right-margin">6</property>
|
||||
<property name="bottom-margin">6</property>
|
||||
<property name="has-tooltip">1</property>
|
||||
<signal name="query-tooltip" handler="text_view_query_tooltip_cb"/>
|
||||
<style>
|
||||
<class name="editor" />
|
||||
</style>
|
||||
</object>
|
||||
</property>
|
||||
<property name="factory">
|
||||
<object class="GtkBuilderListItemFactory">
|
||||
<property name="bytes"><![CDATA[
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="GtkListItem">
|
||||
<property name="child">
|
||||
<object class="GtkImage">
|
||||
<property name="icon-size">large</property>
|
||||
<binding name="paintable">
|
||||
<lookup name="item">GtkListItem</lookup>
|
||||
</binding>
|
||||
</object>
|
||||
</property>
|
||||
</template>
|
||||
</interface>
|
||||
]]></property>
|
||||
</object>
|
||||
</property>
|
||||
<signal name="activate" handler="saved_node_activate_cb"/>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkPaned">
|
||||
<property name="shrink-start-child">false</property>
|
||||
<property name="shrink-end-child">false</property>
|
||||
<property name="position">400</property>
|
||||
<property name="start-child">
|
||||
</property>
|
||||
<property name="end-child">
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="hscrollbar-policy">never</property>
|
||||
<property name="hexpand">1</property>
|
||||
<property name="vexpand">1</property>
|
||||
<property name="min-content-height">100</property>
|
||||
<property name="min-content-width">100</property>
|
||||
<child>
|
||||
<object class="GtkTextView" id="text_view">
|
||||
<property name="wrap-mode">word</property>
|
||||
<property name="monospace">1</property>
|
||||
<property name="top-margin">6</property>
|
||||
<property name="left-margin">6</property>
|
||||
<property name="right-margin">6</property>
|
||||
<property name="bottom-margin">6</property>
|
||||
<property name="has-tooltip">1</property>
|
||||
<signal name="query-tooltip" handler="text_view_query_tooltip_cb"/>
|
||||
<style>
|
||||
<class name="editor" />
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
<property name="end-child">
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkOverlay">
|
||||
<object class="GtkViewport">
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="hexpand">1</property>
|
||||
<property name="vexpand">1</property>
|
||||
<property name="min-content-height">100</property>
|
||||
<property name="min-content-width">100</property>
|
||||
<object class="GtkPicture" id="picture">
|
||||
<property name="can-shrink">0</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">center</property>
|
||||
<child>
|
||||
<object class="GtkViewport">
|
||||
<child>
|
||||
<object class="GtkPicture" id="picture">
|
||||
<property name="can-shrink">0</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">center</property>
|
||||
<child>
|
||||
<object class="GtkDragSource">
|
||||
<property name="actions">copy</property>
|
||||
<signal name="prepare" handler="on_picture_drag_prepare_cb" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkDropTargetAsync">
|
||||
<property name="actions">copy</property>
|
||||
<property name="formats">application/x-gtk-render-node</property>
|
||||
<signal name="drop" handler="on_picture_drop_cb" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<object class="GtkDragSource">
|
||||
<property name="actions">copy</property>
|
||||
<signal name="prepare" handler="on_picture_drag_prepare_cb" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="overlay">
|
||||
<object class="GtkBox">
|
||||
<property name="margin-top">16</property>
|
||||
<property name="margin-start">16</property>
|
||||
<property name="margin-end">16</property>
|
||||
<property name="margin-bottom">16</property>
|
||||
<property name="halign">fill</property>
|
||||
<property name="valign">end</property>
|
||||
<property name="visible" bind-source="compare_button" bind-property="active">0</property>
|
||||
<style>
|
||||
<class name="osd" />
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkScale">
|
||||
<property name="width-request">200</property>
|
||||
<property name="draw-value">0</property>
|
||||
<property name="adjustment">
|
||||
<object class="GtkAdjustment" id="compare_progress">
|
||||
<property name="upper">1</property>
|
||||
<property name="value">0.5</property>
|
||||
<property name="step-increment">0.01</property>
|
||||
<property name="page-increment">0.1</property>
|
||||
<signal name="notify::value" handler="update_compare" swapped="yes"/>
|
||||
</object>
|
||||
</property>
|
||||
<property name="hexpand">1</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="hscrollbar-policy">never</property>
|
||||
<child>
|
||||
<object class="GtkListBox" id="renderer_listbox">
|
||||
<property name="selection-mode">none</property>
|
||||
<object class="GtkDropTargetAsync">
|
||||
<property name="actions">copy</property>
|
||||
<property name="formats">application/x-gtk-render-node</property>
|
||||
<signal name="drop" handler="on_picture_drop_cb" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="hscrollbar-policy">never</property>
|
||||
<child>
|
||||
<object class="GtkListBox" id="renderer_listbox">
|
||||
<property name="selection-mode">none</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
|
||||
@@ -68,7 +68,6 @@ ui_files = [
|
||||
'stackswitcher.ui',
|
||||
'statusbar.ui',
|
||||
'switch.ui',
|
||||
'switch-state.ui',
|
||||
'toggle-button.ui',
|
||||
'video.ui',
|
||||
'volumebutton.ui',
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 3.6 KiB |
@@ -1,43 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<object class="GtkWindow">
|
||||
<property name="decorated">0</property>
|
||||
<property name="resizable">0</property>
|
||||
<property name="default-width">280</property>
|
||||
<property name="default-height">120</property>
|
||||
<style>
|
||||
<class name="nobackground"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<style>
|
||||
<class name="shadow"/>
|
||||
<class name="background"/>
|
||||
<class name="frame"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">3</property>
|
||||
<property name="hexpand">1</property>
|
||||
<property name="vexpand">1</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">center</property>
|
||||
<child>
|
||||
<object class="GtkSwitch">
|
||||
<property name="active">1</property>
|
||||
<property name="state">0</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSwitch">
|
||||
<property name="active">0</property>
|
||||
<property name="state">1</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
||||
@@ -875,10 +875,10 @@ reference.
|
||||
### Adapt to coordinate API changes
|
||||
|
||||
A number of APIs that are accepting or returning coordinates have
|
||||
been changed from `int`s to `double`s: `gtk_widget_translate_coordinates()`,
|
||||
been changed from ints to doubles: `gtk_widget_translate_coordinates()`,
|
||||
`gtk_fixed_put()`, `gtk_fixed_move()`. This change is mostly transparent,
|
||||
except for cases where out parameters are involved: you need to
|
||||
pass `double*` now, instead of `int*`.
|
||||
pass double* now, instead of int*.
|
||||
|
||||
### Adapt to GtkStyleContext API changes
|
||||
|
||||
|
||||
@@ -132,4 +132,6 @@ use `gtk_widget_compute_bounds (widget, widget, &bounds)` instead.
|
||||
The function gtk_widget_get_allocation() is also going away. It does not have a direct
|
||||
replacement, but the previously mentioned alternatives can be used for it too.
|
||||
|
||||
gtk_widget_translate_coordinates90 has been replaced by [method@Gtk.Widget.compute_point].
|
||||
|
||||
The function gtk_widget_get_allocated_baseline() has been renamed to [method@Gtk.Widget.get_baseline].
|
||||
|
||||
@@ -437,7 +437,7 @@ gdk_display_manager_open_display (GdkDisplayManager *manager,
|
||||
}
|
||||
}
|
||||
|
||||
if (!found && !any && !display)
|
||||
if (!found && !display)
|
||||
g_warning ("No such backend: %s", backend);
|
||||
}
|
||||
|
||||
|
||||
@@ -223,7 +223,7 @@ gdk_vulkan_strerror (VkResult result)
|
||||
#if VK_HEADER_VERSION < 140
|
||||
case VK_RESULT_RANGE_SIZE:
|
||||
#endif
|
||||
#if VK_HEADER_VERSION >= 238
|
||||
#if VK_HEADER_VERSION >= 218
|
||||
case VK_ERROR_IMAGE_USAGE_NOT_SUPPORTED_KHR:
|
||||
return "The requested VkImageUsageFlags are not supported. (VK_ERROR_IMAGE_USAGE_NOT_SUPPORTED_KHR)";
|
||||
case VK_ERROR_VIDEO_PICTURE_LAYOUT_NOT_SUPPORTED_KHR:
|
||||
|
||||
@@ -356,8 +356,7 @@ gsk_gl_renderer_render_texture (GskRenderer *renderer,
|
||||
for (x = 0; x < width; x += max_size)
|
||||
{
|
||||
texture = gsk_gl_renderer_render_texture (renderer, root,
|
||||
&GRAPHENE_RECT_INIT (viewport->origin.x + x,
|
||||
viewport->origin.y + y,
|
||||
&GRAPHENE_RECT_INIT (x, y,
|
||||
MIN (max_size, viewport->size.width - x),
|
||||
MIN (max_size, viewport->size.height - y)));
|
||||
gdk_texture_download (texture,
|
||||
|
||||
+155
-164
@@ -54,6 +54,27 @@
|
||||
/* Make sure gradient stops fits in packed array_count */
|
||||
G_STATIC_ASSERT ((MAX_GRADIENT_STOPS * 5) < (1 << GSK_GL_UNIFORM_ARRAY_BITS));
|
||||
|
||||
#define rounded_rect_top_left(r) \
|
||||
(GRAPHENE_RECT_INIT(r->bounds.origin.x, \
|
||||
r->bounds.origin.y, \
|
||||
r->corner[0].width, r->corner[0].height))
|
||||
#define rounded_rect_top_right(r) \
|
||||
(GRAPHENE_RECT_INIT(r->bounds.origin.x + r->bounds.size.width - r->corner[1].width, \
|
||||
r->bounds.origin.y, \
|
||||
r->corner[1].width, r->corner[1].height))
|
||||
#define rounded_rect_bottom_right(r) \
|
||||
(GRAPHENE_RECT_INIT(r->bounds.origin.x + r->bounds.size.width - r->corner[2].width, \
|
||||
r->bounds.origin.y + r->bounds.size.height - r->corner[2].height, \
|
||||
r->corner[2].width, r->corner[2].height))
|
||||
#define rounded_rect_bottom_left(r) \
|
||||
(GRAPHENE_RECT_INIT(r->bounds.origin.x, \
|
||||
r->bounds.origin.y + r->bounds.size.height - r->corner[2].height, \
|
||||
r->corner[3].width, r->corner[3].height))
|
||||
#define rounded_rect_corner0(r) rounded_rect_top_left(r)
|
||||
#define rounded_rect_corner1(r) rounded_rect_top_right(r)
|
||||
#define rounded_rect_corner2(r) rounded_rect_bottom_right(r)
|
||||
#define rounded_rect_corner3(r) rounded_rect_bottom_left(r)
|
||||
#define rounded_rect_corner(r, i) (rounded_rect_corner##i(r))
|
||||
#define ALPHA_IS_CLEAR(alpha) ((alpha) < ((float) 0x00ff / (float) 0xffff))
|
||||
#define RGBA_IS_CLEAR(rgba) ALPHA_IS_CLEAR((rgba)->alpha)
|
||||
|
||||
@@ -408,6 +429,70 @@ rect_intersects (const graphene_rect_t *r1,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
rounded_rect_has_corner (const GskRoundedRect *r,
|
||||
guint i)
|
||||
{
|
||||
return r->corner[i].width > 0 && r->corner[i].height > 0;
|
||||
}
|
||||
|
||||
/* Current clip is NOT rounded but new one is definitely! */
|
||||
static inline gboolean
|
||||
intersect_rounded_rectilinear (const graphene_rect_t *non_rounded,
|
||||
const GskRoundedRect *rounded,
|
||||
GskRoundedRect *result)
|
||||
{
|
||||
gboolean corners[4];
|
||||
|
||||
/* Intersects with top left corner? */
|
||||
corners[0] = rounded_rect_has_corner (rounded, 0) &&
|
||||
rect_intersects (non_rounded,
|
||||
&rounded_rect_corner (rounded, 0));
|
||||
if (corners[0] && !rect_contains_rect (non_rounded,
|
||||
&rounded_rect_corner (rounded, 0)))
|
||||
return FALSE;
|
||||
|
||||
/* top right ? */
|
||||
corners[1] = rounded_rect_has_corner (rounded, 1) &&
|
||||
rect_intersects (non_rounded,
|
||||
&rounded_rect_corner (rounded, 1));
|
||||
if (corners[1] && !rect_contains_rect (non_rounded,
|
||||
&rounded_rect_corner (rounded, 1)))
|
||||
return FALSE;
|
||||
|
||||
/* bottom right ? */
|
||||
corners[2] = rounded_rect_has_corner (rounded, 2) &&
|
||||
rect_intersects (non_rounded,
|
||||
&rounded_rect_corner (rounded, 2));
|
||||
if (corners[2] && !rect_contains_rect (non_rounded,
|
||||
&rounded_rect_corner (rounded, 2)))
|
||||
return FALSE;
|
||||
|
||||
/* bottom left ? */
|
||||
corners[3] = rounded_rect_has_corner (rounded, 3) &&
|
||||
rect_intersects (non_rounded,
|
||||
&rounded_rect_corner (rounded, 3));
|
||||
if (corners[3] && !rect_contains_rect (non_rounded,
|
||||
&rounded_rect_corner (rounded, 3)))
|
||||
return FALSE;
|
||||
|
||||
/* We do intersect with at least one of the corners, but in such a way that the
|
||||
* intersection between the two clips can still be represented by a single rounded
|
||||
* rect in a trivial way. do that.
|
||||
*/
|
||||
graphene_rect_intersection (non_rounded, &rounded->bounds, &result->bounds);
|
||||
|
||||
for (guint i = 0; i < 4; i++)
|
||||
{
|
||||
if (corners[i])
|
||||
result->corner[i] = rounded->corner[i];
|
||||
else
|
||||
result->corner[i].width = result->corner[i].height = 0;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static inline void
|
||||
init_projection_matrix (graphene_matrix_t *projection,
|
||||
const graphene_rect_t *viewport)
|
||||
@@ -466,14 +551,13 @@ extract_matrix_metadata (GskGLRenderModelview *modelview)
|
||||
|
||||
case GSK_TRANSFORM_CATEGORY_2D:
|
||||
{
|
||||
float skew_x, skew_y, angle, dx, dy;
|
||||
float xx, xy, yx, yy, dx, dy;
|
||||
|
||||
gsk_transform_to_2d_components (modelview->transform,
|
||||
&skew_x, &skew_y,
|
||||
&modelview->scale_x, &modelview->scale_y,
|
||||
&angle, &dx, &dy);
|
||||
modelview->dx = 0;
|
||||
modelview->dy = 0;
|
||||
gsk_transform_to_2d (modelview->transform,
|
||||
&xx, &xy, &yx, &yy, &dx, &dy);
|
||||
|
||||
modelview->scale_x = sqrtf (xx * xx + xy * xy);
|
||||
modelview->scale_y = sqrtf (yx * yx + yy * yy);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -834,10 +918,10 @@ gsk_gl_render_job_untransform_bounds (GskGLRenderJob *job,
|
||||
}
|
||||
|
||||
static inline void
|
||||
gsk_gl_render_job_translate_rounded_rect (GskGLRenderJob *job,
|
||||
gsk_gl_render_job_transform_rounded_rect (GskGLRenderJob *job,
|
||||
const GskRoundedRect *rect,
|
||||
GskRoundedRect *out_rect)
|
||||
{
|
||||
{
|
||||
out_rect->bounds.origin.x = job->offset_x + rect->bounds.origin.x;
|
||||
out_rect->bounds.origin.y = job->offset_y + rect->bounds.origin.y;
|
||||
out_rect->bounds.size.width = rect->bounds.size.width;
|
||||
@@ -845,52 +929,6 @@ gsk_gl_render_job_translate_rounded_rect (GskGLRenderJob *job,
|
||||
memcpy (out_rect->corner, rect->corner, sizeof rect->corner);
|
||||
}
|
||||
|
||||
static inline void
|
||||
rounded_rect_scale_corners (const GskRoundedRect *rect,
|
||||
GskRoundedRect *out_rect,
|
||||
float scale_x,
|
||||
float scale_y)
|
||||
{
|
||||
for (guint i = 0; i < G_N_ELEMENTS (out_rect->corner); i++)
|
||||
{
|
||||
out_rect->corner[i].width = rect->corner[i].width * fabs (scale_x);
|
||||
out_rect->corner[i].height = rect->corner[i].height * fabs (scale_y);
|
||||
}
|
||||
|
||||
if (scale_x < 0)
|
||||
{
|
||||
graphene_size_t p;
|
||||
|
||||
p = out_rect->corner[GSK_CORNER_TOP_LEFT];
|
||||
out_rect->corner[GSK_CORNER_TOP_LEFT] = out_rect->corner[GSK_CORNER_TOP_RIGHT];
|
||||
out_rect->corner[GSK_CORNER_TOP_RIGHT] = p;
|
||||
p = out_rect->corner[GSK_CORNER_BOTTOM_LEFT];
|
||||
out_rect->corner[GSK_CORNER_BOTTOM_LEFT] = out_rect->corner[GSK_CORNER_BOTTOM_RIGHT];
|
||||
out_rect->corner[GSK_CORNER_BOTTOM_RIGHT] = p;
|
||||
}
|
||||
|
||||
if (scale_y < 0)
|
||||
{
|
||||
graphene_size_t p;
|
||||
|
||||
p = out_rect->corner[GSK_CORNER_TOP_LEFT];
|
||||
out_rect->corner[GSK_CORNER_TOP_LEFT] = out_rect->corner[GSK_CORNER_BOTTOM_LEFT];
|
||||
out_rect->corner[GSK_CORNER_BOTTOM_LEFT] = p;
|
||||
p = out_rect->corner[GSK_CORNER_TOP_RIGHT];
|
||||
out_rect->corner[GSK_CORNER_TOP_RIGHT] = out_rect->corner[GSK_CORNER_BOTTOM_RIGHT];
|
||||
out_rect->corner[GSK_CORNER_BOTTOM_RIGHT] = p;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
gsk_gl_render_job_transform_rounded_rect (GskGLRenderJob *job,
|
||||
const GskRoundedRect *rect,
|
||||
GskRoundedRect *out_rect)
|
||||
{
|
||||
gsk_gl_render_job_transform_bounds (job, &rect->bounds, &out_rect->bounds);
|
||||
rounded_rect_scale_corners (rect, out_rect, job->scale_x, job->scale_y);
|
||||
}
|
||||
|
||||
static inline void
|
||||
rounded_rect_get_inner (const GskRoundedRect *rect,
|
||||
graphene_rect_t *inner)
|
||||
@@ -1193,12 +1231,13 @@ gsk_gl_render_job_visit_as_fallback (GskGLRenderJob *job,
|
||||
{
|
||||
float scale_x = job->scale_x;
|
||||
float scale_y = job->scale_y;
|
||||
int surface_width = ceilf (node->bounds.size.width * fabs (scale_x));
|
||||
int surface_height = ceilf (node->bounds.size.height * fabs (scale_y));
|
||||
int surface_width = ceilf (node->bounds.size.width * scale_x);
|
||||
int surface_height = ceilf (node->bounds.size.height * scale_y);
|
||||
GdkTexture *texture;
|
||||
cairo_surface_t *surface;
|
||||
cairo_surface_t *rendered_surface;
|
||||
cairo_t *cr;
|
||||
int cached_id;
|
||||
int texture_id;
|
||||
GskTextureKey key;
|
||||
|
||||
@@ -1210,10 +1249,18 @@ gsk_gl_render_job_visit_as_fallback (GskGLRenderJob *job,
|
||||
key.scale_x = scale_x;
|
||||
key.scale_y = scale_y;
|
||||
|
||||
texture_id = gsk_gl_driver_lookup_texture (job->driver, &key);
|
||||
cached_id = gsk_gl_driver_lookup_texture (job->driver, &key);
|
||||
|
||||
if (texture_id != 0)
|
||||
goto done;
|
||||
if (cached_id != 0)
|
||||
{
|
||||
gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, blit));
|
||||
gsk_gl_program_set_uniform_texture (job->current_program,
|
||||
UNIFORM_SHARED_SOURCE, 0,
|
||||
GL_TEXTURE_2D, GL_TEXTURE0, cached_id);
|
||||
gsk_gl_render_job_draw_offscreen_rect (job, &node->bounds);
|
||||
gsk_gl_render_job_end_draw (job);
|
||||
return;
|
||||
}
|
||||
|
||||
/* We first draw the recording surface on an image surface,
|
||||
* just because the scaleY(-1) later otherwise screws up the
|
||||
@@ -1223,7 +1270,7 @@ gsk_gl_render_job_visit_as_fallback (GskGLRenderJob *job,
|
||||
surface_width,
|
||||
surface_height);
|
||||
|
||||
cairo_surface_set_device_scale (rendered_surface, fabs (scale_x), fabs (scale_y));
|
||||
cairo_surface_set_device_scale (rendered_surface, scale_x, scale_y);
|
||||
cr = cairo_create (rendered_surface);
|
||||
|
||||
cairo_save (cr);
|
||||
@@ -1237,16 +1284,15 @@ gsk_gl_render_job_visit_as_fallback (GskGLRenderJob *job,
|
||||
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
|
||||
surface_width,
|
||||
surface_height);
|
||||
cairo_surface_set_device_scale (surface, fabs (scale_x), fabs (scale_y));
|
||||
cairo_surface_set_device_scale (surface, scale_x, scale_y);
|
||||
cr = cairo_create (surface);
|
||||
|
||||
/* We draw upside down here, so it matches what GL does. */
|
||||
cairo_save (cr);
|
||||
cairo_scale (cr, scale_x < 0 ? -1 : 1, scale_y < 0 ? 1 : -1);
|
||||
cairo_translate (cr, scale_x < 0 ? - surface_width / fabs (scale_x) : 0,
|
||||
scale_y < 0 ? 0 : - surface_height / fabs (scale_y));
|
||||
cairo_scale (cr, 1, -1);
|
||||
cairo_translate (cr, 0, - surface_height / scale_y);
|
||||
cairo_set_source_surface (cr, rendered_surface, 0, 0);
|
||||
cairo_rectangle (cr, 0, 0, surface_width / fabs (scale_x), surface_height / fabs (scale_y));
|
||||
cairo_rectangle (cr, 0, 0, surface_width / scale_x, surface_height / scale_y);
|
||||
cairo_fill (cr);
|
||||
cairo_restore (cr);
|
||||
|
||||
@@ -1285,16 +1331,6 @@ gsk_gl_render_job_visit_as_fallback (GskGLRenderJob *job,
|
||||
|
||||
gsk_gl_driver_cache_texture (job->driver, &key, texture_id);
|
||||
|
||||
done:
|
||||
if (scale_x < 0 || scale_y < 0)
|
||||
{
|
||||
GskTransform *transform = gsk_transform_translate (NULL,
|
||||
&GRAPHENE_POINT_INIT (scale_x < 0 ? - surface_width : 0,
|
||||
scale_y < 0 ? - surface_height : 0));
|
||||
gsk_gl_render_job_push_modelview (job, transform);
|
||||
gsk_transform_unref (transform);
|
||||
}
|
||||
|
||||
gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, blit));
|
||||
gsk_gl_program_set_uniform_texture (job->current_program,
|
||||
UNIFORM_SHARED_SOURCE, 0,
|
||||
@@ -1303,9 +1339,6 @@ done:
|
||||
texture_id);
|
||||
gsk_gl_render_job_draw_offscreen_rect (job, &node->bounds);
|
||||
gsk_gl_render_job_end_draw (job);
|
||||
|
||||
if (scale_x < 0 || scale_y < 0)
|
||||
gsk_gl_render_job_pop_modelview (job);
|
||||
}
|
||||
|
||||
static guint
|
||||
@@ -1460,10 +1493,10 @@ blur_node (GskGLRenderJob *job,
|
||||
|
||||
offscreen->texture_id = blur_offscreen (job,
|
||||
offscreen,
|
||||
texture_width * fabs (scale_x),
|
||||
texture_height * fabs (scale_y),
|
||||
blur_radius * fabs (scale_x),
|
||||
blur_radius * fabs (scale_y));
|
||||
texture_width * scale_x,
|
||||
texture_height * scale_y,
|
||||
blur_radius * scale_x,
|
||||
blur_radius * scale_y);
|
||||
init_full_texture_region (offscreen);
|
||||
}
|
||||
|
||||
@@ -1645,7 +1678,6 @@ gsk_gl_render_job_visit_clipped_child (GskGLRenderJob *job,
|
||||
{
|
||||
graphene_rect_t transformed_clip;
|
||||
GskRoundedRect intersection;
|
||||
GskRoundedRectIntersection result;
|
||||
|
||||
gsk_gl_render_job_transform_bounds (job, clip, &transformed_clip);
|
||||
|
||||
@@ -1659,17 +1691,10 @@ gsk_gl_render_job_visit_clipped_child (GskGLRenderJob *job,
|
||||
gsk_gl_render_job_push_clip (job, &intersection);
|
||||
gsk_gl_render_job_visit_node (job, child);
|
||||
gsk_gl_render_job_pop_clip (job);
|
||||
return;
|
||||
}
|
||||
|
||||
result = gsk_rounded_rect_intersect_with_rect (&job->current_clip->rect,
|
||||
&transformed_clip,
|
||||
&intersection);
|
||||
|
||||
if (result == GSK_INTERSECTION_EMPTY)
|
||||
return;
|
||||
|
||||
if (result == GSK_INTERSECTION_NONEMPTY)
|
||||
else if (intersect_rounded_rectilinear (&transformed_clip,
|
||||
&job->current_clip->rect,
|
||||
&intersection))
|
||||
{
|
||||
gsk_gl_render_job_push_clip (job, &intersection);
|
||||
gsk_gl_render_job_visit_node (job, child);
|
||||
@@ -1716,26 +1741,28 @@ gsk_gl_render_job_visit_rounded_clip_node (GskGLRenderJob *job,
|
||||
const GskRenderNode *child = gsk_rounded_clip_node_get_child (node);
|
||||
const GskRoundedRect *clip = gsk_rounded_clip_node_get_clip (node);
|
||||
GskRoundedRect transformed_clip;
|
||||
float scale_x = job->scale_x;
|
||||
float scale_y = job->scale_y;
|
||||
gboolean need_offscreen;
|
||||
|
||||
if (node_is_invisible (child))
|
||||
return;
|
||||
|
||||
gsk_gl_render_job_transform_rounded_rect (job, clip, &transformed_clip);
|
||||
gsk_gl_render_job_transform_bounds (job, &clip->bounds, &transformed_clip.bounds);
|
||||
|
||||
for (guint i = 0; i < G_N_ELEMENTS (transformed_clip.corner); i++)
|
||||
{
|
||||
transformed_clip.corner[i].width = clip->corner[i].width * scale_x;
|
||||
transformed_clip.corner[i].height = clip->corner[i].height * scale_y;
|
||||
}
|
||||
|
||||
if (job->current_clip->is_rectilinear)
|
||||
{
|
||||
GskRoundedRect intersected_clip;
|
||||
GskRoundedRectIntersection result;
|
||||
|
||||
result = gsk_rounded_rect_intersect_with_rect (&transformed_clip,
|
||||
&job->current_clip->rect.bounds,
|
||||
&intersected_clip);
|
||||
|
||||
if (result == GSK_INTERSECTION_EMPTY)
|
||||
return;
|
||||
|
||||
if (result == GSK_INTERSECTION_NONEMPTY)
|
||||
if (intersect_rounded_rectilinear (&job->current_clip->rect.bounds,
|
||||
&transformed_clip,
|
||||
&intersected_clip))
|
||||
{
|
||||
gsk_gl_render_job_push_clip (job, &intersected_clip);
|
||||
gsk_gl_render_job_visit_node (job, child);
|
||||
@@ -1887,7 +1914,7 @@ gsk_gl_render_job_visit_border_node (GskGLRenderJob *job,
|
||||
sizes[3].w = MAX (widths[3], rounded_outline->corner[3].width);
|
||||
}
|
||||
|
||||
gsk_gl_render_job_translate_rounded_rect (job, rounded_outline, &outline);
|
||||
gsk_gl_render_job_transform_rounded_rect (job, rounded_outline, &outline);
|
||||
|
||||
gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, border));
|
||||
|
||||
@@ -1991,7 +2018,7 @@ gsk_gl_render_job_visit_css_background (GskGLRenderJob *job,
|
||||
rgba_to_half (&gsk_border_node_get_colors (node2)[0], color);
|
||||
rgba_to_half (gsk_color_node_get_color (child), color2);
|
||||
|
||||
gsk_gl_render_job_translate_rounded_rect (job, rounded_outline, &outline);
|
||||
gsk_gl_render_job_transform_rounded_rect (job, rounded_outline, &outline);
|
||||
|
||||
gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, filled_border));
|
||||
|
||||
@@ -2132,7 +2159,6 @@ gsk_gl_render_job_visit_transform_node (GskGLRenderJob *job,
|
||||
scale = gsk_transform_translate (gsk_transform_scale (NULL, sx, sy), &GRAPHENE_POINT_INIT (tx, ty));
|
||||
gsk_gl_render_job_push_modelview (job, scale);
|
||||
transform = gsk_transform_transform (gsk_transform_invert (scale), transform);
|
||||
gsk_transform_unref (scale);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2183,7 +2209,7 @@ gsk_gl_render_job_visit_unblurred_inset_shadow_node (GskGLRenderJob *job,
|
||||
GskRoundedRect transformed_outline;
|
||||
guint16 color[4];
|
||||
|
||||
gsk_gl_render_job_translate_rounded_rect (job, outline, &transformed_outline);
|
||||
gsk_gl_render_job_transform_rounded_rect (job, outline, &transformed_outline);
|
||||
|
||||
gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, inset_shadow));
|
||||
gsk_gl_program_set_uniform_rounded_rect (job->current_program,
|
||||
@@ -2283,7 +2309,7 @@ gsk_gl_render_job_visit_blurred_inset_shadow_node (GskGLRenderJob *job,
|
||||
prev_fbo = gsk_gl_command_queue_bind_framebuffer (job->command_queue, render_target->framebuffer_id);
|
||||
gsk_gl_command_queue_clear (job->command_queue, 0, &job->viewport);
|
||||
|
||||
gsk_gl_render_job_translate_rounded_rect (job, &outline_to_blur, &transformed_outline);
|
||||
gsk_gl_render_job_transform_rounded_rect (job, &outline_to_blur, &transformed_outline);
|
||||
|
||||
/* Actual inset shadow outline drawing */
|
||||
gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, inset_shadow));
|
||||
@@ -2316,8 +2342,8 @@ gsk_gl_render_job_visit_blurred_inset_shadow_node (GskGLRenderJob *job,
|
||||
&offscreen,
|
||||
texture_width,
|
||||
texture_height,
|
||||
blur_radius * fabs (scale_x),
|
||||
blur_radius * fabs (scale_y));
|
||||
blur_radius * scale_x,
|
||||
blur_radius * scale_y);
|
||||
|
||||
gsk_gl_driver_release_render_target (job->driver, render_target, TRUE);
|
||||
|
||||
@@ -2339,7 +2365,14 @@ gsk_gl_render_job_visit_blurred_inset_shadow_node (GskGLRenderJob *job,
|
||||
{
|
||||
GskRoundedRect node_clip;
|
||||
|
||||
gsk_gl_render_job_translate_rounded_rect (job, node_outline, &node_clip);
|
||||
gsk_gl_render_job_transform_bounds (job, &node_outline->bounds, &node_clip.bounds);
|
||||
|
||||
for (guint i = 0; i < 4; i ++)
|
||||
{
|
||||
node_clip.corner[i].width = node_outline->corner[i].width * scale_x;
|
||||
node_clip.corner[i].height = node_outline->corner[i].height * scale_y;
|
||||
}
|
||||
|
||||
gsk_gl_render_job_push_clip (job, &node_clip);
|
||||
}
|
||||
|
||||
@@ -2389,7 +2422,7 @@ gsk_gl_render_job_visit_unblurred_outset_shadow_node (GskGLRenderJob *job,
|
||||
|
||||
rgba_to_half (gsk_outset_shadow_node_get_color (node), color);
|
||||
|
||||
gsk_gl_render_job_translate_rounded_rect (job, outline, &transformed_outline);
|
||||
gsk_gl_render_job_transform_rounded_rect (job, outline, &transformed_outline);
|
||||
|
||||
gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, unblurred_outset_shadow));
|
||||
gsk_gl_program_set_uniform_rounded_rect (job->current_program,
|
||||
@@ -2582,8 +2615,8 @@ gsk_gl_render_job_visit_blurred_outset_shadow_node (GskGLRenderJob *job,
|
||||
&offscreen,
|
||||
texture_width,
|
||||
texture_height,
|
||||
blur_radius * fabs (scale_x),
|
||||
blur_radius * fabs (scale_y));
|
||||
blur_radius * scale_x,
|
||||
blur_radius * scale_y);
|
||||
|
||||
gsk_gl_shadow_library_insert (job->driver->shadows_library,
|
||||
&scaled_outline,
|
||||
@@ -2597,7 +2630,7 @@ gsk_gl_render_job_visit_blurred_outset_shadow_node (GskGLRenderJob *job,
|
||||
blurred_texture_id = cached_tid;
|
||||
}
|
||||
|
||||
gsk_gl_render_job_translate_rounded_rect (job, outline, &transformed_outline);
|
||||
gsk_gl_render_job_transform_rounded_rect (job, outline, &transformed_outline);
|
||||
|
||||
if (!do_slicing)
|
||||
{
|
||||
@@ -2833,12 +2866,8 @@ gsk_gl_render_job_visit_cross_fade_node (GskGLRenderJob *job,
|
||||
offscreen_end.reset_clip = TRUE;
|
||||
offscreen_end.bounds = &node->bounds;
|
||||
|
||||
gsk_gl_render_job_set_modelview (job, NULL);
|
||||
|
||||
if (!gsk_gl_render_job_visit_node_with_offscreen (job, start_node, &offscreen_start))
|
||||
{
|
||||
gsk_gl_render_job_pop_modelview (job);
|
||||
|
||||
gsk_gl_render_job_visit_node (job, end_node);
|
||||
return;
|
||||
}
|
||||
@@ -2847,18 +2876,12 @@ gsk_gl_render_job_visit_cross_fade_node (GskGLRenderJob *job,
|
||||
|
||||
if (!gsk_gl_render_job_visit_node_with_offscreen (job, end_node, &offscreen_end))
|
||||
{
|
||||
float prev_alpha;
|
||||
|
||||
gsk_gl_render_job_pop_modelview (job);
|
||||
|
||||
prev_alpha = gsk_gl_render_job_set_alpha (job, job->alpha * progress);
|
||||
float prev_alpha = gsk_gl_render_job_set_alpha (job, job->alpha * progress);
|
||||
gsk_gl_render_job_visit_node (job, start_node);
|
||||
gsk_gl_render_job_set_alpha (job, prev_alpha);
|
||||
return;
|
||||
}
|
||||
|
||||
gsk_gl_render_job_pop_modelview (job);
|
||||
|
||||
g_assert (offscreen_end.texture_id);
|
||||
|
||||
gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, cross_fade));
|
||||
@@ -3252,14 +3275,10 @@ gsk_gl_render_job_visit_blend_node (GskGLRenderJob *job,
|
||||
bottom_offscreen.force_offscreen = TRUE;
|
||||
bottom_offscreen.reset_clip = TRUE;
|
||||
|
||||
gsk_gl_render_job_set_modelview (job, NULL);
|
||||
|
||||
/* TODO: We create 2 textures here as big as the blend node, but both the
|
||||
* start and the end node might be a lot smaller than that. */
|
||||
if (!gsk_gl_render_job_visit_node_with_offscreen (job, bottom_child, &bottom_offscreen))
|
||||
{
|
||||
gsk_gl_render_job_pop_modelview (job);
|
||||
|
||||
gsk_gl_render_job_visit_node (job, top_child);
|
||||
return;
|
||||
}
|
||||
@@ -3268,8 +3287,6 @@ gsk_gl_render_job_visit_blend_node (GskGLRenderJob *job,
|
||||
|
||||
if (!gsk_gl_render_job_visit_node_with_offscreen (job, top_child, &top_offscreen))
|
||||
{
|
||||
gsk_gl_render_job_pop_modelview (job);
|
||||
|
||||
gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, blit));
|
||||
gsk_gl_program_set_uniform_texture (job->current_program,
|
||||
UNIFORM_SHARED_SOURCE, 0,
|
||||
@@ -3283,8 +3300,6 @@ gsk_gl_render_job_visit_blend_node (GskGLRenderJob *job,
|
||||
|
||||
g_assert (top_offscreen.was_offscreen);
|
||||
|
||||
gsk_gl_render_job_pop_modelview (job);
|
||||
|
||||
gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, blend));
|
||||
gsk_gl_program_set_uniform_texture (job->current_program,
|
||||
UNIFORM_SHARED_SOURCE, 0,
|
||||
@@ -3321,14 +3336,11 @@ gsk_gl_render_job_visit_mask_node (GskGLRenderJob *job,
|
||||
mask_offscreen.reset_clip = TRUE;
|
||||
mask_offscreen.do_not_cache = TRUE;
|
||||
|
||||
gsk_gl_render_job_set_modelview (job, NULL);
|
||||
|
||||
/* TODO: We create 2 textures here as big as the mask node, but both
|
||||
* nodes might be a lot smaller than that.
|
||||
*/
|
||||
if (!gsk_gl_render_job_visit_node_with_offscreen (job, source, &source_offscreen))
|
||||
{
|
||||
gsk_gl_render_job_pop_modelview (job);
|
||||
gsk_gl_render_job_visit_node (job, source);
|
||||
return;
|
||||
}
|
||||
@@ -3337,14 +3349,11 @@ gsk_gl_render_job_visit_mask_node (GskGLRenderJob *job,
|
||||
|
||||
if (!gsk_gl_render_job_visit_node_with_offscreen (job, mask, &mask_offscreen))
|
||||
{
|
||||
gsk_gl_render_job_pop_modelview (job);
|
||||
return;
|
||||
}
|
||||
|
||||
g_assert (mask_offscreen.was_offscreen);
|
||||
|
||||
gsk_gl_render_job_pop_modelview (job);
|
||||
|
||||
gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, mask));
|
||||
gsk_gl_program_set_uniform_texture (job->current_program,
|
||||
UNIFORM_SHARED_SOURCE, 0,
|
||||
@@ -3578,8 +3587,8 @@ gsk_gl_render_job_visit_texture (GskGLRenderJob *job,
|
||||
float scale_y = bounds->size.height / texture->height;
|
||||
gboolean use_mipmap;
|
||||
|
||||
use_mipmap = (scale_x * fabs (job->scale_x)) < 0.5 ||
|
||||
(scale_y * fabs (job->scale_y)) < 0.5;
|
||||
use_mipmap = (scale_x * job->scale_x) < 0.5 ||
|
||||
(scale_y * job->scale_y) < 0.5;
|
||||
|
||||
if G_LIKELY (texture->width <= max_texture_size &&
|
||||
texture->height <= max_texture_size)
|
||||
@@ -4111,7 +4120,7 @@ gsk_gl_render_job_visit_node_with_offscreen (GskGLRenderJob *job,
|
||||
}
|
||||
|
||||
if (gsk_render_node_get_node_type (node) == GSK_TEXTURE_NODE &&
|
||||
!offscreen->force_offscreen)
|
||||
offscreen->force_offscreen == FALSE)
|
||||
{
|
||||
GdkTexture *texture = gsk_texture_node_get_texture (node);
|
||||
gsk_gl_render_job_upload_texture (job, texture, FALSE, offscreen);
|
||||
@@ -4129,7 +4138,6 @@ gsk_gl_render_job_visit_node_with_offscreen (GskGLRenderJob *job,
|
||||
gboolean flipped_x = job->scale_x < 0;
|
||||
gboolean flipped_y = job->scale_y < 0;
|
||||
graphene_rect_t viewport;
|
||||
gboolean reset_clip = FALSE;
|
||||
|
||||
if (flipped_x || flipped_y)
|
||||
{
|
||||
@@ -4137,7 +4145,6 @@ gsk_gl_render_job_visit_node_with_offscreen (GskGLRenderJob *job,
|
||||
flipped_x ? -1 : 1,
|
||||
flipped_y ? -1 : 1);
|
||||
gsk_gl_render_job_push_modelview (job, transform);
|
||||
gsk_transform_unref (transform);
|
||||
}
|
||||
|
||||
gsk_gl_render_job_transform_bounds (job, offscreen->bounds, &viewport);
|
||||
@@ -4175,9 +4182,7 @@ gsk_gl_render_job_visit_node_with_offscreen (GskGLRenderJob *job,
|
||||
{
|
||||
GskTransform *transform = gsk_transform_scale (NULL, downscale_x, downscale_y);
|
||||
gsk_gl_render_job_push_modelview (job, transform);
|
||||
gsk_transform_unref (transform);
|
||||
gsk_gl_render_job_transform_bounds (job, offscreen->bounds, &viewport);
|
||||
graphene_rect_scale (&viewport, downscale_x, downscale_y, &viewport);
|
||||
}
|
||||
|
||||
if (downscale_x == 1)
|
||||
@@ -4261,25 +4266,11 @@ gsk_gl_render_job_visit_node_with_offscreen (GskGLRenderJob *job,
|
||||
gsk_gl_command_queue_clear (job->command_queue, 0, &job->viewport);
|
||||
|
||||
if (offscreen->reset_clip)
|
||||
{
|
||||
gsk_gl_render_job_push_clip (job, &GSK_ROUNDED_RECT_INIT_FROM_RECT (job->viewport));
|
||||
reset_clip = TRUE;
|
||||
}
|
||||
else if (flipped_x || flipped_y || downscale_x != 1 || downscale_y != 1)
|
||||
{
|
||||
GskRoundedRect new_clip;
|
||||
float scale_x = flipped_x ? - downscale_x : downscale_x;
|
||||
float scale_y = flipped_y ? - downscale_y : downscale_y;
|
||||
|
||||
graphene_rect_scale (&job->current_clip->rect.bounds, scale_x, scale_y, &new_clip.bounds);
|
||||
rounded_rect_scale_corners (&job->current_clip->rect, &new_clip, scale_x, scale_y);
|
||||
gsk_gl_render_job_push_clip (job, &new_clip);
|
||||
reset_clip = TRUE;
|
||||
}
|
||||
gsk_gl_render_job_push_clip (job, &GSK_ROUNDED_RECT_INIT_FROM_RECT (job->viewport));
|
||||
|
||||
gsk_gl_render_job_visit_node (job, node);
|
||||
|
||||
if (reset_clip)
|
||||
if (offscreen->reset_clip)
|
||||
gsk_gl_render_job_pop_clip (job);
|
||||
|
||||
if (downscale_x != 1 || downscale_y != 1)
|
||||
|
||||
@@ -19,9 +19,6 @@ void main() {
|
||||
gsk_rounded_rect_transform(outside, u_modelview);
|
||||
gsk_rounded_rect_transform(inside, u_modelview);
|
||||
|
||||
gsk_rounded_rect_normalize(outside);
|
||||
gsk_rounded_rect_normalize(inside);
|
||||
|
||||
gsk_rounded_rect_encode(outside, transformed_outside_outline);
|
||||
gsk_rounded_rect_encode(inside, transformed_inside_outline);
|
||||
}
|
||||
@@ -37,9 +34,10 @@ _IN_ _GSK_ROUNDED_RECT_UNIFORM_ transformed_inside_outline;
|
||||
|
||||
void main() {
|
||||
vec2 frag = gsk_get_frag_coord();
|
||||
float outer_coverage = gsk_rounded_rect_coverage(gsk_decode_rect(transformed_outside_outline), frag);
|
||||
float inner_coverage = gsk_rounded_rect_coverage(gsk_decode_rect(transformed_inside_outline), frag);
|
||||
float alpha = clamp(outer_coverage - inner_coverage, 0.0, 1.0);
|
||||
|
||||
float alpha = clamp(gsk_rounded_rect_coverage(gsk_decode_rect(transformed_outside_outline), frag) -
|
||||
gsk_rounded_rect_coverage(gsk_decode_rect(transformed_inside_outline), frag),
|
||||
0.0, 1.0);
|
||||
|
||||
gskSetScaledOutputColor(final_color, alpha);
|
||||
}
|
||||
|
||||
@@ -21,9 +21,6 @@ void main() {
|
||||
gsk_rounded_rect_transform(outside, u_modelview);
|
||||
gsk_rounded_rect_transform(inside, u_modelview);
|
||||
|
||||
gsk_rounded_rect_normalize(outside);
|
||||
gsk_rounded_rect_normalize(inside);
|
||||
|
||||
gsk_rounded_rect_encode(outside, transformed_outside_outline);
|
||||
gsk_rounded_rect_encode(inside, transformed_inside_outline);
|
||||
}
|
||||
|
||||
@@ -22,9 +22,6 @@ void main() {
|
||||
gsk_rounded_rect_transform(outside, u_modelview);
|
||||
gsk_rounded_rect_transform(inside, u_modelview);
|
||||
|
||||
gsk_rounded_rect_normalize(outside);
|
||||
gsk_rounded_rect_normalize(inside);
|
||||
|
||||
gsk_rounded_rect_encode(outside, transformed_outside_outline);
|
||||
gsk_rounded_rect_encode(inside, transformed_inside_outline);
|
||||
}
|
||||
|
||||
@@ -15,7 +15,6 @@ void main() {
|
||||
|
||||
GskRoundedRect outline = gsk_create_rect(u_outline_rect);
|
||||
gsk_rounded_rect_transform(outline, u_modelview);
|
||||
gsk_rounded_rect_normalize(outline);
|
||||
gsk_rounded_rect_encode(outline, transformed_outline);
|
||||
}
|
||||
|
||||
|
||||
@@ -16,15 +16,11 @@ _IN_ vec2 vUv;
|
||||
|
||||
GskRoundedRect gsk_decode_rect(_GSK_ROUNDED_RECT_UNIFORM_ r)
|
||||
{
|
||||
GskRoundedRect rect;
|
||||
#if defined(GSK_GLES) || defined(GSK_LEGACY)
|
||||
rect = GskRoundedRect(r[0], r[1], r[2]);
|
||||
return GskRoundedRect(r[0], r[1], r[2]);
|
||||
#else
|
||||
rect = r;
|
||||
return r;
|
||||
#endif
|
||||
gsk_rounded_rect_normalize (rect);
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
||||
float
|
||||
|
||||
@@ -22,55 +22,6 @@ struct GskRoundedRect
|
||||
vec4 corner_points2; // xy = bottom right, zw = bottom left
|
||||
};
|
||||
|
||||
void gsk_rounded_rect_normalize(inout GskRoundedRect r)
|
||||
{
|
||||
if (r.bounds.x > r.bounds.z)
|
||||
{
|
||||
float t = r.bounds.x;
|
||||
r.bounds.x = r.bounds.z;
|
||||
r.bounds.z = t;
|
||||
|
||||
vec2 c = r.corner_points1.xy;
|
||||
r.corner_points1.xy = r.corner_points1.zw;
|
||||
r.corner_points1.zw = c;
|
||||
|
||||
c = r.corner_points2.xy;
|
||||
r.corner_points2.xy = r.corner_points2.zw;
|
||||
r.corner_points2.zw = c;
|
||||
}
|
||||
|
||||
if (r.bounds.y > r.bounds.w)
|
||||
{
|
||||
float t = r.bounds.y;
|
||||
r.bounds.y = r.bounds.w;
|
||||
r.bounds.w = t;
|
||||
|
||||
vec2 c = r.corner_points1.xy;
|
||||
r.corner_points1.xy = r.corner_points2.xy;
|
||||
r.corner_points2.xy = c;
|
||||
|
||||
c = r.corner_points1.zw;
|
||||
r.corner_points1.zw = r.corner_points2.zw;
|
||||
r.corner_points2.zw = c;
|
||||
}
|
||||
}
|
||||
|
||||
void gsk_bounds_normalize (inout vec4 bounds)
|
||||
{
|
||||
if (bounds.x > bounds.z)
|
||||
{
|
||||
float t = bounds.x;
|
||||
bounds.x = bounds.z;
|
||||
bounds.z = t;
|
||||
}
|
||||
if (bounds.y > bounds.w)
|
||||
{
|
||||
float t = bounds.y;
|
||||
bounds.y = bounds.w;
|
||||
bounds.w = t;
|
||||
}
|
||||
}
|
||||
|
||||
// Transform from a C GskRoundedRect to what we need.
|
||||
GskRoundedRect
|
||||
gsk_create_rect(vec4[3] data)
|
||||
@@ -82,21 +33,13 @@ gsk_create_rect(vec4[3] data)
|
||||
vec4 corner_points2 = vec4(bounds.zw + (data[2].xy * vec2(-1, -1)),
|
||||
bounds.xw + vec2(data[2].zw * vec2(1, -1)));
|
||||
|
||||
GskRoundedRect rect = GskRoundedRect(bounds, corner_points1, corner_points2);
|
||||
|
||||
gsk_rounded_rect_normalize (rect);
|
||||
|
||||
return rect;
|
||||
return GskRoundedRect(bounds, corner_points1, corner_points2);
|
||||
}
|
||||
|
||||
vec4
|
||||
gsk_get_bounds(vec4[3] data)
|
||||
{
|
||||
vec4 bounds = vec4(data[0].xy, data[0].xy + data[0].zw);
|
||||
|
||||
gsk_bounds_normalize (bounds);
|
||||
|
||||
return bounds;
|
||||
return vec4(data[0].xy, data[0].xy + data[0].zw);
|
||||
}
|
||||
|
||||
vec4 gsk_premultiply(vec4 c) {
|
||||
|
||||
+3
-168
@@ -519,174 +519,8 @@ gsk_rounded_rect_intersects_rect (const GskRoundedRect *self,
|
||||
gsk_rounded_rect_locate_point (self, &GRAPHENE_POINT_INIT (rect->origin.x, rect->origin.y + rect->size.height)) == OUTSIDE_TOP_RIGHT ||
|
||||
gsk_rounded_rect_locate_point (self, &GRAPHENE_POINT_INIT (rect->origin.x + rect->size.width, rect->origin.y + rect->size.height)) == OUTSIDE_TOP_LEFT)
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#define rect_point0(r) ((r)->origin)
|
||||
#define rect_point1(r) (GRAPHENE_POINT_INIT ((r)->origin.x + (r)->size.width, (r)->origin.y))
|
||||
#define rect_point2(r) (GRAPHENE_POINT_INIT ((r)->origin.x + (r)->size.width, (r)->origin.y + (r)->size.height))
|
||||
#define rect_point3(r) (GRAPHENE_POINT_INIT ((r)->origin.x, (r)->origin.y + (r)->size.height))
|
||||
|
||||
#define rounded_rect_corner0(r) \
|
||||
(GRAPHENE_RECT_INIT((r)->bounds.origin.x, \
|
||||
(r)->bounds.origin.y, \
|
||||
(r)->corner[0].width, (r)->corner[0].height))
|
||||
#define rounded_rect_corner1(r) \
|
||||
(GRAPHENE_RECT_INIT((r)->bounds.origin.x + (r)->bounds.size.width - (r)->corner[1].width, \
|
||||
(r)->bounds.origin.y, \
|
||||
(r)->corner[1].width, (r)->corner[1].height))
|
||||
#define rounded_rect_corner2(r) \
|
||||
(GRAPHENE_RECT_INIT((r)->bounds.origin.x + (r)->bounds.size.width - (r)->corner[2].width, \
|
||||
(r)->bounds.origin.y + (r)->bounds.size.height - (r)->corner[2].height, \
|
||||
(r)->corner[2].width, (r)->corner[2].height))
|
||||
#define rounded_rect_corner3(r) \
|
||||
(GRAPHENE_RECT_INIT((r)->bounds.origin.x, \
|
||||
(r)->bounds.origin.y + (r)->bounds.size.height - (r)->corner[3].height, \
|
||||
(r)->corner[3].width, (r)->corner[3].height))
|
||||
|
||||
enum {
|
||||
BELOW,
|
||||
INNER,
|
||||
ABOVE
|
||||
};
|
||||
|
||||
static inline void
|
||||
classify_point (const graphene_point_t *p, const graphene_rect_t *rect, int *px, int *py)
|
||||
{
|
||||
if (p->x <= rect->origin.x)
|
||||
*px = BELOW;
|
||||
else if (p->x >= rect->origin.x + rect->size.width)
|
||||
*px = ABOVE;
|
||||
else
|
||||
*px = INNER;
|
||||
|
||||
if (p->y <= rect->origin.y)
|
||||
*py = BELOW;
|
||||
else if (p->y >= rect->origin.y + rect->size.height)
|
||||
*py = ABOVE;
|
||||
else
|
||||
*py = INNER;
|
||||
}
|
||||
|
||||
GskRoundedRectIntersection
|
||||
gsk_rounded_rect_intersect_with_rect (const GskRoundedRect *self,
|
||||
const graphene_rect_t *rect,
|
||||
GskRoundedRect *result)
|
||||
{
|
||||
int px, py, qx, qy;
|
||||
|
||||
if (!graphene_rect_intersection (&self->bounds, rect, &result->bounds))
|
||||
return GSK_INTERSECTION_EMPTY;
|
||||
|
||||
classify_point (&rect_point0 (rect), &rounded_rect_corner0 (self), &px, &py);
|
||||
|
||||
if (px == BELOW && py == BELOW)
|
||||
{
|
||||
classify_point (&rect_point2 (rect), &rounded_rect_corner0 (self), &qx, &qy);
|
||||
|
||||
if (qx == BELOW || qy == BELOW)
|
||||
return GSK_INTERSECTION_EMPTY;
|
||||
else if (qx == INNER && qy == INNER &&
|
||||
gsk_rounded_rect_locate_point (self, &rect_point2 (rect)) != INSIDE)
|
||||
return GSK_INTERSECTION_EMPTY;
|
||||
else if (qx == ABOVE && qy == ABOVE)
|
||||
result->corner[0] = self->corner[0];
|
||||
else
|
||||
return GSK_INTERSECTION_NOT_REPRESENTABLE;
|
||||
}
|
||||
else if ((px == INNER || py == INNER) &&
|
||||
gsk_rounded_rect_locate_point (self, &rect_point0 (rect)) != INSIDE)
|
||||
{
|
||||
if (gsk_rounded_rect_locate_point (self, &rect_point2 (rect)) == OUTSIDE_TOP_LEFT)
|
||||
return GSK_INTERSECTION_EMPTY;
|
||||
else
|
||||
return GSK_INTERSECTION_NOT_REPRESENTABLE;
|
||||
}
|
||||
else
|
||||
result->corner[0].width = result->corner[0].height = 0;
|
||||
|
||||
classify_point (&rect_point1 (rect), &rounded_rect_corner1 (self), &px, &py);
|
||||
|
||||
if (px == ABOVE && py == BELOW)
|
||||
{
|
||||
classify_point (&rect_point3 (rect), &rounded_rect_corner1 (self), &qx, &qy);
|
||||
|
||||
if (qx == ABOVE || qy == BELOW)
|
||||
return GSK_INTERSECTION_EMPTY;
|
||||
else if (qx == INNER && qy == INNER &&
|
||||
gsk_rounded_rect_locate_point (self, &rect_point3 (rect)) != INSIDE)
|
||||
return GSK_INTERSECTION_EMPTY;
|
||||
else if (qx == BELOW && qy == ABOVE)
|
||||
result->corner[1] = self->corner[1];
|
||||
else
|
||||
return GSK_INTERSECTION_NOT_REPRESENTABLE;
|
||||
}
|
||||
else if ((px == INNER || py == INNER) &&
|
||||
gsk_rounded_rect_locate_point (self, &rect_point1 (rect)) != INSIDE)
|
||||
{
|
||||
if (gsk_rounded_rect_locate_point (self, &rect_point3 (rect)) == OUTSIDE_TOP_RIGHT)
|
||||
return GSK_INTERSECTION_EMPTY;
|
||||
else
|
||||
return GSK_INTERSECTION_NOT_REPRESENTABLE;
|
||||
}
|
||||
else
|
||||
result->corner[1].width = result->corner[1].height = 0;
|
||||
|
||||
classify_point (&rect_point2 (rect), &rounded_rect_corner2 (self), &px, &py);
|
||||
|
||||
if (px == ABOVE && py == ABOVE)
|
||||
{
|
||||
classify_point (&rect_point0 (rect), &rounded_rect_corner2 (self), &qx, &qy);
|
||||
|
||||
if (qx == ABOVE || qy == ABOVE)
|
||||
return GSK_INTERSECTION_EMPTY;
|
||||
else if (qx == INNER && qy == INNER &&
|
||||
gsk_rounded_rect_locate_point (self, &rect_point0 (rect)) != INSIDE)
|
||||
return GSK_INTERSECTION_EMPTY;
|
||||
else if (qx == BELOW && qy == BELOW)
|
||||
result->corner[2] = self->corner[2];
|
||||
else
|
||||
return GSK_INTERSECTION_NOT_REPRESENTABLE;
|
||||
}
|
||||
else if ((px == INNER || py == INNER) &&
|
||||
gsk_rounded_rect_locate_point (self, &rect_point2 (rect)) != INSIDE)
|
||||
{
|
||||
if (gsk_rounded_rect_locate_point (self, &rect_point0 (rect)) == OUTSIDE_BOTTOM_RIGHT)
|
||||
return GSK_INTERSECTION_EMPTY;
|
||||
else
|
||||
return GSK_INTERSECTION_NOT_REPRESENTABLE;
|
||||
}
|
||||
else
|
||||
result->corner[2].width = result->corner[2].height = 0;
|
||||
|
||||
classify_point (&rect_point3 (rect), &rounded_rect_corner3 (self), &px, &py);
|
||||
|
||||
if (px == BELOW && py == ABOVE)
|
||||
{
|
||||
classify_point (&rect_point1 (rect), &rounded_rect_corner3 (self), &qx, &qy);
|
||||
|
||||
if (qx == BELOW || qy == ABOVE)
|
||||
return GSK_INTERSECTION_EMPTY;
|
||||
else if (qx == INNER && qy == INNER &&
|
||||
gsk_rounded_rect_locate_point (self, &rect_point1 (rect)) != INSIDE)
|
||||
return GSK_INTERSECTION_EMPTY;
|
||||
else if (qx == ABOVE && qy == BELOW)
|
||||
result->corner[3] = self->corner[3];
|
||||
else
|
||||
return GSK_INTERSECTION_NOT_REPRESENTABLE;
|
||||
}
|
||||
else if ((px == INNER || py == INNER) &&
|
||||
gsk_rounded_rect_locate_point (self, &rect_point3 (rect)) != INSIDE)
|
||||
{
|
||||
if (gsk_rounded_rect_locate_point (self, &rect_point1 (rect)) == OUTSIDE_BOTTOM_LEFT)
|
||||
return GSK_INTERSECTION_EMPTY;
|
||||
else
|
||||
return GSK_INTERSECTION_NOT_REPRESENTABLE;
|
||||
}
|
||||
else
|
||||
result->corner[3].width = result->corner[3].height = 0;
|
||||
|
||||
return GSK_INTERSECTION_NONEMPTY;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -731,7 +565,7 @@ gsk_rounded_rect_path (const GskRoundedRect *self,
|
||||
self->corner[GSK_CORNER_TOP_LEFT].width,
|
||||
self->corner[GSK_CORNER_TOP_LEFT].height,
|
||||
G_PI, 3 * G_PI_2);
|
||||
_cairo_ellipsis (cr,
|
||||
_cairo_ellipsis (cr,
|
||||
self->bounds.origin.x + self->bounds.size.width - self->corner[GSK_CORNER_TOP_RIGHT].width,
|
||||
self->bounds.origin.y + self->corner[GSK_CORNER_TOP_RIGHT].height,
|
||||
self->corner[GSK_CORNER_TOP_RIGHT].width,
|
||||
@@ -815,4 +649,5 @@ gsk_rounded_rect_to_string (const GskRoundedRect *self)
|
||||
self->corner[2].height,
|
||||
self->corner[3].width,
|
||||
self->corner[3].height);
|
||||
|
||||
}
|
||||
|
||||
@@ -34,16 +34,6 @@ gboolean gsk_rounded_rect_equal (gconstpointer
|
||||
gconstpointer rect2) G_GNUC_PURE;
|
||||
char * gsk_rounded_rect_to_string (const GskRoundedRect *self) G_GNUC_MALLOC;
|
||||
|
||||
typedef enum {
|
||||
GSK_INTERSECTION_EMPTY,
|
||||
GSK_INTERSECTION_NONEMPTY,
|
||||
GSK_INTERSECTION_NOT_REPRESENTABLE
|
||||
} GskRoundedRectIntersection;
|
||||
|
||||
GskRoundedRectIntersection gsk_rounded_rect_intersect_with_rect (const GskRoundedRect *self,
|
||||
const graphene_rect_t *rect,
|
||||
GskRoundedRect *result) G_GNUC_PURE;
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
+1
-1
@@ -164,7 +164,7 @@ gskenum_h = gsk_enums[1]
|
||||
gskresources = gnome.compile_resources('gskresources',
|
||||
gsk_resources_xml,
|
||||
dependencies: gsk_private_vulkan_compiled_shaders_deps,
|
||||
source_dir: [meson.current_build_dir(), meson.current_source_dir()],
|
||||
source_dir: meson.current_source_dir(),
|
||||
c_name: '_gsk',
|
||||
extra_args: [ '--manual-register', ],
|
||||
)
|
||||
|
||||
@@ -1012,8 +1012,9 @@ gsk_vulkan_render_pass_get_node_as_texture (GskVulkanRenderPass *self,
|
||||
GskVulkanRender *render,
|
||||
GskVulkanUploader *uploader,
|
||||
GskRenderNode *node,
|
||||
const graphene_rect_t *bounds,
|
||||
GskVulkanClip *current_clip,
|
||||
graphene_rect_t *tex_bounds)
|
||||
graphene_rect_t *tex_rect)
|
||||
{
|
||||
GskVulkanImage *result;
|
||||
cairo_surface_t *surface;
|
||||
@@ -1022,12 +1023,16 @@ gsk_vulkan_render_pass_get_node_as_texture (GskVulkanRenderPass *self,
|
||||
switch ((guint) gsk_render_node_get_node_type (node))
|
||||
{
|
||||
case GSK_TEXTURE_NODE:
|
||||
result = gsk_vulkan_renderer_ref_texture_image (GSK_VULKAN_RENDERER (gsk_vulkan_render_get_renderer (render)),
|
||||
gsk_texture_node_get_texture (node),
|
||||
uploader);
|
||||
gsk_vulkan_render_add_cleanup_image (render, result);
|
||||
*tex_bounds = node->bounds;
|
||||
return result;
|
||||
if (graphene_rect_equal (bounds, &node->bounds))
|
||||
{
|
||||
result = gsk_vulkan_renderer_ref_texture_image (GSK_VULKAN_RENDERER (gsk_vulkan_render_get_renderer (render)),
|
||||
gsk_texture_node_get_texture (node),
|
||||
uploader);
|
||||
gsk_vulkan_render_add_cleanup_image (render, result);
|
||||
*tex_rect = GRAPHENE_RECT_INIT(0, 0, 1, 1);
|
||||
return result;
|
||||
}
|
||||
break;
|
||||
|
||||
case GSK_CAIRO_NODE:
|
||||
/* We're using recording surfaces, so drawing them to an image
|
||||
@@ -1045,9 +1050,9 @@ gsk_vulkan_render_pass_get_node_as_texture (GskVulkanRenderPass *self,
|
||||
graphene_rect_t clipped;
|
||||
|
||||
if (current_clip)
|
||||
graphene_rect_intersection (¤t_clip->rect.bounds, &node->bounds, &clipped);
|
||||
graphene_rect_intersection (¤t_clip->rect.bounds, bounds, &clipped);
|
||||
else
|
||||
clipped = node->bounds;
|
||||
clipped = *bounds;
|
||||
|
||||
if (clipped.size.width == 0 || clipped.size.height == 0)
|
||||
return NULL;
|
||||
@@ -1106,30 +1111,33 @@ gsk_vulkan_render_pass_get_node_as_texture (GskVulkanRenderPass *self,
|
||||
/* assuming the unclipped bounds should go to texture coordinates 0..1,
|
||||
* calculate the coordinates for the clipped texture size
|
||||
*/
|
||||
*tex_bounds = clipped;
|
||||
tex_rect->origin.x = (bounds->origin.x - clipped.origin.x)/clipped.size.width;
|
||||
tex_rect->origin.y = (bounds->origin.y - clipped.origin.y)/clipped.size.height;
|
||||
tex_rect->size.width = bounds->size.width/clipped.size.width;
|
||||
tex_rect->size.height = bounds->size.height/clipped.size.height;
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
GSK_RENDERER_DEBUG (gsk_vulkan_render_get_renderer (render), FALLBACK, "Node as texture not implemented for this case. Using %gx%g fallback surface",
|
||||
ceil (node->bounds.size.width),
|
||||
ceil (node->bounds.size.height));
|
||||
ceil (bounds->size.width),
|
||||
ceil (bounds->size.height));
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
{
|
||||
GskProfiler *profiler = gsk_renderer_get_profiler (gsk_vulkan_render_get_renderer (render));
|
||||
gsk_profiler_counter_add (profiler,
|
||||
self->fallback_pixels,
|
||||
ceil (node->bounds.size.width) * ceil (node->bounds.size.height));
|
||||
ceil (bounds->size.width) * ceil (bounds->size.height));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* 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));
|
||||
ceil (bounds->size.width),
|
||||
ceil (bounds->size.height));
|
||||
cr = cairo_create (surface);
|
||||
cairo_translate (cr, -node->bounds.origin.x, -node->bounds.origin.y);
|
||||
cairo_translate (cr, -bounds->origin.x, -bounds->origin.y);
|
||||
|
||||
gsk_render_node_draw (node, cr);
|
||||
|
||||
@@ -1145,7 +1153,10 @@ gsk_vulkan_render_pass_get_node_as_texture (GskVulkanRenderPass *self,
|
||||
|
||||
gsk_vulkan_render_add_cleanup_image (render, result);
|
||||
|
||||
*tex_bounds = node->bounds;
|
||||
tex_rect->origin.x = (node->bounds.origin.x - bounds->origin.x)/bounds->size.width;
|
||||
tex_rect->origin.y = (node->bounds.origin.y - bounds->origin.y)/bounds->size.height;
|
||||
tex_rect->size.width = node->bounds.size.width/bounds->size.width;
|
||||
tex_rect->size.height = node->bounds.size.height/bounds->size.height;
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -1239,18 +1250,6 @@ gsk_vulkan_render_pass_upload_fallback (GskVulkanRenderPass *self,
|
||||
gsk_vulkan_render_add_cleanup_image (render, op->source);
|
||||
}
|
||||
|
||||
static void
|
||||
get_tex_rect (graphene_rect_t *tex_coords,
|
||||
const graphene_rect_t *rect,
|
||||
const graphene_rect_t *tex)
|
||||
{
|
||||
graphene_rect_init (tex_coords,
|
||||
(rect->origin.x - tex->origin.x) / tex->size.width,
|
||||
(rect->origin.y - tex->origin.y) / tex->size.height,
|
||||
rect->size.width / tex->size.width,
|
||||
rect->size.height / tex->size.height);
|
||||
}
|
||||
|
||||
void
|
||||
gsk_vulkan_render_pass_upload (GskVulkanRenderPass *self,
|
||||
GskVulkanRender *render,
|
||||
@@ -1295,61 +1294,63 @@ gsk_vulkan_render_pass_upload (GskVulkanRenderPass *self,
|
||||
case GSK_VULKAN_OP_OPACITY:
|
||||
{
|
||||
GskRenderNode *child = gsk_opacity_node_get_child (op->render.node);
|
||||
graphene_rect_t tex_bounds;
|
||||
|
||||
op->render.source = gsk_vulkan_render_pass_get_node_as_texture (self,
|
||||
render,
|
||||
uploader,
|
||||
child,
|
||||
&child->bounds,
|
||||
clip,
|
||||
&tex_bounds);
|
||||
get_tex_rect (&op->render.source_rect, &op->render.node->bounds, &tex_bounds);
|
||||
&op->render.source_rect);
|
||||
}
|
||||
break;
|
||||
|
||||
case GSK_VULKAN_OP_REPEAT:
|
||||
{
|
||||
GskRenderNode *child = gsk_repeat_node_get_child (op->render.node);
|
||||
const graphene_rect_t *bounds = &op->render.node->bounds;
|
||||
const graphene_rect_t *child_bounds = gsk_repeat_node_get_child_bounds (op->render.node);
|
||||
graphene_rect_t tex_bounds;
|
||||
|
||||
op->render.source = gsk_vulkan_render_pass_get_node_as_texture (self,
|
||||
render,
|
||||
uploader,
|
||||
child,
|
||||
child_bounds,
|
||||
NULL,
|
||||
&tex_bounds);
|
||||
get_tex_rect (&op->render.source_rect, child_bounds, &tex_bounds);
|
||||
&op->render.source_rect);
|
||||
|
||||
op->render.source_rect.origin.x = (bounds->origin.x - child_bounds->origin.x)/child_bounds->size.width;
|
||||
op->render.source_rect.origin.y = (bounds->origin.y - child_bounds->origin.y)/child_bounds->size.height;
|
||||
op->render.source_rect.size.width = bounds->size.width / child_bounds->size.width;
|
||||
op->render.source_rect.size.height = bounds->size.height / child_bounds->size.height;
|
||||
}
|
||||
break;
|
||||
|
||||
case GSK_VULKAN_OP_BLUR:
|
||||
{
|
||||
GskRenderNode *child = gsk_blur_node_get_child (op->render.node);
|
||||
graphene_rect_t tex_bounds;
|
||||
|
||||
op->render.source = gsk_vulkan_render_pass_get_node_as_texture (self,
|
||||
render,
|
||||
uploader,
|
||||
child,
|
||||
&child->bounds,
|
||||
clip,
|
||||
&tex_bounds);
|
||||
get_tex_rect (&op->render.source_rect, &op->render.node->bounds, &tex_bounds);
|
||||
&op->render.source_rect);
|
||||
}
|
||||
break;
|
||||
|
||||
case GSK_VULKAN_OP_COLOR_MATRIX:
|
||||
{
|
||||
GskRenderNode *child = gsk_color_matrix_node_get_child (op->render.node);
|
||||
graphene_rect_t tex_bounds;
|
||||
|
||||
op->render.source = gsk_vulkan_render_pass_get_node_as_texture (self,
|
||||
render,
|
||||
uploader,
|
||||
child,
|
||||
&child->bounds,
|
||||
clip,
|
||||
&tex_bounds);
|
||||
get_tex_rect (&op->render.source_rect, &op->render.node->bounds, &tex_bounds);
|
||||
&op->render.source_rect);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1357,23 +1358,31 @@ gsk_vulkan_render_pass_upload (GskVulkanRenderPass *self,
|
||||
{
|
||||
GskRenderNode *start = gsk_cross_fade_node_get_start_child (op->render.node);
|
||||
GskRenderNode *end = gsk_cross_fade_node_get_end_child (op->render.node);
|
||||
graphene_rect_t tex_bounds;
|
||||
const graphene_rect_t *bounds = &op->render.node->bounds;
|
||||
|
||||
op->render.source = gsk_vulkan_render_pass_get_node_as_texture (self,
|
||||
render,
|
||||
uploader,
|
||||
start,
|
||||
&start->bounds,
|
||||
clip,
|
||||
&tex_bounds);
|
||||
get_tex_rect (&op->render.source_rect, &op->render.node->bounds, &tex_bounds);
|
||||
&op->render.source_rect);
|
||||
op->render.source_rect.origin.x = (bounds->origin.x - start->bounds.origin.x)/start->bounds.size.width;
|
||||
op->render.source_rect.origin.y = (bounds->origin.y - start->bounds.origin.y)/start->bounds.size.height;
|
||||
op->render.source_rect.size.width = bounds->size.width / start->bounds.size.width;
|
||||
op->render.source_rect.size.height = bounds->size.height / start->bounds.size.height;
|
||||
|
||||
op->render.source2 = gsk_vulkan_render_pass_get_node_as_texture (self,
|
||||
render,
|
||||
uploader,
|
||||
end,
|
||||
&end->bounds,
|
||||
clip,
|
||||
&tex_bounds);
|
||||
get_tex_rect (&op->render.source2_rect, &op->render.node->bounds, &tex_bounds);
|
||||
&op->render.source2_rect);
|
||||
op->render.source2_rect.origin.x = (bounds->origin.x - end->bounds.origin.x)/end->bounds.size.width;
|
||||
op->render.source2_rect.origin.y = (bounds->origin.y - end->bounds.origin.y)/end->bounds.size.height;
|
||||
op->render.source2_rect.size.width = bounds->size.width / end->bounds.size.width;
|
||||
op->render.source2_rect.size.height = bounds->size.height / end->bounds.size.height;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1381,23 +1390,31 @@ gsk_vulkan_render_pass_upload (GskVulkanRenderPass *self,
|
||||
{
|
||||
GskRenderNode *top = gsk_blend_node_get_top_child (op->render.node);
|
||||
GskRenderNode *bottom = gsk_blend_node_get_bottom_child (op->render.node);
|
||||
graphene_rect_t tex_bounds;
|
||||
const graphene_rect_t *bounds = &op->render.node->bounds;
|
||||
|
||||
op->render.source = gsk_vulkan_render_pass_get_node_as_texture (self,
|
||||
render,
|
||||
uploader,
|
||||
top,
|
||||
&top->bounds,
|
||||
clip,
|
||||
&tex_bounds);
|
||||
get_tex_rect (&op->render.source_rect, &op->render.node->bounds, &tex_bounds);
|
||||
&op->render.source_rect);
|
||||
op->render.source_rect.origin.x = (bounds->origin.x - top->bounds.origin.x)/top->bounds.size.width;
|
||||
op->render.source_rect.origin.y = (bounds->origin.y - top->bounds.origin.y)/top->bounds.size.height;
|
||||
op->render.source_rect.size.width = bounds->size.width / top->bounds.size.width;
|
||||
op->render.source_rect.size.height = bounds->size.height / top->bounds.size.height;
|
||||
|
||||
op->render.source2 = gsk_vulkan_render_pass_get_node_as_texture (self,
|
||||
render,
|
||||
uploader,
|
||||
bottom,
|
||||
&bottom->bounds,
|
||||
clip,
|
||||
&tex_bounds);
|
||||
get_tex_rect (&op->render.source2_rect, &op->render.node->bounds, &tex_bounds);
|
||||
&op->render.source2_rect);
|
||||
op->render.source2_rect.origin.x = (bounds->origin.x - bottom->bounds.origin.x)/bottom->bounds.size.width;
|
||||
op->render.source2_rect.origin.y = (bounds->origin.y - bottom->bounds.origin.y)/bottom->bounds.size.height;
|
||||
op->render.source2_rect.size.width = bounds->size.width / bottom->bounds.size.width;
|
||||
op->render.source2_rect.size.height = bounds->size.height / bottom->bounds.size.height;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -51,7 +51,7 @@ G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
/**
|
||||
* GtkInfoBar:
|
||||
*
|
||||
* `GtkInfoBar` can be used to show messages to the user without a dialog.
|
||||
* `GtkInfoBar` can be show messages to the user without a dialog.
|
||||
*
|
||||
* 
|
||||
*
|
||||
|
||||
@@ -102,10 +102,10 @@ gtk_css_filter_clear (GtkCssFilter *filter)
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_filter_init_identity (GtkCssFilter *filter,
|
||||
const GtkCssFilter *other)
|
||||
gtk_css_filter_init_identity (GtkCssFilter *filter,
|
||||
GtkCssFilterType type)
|
||||
{
|
||||
switch (other->type)
|
||||
switch (type)
|
||||
{
|
||||
case GTK_CSS_FILTER_BRIGHTNESS:
|
||||
filter->brightness.value = _gtk_css_number_value_new (1, GTK_CSS_NUMBER);
|
||||
@@ -135,7 +135,7 @@ gtk_css_filter_init_identity (GtkCssFilter *filter,
|
||||
filter->blur.value = _gtk_css_number_value_new (0, GTK_CSS_PX);
|
||||
break;
|
||||
case GTK_CSS_FILTER_DROP_SHADOW:
|
||||
filter->drop_shadow.value = gtk_css_shadow_value_new_filter (other->drop_shadow.value);
|
||||
filter->drop_shadow.value = gtk_css_shadow_value_new_filter ();
|
||||
break;
|
||||
case GTK_CSS_FILTER_NONE:
|
||||
default:
|
||||
@@ -143,7 +143,7 @@ gtk_css_filter_init_identity (GtkCssFilter *filter,
|
||||
break;
|
||||
}
|
||||
|
||||
filter->type = other->type;
|
||||
filter->type = type;
|
||||
}
|
||||
|
||||
#define R 0.2126
|
||||
@@ -464,7 +464,7 @@ gtk_css_value_filter_equal (const GtkCssValue *value1,
|
||||
{
|
||||
GtkCssFilter filter;
|
||||
|
||||
gtk_css_filter_init_identity (&filter, &larger->filters[i]);
|
||||
gtk_css_filter_init_identity (&filter, larger->filters[i].type);
|
||||
|
||||
if (!gtk_css_filter_equal (&larger->filters[i], &filter))
|
||||
{
|
||||
@@ -588,7 +588,7 @@ gtk_css_value_filter_transition (GtkCssValue *start,
|
||||
{
|
||||
GtkCssFilter filter;
|
||||
|
||||
gtk_css_filter_init_identity (&filter, &start->filters[i]);
|
||||
gtk_css_filter_init_identity (&filter, start->filters[i].type);
|
||||
gtk_css_filter_transition (&result->filters[i],
|
||||
&start->filters[i],
|
||||
&filter,
|
||||
@@ -600,7 +600,7 @@ gtk_css_value_filter_transition (GtkCssValue *start,
|
||||
{
|
||||
GtkCssFilter filter;
|
||||
|
||||
gtk_css_filter_init_identity (&filter, &end->filters[i]);
|
||||
gtk_css_filter_init_identity (&filter, end->filters[i].type);
|
||||
gtk_css_filter_transition (&result->filters[i],
|
||||
&filter,
|
||||
&end->filters[i],
|
||||
|
||||
@@ -331,7 +331,7 @@ gtk_css_shadow_value_new (ShadowValue *shadows,
|
||||
}
|
||||
|
||||
GtkCssValue *
|
||||
gtk_css_shadow_value_new_filter (const GtkCssValue *other)
|
||||
gtk_css_shadow_value_new_filter (void)
|
||||
{
|
||||
ShadowValue value;
|
||||
|
||||
@@ -340,7 +340,7 @@ gtk_css_shadow_value_new_filter (const GtkCssValue *other)
|
||||
value.voffset = _gtk_css_number_value_new (0, GTK_CSS_NUMBER);
|
||||
value.radius = _gtk_css_number_value_new (0, GTK_CSS_NUMBER);
|
||||
value.spread = _gtk_css_number_value_new (0, GTK_CSS_NUMBER);
|
||||
value.color = gtk_css_value_ref (other->shadows[0].color);
|
||||
value.color = _gtk_css_color_value_new_current_color ();
|
||||
|
||||
return gtk_css_shadow_value_new (&value, 1, TRUE);
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
G_BEGIN_DECLS
|
||||
|
||||
GtkCssValue * gtk_css_shadow_value_new_none (void);
|
||||
GtkCssValue * gtk_css_shadow_value_new_filter (const GtkCssValue *other);
|
||||
GtkCssValue * gtk_css_shadow_value_new_filter (void);
|
||||
|
||||
GtkCssValue * gtk_css_shadow_value_parse (GtkCssParser *parser,
|
||||
gboolean box_shadow_mode);
|
||||
|
||||
@@ -563,11 +563,12 @@ add_emoji (GtkWidget *box,
|
||||
int i;
|
||||
PangoLayout *layout;
|
||||
PangoRectangle rect;
|
||||
gunichar code = 0;
|
||||
|
||||
codes = g_variant_get_child_value (item, 0);
|
||||
for (i = 0; i < g_variant_n_children (codes); i++)
|
||||
{
|
||||
gunichar code;
|
||||
|
||||
g_variant_get_child (codes, i, "u", &code);
|
||||
if (code == 0)
|
||||
code = modifier;
|
||||
@@ -575,10 +576,7 @@ add_emoji (GtkWidget *box,
|
||||
p += g_unichar_to_utf8 (code, p);
|
||||
}
|
||||
g_variant_unref (codes);
|
||||
|
||||
if (code != 0xFE0F && code != 0xFE0E)
|
||||
p += g_unichar_to_utf8 (0xFE0F, p); /* Append a variation selector, if there isn't one already */
|
||||
|
||||
p += g_unichar_to_utf8 (0xFE0F, p); /* U+FE0F is the Emoji variation selector */
|
||||
p[0] = 0;
|
||||
|
||||
label = gtk_label_new (text);
|
||||
|
||||
+3
-4
@@ -106,10 +106,9 @@
|
||||
* ╰── <child>
|
||||
* ```
|
||||
*
|
||||
* `GtkExpander` has a main node `expander-widget`, and subnode `box` containing
|
||||
* the title and child widget. The box subnode `title` contains node `expander`,
|
||||
* i.e. the expand/collapse arrow; then the label widget if any. The arrow of an
|
||||
* expander that is showing its child gets the `:checked` pseudoclass set on it.
|
||||
* `GtkExpander` has three CSS nodes, the main node with the name expander-widget,
|
||||
* a subnode with name title and node below it with name expander. The arrow of an
|
||||
* expander that is showing its child gets the :checked pseudoclass added to it.
|
||||
*
|
||||
* # Accessibility
|
||||
*
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
* space as well as it can.
|
||||
*
|
||||
* Users of this widget should take care to plan behaviour for the common case
|
||||
* where the text doesn't fit exactly in the allocated space.
|
||||
* where the text doesn't fit exactly in the allocated space, .
|
||||
*
|
||||
* Since: 4.8
|
||||
*/
|
||||
|
||||
+1
-8
@@ -34,14 +34,7 @@
|
||||
* empty area, or by dragging the handle.
|
||||
*
|
||||
* `GtkSwitch` can also handle situations where the underlying state
|
||||
* changes with a delay. In this case, the slider position indicates
|
||||
* the user's recent change (as indicated by the [property@Gtk.Switch:active]
|
||||
* property), and the color indicates whether the underlying state (represented
|
||||
* by the [property@Gtk.Switch:state] property) has been updated yet.
|
||||
*
|
||||
* 
|
||||
*
|
||||
* See [signal@Gtk.Switch::state-set] for details.
|
||||
* changes with a delay. See [signal@Gtk.Switch::state-set] for details.
|
||||
*
|
||||
* # CSS nodes
|
||||
*
|
||||
|
||||
@@ -2810,7 +2810,6 @@ gtk_widget_real_hide (GtkWidget *widget)
|
||||
g_clear_pointer (&priv->transform, gsk_transform_unref);
|
||||
priv->width = 0;
|
||||
priv->height = 0;
|
||||
priv->baseline = 0;
|
||||
gtk_widget_update_paintables (widget);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
gtk_tests = [
|
||||
# testname, optional extra sources
|
||||
['testgridchanges'],
|
||||
['input'],
|
||||
['testpopup'],
|
||||
['testupload'],
|
||||
|
||||
@@ -0,0 +1,189 @@
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#define CONTENT_TYPE_WIDGET (content_widget_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (ContentWidget, content_widget, CONTENT, WIDGET, GtkWidget)
|
||||
|
||||
struct _ContentWidget
|
||||
{
|
||||
GtkWidget parent_instance;
|
||||
|
||||
int pos;
|
||||
GskRenderNode *content[10];
|
||||
|
||||
int width, height;
|
||||
};
|
||||
|
||||
struct _ContentWidgetClass
|
||||
{
|
||||
GtkWidgetClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (ContentWidget, content_widget, GTK_TYPE_WIDGET)
|
||||
|
||||
static void
|
||||
content_widget_init (ContentWidget *self)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
content_widget_measure (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
int for_size,
|
||||
int *minimum,
|
||||
int *natural,
|
||||
int *minimum_content,
|
||||
int *natural_content)
|
||||
{
|
||||
ContentWidget *self = CONTENT_WIDGET (widget);
|
||||
|
||||
*minimum_content = *natural_content = -1;
|
||||
if (orientation == GTK_ORIENTATION_VERTICAL)
|
||||
*minimum = *natural = self->height;
|
||||
else
|
||||
*minimum = *natural = self->width;
|
||||
}
|
||||
|
||||
static void
|
||||
content_widget_snapshot (GtkWidget *widget,
|
||||
GtkSnapshot *snapshot)
|
||||
{
|
||||
ContentWidget *self = CONTENT_WIDGET (widget);
|
||||
|
||||
gtk_snapshot_append_node (snapshot, self->content[self->pos]);
|
||||
}
|
||||
|
||||
static void
|
||||
content_widget_realize (GtkWidget *widget)
|
||||
{
|
||||
ContentWidget *self = CONTENT_WIDGET (widget);
|
||||
PangoLayout *layout;
|
||||
|
||||
GTK_WIDGET_CLASS (content_widget_parent_class)->realize (widget);
|
||||
|
||||
layout = gtk_widget_create_pango_layout (widget, "");
|
||||
|
||||
self->width = self->height = 0;
|
||||
|
||||
for (unsigned int i = 0; i < 10; i++)
|
||||
{
|
||||
char text[20];
|
||||
GtkSnapshot *snapshot;
|
||||
graphene_rect_t bounds;
|
||||
|
||||
g_snprintf (text, sizeof (text), "%u", i);
|
||||
pango_layout_set_text (layout, text, -1);
|
||||
|
||||
snapshot = gtk_snapshot_new ();
|
||||
gtk_snapshot_append_layout (snapshot, layout, &(GdkRGBA){ 0., 0., 0., 1. });
|
||||
self->content[i] = gtk_snapshot_free_to_node (snapshot);
|
||||
|
||||
gsk_render_node_get_bounds (self->content[i], &bounds);
|
||||
self->width = MAX (self->width, ceilf (bounds.origin.x + bounds.size.width));
|
||||
self->height = MAX (self->height, ceilf (bounds.origin.y + bounds.size.height));
|
||||
}
|
||||
|
||||
g_object_unref (layout);
|
||||
}
|
||||
|
||||
static void
|
||||
content_widget_unrealize (GtkWidget *widget)
|
||||
{
|
||||
ContentWidget *self = CONTENT_WIDGET (widget);
|
||||
|
||||
for (unsigned int i =0; i < 10; i++)
|
||||
g_clear_pointer (&self->content[i], gsk_render_node_unref);
|
||||
|
||||
GTK_WIDGET_CLASS (content_widget_parent_class)->unrealize (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
content_widget_class_init (ContentWidgetClass *class)
|
||||
{
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
|
||||
|
||||
widget_class->snapshot = content_widget_snapshot;
|
||||
widget_class->measure = content_widget_measure;
|
||||
widget_class->realize = content_widget_realize;
|
||||
widget_class->unrealize = content_widget_unrealize;
|
||||
|
||||
gtk_widget_class_set_css_name (widget_class, "content");
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
content_widget_new (void)
|
||||
{
|
||||
return g_object_new (CONTENT_TYPE_WIDGET, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
content_widget_set_pos (ContentWidget *self,
|
||||
int pos)
|
||||
{
|
||||
g_return_if_fail (CONTENT_IS_WIDGET (self));
|
||||
g_return_if_fail (0 <= pos && pos < 10);
|
||||
|
||||
self->pos = pos;
|
||||
gtk_widget_queue_draw (GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
static GtkWidget *cells[100][100];
|
||||
|
||||
static gboolean
|
||||
change_content (GtkWidget *widget,
|
||||
GdkFrameClock *clock,
|
||||
gpointer user_data)
|
||||
{
|
||||
for (unsigned int i = 0; i < 100; i++)
|
||||
for (unsigned int j = 0; j < 100; j++)
|
||||
content_widget_set_pos (CONTENT_WIDGET (cells[i][j]), g_random_int_range (0, 9));
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
static const char css[] =
|
||||
"content {\n"
|
||||
" background: pink;\n"
|
||||
" border: 1px solid black;\n"
|
||||
"}";
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
GtkWidget *window, *sw, *grid;
|
||||
GtkCssProvider *provider;
|
||||
|
||||
gtk_init ();
|
||||
|
||||
provider = gtk_css_provider_new ();
|
||||
gtk_css_provider_load_from_data (provider, css, -1);
|
||||
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
|
||||
GTK_STYLE_PROVIDER (provider),
|
||||
1000);
|
||||
|
||||
window = gtk_window_new ();
|
||||
|
||||
sw = gtk_scrolled_window_new ();
|
||||
gtk_window_set_child (GTK_WINDOW (window), sw);
|
||||
|
||||
grid = gtk_grid_new ();
|
||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), grid);
|
||||
|
||||
for (unsigned int i = 0; i < 100; i++)
|
||||
for (unsigned int j = 0; j < 100; j++)
|
||||
{
|
||||
GtkWidget *child;
|
||||
|
||||
child = content_widget_new ();
|
||||
gtk_grid_attach (GTK_GRID (grid), child, i, j, 1, 1);
|
||||
cells[i][j] = child;
|
||||
}
|
||||
|
||||
gtk_widget_add_tick_callback (window, change_content, NULL, NULL);
|
||||
|
||||
gtk_window_present (GTK_WINDOW (window));
|
||||
|
||||
while (g_list_model_get_n_items (gtk_window_get_toplevels ()) > 0)
|
||||
g_main_context_iteration (NULL, FALSE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user