Compare commits
107 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c5988a22a4 | |||
| 498bf67cec | |||
| 65455cdb91 | |||
| d4963ba2e5 | |||
| ec5fed6cc4 | |||
| b7ae5404a3 | |||
| fb4f210430 | |||
| 82df109444 | |||
| bd84142f43 | |||
| 65074bbbac | |||
| 21fb5ec0b2 | |||
| e57f92b7e9 | |||
| e94e348ad5 | |||
| 91234e75f8 | |||
| 212e9a6957 | |||
| b4b7e9b040 | |||
| c3fcf0f7b0 | |||
| 60fc48e71f | |||
| 01d9886eea | |||
| a97231c8bf | |||
| 8ac8a027b2 | |||
| 070f3a61ac | |||
| 022347fa85 | |||
| ebb6076aca | |||
| 7b66bc45aa | |||
| 698aa7c0f3 | |||
| 70699efc71 | |||
| cebc95f253 | |||
| f9c6bd125b | |||
| 4733ca193b | |||
| c7b345f73e | |||
| 1fbc61f2cb | |||
| 565694ede5 | |||
| 0df03b054d | |||
| 73d01d3130 | |||
| 80f3357117 | |||
| d5b34aecdd | |||
| d16d2135e6 | |||
| 53b52abd30 | |||
| e55e9e3b36 | |||
| 9f9cea219f | |||
| dbee1a8160 | |||
| 133cd87bdf | |||
| 9f8e84cb60 | |||
| b8057b088e | |||
| cf8cca8724 | |||
| d97767014c | |||
| 2f974a1f5a | |||
| 4e2c7d5eb0 | |||
| a5d1cb93ef | |||
| 401b902cbf | |||
| 9f2778b97c | |||
| ed4eeb8adb | |||
| fb36d30685 | |||
| 385b9a7241 | |||
| c2abf30c46 | |||
| 50a47f55d9 | |||
| cd7fe772a7 | |||
| 317bba756e | |||
| 2212049e8f | |||
| 0f26a006ee | |||
| 3c451b3ec7 | |||
| 323adf9aa8 | |||
| 70f0cde730 | |||
| 14e78663ee | |||
| d8279209a2 | |||
| a0527ff0bd | |||
| 771ea81715 | |||
| f22a3f9ec6 | |||
| 246876a404 | |||
| 27a086b5f0 | |||
| 8158945de9 | |||
| 1c85141612 | |||
| 690381672b | |||
| 3d7ff44dc5 | |||
| a518c59098 | |||
| 1dd5e92499 | |||
| fbd3c5ebd0 | |||
| 48dc7df5b7 | |||
| 0c4c90d606 | |||
| da954d20f9 | |||
| ff262c081e | |||
| c6967234de | |||
| cdbfb35067 | |||
| 53e17ab14e | |||
| 550e98090a | |||
| 2771befdd9 | |||
| 911730493d | |||
| d05f47a695 | |||
| 11dc15207e | |||
| 4ea748a676 | |||
| b78d2a7f75 | |||
| 1fd9e1e916 | |||
| 24ceb47cbc | |||
| 8872e1cbb0 | |||
| c1e2ffac83 | |||
| 17df646663 | |||
| 6f8fae590f | |||
| 4146db0003 | |||
| 9c228cc634 | |||
| df2cdb6913 | |||
| 22a5447039 | |||
| a2475051fa | |||
| d41fb7c5a6 | |||
| 3b28c46595 | |||
| f57300b924 | |||
| 473881357c |
@@ -19,6 +19,7 @@ flatpak build ${builddir} meson \
|
||||
--buildtype=debugoptimized \
|
||||
-Dx11-backend=true \
|
||||
-Dwayland-backend=true \
|
||||
-Dvulkan=disabled \
|
||||
-Dbuild-tests=false \
|
||||
-Dbuild-testsuite=false \
|
||||
-Dbuild-examples=false \
|
||||
@@ -27,7 +28,7 @@ flatpak build ${builddir} meson \
|
||||
-Ddemo-profile=devel \
|
||||
_flatpak_build
|
||||
|
||||
flatpak build ${builddir} ninja -C _flatpak_build install
|
||||
flatpak build --env=CI_COMMIT_SHORT_SHA=$CI_COMMIT_SHORT_SHA ${builddir} ninja -C _flatpak_build install
|
||||
|
||||
flatpak-builder \
|
||||
--user --disable-rofiles-fuse \
|
||||
|
||||
+1
-1
@@ -213,7 +213,7 @@ Closes #1234
|
||||
`git commit -a --author "Joe Coder <joe@coder.org>"` and `--signoff`.
|
||||
|
||||
- If your commit is addressing an issue, use the
|
||||
[GitLab syntax](https://docs.gitlab.com/ce/user/project/issues/automatic_issue_closing.html)
|
||||
[GitLab syntax](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically)
|
||||
to automatically close the issue when merging the commit with the upstream
|
||||
repository:
|
||||
|
||||
|
||||
@@ -185,6 +185,7 @@
|
||||
"builddir" : true,
|
||||
"config-opts" : [
|
||||
"--libdir=/app/lib",
|
||||
"-Dvulkan=disabled",
|
||||
"-Dbuildtype=debugoptimized",
|
||||
"-Ddemo-profile=devel"
|
||||
],
|
||||
@@ -199,6 +200,7 @@
|
||||
],
|
||||
"build-options" : {
|
||||
"env" : {
|
||||
"GSK_RENDERER" : "opengl"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,6 +114,7 @@
|
||||
"builddir" : true,
|
||||
"config-opts" : [
|
||||
"--libdir=/app/lib",
|
||||
"-Dvulkan=disabled",
|
||||
"-Dbuildtype=debugoptimized",
|
||||
"-Ddemo-profile=devel"
|
||||
],
|
||||
|
||||
@@ -114,6 +114,7 @@
|
||||
"builddir" : true,
|
||||
"config-opts" : [
|
||||
"--libdir=/app/lib",
|
||||
"-Dvulkan=disabled",
|
||||
"-Dbuildtype=debugoptimized",
|
||||
"-Ddemo-profile=devel"
|
||||
],
|
||||
@@ -129,6 +130,8 @@
|
||||
"build-options" : {
|
||||
"env" : {
|
||||
"DBUS_SESSION_BUS_ADDRESS" : "''",
|
||||
"GSK_RENDERER" : "opengl",
|
||||
"GDK_DEBUG" : "vulkan-disable",
|
||||
"G_ENABLE_DEBUG" : "true"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,6 +114,7 @@
|
||||
"builddir" : true,
|
||||
"config-opts" : [
|
||||
"--libdir=/app/lib",
|
||||
"-Dvulkan=disabled",
|
||||
"-Dbuildtype=debugoptimized",
|
||||
"-Ddemo-profile=devel"
|
||||
],
|
||||
@@ -129,6 +130,8 @@
|
||||
"build-options" : {
|
||||
"env" : {
|
||||
"DBUS_SESSION_BUS_ADDRESS" : "''",
|
||||
"GSK_RENDERER" : "opengl",
|
||||
"GDK_DEBUG" : "vulkan-disable",
|
||||
"G_ENABLE_DEBUG" : "true"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#include "demos.h"
|
||||
#include "fontify.h"
|
||||
|
||||
#include "demo_conf.h"
|
||||
#include "profile_conf.h"
|
||||
|
||||
static GtkWidget *info_view;
|
||||
static GtkWidget *source_view;
|
||||
|
||||
@@ -236,7 +236,7 @@ foreach flag: common_cflags
|
||||
endif
|
||||
endforeach
|
||||
|
||||
gtkdemo_deps += [ demo_conf_h ]
|
||||
gtkdemo_deps += [ profile_conf_h ]
|
||||
|
||||
executable('gtk4-demo',
|
||||
sources: [demos, demos_h, extra_demo_sources, gtkdemo_resources],
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "iconbrowserapp.h"
|
||||
#include "iconbrowserwin.h"
|
||||
|
||||
#include "demo_conf.h"
|
||||
#include "profile_conf.h"
|
||||
|
||||
struct _IconBrowserApp
|
||||
{
|
||||
|
||||
@@ -14,7 +14,7 @@ iconbrowser_resources = gnome.compile_resources('iconbrowser_resources',
|
||||
executable('gtk4-icon-browser',
|
||||
sources: [iconbrowser_sources, iconbrowser_resources],
|
||||
c_args: common_cflags,
|
||||
dependencies: [ libgtk_dep, demo_conf_h ],
|
||||
dependencies: [ libgtk_dep, profile_conf_h ],
|
||||
include_directories: confinc,
|
||||
win_subsystem: 'windows',
|
||||
link_args: extra_demo_ldflags,
|
||||
|
||||
@@ -1,16 +1,3 @@
|
||||
gen_demo_header = find_program('../build-aux/meson/gen-demo-header.py')
|
||||
demo_profile = get_option('demo-profile')
|
||||
|
||||
demo_conf_h = declare_dependency(
|
||||
sources: custom_target('demo-header',
|
||||
command: [gen_demo_header, meson.project_source_root(), demo_profile],
|
||||
capture: true,
|
||||
output: 'demo_conf.h',
|
||||
build_by_default: true,
|
||||
build_always_stale: true,
|
||||
)
|
||||
)
|
||||
|
||||
# appdata
|
||||
|
||||
appdata_config = configuration_data()
|
||||
|
||||
@@ -12,7 +12,7 @@ node_editor_resources = gnome.compile_resources('node_editor_resources',
|
||||
|
||||
executable('gtk4-node-editor',
|
||||
sources: [node_editor_sources, node_editor_resources],
|
||||
dependencies: [ libgtk_dep, demo_conf_h ],
|
||||
dependencies: [ libgtk_dep, profile_conf_h ],
|
||||
include_directories: confinc,
|
||||
c_args: common_cflags,
|
||||
win_subsystem: 'windows',
|
||||
|
||||
@@ -19,15 +19,13 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef HAVE_PANGOFT
|
||||
#include <pango/pangofc-fontmap.h>
|
||||
#endif
|
||||
#include <glib/gstdio.h>
|
||||
|
||||
#include "node-editor-application.h"
|
||||
|
||||
#include "node-editor-window.h"
|
||||
|
||||
#include "demo_conf.h"
|
||||
#include "profile_conf.h"
|
||||
|
||||
static const char *css =
|
||||
"textview.editor {"
|
||||
@@ -49,47 +47,11 @@ struct _NodeEditorApplicationClass
|
||||
GtkApplicationClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (NodeEditorApplication, node_editor_application, GTK_TYPE_APPLICATION);
|
||||
|
||||
static void
|
||||
maybe_add_test_fonts (void)
|
||||
{
|
||||
#ifdef HAVE_PANGOFT
|
||||
const char *subdir = "testsuite/gsk/fonts";
|
||||
const char *source_dir;
|
||||
char *dir;
|
||||
|
||||
source_dir = g_getenv ("GTK_SOURCE_DIR");
|
||||
|
||||
if (source_dir)
|
||||
{
|
||||
char *abs_source_dir = g_canonicalize_filename (source_dir, NULL);
|
||||
dir = g_canonicalize_filename (subdir, abs_source_dir);
|
||||
g_free (abs_source_dir);
|
||||
}
|
||||
else
|
||||
{
|
||||
char *current_dir = g_get_current_dir ();
|
||||
dir = g_canonicalize_filename (subdir, current_dir);
|
||||
g_free (current_dir);
|
||||
}
|
||||
|
||||
if (g_file_test (dir, G_FILE_TEST_EXISTS))
|
||||
{
|
||||
FcConfig *config;
|
||||
|
||||
config = FcConfigGetCurrent ();
|
||||
FcConfigAppFontAddDir (config, (const FcChar8 *) dir);
|
||||
}
|
||||
|
||||
g_free (dir);
|
||||
#endif
|
||||
}
|
||||
G_DEFINE_TYPE(NodeEditorApplication, node_editor_application, GTK_TYPE_APPLICATION);
|
||||
|
||||
static void
|
||||
node_editor_application_init (NodeEditorApplication *app)
|
||||
{
|
||||
maybe_add_test_fonts ();
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -287,11 +249,63 @@ node_editor_application_class_init (NodeEditorApplicationClass *class)
|
||||
application_class->open = node_editor_application_open;
|
||||
}
|
||||
|
||||
static void
|
||||
print_version (void)
|
||||
{
|
||||
g_print ("gtk4-node-editor %s%s%s\n",
|
||||
PACKAGE_VERSION,
|
||||
g_strcmp0 (PROFILE, "devel") == 0 ? "-" : "",
|
||||
g_strcmp0 (PROFILE, "devel") == 0 ? VCS_TAG : "");
|
||||
}
|
||||
|
||||
static int
|
||||
local_options (GApplication *app,
|
||||
GVariantDict *options,
|
||||
gpointer data)
|
||||
{
|
||||
gboolean version = FALSE;
|
||||
gboolean reset = FALSE;
|
||||
|
||||
g_variant_dict_lookup (options, "version", "b", &version);
|
||||
|
||||
if (version)
|
||||
{
|
||||
print_version ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
g_variant_dict_lookup (options, "reset", "b", &reset);
|
||||
|
||||
if (reset)
|
||||
{
|
||||
char *path;
|
||||
|
||||
path = get_autosave_path ("-unsafe");
|
||||
g_remove (path);
|
||||
g_free (path);
|
||||
path = get_autosave_path (NULL);
|
||||
g_remove (path);
|
||||
g_free (path);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
NodeEditorApplication *
|
||||
node_editor_application_new (void)
|
||||
{
|
||||
return g_object_new (NODE_EDITOR_APPLICATION_TYPE,
|
||||
"application-id", "org.gtk.gtk4.NodeEditor",
|
||||
"flags", G_APPLICATION_HANDLES_OPEN,
|
||||
NULL);
|
||||
NodeEditorApplication *app;
|
||||
|
||||
app = g_object_new (NODE_EDITOR_APPLICATION_TYPE,
|
||||
"application-id", "org.gtk.gtk4.NodeEditor",
|
||||
"flags", G_APPLICATION_HANDLES_OPEN,
|
||||
NULL);
|
||||
|
||||
g_application_add_main_option (G_APPLICATION (app), "version", 0, 0,G_OPTION_ARG_NONE, "Show program version", NULL);
|
||||
g_application_add_main_option (G_APPLICATION (app), "reset", 0, 0,G_OPTION_ARG_NONE, "Remove autosave content", NULL);
|
||||
|
||||
g_signal_connect (app, "handle-local-options", G_CALLBACK (local_options), NULL);
|
||||
|
||||
return app;
|
||||
}
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
#include "gsk/broadway/gskbroadwayrenderer.h"
|
||||
#endif
|
||||
|
||||
#include <glib/gstdio.h>
|
||||
|
||||
#include <cairo.h>
|
||||
#ifdef CAIRO_HAS_SVG_SURFACE
|
||||
#include <cairo-svg.h>
|
||||
@@ -55,6 +57,7 @@ struct _NodeEditorWindow
|
||||
GtkWidget *testcase_name_entry;
|
||||
GtkWidget *testcase_save_button;
|
||||
GtkWidget *scale_scale;
|
||||
GtkWidget *crash_warning;
|
||||
|
||||
GtkWidget *renderer_listbox;
|
||||
GListStore *renderers;
|
||||
@@ -64,6 +67,9 @@ struct _NodeEditorWindow
|
||||
GFileMonitor *file_monitor;
|
||||
|
||||
GArray *errors;
|
||||
|
||||
guint update_timeout;
|
||||
gboolean auto_reload;
|
||||
};
|
||||
|
||||
struct _NodeEditorWindowClass
|
||||
@@ -71,6 +77,13 @@ struct _NodeEditorWindowClass
|
||||
GtkApplicationWindowClass parent_class;
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_AUTO_RELOAD = 1,
|
||||
NUM_PROPERTIES
|
||||
};
|
||||
|
||||
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
|
||||
|
||||
G_DEFINE_TYPE(NodeEditorWindow, node_editor_window, GTK_TYPE_APPLICATION_WINDOW);
|
||||
|
||||
static void
|
||||
@@ -163,19 +176,84 @@ text_iter_skip_whitespace_backward (GtkTextIter *iter)
|
||||
}
|
||||
|
||||
static void
|
||||
text_changed (GtkTextBuffer *buffer,
|
||||
NodeEditorWindow *self)
|
||||
highlight_text (NodeEditorWindow *self)
|
||||
{
|
||||
GtkTextIter iter;
|
||||
GtkTextIter start, end;
|
||||
|
||||
gtk_text_buffer_get_start_iter (self->text_buffer, &iter);
|
||||
|
||||
while (!gtk_text_iter_is_end (&iter))
|
||||
{
|
||||
gunichar c = gtk_text_iter_get_char (&iter);
|
||||
|
||||
if (c == '{')
|
||||
{
|
||||
GtkTextIter word_end = iter;
|
||||
GtkTextIter word_start;
|
||||
|
||||
gtk_text_iter_backward_char (&word_end);
|
||||
text_iter_skip_whitespace_backward (&word_end);
|
||||
|
||||
word_start = word_end;
|
||||
gtk_text_iter_backward_word_start (&word_start);
|
||||
text_iter_skip_alpha_backward (&word_start);
|
||||
|
||||
gtk_text_buffer_apply_tag_by_name (self->text_buffer, "nodename", &word_start, &word_end);
|
||||
}
|
||||
else if (c == ':')
|
||||
{
|
||||
GtkTextIter word_end = iter;
|
||||
GtkTextIter word_start;
|
||||
|
||||
gtk_text_iter_backward_char (&word_end);
|
||||
text_iter_skip_whitespace_backward (&word_end);
|
||||
|
||||
word_start = word_end;
|
||||
gtk_text_iter_backward_word_start (&word_start);
|
||||
text_iter_skip_alpha_backward (&word_start);
|
||||
|
||||
gtk_text_buffer_apply_tag_by_name (self->text_buffer, "propname", &word_start, &word_end);
|
||||
}
|
||||
else if (c == '"')
|
||||
{
|
||||
GtkTextIter string_start = iter;
|
||||
GtkTextIter string_end = iter;
|
||||
|
||||
gtk_text_iter_forward_char (&iter);
|
||||
while (!gtk_text_iter_is_end (&iter))
|
||||
{
|
||||
c = gtk_text_iter_get_char (&iter);
|
||||
|
||||
if (c == '"')
|
||||
{
|
||||
gtk_text_iter_forward_char (&iter);
|
||||
string_end = iter;
|
||||
break;
|
||||
}
|
||||
|
||||
gtk_text_iter_forward_char (&iter);
|
||||
}
|
||||
|
||||
gtk_text_buffer_apply_tag_by_name (self->text_buffer, "string", &string_start, &string_end);
|
||||
}
|
||||
|
||||
gtk_text_iter_forward_char (&iter);
|
||||
}
|
||||
|
||||
gtk_text_buffer_get_bounds (self->text_buffer, &start, &end);
|
||||
gtk_text_buffer_apply_tag_by_name (self->text_buffer, "no-hyphens", &start, &end);
|
||||
}
|
||||
|
||||
static void
|
||||
reload (NodeEditorWindow *self)
|
||||
{
|
||||
char *text;
|
||||
GBytes *bytes;
|
||||
GtkTextIter iter;
|
||||
GtkTextIter start, end;
|
||||
float scale;
|
||||
GskRenderNode *big_node;
|
||||
|
||||
g_array_remove_range (self->errors, 0, self->errors->len);
|
||||
text = get_current_text (self->text_buffer);
|
||||
text_buffer_remove_all_tags (self->text_buffer);
|
||||
bytes = g_bytes_new_take (text, strlen (text));
|
||||
|
||||
g_clear_pointer (&self->node, gsk_render_node_unref);
|
||||
@@ -236,73 +314,19 @@ text_changed (GtkTextBuffer *buffer,
|
||||
}
|
||||
|
||||
g_clear_pointer (&big_node, gsk_render_node_unref);
|
||||
}
|
||||
|
||||
gtk_text_buffer_get_start_iter (self->text_buffer, &iter);
|
||||
static void
|
||||
text_changed (GtkTextBuffer *buffer,
|
||||
NodeEditorWindow *self)
|
||||
{
|
||||
g_array_remove_range (self->errors, 0, self->errors->len);
|
||||
text_buffer_remove_all_tags (self->text_buffer);
|
||||
|
||||
while (!gtk_text_iter_is_end (&iter))
|
||||
{
|
||||
gunichar c = gtk_text_iter_get_char (&iter);
|
||||
if (self->auto_reload)
|
||||
reload (self);
|
||||
|
||||
if (c == '{')
|
||||
{
|
||||
GtkTextIter word_end = iter;
|
||||
GtkTextIter word_start;
|
||||
|
||||
gtk_text_iter_backward_char (&word_end);
|
||||
text_iter_skip_whitespace_backward (&word_end);
|
||||
|
||||
word_start = word_end;
|
||||
gtk_text_iter_backward_word_start (&word_start);
|
||||
text_iter_skip_alpha_backward (&word_start);
|
||||
|
||||
gtk_text_buffer_apply_tag_by_name (self->text_buffer, "nodename",
|
||||
&word_start, &word_end);
|
||||
}
|
||||
else if (c == ':')
|
||||
{
|
||||
GtkTextIter word_end = iter;
|
||||
GtkTextIter word_start;
|
||||
|
||||
gtk_text_iter_backward_char (&word_end);
|
||||
text_iter_skip_whitespace_backward (&word_end);
|
||||
|
||||
word_start = word_end;
|
||||
gtk_text_iter_backward_word_start (&word_start);
|
||||
text_iter_skip_alpha_backward (&word_start);
|
||||
|
||||
gtk_text_buffer_apply_tag_by_name (self->text_buffer, "propname",
|
||||
&word_start, &word_end);
|
||||
}
|
||||
else if (c == '"')
|
||||
{
|
||||
GtkTextIter string_start = iter;
|
||||
GtkTextIter string_end = iter;
|
||||
|
||||
gtk_text_iter_forward_char (&iter);
|
||||
while (!gtk_text_iter_is_end (&iter))
|
||||
{
|
||||
c = gtk_text_iter_get_char (&iter);
|
||||
|
||||
if (c == '"')
|
||||
{
|
||||
gtk_text_iter_forward_char (&iter);
|
||||
string_end = iter;
|
||||
break;
|
||||
}
|
||||
|
||||
gtk_text_iter_forward_char (&iter);
|
||||
}
|
||||
|
||||
gtk_text_buffer_apply_tag_by_name (self->text_buffer, "string",
|
||||
&string_start, &string_end);
|
||||
}
|
||||
|
||||
gtk_text_iter_forward_char (&iter);
|
||||
}
|
||||
|
||||
gtk_text_buffer_get_bounds (self->text_buffer, &start, &end);
|
||||
gtk_text_buffer_apply_tag_by_name (self->text_buffer, "no-hyphens",
|
||||
&start, &end);
|
||||
highlight_text (self);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1101,6 +1125,9 @@ node_editor_window_finalize (GObject *object)
|
||||
{
|
||||
NodeEditorWindow *self = (NodeEditorWindow *)object;
|
||||
|
||||
if (self->update_timeout)
|
||||
g_source_remove (self->update_timeout);
|
||||
|
||||
g_array_free (self->errors, TRUE);
|
||||
|
||||
g_clear_pointer (&self->node, gsk_render_node_unref);
|
||||
@@ -1540,6 +1567,79 @@ edit_action_cb (GtkWidget *widget,
|
||||
node_editor_window_edit (self, &start);
|
||||
}
|
||||
|
||||
static void
|
||||
node_editor_window_map (GtkWidget *widget)
|
||||
{
|
||||
char *path;
|
||||
|
||||
GTK_WIDGET_CLASS (node_editor_window_parent_class)->map (widget);
|
||||
|
||||
path = get_autosave_path (NULL);
|
||||
if (g_file_test (path, G_FILE_TEST_EXISTS))
|
||||
{
|
||||
g_free (path);
|
||||
return;
|
||||
}
|
||||
|
||||
g_free (path);
|
||||
}
|
||||
|
||||
static void
|
||||
node_editor_window_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
NodeEditorWindow *self = NODE_EDITOR_WINDOW (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_AUTO_RELOAD:
|
||||
{
|
||||
gboolean auto_reload = g_value_get_boolean (value);
|
||||
if (self->auto_reload != auto_reload)
|
||||
{
|
||||
self->auto_reload = auto_reload;
|
||||
|
||||
if (self->auto_reload)
|
||||
reload (self);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
node_editor_window_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
NodeEditorWindow *self = NODE_EDITOR_WINDOW (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_AUTO_RELOAD:
|
||||
g_value_set_boolean (value, self->auto_reload);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
close_crash_warning (GtkButton *button,
|
||||
NodeEditorWindow *self)
|
||||
{
|
||||
gtk_revealer_set_reveal_child (GTK_REVEALER (self->crash_warning), FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
node_editor_window_class_init (NodeEditorWindowClass *class)
|
||||
{
|
||||
@@ -1551,6 +1651,8 @@ node_editor_window_class_init (NodeEditorWindowClass *class)
|
||||
|
||||
object_class->dispose = node_editor_window_dispose;
|
||||
object_class->finalize = node_editor_window_finalize;
|
||||
object_class->set_property = node_editor_window_set_property;
|
||||
object_class->get_property = node_editor_window_get_property;
|
||||
|
||||
gtk_widget_class_set_template_from_resource (widget_class,
|
||||
"/org/gtk/gtk4/node-editor/node-editor-window.ui");
|
||||
@@ -1558,6 +1660,14 @@ node_editor_window_class_init (NodeEditorWindowClass *class)
|
||||
widget_class->realize = node_editor_window_realize;
|
||||
widget_class->unrealize = node_editor_window_unrealize;
|
||||
|
||||
widget_class->map = node_editor_window_map;
|
||||
|
||||
properties[PROP_AUTO_RELOAD] = g_param_spec_boolean ("auto-reload", NULL, NULL,
|
||||
TRUE,
|
||||
G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_STATIC_NAME);
|
||||
|
||||
g_object_class_install_properties (object_class, NUM_PROPERTIES, properties);
|
||||
|
||||
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, renderer_listbox);
|
||||
@@ -1567,6 +1677,7 @@ 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, crash_warning);
|
||||
|
||||
gtk_widget_class_bind_template_callback (widget_class, text_view_query_tooltip_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, open_cb);
|
||||
@@ -1579,6 +1690,7 @@ node_editor_window_class_init (NodeEditorWindowClass *class)
|
||||
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, click_gesture_pressed);
|
||||
gtk_widget_class_bind_template_callback (widget_class, close_crash_warning);
|
||||
|
||||
gtk_widget_class_install_action (widget_class, "smart-edit", NULL, edit_action_cb);
|
||||
|
||||
@@ -1630,11 +1742,133 @@ static GActionEntry win_entries[] = {
|
||||
{ "open", window_open, NULL, NULL, NULL },
|
||||
};
|
||||
|
||||
char *
|
||||
get_autosave_path (const char *suffix)
|
||||
{
|
||||
char *path;
|
||||
char *name;
|
||||
|
||||
name = g_strconcat ("autosave", suffix, NULL);
|
||||
path = g_build_filename (g_get_user_cache_dir (), "gtk4-node-editor", name, NULL);
|
||||
g_free (name);
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
static void
|
||||
set_initial_text (NodeEditorWindow *self)
|
||||
{
|
||||
char *path, *path1;
|
||||
char *initial_text;
|
||||
gsize len;
|
||||
|
||||
path = get_autosave_path (NULL);
|
||||
path1 = get_autosave_path ("-unsafe");
|
||||
|
||||
if (g_file_get_contents (path, &initial_text, &len, NULL))
|
||||
{
|
||||
gtk_text_buffer_set_text (self->text_buffer, initial_text, len);
|
||||
g_free (initial_text);
|
||||
}
|
||||
else if (g_file_get_contents (path1, &initial_text, &len, NULL))
|
||||
{
|
||||
self->auto_reload = FALSE;
|
||||
gtk_revealer_set_reveal_child (GTK_REVEALER (self->crash_warning), TRUE);
|
||||
|
||||
gtk_text_buffer_set_text (self->text_buffer, initial_text, len);
|
||||
g_free (initial_text);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Default */
|
||||
gtk_text_buffer_set_text (self->text_buffer,
|
||||
"shadow {\n"
|
||||
" child: texture {\n"
|
||||
" bounds: 0 0 128 128;\n"
|
||||
" texture: url(\"resource:///org/gtk/gtk4/node-editor/icons/apps/org.gtk.gtk4.NodeEditor.svg\");\n"
|
||||
" }\n"
|
||||
" shadows: rgba(0,0,0,0.5) 0 1 12;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"transform {\n"
|
||||
" child: text {\n"
|
||||
" color: rgb(46,52,54);\n"
|
||||
" font: \"Cantarell Bold 11\";\n"
|
||||
" glyphs: \"GTK Node Editor\";\n"
|
||||
" offset: 8 14.418;\n"
|
||||
" }\n"
|
||||
" transform: translate(0, 140);\n"
|
||||
"}", -1);
|
||||
}
|
||||
|
||||
g_free (path);
|
||||
g_free (path1);
|
||||
}
|
||||
|
||||
static void
|
||||
autosave_contents (NodeEditorWindow *self)
|
||||
{
|
||||
char *path = NULL;
|
||||
char *dir = NULL;
|
||||
char *contents;
|
||||
GtkTextIter start, end;
|
||||
|
||||
gtk_text_buffer_get_bounds (self->text_buffer, &start, &end);
|
||||
contents = gtk_text_buffer_get_text (self->text_buffer, &start, &end, TRUE);
|
||||
path = get_autosave_path ("-unsafe");
|
||||
dir = g_path_get_dirname (path);
|
||||
g_mkdir_with_parents (dir, 0755);
|
||||
g_file_set_contents (path, contents, -1, NULL);
|
||||
|
||||
g_free (dir);
|
||||
g_free (path);
|
||||
g_free (contents);
|
||||
}
|
||||
|
||||
static void
|
||||
mark_autosave_as_safe (void)
|
||||
{
|
||||
char *path1 = NULL;
|
||||
char *path2 = NULL;
|
||||
|
||||
path1 = get_autosave_path ("-unsafe");
|
||||
path2 = get_autosave_path (NULL);
|
||||
|
||||
g_rename (path1, path2);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
update_timeout_cb (gpointer data)
|
||||
{
|
||||
NodeEditorWindow *self = data;
|
||||
|
||||
self->update_timeout = 0;
|
||||
|
||||
mark_autosave_as_safe ();
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static void
|
||||
initiate_autosave (NodeEditorWindow *self)
|
||||
{
|
||||
autosave_contents (self);
|
||||
|
||||
if (self->update_timeout != 0)
|
||||
g_source_remove (self->update_timeout);
|
||||
|
||||
self->update_timeout = g_timeout_add (100, update_timeout_cb, self);
|
||||
}
|
||||
|
||||
static void
|
||||
node_editor_window_init (NodeEditorWindow *self)
|
||||
{
|
||||
GAction *action;
|
||||
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
|
||||
self->auto_reload = TRUE;
|
||||
|
||||
self->renderers = g_list_store_new (GDK_TYPE_PAINTABLE);
|
||||
gtk_list_box_bind_model (GTK_LIST_BOX (self->renderer_listbox),
|
||||
G_LIST_MODEL (self->renderers),
|
||||
@@ -1647,6 +1881,10 @@ node_editor_window_init (NodeEditorWindow *self)
|
||||
|
||||
g_action_map_add_action_entries (G_ACTION_MAP (self), win_entries, G_N_ELEMENTS (win_entries), self);
|
||||
|
||||
action = G_ACTION (g_property_action_new ("auto-reload", self, "auto-reload"));
|
||||
g_action_map_add_action (G_ACTION_MAP (self), action);
|
||||
g_object_unref (action);
|
||||
|
||||
self->tag_table = gtk_text_tag_table_new ();
|
||||
gtk_text_tag_table_add (self->tag_table,
|
||||
g_object_new (GTK_TYPE_TEXT_TAG,
|
||||
@@ -1684,25 +1922,9 @@ node_editor_window_init (NodeEditorWindow *self)
|
||||
g_signal_connect (self->scale_scale, "notify::value", G_CALLBACK (scale_changed), self);
|
||||
gtk_text_view_set_buffer (GTK_TEXT_VIEW (self->text_view), self->text_buffer);
|
||||
|
||||
/* Default */
|
||||
gtk_text_buffer_set_text (self->text_buffer,
|
||||
"shadow {\n"
|
||||
" child: texture {\n"
|
||||
" bounds: 0 0 128 128;\n"
|
||||
" texture: url(\"resource:///org/gtk/gtk4/node-editor/icons/apps/org.gtk.gtk4.NodeEditor.svg\");\n"
|
||||
" }\n"
|
||||
" shadows: rgba(0,0,0,0.5) 0 1 12;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"transform {\n"
|
||||
" child: text {\n"
|
||||
" color: rgb(46,52,54);\n"
|
||||
" font: \"Cantarell Bold 11\";\n"
|
||||
" glyphs: \"GTK Node Editor\";\n"
|
||||
" offset: 8 14.418;\n"
|
||||
" }\n"
|
||||
" transform: translate(0, 140);\n"
|
||||
"}", -1);
|
||||
set_initial_text (self);
|
||||
|
||||
g_signal_connect_swapped (self->text_buffer, "changed", G_CALLBACK (initiate_autosave), self);
|
||||
|
||||
if (g_getenv ("GSK_RENDERER"))
|
||||
{
|
||||
|
||||
@@ -37,3 +37,5 @@ NodeEditorWindow * node_editor_window_new (NodeEditorApplication
|
||||
|
||||
gboolean node_editor_window_load (NodeEditorWindow *self,
|
||||
GFile *file);
|
||||
|
||||
char * get_autosave_path (const char *suffix);
|
||||
|
||||
@@ -2,6 +2,14 @@
|
||||
<interface>
|
||||
<menu id="gear_menu">
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_Reload automatically</attribute>
|
||||
<attribute name="action">win.auto-reload</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_Help</attribute>
|
||||
<attribute name="action">app.help</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_Help</attribute>
|
||||
<attribute name="action">app.help</attribute>
|
||||
@@ -24,7 +32,6 @@
|
||||
</item>
|
||||
</section>
|
||||
</menu>
|
||||
|
||||
<object class="GtkPopover" id="testcase_popover">
|
||||
<child>
|
||||
<object class="GtkGrid">
|
||||
@@ -39,7 +46,7 @@
|
||||
<object class="GtkEntry" id="testcase_name_entry">
|
||||
<property name="hexpand">1</property>
|
||||
<property name="activates-default">1</property>
|
||||
<signal name="notify::text" handler="testcase_name_entry_changed_cb" />
|
||||
<signal name="notify::text" handler="testcase_name_entry_changed_cb"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -52,7 +59,6 @@
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="wrap">1</property>
|
||||
@@ -66,7 +72,6 @@
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="GtkLabel" id="testcase_error_label">
|
||||
<property name="wrap">1</property>
|
||||
@@ -78,7 +83,6 @@
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="GtkButton" id="testcase_save_button">
|
||||
<property name="label">Save</property>
|
||||
@@ -86,9 +90,9 @@
|
||||
<property name="halign">end</property>
|
||||
<property name="receives-default">1</property>
|
||||
<property name="sensitive">0</property>
|
||||
<signal name="clicked" handler="testcase_save_clicked_cb" />
|
||||
<signal name="clicked" handler="testcase_save_clicked_cb"/>
|
||||
<style>
|
||||
<class name="suggested-action" />
|
||||
<class name="suggested-action"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="row">4</property>
|
||||
@@ -100,7 +104,6 @@
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
||||
<template class="NodeEditorWindow" parent="GtkApplicationWindow">
|
||||
<property name="title" translatable="yes">GTK Node Editor</property>
|
||||
<property name="default-width">1024</property>
|
||||
@@ -185,83 +188,128 @@
|
||||
</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">
|
||||
<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>
|
||||
<property name="extra-menu">extra_menu</property>
|
||||
<signal name="query-tooltip" handler="text_view_query_tooltip_cb"/>
|
||||
<object class="GtkOverlay">
|
||||
<child type="overlay">
|
||||
<object class="GtkRevealer" id="crash_warning">
|
||||
<property name="transition-type">slide-down</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">start</property>
|
||||
<property name="child">
|
||||
<object class="GtkFrame">
|
||||
<style>
|
||||
<class name="editor" />
|
||||
<class name="app-notification"/>
|
||||
</style>
|
||||
<property name="child">
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">20</property>
|
||||
<property name="margin-start">10</property>
|
||||
<property name="margin-end">10</property>
|
||||
<property name="margin-top">10</property>
|
||||
<property name="margin-bottom">10</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="hexpand">1</property>
|
||||
<property name="halign">1</property>
|
||||
<property name="label" translatable="1">The application may have crashed.
|
||||
As a precaution, auto-loading has been turned off.
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="valign">3</property>
|
||||
<property name="use-underline">1</property>
|
||||
<property name="label" translatable="1">_Close</property>
|
||||
<signal name="clicked" handler="close_crash_warning"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<property name="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">
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="hscrollbar-policy">never</property>
|
||||
<property name="hexpand">1</property>
|
||||
<property name="vexpand">1</property>
|
||||
<child>
|
||||
<object class="GtkGestureClick">
|
||||
<property name="button">1</property>
|
||||
<signal name="pressed" handler="click_gesture_pressed"/>
|
||||
<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>
|
||||
<property name="extra-menu">extra_menu</property>
|
||||
<signal name="query-tooltip" handler="text_view_query_tooltip_cb"/>
|
||||
<style>
|
||||
<class name="editor"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkGestureClick">
|
||||
<property name="button">1</property>
|
||||
<signal name="pressed" handler="click_gesture_pressed"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
<property name="end-child">
|
||||
<object class="GtkBox">
|
||||
<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>
|
||||
</property>
|
||||
<property name="end-child">
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkViewport">
|
||||
<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>
|
||||
<child>
|
||||
<object class="GtkPicture" id="picture">
|
||||
<property name="can-shrink">0</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">center</property>
|
||||
<object class="GtkViewport">
|
||||
<child>
|
||||
<object class="GtkDragSource">
|
||||
<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>
|
||||
<signal name="prepare" handler="on_picture_drag_prepare_cb" swapped="no"/>
|
||||
<property name="formats">application/x-gtk-render-node</property>
|
||||
<signal name="drop" handler="on_picture_drop_cb" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="hscrollbar-policy">never</property>
|
||||
<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 class="GtkListBox" id="renderer_listbox">
|
||||
<property name="selection-mode">none</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>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
|
||||
@@ -322,27 +322,39 @@ stroke bounds of the path.
|
||||
|
||||
### text
|
||||
|
||||
| property | syntax | default | printed |
|
||||
| -------- | ---------------- | ---------------------- | ----------- |
|
||||
| color | `<color>` | black | non-default |
|
||||
| font | `<string>` | "Cantarell 11" | always |
|
||||
| glyphs | `<glyphs>` | "Hello" | always |
|
||||
| offset | `<point>` | 0 0 | non-default |
|
||||
| property | syntax | default | printed |
|
||||
| -------- | ------------------- | ------------------- | ----------- |
|
||||
| color | `<color>` | black | non-default |
|
||||
| font | `<string>` `<url>`? | "Cantarell 11" | always |
|
||||
| glyphs | `<glyphs>` | "Hello" | always |
|
||||
| offset | `<point>` | 0 0 | non-default |
|
||||
|
||||
Creates a node like `gsk_text_node_new()` with the given properties.
|
||||
|
||||
If a url is specified for the font, it must point to a font file for the
|
||||
font that is specified in the string. It can be either a data url containing
|
||||
a base64-encoded font file, or a regular url that points to a font file.
|
||||
|
||||
Glyphs can be specified as an ASCII string, or as a comma-separated list of
|
||||
their glyph ID and advance width. Optionally, x and y offsets and flags can
|
||||
be specified as well, like this: 40 10 0 0 color.
|
||||
|
||||
If the given font does not exist or the given glyphs are invalid for the given
|
||||
font, an error node will be returned.
|
||||
|
||||
### texture
|
||||
|
||||
| property | syntax | default | printed |
|
||||
| -------- | ---------------- | ---------------------- | ----------- |
|
||||
| bounds | `<rect>` | 50 | always |
|
||||
| texture | `<url>` | *see below* | always |
|
||||
| property | syntax | default | printed |
|
||||
| -------- | ------------------- | ---------------------- | ----------- |
|
||||
| bounds | `<rect>` | 50 | always |
|
||||
| texture | `<string>`?`<url>`? | *see below* | always |
|
||||
|
||||
Creates a node like `gsk_texture_node_new()` with the given properties.
|
||||
|
||||
If a string is specified for the texture, it will be used as a name for the text.
|
||||
Textures can be reused by specifying the name of a previously used texture. In
|
||||
that case, the url can be omitted.
|
||||
|
||||
The default texture is a 10x10 checkerboard with the top left and bottom right
|
||||
5x5 being in the color #FF00CC and the other part being transparent. A possible
|
||||
representation for this texture is `url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAABmJLR0QA/wD/AP+gvaeTAAAAKUlEQVQYlWP8z3DmPwMaYGQwYUQXY0IXwAUGUCGGoxkYGBiweXAoeAYAz44F3e3U1xUAAAAASUVORK5CYII=")
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
executable('gtk4-print-editor',
|
||||
sources: ['print-editor.c'],
|
||||
c_args: common_cflags,
|
||||
dependencies: [ libgtk_dep, demo_conf_h ],
|
||||
dependencies: [ libgtk_dep, profile_conf_h ],
|
||||
include_directories: confinc,
|
||||
win_subsystem: 'windows',
|
||||
link_args: extra_demo_ldflags,
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include <glib/gi18n.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "demo_conf.h"
|
||||
#include "profile_conf.h"
|
||||
|
||||
static GtkWidget *main_window;
|
||||
static GFile *filename = NULL;
|
||||
|
||||
@@ -66,7 +66,7 @@ endif
|
||||
executable('gtk4-widget-factory',
|
||||
sources: ['widget-factory.c', widgetfactory_resources],
|
||||
c_args: common_cflags,
|
||||
dependencies: [ libgtk_dep, demo_conf_h ],
|
||||
dependencies: [ libgtk_dep, profile_conf_h ],
|
||||
include_directories: confinc,
|
||||
win_subsystem: 'windows',
|
||||
link_args: extra_demo_ldflags,
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#include <glib/gi18n.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "demo_conf.h"
|
||||
#include "profile_conf.h"
|
||||
|
||||
static void
|
||||
change_dark_state (GSimpleAction *action,
|
||||
|
||||
@@ -30,6 +30,14 @@ OPTIONS
|
||||
|
||||
Show the application help.
|
||||
|
||||
``--version``
|
||||
|
||||
Show the program version.
|
||||
|
||||
``--reset``
|
||||
|
||||
Don't restore autosaved content and remove autosave files.
|
||||
|
||||
ENVIRONMENT
|
||||
-----------
|
||||
|
||||
|
||||
@@ -12,9 +12,10 @@ SYNOPSIS
|
||||
--------
|
||||
| **gtk4-rendernode-tool** <COMMAND> [OPTIONS...] <FILE>
|
||||
|
|
||||
| **gtk4-rendernode-tool** benchmark [OPTIONS...] <FILE>
|
||||
| **gtk4-rendernode-tool** info [OPTIONS...] <FILE>
|
||||
| **gtk4-rendernode-tool** show [OPTIONS...] <FILE>
|
||||
| **gtk4-rendernode-tool** render [OPTIONS...] <FILE> [<FILE>]
|
||||
| **gtk4-rendernode-tool** show [OPTIONS...] <FILE>
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
@@ -50,3 +51,31 @@ The name of the file to write can be specified as a second FILE argument.
|
||||
|
||||
Use the given renderer. Use ``--renderer=help`` to get a information
|
||||
about poassible values for the ``RENDERER``.
|
||||
|
||||
Benchmark
|
||||
^^^^^^^^^
|
||||
|
||||
The ``benchmark`` command benchmarks rendering of a node with the existing renderers
|
||||
and prints the runtimes.
|
||||
|
||||
``--renderer=RENDERER``
|
||||
|
||||
Add the given renderer. This argument can be passed multiple times to test multiple
|
||||
renderers. By default, all major GTK renderers are run.
|
||||
|
||||
``--runs=RUNS``
|
||||
|
||||
Number of times to render the node on each renderer. By default, this is 3 times.
|
||||
Keep in mind that the first run is often used to populate caches and might be
|
||||
significantly slower.
|
||||
|
||||
``--no-download``
|
||||
|
||||
Do not attempt to download the result. This may cause the measurement to not include
|
||||
the execution of the commands on the GPU. It can be useful to use this flag to test
|
||||
command submission performance.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -357,7 +357,7 @@ devices.
|
||||
### `GDK_VULKAN_SKIP`
|
||||
|
||||
This variable can be set to a list of values, which cause GDK to
|
||||
disable features of the Vulkan support.
|
||||
disable features of the Vulkan support.
|
||||
Note that these features may already be disabled if the Vulkan driver
|
||||
does not support them.
|
||||
|
||||
@@ -415,19 +415,24 @@ using and the GDK backend supports them:
|
||||
`vulkan`
|
||||
: Selects the Vulkan renderer
|
||||
|
||||
Note that on Windows, if one is running Nahimic 3 on a system with
|
||||
nVidia graphics, one needs to stop the "Nahimic service" or insert
|
||||
the GTK application into the Nahimic blacklist, as noted in
|
||||
https://www.nvidia.com/en-us/geforce/forums/game-ready-drivers/13/297952/nahimic-and-nvidia-drivers-conflict/2334568/, or use the cairo renderer (at the cost of being unable to use
|
||||
OpenGL features), or use GDK_DEBUG=gl-gles if you know that GLES
|
||||
support is enabled for the build.
|
||||
|
||||
This is a known issue, as the above link indicates, and affects quite
|
||||
a number of applications--sadly, since this issue lies within the
|
||||
nVidia graphics driver and/or the Nahimic 3 code, we are not able
|
||||
to rememdy this on the GTK side; the best bet before trying the above
|
||||
workarounds is to try to update your graphics drivers and Nahimic
|
||||
installation.
|
||||
::: note
|
||||
If you are running the Nahimic 3 service on a Windows system with
|
||||
nVidia graphics, you need to perform one of the following:
|
||||
|
||||
- stop the "Nahimic service"
|
||||
- insert the GTK application into the Nahimic blocklist, as noted in the
|
||||
[nVidia forums](https://www.nvidia.com/en-us/geforce/forums/game-ready-drivers/13/297952/nahimic-and-nvidia-drivers-conflict/2334568/)
|
||||
- use the cairo renderer (at the cost of being unable to use OpenGL features)
|
||||
- use `GDK_DEBUG=gl-gles`, if you know that GLES support is enabled for the build.
|
||||
|
||||
This is a known issue, as the above link indicates, and affects quite
|
||||
a number of applications—sadly, since this issue lies within the
|
||||
nVidia graphics driver and/or the Nahimic 3 code, we are not able
|
||||
to rememdy this on the GTK side; the best bet before trying the above
|
||||
workarounds is to try to update your graphics drivers and Nahimic
|
||||
installation.
|
||||
|
||||
|
||||
### `GSK_GPU_SKIP`
|
||||
|
||||
|
||||
+2
-1
@@ -289,7 +289,8 @@ gdk_device_class_init (GdkDeviceClass *klass)
|
||||
*/
|
||||
device_props[PROP_MODIFIER_STATE] =
|
||||
g_param_spec_flags ("modifier-state", NULL, NULL,
|
||||
GDK_TYPE_MODIFIER_TYPE, 0,
|
||||
GDK_TYPE_MODIFIER_TYPE,
|
||||
GDK_NO_MODIFIER_MASK,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_object_class_install_properties (object_class, LAST_PROP, device_props);
|
||||
|
||||
+4
-4
@@ -56,10 +56,10 @@ static struct {
|
||||
GdkCursor *cursor;
|
||||
} drag_cursors[] = {
|
||||
{ GDK_ACTION_ASK, "dnd-ask", NULL },
|
||||
{ GDK_ACTION_COPY, "dnd-copy", NULL },
|
||||
{ GDK_ACTION_MOVE, "dnd-move", NULL },
|
||||
{ GDK_ACTION_LINK, "dnd-link", NULL },
|
||||
{ 0, "dnd-none", NULL },
|
||||
{ GDK_ACTION_COPY, "copy", NULL },
|
||||
{ GDK_ACTION_MOVE, "move", NULL },
|
||||
{ GDK_ACTION_LINK, "alias", NULL },
|
||||
{ 0, "no-drop", NULL },
|
||||
};
|
||||
|
||||
enum {
|
||||
|
||||
+9
-1
@@ -161,7 +161,12 @@ gdk_gl_texture_find_format (GdkGLContext *context,
|
||||
if (!(gdk_gl_context_get_format_flags (context, format) & GDK_GL_FORMAT_RENDERABLE))
|
||||
continue;
|
||||
|
||||
gdk_memory_format_gl_format (format, &q_internal_format, &q_format, &q_type, q_swizzle);
|
||||
gdk_memory_format_gl_format (format,
|
||||
gdk_gl_context_get_use_es (context),
|
||||
&q_internal_format,
|
||||
&q_format,
|
||||
&q_type,
|
||||
q_swizzle);
|
||||
|
||||
if (q_format != gl_format || q_type != gl_type)
|
||||
continue;
|
||||
@@ -193,6 +198,7 @@ gdk_gl_texture_do_download (GdkGLTexture *self,
|
||||
((gdk_gl_context_get_format_flags (context, format) & GDK_GL_FORMAT_USABLE) == GDK_GL_FORMAT_USABLE))
|
||||
{
|
||||
gdk_memory_format_gl_format (format,
|
||||
gdk_gl_context_get_use_es (context),
|
||||
&gl_internal_format,
|
||||
&gl_format, &gl_type, gl_swizzle);
|
||||
if (download->stride == expected_stride &&
|
||||
@@ -255,6 +261,7 @@ gdk_gl_texture_do_download (GdkGLTexture *self,
|
||||
actual_format = gdk_memory_format_get_straight (actual_format);
|
||||
|
||||
gdk_memory_format_gl_format (actual_format,
|
||||
gdk_gl_context_get_use_es (context),
|
||||
&gl_internal_format,
|
||||
&gl_read_format, &gl_read_type, gl_swizzle);
|
||||
}
|
||||
@@ -266,6 +273,7 @@ gdk_gl_texture_do_download (GdkGLTexture *self,
|
||||
actual_format = gdk_memory_format_get_straight (actual_format);
|
||||
|
||||
gdk_memory_format_gl_format (actual_format,
|
||||
gdk_gl_context_get_use_es (context),
|
||||
&gl_internal_format,
|
||||
&gl_read_format, &gl_read_type, gl_swizzle);
|
||||
}
|
||||
|
||||
+79
-36
@@ -335,7 +335,8 @@ struct _GdkMemoryFormatDescription
|
||||
GdkMemoryDepth depth;
|
||||
const GdkMemoryFormat *fallbacks;
|
||||
struct {
|
||||
GLint internal_format;
|
||||
GLint internal_gl_format;
|
||||
GLint internal_gles_format;
|
||||
GLenum format;
|
||||
GLenum type;
|
||||
GLint swizzle[4];
|
||||
@@ -375,7 +376,8 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
-1,
|
||||
},
|
||||
.gl = {
|
||||
.internal_format = GL_RGBA8,
|
||||
.internal_gl_format = GL_RGBA8,
|
||||
.internal_gles_format = GL_BGRA,
|
||||
.format = GL_BGRA,
|
||||
.type = GL_UNSIGNED_BYTE,
|
||||
.swizzle = { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA },
|
||||
@@ -402,7 +404,8 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
-1,
|
||||
},
|
||||
.gl = {
|
||||
.internal_format = GL_RGBA8,
|
||||
.internal_gl_format = GL_RGBA8,
|
||||
.internal_gles_format = GL_RGBA8,
|
||||
.format = GL_BGRA,
|
||||
.type = GDK_GL_UNSIGNED_BYTE_FLIPPED,
|
||||
.swizzle = { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA },
|
||||
@@ -429,7 +432,8 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
-1,
|
||||
},
|
||||
.gl = {
|
||||
.internal_format = GL_RGBA8,
|
||||
.internal_gl_format = GL_RGBA8,
|
||||
.internal_gles_format = GL_RGBA8,
|
||||
.format = GL_RGBA,
|
||||
.type = GL_UNSIGNED_BYTE,
|
||||
.swizzle = { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA },
|
||||
@@ -455,7 +459,8 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
-1,
|
||||
},
|
||||
.gl = {
|
||||
.internal_format = GL_RGBA8,
|
||||
.internal_gl_format = GL_RGBA8,
|
||||
.internal_gles_format = GL_RGBA8,
|
||||
.format = GL_RGBA,
|
||||
.type = GDK_GL_UNSIGNED_BYTE_FLIPPED,
|
||||
.swizzle = { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA },
|
||||
@@ -482,7 +487,8 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
-1,
|
||||
},
|
||||
.gl = {
|
||||
.internal_format = GL_RGBA8,
|
||||
.internal_gl_format = GL_RGBA8,
|
||||
.internal_gles_format = GL_BGRA,
|
||||
.format = GL_BGRA,
|
||||
.type = GL_UNSIGNED_BYTE,
|
||||
.swizzle = { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA },
|
||||
@@ -509,7 +515,8 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
-1,
|
||||
},
|
||||
.gl = {
|
||||
.internal_format = GL_RGBA8,
|
||||
.internal_gl_format = GL_RGBA8,
|
||||
.internal_gles_format = GL_RGBA8,
|
||||
.format = GL_BGRA,
|
||||
.type = GDK_GL_UNSIGNED_BYTE_FLIPPED,
|
||||
.swizzle = { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA },
|
||||
@@ -536,7 +543,8 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
-1,
|
||||
},
|
||||
.gl = {
|
||||
.internal_format = GL_RGBA8,
|
||||
.internal_gl_format = GL_RGBA8,
|
||||
.internal_gles_format = GL_RGBA8,
|
||||
.format = GL_RGBA,
|
||||
.type = GL_UNSIGNED_BYTE,
|
||||
.swizzle = { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA },
|
||||
@@ -562,7 +570,8 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
-1,
|
||||
},
|
||||
.gl = {
|
||||
.internal_format = GL_RGBA8,
|
||||
.internal_gl_format = GL_RGBA8,
|
||||
.internal_gles_format = GL_RGBA8,
|
||||
.format = GL_RGBA,
|
||||
.type = GDK_GL_UNSIGNED_BYTE_FLIPPED,
|
||||
.swizzle = { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA },
|
||||
@@ -590,7 +599,8 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
-1,
|
||||
},
|
||||
.gl = {
|
||||
.internal_format = GL_RGBA8,
|
||||
.internal_gl_format = GL_RGBA8,
|
||||
.internal_gles_format = GL_BGRA,
|
||||
.format = GL_BGRA,
|
||||
.type = GL_UNSIGNED_BYTE,
|
||||
.swizzle = { GL_RED, GL_GREEN, GL_BLUE, GL_ONE },
|
||||
@@ -618,7 +628,8 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
-1,
|
||||
},
|
||||
.gl = {
|
||||
.internal_format = GL_RGBA8,
|
||||
.internal_gl_format = GL_RGBA8,
|
||||
.internal_gles_format = GL_RGBA8,
|
||||
.format = GL_BGRA,
|
||||
.type = GDK_GL_UNSIGNED_BYTE_FLIPPED,
|
||||
.swizzle = { GL_RED, GL_GREEN, GL_BLUE, GL_ONE },
|
||||
@@ -646,7 +657,8 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
-1,
|
||||
},
|
||||
.gl = {
|
||||
.internal_format = GL_RGBA8,
|
||||
.internal_gl_format = GL_RGBA8,
|
||||
.internal_gles_format = GL_RGBA8,
|
||||
.format = GL_RGBA,
|
||||
.type = GL_UNSIGNED_BYTE,
|
||||
.swizzle = { GL_RED, GL_GREEN, GL_BLUE, GL_ONE },
|
||||
@@ -673,7 +685,8 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
-1,
|
||||
},
|
||||
.gl = {
|
||||
.internal_format = GL_RGBA8,
|
||||
.internal_gl_format = GL_RGBA8,
|
||||
.internal_gles_format = GL_RGBA8,
|
||||
.format = GL_RGBA,
|
||||
.type = GDK_GL_UNSIGNED_BYTE_FLIPPED,
|
||||
.swizzle = { GL_RED, GL_GREEN, GL_BLUE, GL_ONE },
|
||||
@@ -701,7 +714,8 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
-1,
|
||||
},
|
||||
.gl = {
|
||||
.internal_format = GL_RGB8,
|
||||
.internal_gl_format = GL_RGB8,
|
||||
.internal_gles_format = GL_RGB8,
|
||||
.format = GL_RGB,
|
||||
.type = GL_UNSIGNED_BYTE,
|
||||
.swizzle = { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA },
|
||||
@@ -728,7 +742,8 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
-1,
|
||||
},
|
||||
.gl = {
|
||||
.internal_format = GL_RGB8,
|
||||
.internal_gl_format = GL_RGB8,
|
||||
.internal_gles_format = GL_RGB8,
|
||||
.format = GL_BGR,
|
||||
.type = GL_UNSIGNED_BYTE,
|
||||
.swizzle = { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA },
|
||||
@@ -759,7 +774,8 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
-1,
|
||||
},
|
||||
.gl = {
|
||||
.internal_format = GL_RGB16,
|
||||
.internal_gl_format = GL_RGB16,
|
||||
.internal_gles_format = GL_RGB16,
|
||||
.format = GL_RGB,
|
||||
.type = GL_UNSIGNED_SHORT,
|
||||
.swizzle = { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA },
|
||||
@@ -788,7 +804,8 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
-1,
|
||||
},
|
||||
.gl = {
|
||||
.internal_format = GL_RGBA16,
|
||||
.internal_gl_format = GL_RGBA16,
|
||||
.internal_gles_format = GL_RGBA16,
|
||||
.format = GL_RGBA,
|
||||
.type = GL_UNSIGNED_SHORT,
|
||||
.swizzle = { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA },
|
||||
@@ -817,7 +834,8 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
-1,
|
||||
},
|
||||
.gl = {
|
||||
.internal_format = GL_RGBA16,
|
||||
.internal_gl_format = GL_RGBA16,
|
||||
.internal_gles_format = GL_RGBA16,
|
||||
.format = GL_RGBA,
|
||||
.type = GL_UNSIGNED_SHORT,
|
||||
.swizzle = { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA },
|
||||
@@ -846,7 +864,8 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
-1,
|
||||
},
|
||||
.gl = {
|
||||
.internal_format = GL_RGB16F,
|
||||
.internal_gl_format = GL_RGB16F,
|
||||
.internal_gles_format = GL_RGB16F,
|
||||
.format = GL_RGB,
|
||||
.type = GL_HALF_FLOAT,
|
||||
.swizzle = { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA },
|
||||
@@ -874,7 +893,8 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
-1,
|
||||
},
|
||||
.gl = {
|
||||
.internal_format = GL_RGBA16F,
|
||||
.internal_gl_format = GL_RGBA16F,
|
||||
.internal_gles_format = GL_RGBA16F,
|
||||
.format = GL_RGBA,
|
||||
.type = GL_HALF_FLOAT,
|
||||
.swizzle = { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA },
|
||||
@@ -902,7 +922,8 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
-1,
|
||||
},
|
||||
.gl = {
|
||||
.internal_format = GL_RGBA16F,
|
||||
.internal_gl_format = GL_RGBA16F,
|
||||
.internal_gles_format = GL_RGBA16F,
|
||||
.format = GL_RGBA,
|
||||
.type = GL_HALF_FLOAT,
|
||||
.swizzle = { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA },
|
||||
@@ -931,7 +952,8 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
-1,
|
||||
},
|
||||
.gl = {
|
||||
.internal_format = GL_RGB32F,
|
||||
.internal_gl_format = GL_RGB32F,
|
||||
.internal_gles_format = GL_RGB32F,
|
||||
.format = GL_RGB,
|
||||
.type = GL_FLOAT,
|
||||
.swizzle = { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA },
|
||||
@@ -959,7 +981,8 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
-1,
|
||||
},
|
||||
.gl = {
|
||||
.internal_format = GL_RGBA32F,
|
||||
.internal_gl_format = GL_RGBA32F,
|
||||
.internal_gles_format = GL_RGBA32F,
|
||||
.format = GL_RGBA,
|
||||
.type = GL_FLOAT,
|
||||
.swizzle = { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA },
|
||||
@@ -987,7 +1010,8 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
-1,
|
||||
},
|
||||
.gl = {
|
||||
.internal_format = GL_RGBA32F,
|
||||
.internal_gl_format = GL_RGBA32F,
|
||||
.internal_gles_format = GL_RGBA32F,
|
||||
.format = GL_RGBA,
|
||||
.type = GL_FLOAT,
|
||||
.swizzle = { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA },
|
||||
@@ -1014,7 +1038,8 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
-1,
|
||||
},
|
||||
.gl = {
|
||||
.internal_format = GL_RG8,
|
||||
.internal_gl_format = GL_RG8,
|
||||
.internal_gles_format = GL_RG8,
|
||||
.format = GL_RG,
|
||||
.type = GL_UNSIGNED_BYTE,
|
||||
.swizzle = { GL_RED, GL_RED, GL_RED, GL_GREEN },
|
||||
@@ -1041,7 +1066,8 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
-1,
|
||||
},
|
||||
.gl = {
|
||||
.internal_format = GL_RG8,
|
||||
.internal_gl_format = GL_RG8,
|
||||
.internal_gles_format = GL_RG8,
|
||||
.format = GL_RG,
|
||||
.type = GL_UNSIGNED_BYTE,
|
||||
.swizzle = { GL_RED, GL_RED, GL_RED, GL_GREEN },
|
||||
@@ -1068,7 +1094,8 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
-1,
|
||||
},
|
||||
.gl = {
|
||||
.internal_format = GL_R8,
|
||||
.internal_gl_format = GL_R8,
|
||||
.internal_gles_format = GL_R8,
|
||||
.format = GL_RED,
|
||||
.type = GL_UNSIGNED_BYTE,
|
||||
.swizzle = { GL_RED, GL_RED, GL_RED, GL_ONE },
|
||||
@@ -1098,7 +1125,8 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
-1,
|
||||
},
|
||||
.gl = {
|
||||
.internal_format = GL_RG16,
|
||||
.internal_gl_format = GL_RG16,
|
||||
.internal_gles_format = GL_RG16,
|
||||
.format = GL_RG,
|
||||
.type = GL_UNSIGNED_SHORT,
|
||||
.swizzle = { GL_RED, GL_RED, GL_RED, GL_GREEN },
|
||||
@@ -1128,7 +1156,8 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
-1,
|
||||
},
|
||||
.gl = {
|
||||
.internal_format = GL_RG16,
|
||||
.internal_gl_format = GL_RG16,
|
||||
.internal_gles_format = GL_RG16,
|
||||
.format = GL_RG,
|
||||
.type = GL_UNSIGNED_SHORT,
|
||||
.swizzle = { GL_RED, GL_RED, GL_RED, GL_GREEN },
|
||||
@@ -1158,7 +1187,8 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
-1,
|
||||
},
|
||||
.gl = {
|
||||
.internal_format = GL_R16,
|
||||
.internal_gl_format = GL_R16,
|
||||
.internal_gles_format = GL_R16,
|
||||
.format = GL_RED,
|
||||
.type = GL_UNSIGNED_SHORT,
|
||||
.swizzle = { GL_RED, GL_RED, GL_RED, GL_ONE },
|
||||
@@ -1185,7 +1215,8 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
-1,
|
||||
},
|
||||
.gl = {
|
||||
.internal_format = GL_R8,
|
||||
.internal_gl_format = GL_R8,
|
||||
.internal_gles_format = GL_R8,
|
||||
.format = GL_RED,
|
||||
.type = GL_UNSIGNED_BYTE,
|
||||
.swizzle = { GL_RED, GL_RED, GL_RED, GL_RED },
|
||||
@@ -1215,7 +1246,8 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
-1,
|
||||
},
|
||||
.gl = {
|
||||
.internal_format = GL_R16,
|
||||
.internal_gl_format = GL_R16,
|
||||
.internal_gles_format = GL_R16,
|
||||
.format = GL_RED,
|
||||
.type = GL_UNSIGNED_SHORT,
|
||||
.swizzle = { GL_RED, GL_RED, GL_RED, GL_RED },
|
||||
@@ -1244,7 +1276,8 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
-1,
|
||||
},
|
||||
.gl = {
|
||||
.internal_format = GL_R16F,
|
||||
.internal_gl_format = GL_R16F,
|
||||
.internal_gles_format = GL_R16F,
|
||||
.format = GL_RED,
|
||||
.type = GL_HALF_FLOAT,
|
||||
.swizzle = { GL_RED, GL_RED, GL_RED, GL_RED },
|
||||
@@ -1273,7 +1306,8 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
-1,
|
||||
},
|
||||
.gl = {
|
||||
.internal_format = GL_R32F,
|
||||
.internal_gl_format = GL_R32F,
|
||||
.internal_gles_format = GL_R32F,
|
||||
.format = GL_RED,
|
||||
.type = GL_FLOAT,
|
||||
.swizzle = { GL_RED, GL_RED, GL_RED, GL_RED },
|
||||
@@ -1473,12 +1507,16 @@ gdk_memory_depth_get_alpha_format (GdkMemoryDepth depth)
|
||||
|
||||
void
|
||||
gdk_memory_format_gl_format (GdkMemoryFormat format,
|
||||
gboolean gles,
|
||||
GLint *out_internal_format,
|
||||
GLenum *out_format,
|
||||
GLenum *out_type,
|
||||
GLint out_swizzle[4])
|
||||
{
|
||||
*out_internal_format = memory_formats[format].gl.internal_format;
|
||||
if (gles)
|
||||
*out_internal_format = memory_formats[format].gl.internal_gles_format;
|
||||
else
|
||||
*out_internal_format = memory_formats[format].gl.internal_gl_format;
|
||||
*out_format = memory_formats[format].gl.format;
|
||||
*out_type = memory_formats[format].gl.type;
|
||||
memcpy (out_swizzle, memory_formats[format].gl.swizzle, sizeof(GLint) * 4);
|
||||
@@ -1487,6 +1525,7 @@ gdk_memory_format_gl_format (GdkMemoryFormat format,
|
||||
/*
|
||||
* gdk_memory_format_gl_rgba_format:
|
||||
* @format: The format to query
|
||||
* @gles: TRUE for GLES, FALSE for GL
|
||||
* @out_actual_format: The actual RGBA format
|
||||
* @out_internal_format: the GL internal format
|
||||
* @out_format: the GL format
|
||||
@@ -1504,6 +1543,7 @@ gdk_memory_format_gl_format (GdkMemoryFormat format,
|
||||
**/
|
||||
gboolean
|
||||
gdk_memory_format_gl_rgba_format (GdkMemoryFormat format,
|
||||
gboolean gles,
|
||||
GdkMemoryFormat *out_actual_format,
|
||||
GLint *out_internal_format,
|
||||
GLenum *out_format,
|
||||
@@ -1516,7 +1556,10 @@ gdk_memory_format_gl_rgba_format (GdkMemoryFormat format,
|
||||
return FALSE;
|
||||
|
||||
*out_actual_format = actual;
|
||||
*out_internal_format = memory_formats[actual].gl.internal_format;
|
||||
if (gles)
|
||||
*out_internal_format = memory_formats[actual].gl.internal_gles_format;
|
||||
else
|
||||
*out_internal_format = memory_formats[actual].gl.internal_gl_format;
|
||||
*out_format = memory_formats[actual].gl.format;
|
||||
*out_type = memory_formats[actual].gl.type;
|
||||
memcpy (out_swizzle, memory_formats[format].gl.rgba_swizzle, sizeof(GLint) * 4);
|
||||
|
||||
@@ -55,11 +55,13 @@ GdkMemoryDepth gdk_memory_depth_merge (GdkMemoryDepth
|
||||
GdkMemoryFormat gdk_memory_depth_get_format (GdkMemoryDepth depth) G_GNUC_CONST;
|
||||
GdkMemoryFormat gdk_memory_depth_get_alpha_format (GdkMemoryDepth depth) G_GNUC_CONST;
|
||||
void gdk_memory_format_gl_format (GdkMemoryFormat format,
|
||||
gboolean gles,
|
||||
GLint *out_internal_format,
|
||||
GLenum *out_format,
|
||||
GLenum *out_type,
|
||||
GLint out_swizzle[4]);
|
||||
gboolean gdk_memory_format_gl_rgba_format (GdkMemoryFormat format,
|
||||
gboolean gles,
|
||||
GdkMemoryFormat *out_actual_format,
|
||||
GLint *out_internal_format,
|
||||
GLenum *out_format,
|
||||
|
||||
@@ -1973,8 +1973,10 @@ gdk_wayland_toplevel_titlebar_gesture (GdkToplevel *toplevel,
|
||||
return FALSE;
|
||||
|
||||
seat = gdk_display_get_default_seat (surface->display);
|
||||
wl_seat = gdk_wayland_seat_get_wl_seat (seat);
|
||||
if (!seat)
|
||||
return FALSE;
|
||||
|
||||
wl_seat = gdk_wayland_seat_get_wl_seat (seat);
|
||||
serial = _gdk_wayland_seat_get_last_implicit_grab_serial (GDK_WAYLAND_SEAT (seat), NULL);
|
||||
|
||||
gtk_surface1_titlebar_gesture (wayland_toplevel->display_server.gtk_surface,
|
||||
@@ -2155,15 +2157,14 @@ gdk_wayland_toplevel_focus (GdkToplevel *toplevel,
|
||||
GdkWaylandSurface *wayland_surface = GDK_WAYLAND_SURFACE (toplevel);
|
||||
GdkDisplay *display = gdk_surface_get_display (surface);
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||
GdkWaylandSeat *seat =
|
||||
GDK_WAYLAND_SEAT (gdk_display_get_default_seat (display));
|
||||
gchar *startup_id = NULL;
|
||||
|
||||
startup_id = g_steal_pointer (&display_wayland->startup_notification_id);
|
||||
|
||||
if (display_wayland->xdg_activation)
|
||||
if (seat && display_wayland->xdg_activation)
|
||||
{
|
||||
GdkWaylandSeat *seat =
|
||||
GDK_WAYLAND_SEAT (gdk_display_get_default_seat (display));
|
||||
|
||||
/* If the focus request does not have a startup ID associated, get a
|
||||
* new token to activate the window.
|
||||
*/
|
||||
|
||||
@@ -1504,6 +1504,7 @@ memory_format_gl_format (GskGLCommandQueue *self,
|
||||
if ((flags & required_flags) == required_flags)
|
||||
{
|
||||
gdk_memory_format_gl_format (data_format,
|
||||
gdk_gl_context_get_use_es (self->context),
|
||||
gl_internalformat,
|
||||
gl_format,
|
||||
gl_type,
|
||||
@@ -1514,6 +1515,7 @@ memory_format_gl_format (GskGLCommandQueue *self,
|
||||
|
||||
/* Second, try the potential RGBA format */
|
||||
if (gdk_memory_format_gl_rgba_format (data_format,
|
||||
gdk_gl_context_get_use_es (self->context),
|
||||
&alt_format,
|
||||
gl_internalformat,
|
||||
gl_format,
|
||||
@@ -1529,6 +1531,7 @@ memory_format_gl_format (GskGLCommandQueue *self,
|
||||
return data_format;
|
||||
|
||||
gdk_memory_format_gl_format (alt_format,
|
||||
gdk_gl_context_get_use_es (self->context),
|
||||
gl_internalformat,
|
||||
gl_format,
|
||||
gl_type,
|
||||
@@ -1546,6 +1549,7 @@ memory_format_gl_format (GskGLCommandQueue *self,
|
||||
if (((flags & required_flags) == required_flags))
|
||||
{
|
||||
gdk_memory_format_gl_format (fallbacks[i],
|
||||
gdk_gl_context_get_use_es (self->context),
|
||||
gl_internalformat,
|
||||
gl_format,
|
||||
gl_type,
|
||||
|
||||
@@ -638,6 +638,7 @@ gsk_gl_device_find_gl_format (GskGLDevice *self,
|
||||
*out_format = format;
|
||||
*out_flags = flags;
|
||||
gdk_memory_format_gl_format (format,
|
||||
gdk_gl_context_get_use_es (context),
|
||||
out_gl_internal_format,
|
||||
out_gl_format,
|
||||
out_gl_type,
|
||||
@@ -647,6 +648,7 @@ gsk_gl_device_find_gl_format (GskGLDevice *self,
|
||||
|
||||
/* Second, try the potential RGBA format */
|
||||
if (gdk_memory_format_gl_rgba_format (format,
|
||||
gdk_gl_context_get_use_es (context),
|
||||
&alt_format,
|
||||
out_gl_internal_format,
|
||||
out_gl_format,
|
||||
@@ -670,6 +672,7 @@ gsk_gl_device_find_gl_format (GskGLDevice *self,
|
||||
*out_format = fallbacks[i];
|
||||
*out_flags = flags;
|
||||
gdk_memory_format_gl_format (fallbacks[i],
|
||||
gdk_gl_context_get_use_es (context),
|
||||
out_gl_internal_format,
|
||||
out_gl_format,
|
||||
out_gl_type,
|
||||
|
||||
+481
-324
@@ -3,17 +3,28 @@
|
||||
#include "gskgpudeviceprivate.h"
|
||||
|
||||
#include "gskgpuframeprivate.h"
|
||||
#include "gskgpuimageprivate.h"
|
||||
#include "gskgpuuploadopprivate.h"
|
||||
|
||||
#include "gdk/gdkdisplayprivate.h"
|
||||
#include "gdk/gdktextureprivate.h"
|
||||
|
||||
#include "gsk/gskdebugprivate.h"
|
||||
|
||||
#define MAX_SLICES_PER_ATLAS 64
|
||||
|
||||
#define ATLAS_SIZE 1024
|
||||
|
||||
#define MAX_ATLAS_ITEM_SIZE 256
|
||||
|
||||
G_STATIC_ASSERT (MAX_ATLAS_ITEM_SIZE < ATLAS_SIZE);
|
||||
|
||||
#define MAX_DEAD_PIXELS (ATLAS_SIZE * ATLAS_SIZE / 2)
|
||||
|
||||
#define CACHE_GC_TIMEOUT 1 /* seconds */
|
||||
|
||||
#define CACHE_MAX_AGE (G_TIME_SPAN_SECOND * 4) /* 4 seconds, in µs */
|
||||
|
||||
typedef struct _GskGpuCached GskGpuCached;
|
||||
typedef struct _GskGpuCachedClass GskGpuCachedClass;
|
||||
typedef struct _GskGpuCachedAtlas GskGpuCachedAtlas;
|
||||
@@ -21,6 +32,15 @@ typedef struct _GskGpuCachedGlyph GskGpuCachedGlyph;
|
||||
typedef struct _GskGpuCachedTexture GskGpuCachedTexture;
|
||||
typedef struct _GskGpuDevicePrivate GskGpuDevicePrivate;
|
||||
|
||||
typedef struct _GlyphKey GlyphKey;
|
||||
struct _GlyphKey
|
||||
{
|
||||
PangoFont *font;
|
||||
PangoGlyph glyph;
|
||||
GskGpuGlyphLookupFlags flags;
|
||||
float scale;
|
||||
};
|
||||
|
||||
struct _GskGpuDevicePrivate
|
||||
{
|
||||
GdkDisplay *display;
|
||||
@@ -34,6 +54,11 @@ struct _GskGpuDevicePrivate
|
||||
GHashTable *glyph_cache;
|
||||
|
||||
GskGpuCachedAtlas *current_atlas;
|
||||
|
||||
struct {
|
||||
GlyphKey key;
|
||||
GskGpuCachedGlyph *value;
|
||||
} front[256];
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (GskGpuDevice, gsk_gpu_device, G_TYPE_OBJECT)
|
||||
@@ -48,18 +73,40 @@ struct _GskGpuCachedClass
|
||||
GskGpuCached *cached);
|
||||
gboolean (* should_collect) (GskGpuDevice *device,
|
||||
GskGpuCached *cached,
|
||||
gint64 timestsamp);
|
||||
gint64 timestamp);
|
||||
};
|
||||
|
||||
struct _GskGpuCached
|
||||
{
|
||||
const GskGpuCachedClass *class;
|
||||
|
||||
|
||||
GskGpuCachedAtlas *atlas;
|
||||
GskGpuCached *next;
|
||||
GskGpuCached *prev;
|
||||
|
||||
gint64 timestamp;
|
||||
gboolean stale;
|
||||
guint pixels; /* For glyphs, pixels. For atlases, dead pixels */
|
||||
};
|
||||
|
||||
static inline void
|
||||
mark_as_stale (GskGpuCached *cached,
|
||||
gboolean stale)
|
||||
{
|
||||
if (cached->stale != stale)
|
||||
{
|
||||
cached->stale = stale;
|
||||
|
||||
if (cached->atlas)
|
||||
{
|
||||
if (stale)
|
||||
((GskGpuCached *) cached->atlas)->pixels += cached->pixels;
|
||||
else
|
||||
((GskGpuCached *) cached->atlas)->pixels -= cached->pixels;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gpu_cached_free (GskGpuDevice *device,
|
||||
GskGpuCached *cached)
|
||||
@@ -75,6 +122,8 @@ gsk_gpu_cached_free (GskGpuDevice *device,
|
||||
else
|
||||
priv->first_cached = cached->next;
|
||||
|
||||
mark_as_stale (cached, TRUE);
|
||||
|
||||
cached->class->free (device, cached);
|
||||
}
|
||||
|
||||
@@ -114,7 +163,8 @@ gsk_gpu_cached_use (GskGpuDevice *device,
|
||||
GskGpuCached *cached,
|
||||
gint64 timestamp)
|
||||
{
|
||||
/* FIXME */
|
||||
cached->timestamp = timestamp;
|
||||
mark_as_stale (cached, FALSE);
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
@@ -137,10 +187,23 @@ static void
|
||||
gsk_gpu_cached_atlas_free (GskGpuDevice *device,
|
||||
GskGpuCached *cached)
|
||||
{
|
||||
GskGpuDevicePrivate *priv = gsk_gpu_device_get_instance_private (device);
|
||||
GskGpuCachedAtlas *self = (GskGpuCachedAtlas *) cached;
|
||||
GskGpuCached *c, *next;
|
||||
|
||||
/* Free all remaining glyphs on this atlas */
|
||||
for (c = priv->first_cached; c != NULL; c = next)
|
||||
{
|
||||
next = c->next;
|
||||
if (c->atlas == self)
|
||||
gsk_gpu_cached_free (device, c);
|
||||
}
|
||||
|
||||
if (priv->current_atlas == self)
|
||||
priv->current_atlas = NULL;
|
||||
|
||||
g_object_unref (self->image);
|
||||
|
||||
|
||||
g_free (self);
|
||||
}
|
||||
|
||||
@@ -149,8 +212,7 @@ gsk_gpu_cached_atlas_should_collect (GskGpuDevice *device,
|
||||
GskGpuCached *cached,
|
||||
gint64 timestamp)
|
||||
{
|
||||
/* FIXME */
|
||||
return FALSE;
|
||||
return cached->pixels > MAX_DEAD_PIXELS;
|
||||
}
|
||||
|
||||
static const GskGpuCachedClass GSK_GPU_CACHED_ATLAS_CLASS =
|
||||
@@ -171,298 +233,6 @@ gsk_gpu_cached_atlas_new (GskGpuDevice *device)
|
||||
return self;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
/* {{{ CachedTexture */
|
||||
|
||||
struct _GskGpuCachedTexture
|
||||
{
|
||||
GskGpuCached parent;
|
||||
|
||||
/* atomic */ GdkTexture *texture;
|
||||
GskGpuImage *image;
|
||||
};
|
||||
|
||||
static void
|
||||
gsk_gpu_cached_texture_free (GskGpuDevice *device,
|
||||
GskGpuCached *cached)
|
||||
{
|
||||
GskGpuCachedTexture *self = (GskGpuCachedTexture *) cached;
|
||||
gboolean texture_still_alive;
|
||||
|
||||
texture_still_alive = g_atomic_pointer_exchange (&self->texture, NULL) != NULL;
|
||||
g_object_unref (self->image);
|
||||
|
||||
if (!texture_still_alive)
|
||||
g_free (self);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gsk_gpu_cached_texture_should_collect (GskGpuDevice *device,
|
||||
GskGpuCached *cached,
|
||||
gint64 timestamp)
|
||||
{
|
||||
/* FIXME */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static const GskGpuCachedClass GSK_GPU_CACHED_TEXTURE_CLASS =
|
||||
{
|
||||
sizeof (GskGpuCachedTexture),
|
||||
gsk_gpu_cached_texture_free,
|
||||
gsk_gpu_cached_texture_should_collect
|
||||
};
|
||||
|
||||
static void
|
||||
gsk_gpu_cached_texture_destroy_cb (gpointer data)
|
||||
{
|
||||
GskGpuCachedTexture *cache = data;
|
||||
gboolean cache_still_alive;
|
||||
|
||||
cache_still_alive = g_atomic_pointer_exchange (&cache->texture, NULL) != NULL;
|
||||
|
||||
if (!cache_still_alive)
|
||||
g_free (cache);
|
||||
}
|
||||
|
||||
static GskGpuCachedTexture *
|
||||
gsk_gpu_cached_texture_new (GskGpuDevice *device,
|
||||
GdkTexture *texture,
|
||||
GskGpuImage *image)
|
||||
{
|
||||
GskGpuDevicePrivate *priv = gsk_gpu_device_get_instance_private (device);
|
||||
GskGpuCachedTexture *self;
|
||||
|
||||
if (gdk_texture_get_render_data (texture, device))
|
||||
gdk_texture_clear_render_data (texture);
|
||||
else if ((self = g_hash_table_lookup (priv->texture_cache, texture)))
|
||||
{
|
||||
g_hash_table_remove (priv->texture_cache, texture);
|
||||
g_object_weak_unref (G_OBJECT (texture), (GWeakNotify) gsk_gpu_cached_texture_destroy_cb, self);
|
||||
}
|
||||
|
||||
self = gsk_gpu_cached_new (device, &GSK_GPU_CACHED_TEXTURE_CLASS, NULL);
|
||||
self->texture = texture;
|
||||
self->image = g_object_ref (image);
|
||||
|
||||
if (!gdk_texture_set_render_data (texture, device, self, gsk_gpu_cached_texture_destroy_cb))
|
||||
{
|
||||
g_object_weak_ref (G_OBJECT (texture), (GWeakNotify) gsk_gpu_cached_texture_destroy_cb, self);
|
||||
g_hash_table_insert (priv->texture_cache, texture, self);
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
/* {{{ CachedGlyph */
|
||||
|
||||
struct _GskGpuCachedGlyph
|
||||
{
|
||||
GskGpuCached parent;
|
||||
|
||||
PangoFont *font;
|
||||
PangoGlyph glyph;
|
||||
GskGpuGlyphLookupFlags flags;
|
||||
float scale;
|
||||
|
||||
GskGpuImage *image;
|
||||
graphene_rect_t bounds;
|
||||
graphene_point_t origin;
|
||||
};
|
||||
|
||||
static void
|
||||
gsk_gpu_cached_glyph_free (GskGpuDevice *device,
|
||||
GskGpuCached *cached)
|
||||
{
|
||||
GskGpuCachedGlyph *self = (GskGpuCachedGlyph *) cached;
|
||||
|
||||
g_object_unref (self->font);
|
||||
g_object_unref (self->image);
|
||||
|
||||
g_free (self);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gsk_gpu_cached_glyph_should_collect (GskGpuDevice *device,
|
||||
GskGpuCached *cached,
|
||||
gint64 timestsamp)
|
||||
{
|
||||
/* FIXME */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static guint
|
||||
gsk_gpu_cached_glyph_hash (gconstpointer data)
|
||||
{
|
||||
const GskGpuCachedGlyph *glyph = data;
|
||||
|
||||
return GPOINTER_TO_UINT (glyph->font) ^
|
||||
glyph->glyph ^
|
||||
(glyph->flags << 24) ^
|
||||
((guint) glyph->scale * PANGO_SCALE);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gsk_gpu_cached_glyph_equal (gconstpointer v1,
|
||||
gconstpointer v2)
|
||||
{
|
||||
const GskGpuCachedGlyph *glyph1 = v1;
|
||||
const GskGpuCachedGlyph *glyph2 = v2;
|
||||
|
||||
return glyph1->font == glyph2->font
|
||||
&& glyph1->glyph == glyph2->glyph
|
||||
&& glyph1->flags == glyph2->flags
|
||||
&& glyph1->scale == glyph2->scale;
|
||||
}
|
||||
|
||||
static const GskGpuCachedClass GSK_GPU_CACHED_GLYPH_CLASS =
|
||||
{
|
||||
sizeof (GskGpuCachedGlyph),
|
||||
gsk_gpu_cached_glyph_free,
|
||||
gsk_gpu_cached_glyph_should_collect
|
||||
};
|
||||
|
||||
/* }}} */
|
||||
/* {{{ GskGpuDevice */
|
||||
|
||||
void
|
||||
gsk_gpu_device_gc (GskGpuDevice *self,
|
||||
gint64 timestamp)
|
||||
{
|
||||
GskGpuDevicePrivate *priv = gsk_gpu_device_get_instance_private (self);
|
||||
GskGpuCached *cached, *next;
|
||||
|
||||
for (cached = priv->first_cached; cached != NULL; cached = next)
|
||||
{
|
||||
next = cached->next;
|
||||
if (gsk_gpu_cached_should_collect (self, cached, timestamp))
|
||||
gsk_gpu_cached_free (self, priv->first_cached);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gpu_device_clear_cache (GskGpuDevice *self)
|
||||
{
|
||||
GskGpuDevicePrivate *priv = gsk_gpu_device_get_instance_private (self);
|
||||
|
||||
for (GskGpuCached *cached = priv->first_cached; cached; cached = cached->next)
|
||||
{
|
||||
if (cached->prev == NULL)
|
||||
g_assert (priv->first_cached == cached);
|
||||
else
|
||||
g_assert (cached->prev->next == cached);
|
||||
if (cached->next == NULL)
|
||||
g_assert (priv->last_cached == cached);
|
||||
else
|
||||
g_assert (cached->next->prev == cached);
|
||||
}
|
||||
|
||||
while (priv->first_cached)
|
||||
gsk_gpu_cached_free (self, priv->first_cached);
|
||||
|
||||
g_assert (priv->last_cached == NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gpu_device_dispose (GObject *object)
|
||||
{
|
||||
GskGpuDevice *self = GSK_GPU_DEVICE (object);
|
||||
GskGpuDevicePrivate *priv = gsk_gpu_device_get_instance_private (self);
|
||||
|
||||
gsk_gpu_device_clear_cache (self);
|
||||
g_hash_table_unref (priv->glyph_cache);
|
||||
g_hash_table_unref (priv->texture_cache);
|
||||
|
||||
G_OBJECT_CLASS (gsk_gpu_device_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gpu_device_finalize (GObject *object)
|
||||
{
|
||||
GskGpuDevice *self = GSK_GPU_DEVICE (object);
|
||||
GskGpuDevicePrivate *priv = gsk_gpu_device_get_instance_private (self);
|
||||
|
||||
g_object_unref (priv->display);
|
||||
|
||||
G_OBJECT_CLASS (gsk_gpu_device_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gpu_device_class_init (GskGpuDeviceClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->dispose = gsk_gpu_device_dispose;
|
||||
object_class->finalize = gsk_gpu_device_finalize;
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gpu_device_init (GskGpuDevice *self)
|
||||
{
|
||||
GskGpuDevicePrivate *priv = gsk_gpu_device_get_instance_private (self);
|
||||
|
||||
priv->glyph_cache = g_hash_table_new (gsk_gpu_cached_glyph_hash,
|
||||
gsk_gpu_cached_glyph_equal);
|
||||
priv->texture_cache = g_hash_table_new (g_direct_hash,
|
||||
g_direct_equal);
|
||||
}
|
||||
|
||||
void
|
||||
gsk_gpu_device_setup (GskGpuDevice *self,
|
||||
GdkDisplay *display,
|
||||
gsize max_image_size)
|
||||
{
|
||||
GskGpuDevicePrivate *priv = gsk_gpu_device_get_instance_private (self);
|
||||
|
||||
priv->display = g_object_ref (display);
|
||||
priv->max_image_size = max_image_size;
|
||||
}
|
||||
|
||||
GdkDisplay *
|
||||
gsk_gpu_device_get_display (GskGpuDevice *self)
|
||||
{
|
||||
GskGpuDevicePrivate *priv = gsk_gpu_device_get_instance_private (self);
|
||||
|
||||
return priv->display;
|
||||
}
|
||||
|
||||
gsize
|
||||
gsk_gpu_device_get_max_image_size (GskGpuDevice *self)
|
||||
{
|
||||
GskGpuDevicePrivate *priv = gsk_gpu_device_get_instance_private (self);
|
||||
|
||||
return priv->max_image_size;
|
||||
}
|
||||
|
||||
GskGpuImage *
|
||||
gsk_gpu_device_create_offscreen_image (GskGpuDevice *self,
|
||||
gboolean with_mipmap,
|
||||
GdkMemoryDepth depth,
|
||||
gsize width,
|
||||
gsize height)
|
||||
{
|
||||
return GSK_GPU_DEVICE_GET_CLASS (self)->create_offscreen_image (self, with_mipmap, depth, width, height);
|
||||
}
|
||||
|
||||
GskGpuImage *
|
||||
gsk_gpu_device_create_upload_image (GskGpuDevice *self,
|
||||
gboolean with_mipmap,
|
||||
GdkMemoryFormat format,
|
||||
gsize width,
|
||||
gsize height)
|
||||
{
|
||||
return GSK_GPU_DEVICE_GET_CLASS (self)->create_upload_image (self, with_mipmap, format, width, height);
|
||||
}
|
||||
|
||||
GskGpuImage *
|
||||
gsk_gpu_device_create_download_image (GskGpuDevice *self,
|
||||
GdkMemoryDepth depth,
|
||||
gsize width,
|
||||
gsize height)
|
||||
{
|
||||
return GSK_GPU_DEVICE_GET_CLASS (self)->create_download_image (self, depth, width, height);
|
||||
}
|
||||
|
||||
/* This rounds up to the next number that has <= 2 bits set:
|
||||
* 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96, 128, ...
|
||||
* That is roughly sqrt(2), so it should limit waste
|
||||
@@ -520,25 +290,397 @@ gsk_gpu_cached_atlas_allocate (GskGpuCachedAtlas *atlas,
|
||||
if (!can_add_slice)
|
||||
return FALSE;
|
||||
|
||||
if (y + height > ATLAS_SIZE)
|
||||
return FALSE;
|
||||
|
||||
atlas->n_slices++;
|
||||
if (atlas->n_slices == MAX_SLICES_PER_ATLAS)
|
||||
atlas->slices[i].height = ATLAS_SIZE - y;
|
||||
else
|
||||
atlas->slices[i].height = round_up_atlas_size (MAX (height, 4));
|
||||
atlas->slices[i].height = MIN (round_up_atlas_size (MAX (height, 4)), ATLAS_SIZE - y);
|
||||
|
||||
atlas->slices[i].width = 0;
|
||||
best_y = y;
|
||||
best_slice = i;
|
||||
}
|
||||
|
||||
g_assert (best_slice < MAX_SLICES_PER_ATLAS);
|
||||
|
||||
*out_x = atlas->slices[best_slice].width;
|
||||
*out_y = best_y;
|
||||
|
||||
atlas->slices[best_slice].width += width;
|
||||
|
||||
g_assert (atlas->slices[best_slice].height >= height);
|
||||
g_assert (atlas->slices[best_slice].width <= ATLAS_SIZE);
|
||||
g_assert (best_y + atlas->slices[best_slice].height <= ATLAS_SIZE);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
/* {{{ CachedTexture */
|
||||
|
||||
struct _GskGpuCachedTexture
|
||||
{
|
||||
GskGpuCached parent;
|
||||
|
||||
/* atomic */ GdkTexture *texture;
|
||||
GskGpuImage *image;
|
||||
};
|
||||
|
||||
static void
|
||||
gsk_gpu_cached_texture_free (GskGpuDevice *device,
|
||||
GskGpuCached *cached)
|
||||
{
|
||||
GskGpuCachedTexture *self = (GskGpuCachedTexture *) cached;
|
||||
gboolean texture_still_alive;
|
||||
|
||||
texture_still_alive = g_atomic_pointer_exchange (&self->texture, NULL) != NULL;
|
||||
g_clear_object (&self->image);
|
||||
|
||||
if (!texture_still_alive)
|
||||
g_free (self);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gsk_gpu_cached_texture_should_collect (GskGpuDevice *device,
|
||||
GskGpuCached *cached,
|
||||
gint64 timestamp)
|
||||
{
|
||||
return timestamp - cached->timestamp > CACHE_MAX_AGE;
|
||||
}
|
||||
|
||||
static const GskGpuCachedClass GSK_GPU_CACHED_TEXTURE_CLASS =
|
||||
{
|
||||
sizeof (GskGpuCachedTexture),
|
||||
gsk_gpu_cached_texture_free,
|
||||
gsk_gpu_cached_texture_should_collect
|
||||
};
|
||||
|
||||
static void
|
||||
gsk_gpu_cached_texture_destroy_cb (gpointer data)
|
||||
{
|
||||
GskGpuCachedTexture *cache = data;
|
||||
gboolean cache_still_alive;
|
||||
|
||||
cache_still_alive = g_atomic_pointer_exchange (&cache->texture, NULL) != NULL;
|
||||
|
||||
if (!cache_still_alive)
|
||||
g_free (cache);
|
||||
}
|
||||
|
||||
static GskGpuCachedTexture *
|
||||
gsk_gpu_cached_texture_new (GskGpuDevice *device,
|
||||
GdkTexture *texture,
|
||||
GskGpuImage *image)
|
||||
{
|
||||
GskGpuDevicePrivate *priv = gsk_gpu_device_get_instance_private (device);
|
||||
GskGpuCachedTexture *self;
|
||||
|
||||
if (gdk_texture_get_render_data (texture, device))
|
||||
gdk_texture_clear_render_data (texture);
|
||||
else if ((self = g_hash_table_lookup (priv->texture_cache, texture)))
|
||||
{
|
||||
g_hash_table_remove (priv->texture_cache, texture);
|
||||
g_object_weak_unref (G_OBJECT (texture), (GWeakNotify) gsk_gpu_cached_texture_destroy_cb, self);
|
||||
}
|
||||
|
||||
self = gsk_gpu_cached_new (device, &GSK_GPU_CACHED_TEXTURE_CLASS, NULL);
|
||||
self->texture = texture;
|
||||
self->image = g_object_ref (image);
|
||||
|
||||
if (!gdk_texture_set_render_data (texture, device, self, gsk_gpu_cached_texture_destroy_cb))
|
||||
{
|
||||
g_object_weak_ref (G_OBJECT (texture), (GWeakNotify) gsk_gpu_cached_texture_destroy_cb, self);
|
||||
g_hash_table_insert (priv->texture_cache, texture, self);
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
/* {{{ CachedGlyph */
|
||||
|
||||
struct _GskGpuCachedGlyph
|
||||
{
|
||||
GskGpuCached parent;
|
||||
|
||||
GlyphKey key;
|
||||
|
||||
GskGpuImage *image;
|
||||
graphene_rect_t bounds;
|
||||
graphene_point_t origin;
|
||||
};
|
||||
|
||||
static void
|
||||
gsk_gpu_cached_glyph_free (GskGpuDevice *device,
|
||||
GskGpuCached *cached)
|
||||
{
|
||||
GskGpuDevicePrivate *priv = gsk_gpu_device_get_instance_private (device);
|
||||
GskGpuCachedGlyph *self = (GskGpuCachedGlyph *) cached;
|
||||
|
||||
g_hash_table_remove (priv->glyph_cache, self);
|
||||
|
||||
g_object_unref (self->key.font);
|
||||
g_object_unref (self->image);
|
||||
|
||||
g_free (self);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gsk_gpu_cached_glyph_should_collect (GskGpuDevice *device,
|
||||
GskGpuCached *cached,
|
||||
gint64 timestamp)
|
||||
{
|
||||
if (timestamp - cached->timestamp > CACHE_MAX_AGE)
|
||||
mark_as_stale (cached, TRUE);
|
||||
|
||||
/* Glyphs are only collected when their atlas is freed */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static guint
|
||||
gsk_gpu_cached_glyph_hash (gconstpointer data)
|
||||
{
|
||||
const GskGpuCachedGlyph *glyph = data;
|
||||
|
||||
return GPOINTER_TO_UINT (glyph->key.font) ^
|
||||
glyph->key.glyph ^
|
||||
(glyph->key.flags << 24) ^
|
||||
((guint) glyph->key.scale * PANGO_SCALE);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gsk_gpu_cached_glyph_equal (gconstpointer v1,
|
||||
gconstpointer v2)
|
||||
{
|
||||
const GskGpuCachedGlyph *glyph1 = v1;
|
||||
const GskGpuCachedGlyph *glyph2 = v2;
|
||||
|
||||
return glyph1->key.font == glyph2->key.font
|
||||
&& glyph1->key.glyph == glyph2->key.glyph
|
||||
&& glyph1->key.flags == glyph2->key.flags
|
||||
&& glyph1->key.scale == glyph2->key.scale;
|
||||
}
|
||||
|
||||
static const GskGpuCachedClass GSK_GPU_CACHED_GLYPH_CLASS =
|
||||
{
|
||||
sizeof (GskGpuCachedGlyph),
|
||||
gsk_gpu_cached_glyph_free,
|
||||
gsk_gpu_cached_glyph_should_collect
|
||||
};
|
||||
|
||||
/* }}} */
|
||||
/* {{{ GskGpuDevice */
|
||||
|
||||
static void
|
||||
print_cache_stats (GskGpuDevice *self)
|
||||
{
|
||||
GskGpuDevicePrivate *priv = gsk_gpu_device_get_instance_private (self);
|
||||
GskGpuCached *cached;
|
||||
guint glyphs = 0;
|
||||
guint stale_glyphs = 0;
|
||||
guint textures = 0;
|
||||
guint atlases = 0;
|
||||
GString *ratios = g_string_new ("");
|
||||
|
||||
for (cached = priv->first_cached; cached != NULL; cached = cached->next)
|
||||
{
|
||||
if (cached->class == &GSK_GPU_CACHED_GLYPH_CLASS)
|
||||
{
|
||||
glyphs++;
|
||||
if (cached->stale)
|
||||
stale_glyphs++;
|
||||
}
|
||||
else if (cached->class == &GSK_GPU_CACHED_TEXTURE_CLASS)
|
||||
textures++;
|
||||
else if (cached->class == &GSK_GPU_CACHED_ATLAS_CLASS)
|
||||
{
|
||||
double ratio;
|
||||
|
||||
atlases++;
|
||||
|
||||
ratio = (double) cached->pixels / (double) (ATLAS_SIZE * ATLAS_SIZE);
|
||||
|
||||
if (ratios->len == 0)
|
||||
g_string_append (ratios, " (ratios ");
|
||||
else
|
||||
g_string_append (ratios, ", ");
|
||||
g_string_append_printf (ratios, "%.2f", ratio);
|
||||
}
|
||||
}
|
||||
|
||||
if (ratios->len > 0)
|
||||
g_string_append (ratios, ")");
|
||||
|
||||
gdk_debug_message ("cached items\n"
|
||||
" glyphs: %5u (%u stale)\n"
|
||||
" textures: %5u\n"
|
||||
" atlases: %5u%s",
|
||||
glyphs, stale_glyphs, textures, atlases, ratios->str);
|
||||
|
||||
g_string_free (ratios, TRUE);
|
||||
}
|
||||
|
||||
void
|
||||
gsk_gpu_device_gc (GskGpuDevice *self,
|
||||
gint64 timestamp)
|
||||
{
|
||||
GskGpuDevicePrivate *priv = gsk_gpu_device_get_instance_private (self);
|
||||
GskGpuCached *cached, *prev;
|
||||
|
||||
/* We walk the cache from the end so we don't end up with prev
|
||||
* begin a leftover glyph on the atlas we are freeing
|
||||
*/
|
||||
for (cached = priv->last_cached; cached != NULL; cached = prev)
|
||||
{
|
||||
prev = cached->prev;
|
||||
if (gsk_gpu_cached_should_collect (self, cached, timestamp))
|
||||
gsk_gpu_cached_free (self, cached);
|
||||
}
|
||||
|
||||
if (GSK_DEBUG_CHECK (GLYPH_CACHE))
|
||||
print_cache_stats (self);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gpu_device_clear_cache (GskGpuDevice *self)
|
||||
{
|
||||
GskGpuDevicePrivate *priv = gsk_gpu_device_get_instance_private (self);
|
||||
|
||||
for (GskGpuCached *cached = priv->first_cached; cached; cached = cached->next)
|
||||
{
|
||||
if (cached->prev == NULL)
|
||||
g_assert (priv->first_cached == cached);
|
||||
else
|
||||
g_assert (cached->prev->next == cached);
|
||||
if (cached->next == NULL)
|
||||
g_assert (priv->last_cached == cached);
|
||||
else
|
||||
g_assert (cached->next->prev == cached);
|
||||
}
|
||||
|
||||
/* We clear the cache from the end so glyphs get freed before their atlas */
|
||||
while (priv->last_cached)
|
||||
gsk_gpu_cached_free (self, priv->last_cached);
|
||||
|
||||
g_assert (priv->last_cached == NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gpu_device_dispose (GObject *object)
|
||||
{
|
||||
GskGpuDevice *self = GSK_GPU_DEVICE (object);
|
||||
GskGpuDevicePrivate *priv = gsk_gpu_device_get_instance_private (self);
|
||||
|
||||
gsk_gpu_device_clear_cache (self);
|
||||
g_hash_table_unref (priv->glyph_cache);
|
||||
g_hash_table_unref (priv->texture_cache);
|
||||
g_clear_handle_id (&priv->cache_gc_source, g_source_remove);
|
||||
|
||||
G_OBJECT_CLASS (gsk_gpu_device_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gpu_device_finalize (GObject *object)
|
||||
{
|
||||
GskGpuDevice *self = GSK_GPU_DEVICE (object);
|
||||
GskGpuDevicePrivate *priv = gsk_gpu_device_get_instance_private (self);
|
||||
|
||||
g_object_unref (priv->display);
|
||||
|
||||
G_OBJECT_CLASS (gsk_gpu_device_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gpu_device_class_init (GskGpuDeviceClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->dispose = gsk_gpu_device_dispose;
|
||||
object_class->finalize = gsk_gpu_device_finalize;
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gpu_device_init (GskGpuDevice *self)
|
||||
{
|
||||
GskGpuDevicePrivate *priv = gsk_gpu_device_get_instance_private (self);
|
||||
|
||||
priv->glyph_cache = g_hash_table_new (gsk_gpu_cached_glyph_hash,
|
||||
gsk_gpu_cached_glyph_equal);
|
||||
priv->texture_cache = g_hash_table_new (g_direct_hash,
|
||||
g_direct_equal);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
cache_gc_source_callback (gpointer data)
|
||||
{
|
||||
GskGpuDevice *self = data;
|
||||
|
||||
gsk_gpu_device_gc (self, g_get_monotonic_time ());
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
void
|
||||
gsk_gpu_device_setup (GskGpuDevice *self,
|
||||
GdkDisplay *display,
|
||||
gsize max_image_size)
|
||||
{
|
||||
GskGpuDevicePrivate *priv = gsk_gpu_device_get_instance_private (self);
|
||||
|
||||
priv->display = g_object_ref (display);
|
||||
priv->max_image_size = max_image_size;
|
||||
|
||||
priv->cache_gc_source = g_timeout_add_seconds (CACHE_GC_TIMEOUT, cache_gc_source_callback, self);
|
||||
}
|
||||
|
||||
GdkDisplay *
|
||||
gsk_gpu_device_get_display (GskGpuDevice *self)
|
||||
{
|
||||
GskGpuDevicePrivate *priv = gsk_gpu_device_get_instance_private (self);
|
||||
|
||||
return priv->display;
|
||||
}
|
||||
|
||||
gsize
|
||||
gsk_gpu_device_get_max_image_size (GskGpuDevice *self)
|
||||
{
|
||||
GskGpuDevicePrivate *priv = gsk_gpu_device_get_instance_private (self);
|
||||
|
||||
return priv->max_image_size;
|
||||
}
|
||||
|
||||
GskGpuImage *
|
||||
gsk_gpu_device_create_offscreen_image (GskGpuDevice *self,
|
||||
gboolean with_mipmap,
|
||||
GdkMemoryDepth depth,
|
||||
gsize width,
|
||||
gsize height)
|
||||
{
|
||||
return GSK_GPU_DEVICE_GET_CLASS (self)->create_offscreen_image (self, with_mipmap, depth, width, height);
|
||||
}
|
||||
|
||||
GskGpuImage *
|
||||
gsk_gpu_device_create_upload_image (GskGpuDevice *self,
|
||||
gboolean with_mipmap,
|
||||
GdkMemoryFormat format,
|
||||
gsize width,
|
||||
gsize height)
|
||||
{
|
||||
return GSK_GPU_DEVICE_GET_CLASS (self)->create_upload_image (self, with_mipmap, format, width, height);
|
||||
}
|
||||
|
||||
GskGpuImage *
|
||||
gsk_gpu_device_create_download_image (GskGpuDevice *self,
|
||||
GdkMemoryDepth depth,
|
||||
gsize width,
|
||||
gsize height)
|
||||
{
|
||||
return GSK_GPU_DEVICE_GET_CLASS (self)->create_download_image (self, depth, width, height);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gpu_device_ensure_atlas (GskGpuDevice *self,
|
||||
gboolean recreate,
|
||||
@@ -576,20 +718,14 @@ gsk_gpu_device_add_atlas_image (GskGpuDevice *self,
|
||||
return NULL;
|
||||
|
||||
gsk_gpu_device_ensure_atlas (self, FALSE, timestamp);
|
||||
|
||||
|
||||
if (gsk_gpu_cached_atlas_allocate (priv->current_atlas, width, height, out_x, out_y))
|
||||
{
|
||||
gsk_gpu_cached_use (self, (GskGpuCached *) priv->current_atlas, timestamp);
|
||||
return priv->current_atlas->image;
|
||||
}
|
||||
return priv->current_atlas->image;
|
||||
|
||||
gsk_gpu_device_ensure_atlas (self, TRUE, timestamp);
|
||||
|
||||
if (gsk_gpu_cached_atlas_allocate (priv->current_atlas, width, height, out_x, out_y))
|
||||
{
|
||||
gsk_gpu_cached_use (self, (GskGpuCached *) priv->current_atlas, timestamp);
|
||||
return priv->current_atlas->image;
|
||||
}
|
||||
return priv->current_atlas->image;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -606,10 +742,8 @@ gsk_gpu_device_lookup_texture_image (GskGpuDevice *self,
|
||||
if (cache == NULL)
|
||||
cache = g_hash_table_lookup (priv->texture_cache, texture);
|
||||
|
||||
if (cache)
|
||||
{
|
||||
return g_object_ref (cache->image);
|
||||
}
|
||||
if (cache && cache->image)
|
||||
return g_object_ref (cache->image);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -639,10 +773,10 @@ gsk_gpu_device_lookup_glyph_image (GskGpuDevice *self,
|
||||
{
|
||||
GskGpuDevicePrivate *priv = gsk_gpu_device_get_instance_private (self);
|
||||
GskGpuCachedGlyph lookup = {
|
||||
.font = font,
|
||||
.glyph = glyph,
|
||||
.flags = flags,
|
||||
.scale = scale
|
||||
.key.font = font,
|
||||
.key.glyph = glyph,
|
||||
.key.flags = flags,
|
||||
.key.scale = scale
|
||||
};
|
||||
GskGpuCachedGlyph *cache;
|
||||
PangoRectangle ink_rect;
|
||||
@@ -650,18 +784,35 @@ gsk_gpu_device_lookup_glyph_image (GskGpuDevice *self,
|
||||
graphene_point_t origin;
|
||||
GskGpuImage *image;
|
||||
gsize atlas_x, atlas_y, padding;
|
||||
guint64 timestamp = gsk_gpu_frame_get_timestamp (frame);
|
||||
guint front_index = glyph & 0xFF;
|
||||
|
||||
if (memcmp (&lookup.key, &priv->front[front_index], sizeof (GlyphKey)) == 0)
|
||||
{
|
||||
cache = priv->front[front_index].value;
|
||||
|
||||
gsk_gpu_cached_use (self, (GskGpuCached *) cache, timestamp);
|
||||
|
||||
*out_bounds = cache->bounds;
|
||||
*out_origin = cache->origin;
|
||||
|
||||
return cache->image;
|
||||
}
|
||||
|
||||
cache = g_hash_table_lookup (priv->glyph_cache, &lookup);
|
||||
if (cache)
|
||||
{
|
||||
gsk_gpu_cached_use (self, (GskGpuCached *) cache, gsk_gpu_frame_get_timestamp (frame));
|
||||
memcpy (&priv->front[front_index].key, &lookup.key, sizeof (GlyphKey));
|
||||
priv->front[front_index].value = cache;
|
||||
|
||||
gsk_gpu_cached_use (self, (GskGpuCached *) cache, timestamp);
|
||||
|
||||
*out_bounds = cache->bounds;
|
||||
*out_origin = cache->origin;
|
||||
|
||||
return cache->image;
|
||||
}
|
||||
|
||||
cache = g_new (GskGpuCachedGlyph, 1);
|
||||
pango_font_get_glyph_extents (font, glyph, &ink_rect, NULL);
|
||||
origin.x = floor (ink_rect.x * scale / PANGO_SCALE);
|
||||
origin.y = floor (ink_rect.y * scale / PANGO_SCALE);
|
||||
@@ -670,7 +821,7 @@ gsk_gpu_device_lookup_glyph_image (GskGpuDevice *self,
|
||||
padding = 1;
|
||||
|
||||
image = gsk_gpu_device_add_atlas_image (self,
|
||||
gsk_gpu_frame_get_timestamp (frame),
|
||||
timestamp,
|
||||
rect.size.width + 2 * padding, rect.size.height + 2 * padding,
|
||||
&atlas_x, &atlas_y);
|
||||
if (image)
|
||||
@@ -689,12 +840,13 @@ gsk_gpu_device_lookup_glyph_image (GskGpuDevice *self,
|
||||
cache = gsk_gpu_cached_new (self, &GSK_GPU_CACHED_GLYPH_CLASS, NULL);
|
||||
}
|
||||
|
||||
cache->font = g_object_ref (font),
|
||||
cache->glyph = glyph,
|
||||
cache->flags = flags,
|
||||
cache->scale = scale,
|
||||
cache->key.font = g_object_ref (font),
|
||||
cache->key.glyph = glyph,
|
||||
cache->key.flags = flags,
|
||||
cache->key.scale = scale,
|
||||
cache->bounds = rect,
|
||||
cache->image = image,
|
||||
((GskGpuCached *) cache)->pixels = (rect.size.width + 2 * padding) * (rect.size.height + 2 * padding);
|
||||
cache->origin = GRAPHENE_POINT_INIT (- origin.x + (flags & 3) / 4.f,
|
||||
- origin.y + ((flags >> 2) & 3) / 4.f);
|
||||
|
||||
@@ -713,11 +865,16 @@ gsk_gpu_device_lookup_glyph_image (GskGpuDevice *self,
|
||||
cache->origin.y + padding));
|
||||
|
||||
g_hash_table_insert (priv->glyph_cache, cache, cache);
|
||||
gsk_gpu_cached_use (self, (GskGpuCached *) cache, gsk_gpu_frame_get_timestamp (frame));
|
||||
gsk_gpu_cached_use (self, (GskGpuCached *) cache, timestamp);
|
||||
|
||||
memcpy (&priv->front[front_index].key, &lookup.key, sizeof (GlyphKey));
|
||||
priv->front[front_index].value = cache;
|
||||
|
||||
*out_bounds = cache->bounds;
|
||||
*out_origin = cache->origin;
|
||||
|
||||
return cache->image;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
/* vim:set foldmethod=marker expandtab: */
|
||||
|
||||
@@ -5658,6 +5658,7 @@ struct _GskTextNode
|
||||
{
|
||||
GskRenderNode render_node;
|
||||
|
||||
PangoFontMap *fontmap;
|
||||
PangoFont *font;
|
||||
gboolean has_color_glyphs;
|
||||
|
||||
@@ -5675,6 +5676,7 @@ gsk_text_node_finalize (GskRenderNode *node)
|
||||
GskRenderNodeClass *parent_class = g_type_class_peek (g_type_parent (GSK_TYPE_TEXT_NODE));
|
||||
|
||||
g_object_unref (self->font);
|
||||
g_object_unref (self->fontmap);
|
||||
g_free (self->glyphs);
|
||||
|
||||
parent_class->finalize (node);
|
||||
@@ -5788,6 +5790,7 @@ gsk_text_node_new (PangoFont *font,
|
||||
node = (GskRenderNode *) self;
|
||||
node->offscreen_for_opacity = FALSE;
|
||||
|
||||
self->fontmap = g_object_ref (pango_font_get_font_map (font));
|
||||
self->font = g_object_ref (font);
|
||||
self->color = *color;
|
||||
self->offset = *offset;
|
||||
|
||||
+280
-26
@@ -46,12 +46,20 @@
|
||||
#include <cairo-script-interpreter.h>
|
||||
#endif
|
||||
|
||||
#include <pango/pangocairo.h>
|
||||
#ifdef HAVE_PANGOFT
|
||||
#include <pango/pangofc-fontmap.h>
|
||||
#endif
|
||||
|
||||
#include <glib/gstdio.h>
|
||||
|
||||
typedef struct _Context Context;
|
||||
|
||||
struct _Context
|
||||
{
|
||||
GHashTable *named_nodes;
|
||||
GHashTable *named_textures;
|
||||
PangoFontMap *fontmap;
|
||||
};
|
||||
|
||||
typedef struct _Declaration Declaration;
|
||||
@@ -65,7 +73,7 @@ struct _Declaration
|
||||
};
|
||||
|
||||
static void
|
||||
context_init (Context *context)
|
||||
context_init (Context *context)
|
||||
{
|
||||
memset (context, 0, sizeof (Context));
|
||||
}
|
||||
@@ -75,6 +83,7 @@ context_finish (Context *context)
|
||||
{
|
||||
g_clear_pointer (&context->named_nodes, g_hash_table_unref);
|
||||
g_clear_pointer (&context->named_textures, g_hash_table_unref);
|
||||
g_clear_object (&context->fontmap);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -844,20 +853,35 @@ parse_mask_mode (GtkCssParser *parser,
|
||||
}
|
||||
|
||||
static PangoFont *
|
||||
font_from_string (const char *string)
|
||||
font_from_string (PangoFontMap *fontmap,
|
||||
const char *string)
|
||||
{
|
||||
PangoFontDescription *desc;
|
||||
PangoFontMap *font_map;
|
||||
PangoContext *context;
|
||||
PangoContext *ctx;
|
||||
PangoFont *font;
|
||||
|
||||
desc = pango_font_description_from_string (string);
|
||||
font_map = pango_cairo_font_map_get_default ();
|
||||
context = pango_font_map_create_context (font_map);
|
||||
font = pango_font_map_load_font (font_map, context, desc);
|
||||
ctx = pango_font_map_create_context (fontmap);
|
||||
font = pango_font_map_load_font (fontmap, ctx, desc);
|
||||
g_object_unref (ctx);
|
||||
|
||||
if (font)
|
||||
{
|
||||
PangoFontDescription *desc2;
|
||||
const char *family, *family2;
|
||||
|
||||
desc2 = pango_font_describe (font);
|
||||
|
||||
family = pango_font_description_get_family (desc);
|
||||
family2 = pango_font_description_get_family (desc2);
|
||||
|
||||
if (g_strcmp0 (family, family2) != 0)
|
||||
g_clear_object (&font);
|
||||
|
||||
pango_font_description_free (desc2);
|
||||
}
|
||||
|
||||
pango_font_description_free (desc);
|
||||
g_object_unref (context);
|
||||
|
||||
return font;
|
||||
}
|
||||
@@ -926,22 +950,204 @@ create_ascii_glyphs (PangoFont *font)
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef HAVE_PANGOFT
|
||||
|
||||
static void
|
||||
delete_file (gpointer data)
|
||||
{
|
||||
char *path = data;
|
||||
|
||||
g_remove (path);
|
||||
g_free (path);
|
||||
}
|
||||
|
||||
static void
|
||||
ensure_fontmap (Context *context)
|
||||
{
|
||||
FcConfig *config;
|
||||
GPtrArray *files;
|
||||
|
||||
if (context->fontmap)
|
||||
return;
|
||||
|
||||
context->fontmap = pango_cairo_font_map_new ();
|
||||
|
||||
config = FcInitLoadConfig ();
|
||||
pango_fc_font_map_set_config (PANGO_FC_FONT_MAP (context->fontmap), config);
|
||||
FcConfigDestroy (config);
|
||||
|
||||
files = g_ptr_array_new_with_free_func (delete_file);
|
||||
|
||||
g_object_set_data_full (G_OBJECT (context->fontmap), "font-files", files, (GDestroyNotify) g_ptr_array_unref);
|
||||
}
|
||||
|
||||
static void
|
||||
add_font_from_file (Context *context,
|
||||
const char *path,
|
||||
GError **error)
|
||||
{
|
||||
FcConfig *config;
|
||||
GPtrArray *files;
|
||||
|
||||
ensure_fontmap (context);
|
||||
|
||||
if (!PANGO_IS_FC_FONT_MAP (context->fontmap))
|
||||
{
|
||||
g_set_error (error,
|
||||
GTK_CSS_PARSER_ERROR,
|
||||
GTK_CSS_PARSER_ERROR_FAILED,
|
||||
"Custom fonts are not implemented for %s", G_OBJECT_TYPE_NAME (context->fontmap));
|
||||
return;
|
||||
}
|
||||
|
||||
config = pango_fc_font_map_get_config (PANGO_FC_FONT_MAP (context->fontmap));
|
||||
|
||||
if (!FcConfigAppFontAddFile (config, (FcChar8 *) path))
|
||||
{
|
||||
g_set_error (error,
|
||||
GTK_CSS_PARSER_ERROR,
|
||||
GTK_CSS_PARSER_ERROR_FAILED,
|
||||
"Failed to add %s to FcConfig", path);
|
||||
return;
|
||||
}
|
||||
|
||||
files = (GPtrArray *) g_object_get_data (G_OBJECT (context->fontmap), "font-files");
|
||||
g_ptr_array_add (files, g_strdup (path));
|
||||
|
||||
pango_fc_font_map_config_changed (PANGO_FC_FONT_MAP (context->fontmap));
|
||||
}
|
||||
|
||||
static void
|
||||
add_font_from_bytes (Context *context,
|
||||
GBytes *bytes,
|
||||
GError **error)
|
||||
{
|
||||
GFile *file;
|
||||
GIOStream *iostream;
|
||||
GOutputStream *ostream;
|
||||
|
||||
file = g_file_new_tmp ("gtk4-font-XXXXXX.ttf", (GFileIOStream **) &iostream, error);
|
||||
if (!file)
|
||||
return;
|
||||
|
||||
ostream = g_io_stream_get_output_stream (iostream);
|
||||
if (g_output_stream_write_bytes (ostream, bytes, NULL, error) == -1)
|
||||
{
|
||||
g_object_unref (file);
|
||||
g_object_unref (iostream);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
g_io_stream_close (iostream, NULL, NULL);
|
||||
g_object_unref (iostream);
|
||||
|
||||
add_font_from_file (context, g_file_peek_path (file), error);
|
||||
|
||||
g_object_unref (file);
|
||||
}
|
||||
|
||||
#else /* !HAVE_PANGOFT */
|
||||
|
||||
static void
|
||||
add_font_from_bytes (Context *context,
|
||||
GBytes *bytes,
|
||||
GError **error)
|
||||
{
|
||||
g_set_error (error,
|
||||
GTK_CSS_PARSER_ERROR,
|
||||
GTK_CSS_PARSER_ERROR_FAILED,
|
||||
"Not implemented");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static gboolean
|
||||
parse_font (GtkCssParser *parser,
|
||||
Context *context,
|
||||
gpointer out_font)
|
||||
{
|
||||
PangoFont *font;
|
||||
PangoFont *font = NULL;
|
||||
char *s;
|
||||
GtkCssLocation start_location;
|
||||
PangoFontMap *fontmap;
|
||||
|
||||
fontmap = pango_cairo_font_map_get_default ();
|
||||
|
||||
s = gtk_css_parser_consume_string (parser);
|
||||
if (s == NULL)
|
||||
return FALSE;
|
||||
|
||||
font = font_from_string (s);
|
||||
if (font == NULL)
|
||||
start_location = *gtk_css_parser_get_start_location (parser);
|
||||
|
||||
if (gtk_css_parser_try_token (parser, GTK_CSS_TOKEN_URL) ||
|
||||
gtk_css_parser_has_function (parser, "url"))
|
||||
{
|
||||
gtk_css_parser_error_syntax (parser, "This font does not exist.");
|
||||
char *url;
|
||||
char *scheme;
|
||||
GBytes *bytes = NULL;
|
||||
GError *error = NULL;
|
||||
|
||||
/* If we have a url, it is a bug if the font already exists in our custom fontmap */
|
||||
if (context->fontmap)
|
||||
{
|
||||
font = font_from_string (context->fontmap, s);
|
||||
if (font)
|
||||
{
|
||||
g_object_unref (font);
|
||||
gtk_css_parser_error_value (parser, "This font already exists.");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
url = gtk_css_parser_consume_url (parser);
|
||||
|
||||
scheme = g_uri_parse_scheme (url);
|
||||
if (scheme && g_ascii_strcasecmp (scheme, "data") == 0)
|
||||
{
|
||||
bytes = gtk_css_data_url_parse (url, NULL, &error);
|
||||
}
|
||||
else
|
||||
{
|
||||
GFile *file;
|
||||
|
||||
file = g_file_new_for_uri (url);
|
||||
bytes = g_file_load_bytes (file, NULL, NULL, &error);
|
||||
g_object_unref (file);
|
||||
}
|
||||
|
||||
g_free (scheme);
|
||||
g_free (url);
|
||||
|
||||
if (bytes)
|
||||
{
|
||||
add_font_from_bytes (context, bytes, &error);
|
||||
g_bytes_unref (bytes);
|
||||
|
||||
fontmap = context->fontmap;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_assert (error != NULL);
|
||||
|
||||
gtk_css_parser_emit_error (parser,
|
||||
&start_location,
|
||||
gtk_css_parser_get_end_location (parser),
|
||||
error);
|
||||
g_clear_error (&error);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
font = font_from_string (fontmap, s);
|
||||
|
||||
if (!font && context->fontmap && fontmap != context->fontmap)
|
||||
font = font_from_string (context->fontmap, s);
|
||||
|
||||
if (!font)
|
||||
{
|
||||
gtk_css_parser_error_value (parser, "This font does not exist.");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -2013,7 +2219,7 @@ parse_text_node (GtkCssParser *parser,
|
||||
|
||||
if (font == NULL)
|
||||
{
|
||||
font = font_from_string ("Cantarell 11");
|
||||
font = font_from_string (pango_cairo_font_map_get_default (), "Cantarell 11");
|
||||
g_assert (font);
|
||||
}
|
||||
|
||||
@@ -2629,6 +2835,7 @@ typedef struct
|
||||
gsize named_node_counter;
|
||||
GHashTable *named_textures;
|
||||
gsize named_texture_counter;
|
||||
GHashTable *serialized_fonts;
|
||||
} Printer;
|
||||
|
||||
static void
|
||||
@@ -2781,6 +2988,7 @@ printer_init (Printer *self,
|
||||
self->named_node_counter = 0;
|
||||
self->named_textures = g_hash_table_new_full (NULL, NULL, NULL, g_free);
|
||||
self->named_texture_counter = 0;
|
||||
self->serialized_fonts = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
|
||||
printer_init_duplicates_for_node (self, node);
|
||||
}
|
||||
@@ -2792,6 +3000,7 @@ printer_clear (Printer *self)
|
||||
g_string_free (self->str, TRUE);
|
||||
g_hash_table_unref (self->named_nodes);
|
||||
g_hash_table_unref (self->named_textures);
|
||||
g_hash_table_unref (self->serialized_fonts);
|
||||
}
|
||||
|
||||
#define IDENT_LEVEL 2 /* Spaces per level */
|
||||
@@ -3235,6 +3444,59 @@ append_texture_param (Printer *p,
|
||||
g_bytes_unref (bytes);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_text_node_serialize_font (GskRenderNode *node,
|
||||
Printer *p)
|
||||
{
|
||||
PangoFont *font = gsk_text_node_get_font (node);
|
||||
PangoFontMap *fontmap = pango_font_get_font_map (font);
|
||||
PangoFontDescription *desc;
|
||||
char *s;
|
||||
|
||||
desc = pango_font_describe (font);
|
||||
s = pango_font_description_to_string (desc);
|
||||
g_string_append_printf (p->str, "\"%s\"", s);
|
||||
g_free (s);
|
||||
pango_font_description_free (desc);
|
||||
|
||||
/* Check if this is a custom font that we created from a url */
|
||||
if (!g_object_get_data (G_OBJECT (fontmap), "font-files"))
|
||||
return;
|
||||
|
||||
#ifdef HAVE_PANGOFT
|
||||
{
|
||||
FcPattern *pat;
|
||||
FcResult res;
|
||||
const char *file;
|
||||
char *data;
|
||||
gsize len;
|
||||
char *b64;
|
||||
|
||||
pat = pango_fc_font_get_pattern (PANGO_FC_FONT (font));
|
||||
res = FcPatternGetString (pat, FC_FILE, 0, (FcChar8 **)&file);
|
||||
if (res != FcResultMatch)
|
||||
return;
|
||||
|
||||
if (g_hash_table_contains (p->serialized_fonts, file))
|
||||
return;
|
||||
|
||||
if (!g_file_get_contents (file, &data, &len, NULL))
|
||||
return;
|
||||
|
||||
g_hash_table_add (p->serialized_fonts, (gpointer) file);
|
||||
|
||||
b64 = base64_encode_with_linebreaks ((const guchar *) data, len);
|
||||
|
||||
g_string_append (p->str, " url(\"data:font/ttf;base64,");
|
||||
append_escaping_newlines (p->str, b64);
|
||||
g_string_append (p->str, "\")");
|
||||
|
||||
g_free (b64);
|
||||
g_free (data);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
gsk_text_node_serialize_glyphs (GskRenderNode *node,
|
||||
GString *p)
|
||||
@@ -3788,29 +4050,21 @@ render_node_print (Printer *p,
|
||||
{
|
||||
const graphene_point_t *offset = gsk_text_node_get_offset (node);
|
||||
const GdkRGBA *color = gsk_text_node_get_color (node);
|
||||
PangoFont *font = gsk_text_node_get_font (node);
|
||||
PangoFontDescription *desc;
|
||||
char *font_name;
|
||||
|
||||
start_node (p, "text", node_name);
|
||||
|
||||
if (!gdk_rgba_equal (color, &GDK_RGBA("000000")))
|
||||
if (!gdk_rgba_equal (color, &GDK_RGBA ("000000")))
|
||||
append_rgba_param (p, "color", color);
|
||||
|
||||
_indent (p);
|
||||
desc = pango_font_describe (font);
|
||||
font_name = pango_font_description_to_string (desc);
|
||||
g_string_append_printf (p->str, "font: \"%s\";\n", font_name);
|
||||
g_free (font_name);
|
||||
pango_font_description_free (desc);
|
||||
g_string_append (p->str, "font: ");
|
||||
gsk_text_node_serialize_font (node, p);
|
||||
g_string_append (p->str, ";\n");
|
||||
|
||||
_indent (p);
|
||||
g_string_append (p->str, "glyphs: ");
|
||||
|
||||
gsk_text_node_serialize_glyphs (node, p->str);
|
||||
|
||||
g_string_append_c (p->str, ';');
|
||||
g_string_append_c (p->str, '\n');
|
||||
g_string_append (p->str, ";\n");
|
||||
|
||||
if (!graphene_point_equal (offset, graphene_point_zero ()))
|
||||
append_point_param (p, "offset", offset);
|
||||
|
||||
@@ -6,4 +6,3 @@
|
||||
GskRenderNode * gsk_render_node_deserialize_from_bytes (GBytes *bytes,
|
||||
GskParseErrorFunc error_func,
|
||||
gpointer user_data);
|
||||
|
||||
|
||||
@@ -191,7 +191,7 @@ gtk_cell_renderer_accel_class_init (GtkCellRendererAccelClass *cell_accel_class)
|
||||
PROP_ACCEL_MODS,
|
||||
g_param_spec_flags ("accel-mods", NULL, NULL,
|
||||
GDK_TYPE_MODIFIER_TYPE,
|
||||
0,
|
||||
GDK_NO_MODIFIER_MASK,
|
||||
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
|
||||
|
||||
/**
|
||||
|
||||
@@ -1355,22 +1355,6 @@ gtk_at_context_get_text_accumulate (GtkATContext *self,
|
||||
}
|
||||
}
|
||||
|
||||
/* Step 2.G */
|
||||
if (GTK_IS_LABEL (self->accessible))
|
||||
{
|
||||
const char *text = gtk_label_get_text (GTK_LABEL (self->accessible));
|
||||
if (text && not_just_space (text))
|
||||
append_with_space (res, text);
|
||||
return;
|
||||
}
|
||||
else if (GTK_IS_INSCRIPTION (self->accessible))
|
||||
{
|
||||
const char *text = gtk_inscription_get_text (GTK_INSCRIPTION (self->accessible));
|
||||
if (text && not_just_space (text))
|
||||
append_with_space (res, text);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Step 2.I */
|
||||
if (GTK_IS_WIDGET (self->accessible))
|
||||
{
|
||||
|
||||
@@ -269,11 +269,12 @@ gtk_column_view_cell_widget_size_allocate (GtkWidget *widget,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_column_view_cell_widget_dispose (GObject *object)
|
||||
/* This should be to be called when unsetting the parent, but we have no
|
||||
* set_parent vfunc().
|
||||
*/
|
||||
void
|
||||
gtk_column_view_cell_widget_unset_column (GtkColumnViewCellWidget *self)
|
||||
{
|
||||
GtkColumnViewCellWidget *self = GTK_COLUMN_VIEW_CELL_WIDGET (object);
|
||||
|
||||
if (self->column)
|
||||
{
|
||||
gtk_column_view_column_remove_cell (self->column, self);
|
||||
@@ -288,6 +289,15 @@ gtk_column_view_cell_widget_dispose (GObject *object)
|
||||
|
||||
g_clear_object (&self->column);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_column_view_cell_widget_dispose (GObject *object)
|
||||
{
|
||||
GtkColumnViewCellWidget *self = GTK_COLUMN_VIEW_CELL_WIDGET (object);
|
||||
|
||||
/* unset_parent() forgot to call this. Be very angry. */
|
||||
g_warn_if_fail (self->column == NULL);
|
||||
|
||||
G_OBJECT_CLASS (gtk_column_view_cell_widget_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
@@ -46,5 +46,6 @@ void gtk_column_view_cell_widget_remove (
|
||||
GtkColumnViewCellWidget * gtk_column_view_cell_widget_get_next (GtkColumnViewCellWidget *self);
|
||||
GtkColumnViewCellWidget * gtk_column_view_cell_widget_get_prev (GtkColumnViewCellWidget *self);
|
||||
GtkColumnViewColumn * gtk_column_view_cell_widget_get_column (GtkColumnViewCellWidget *self);
|
||||
void gtk_column_view_cell_widget_unset_column (GtkColumnViewCellWidget *self);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
@@ -592,6 +592,9 @@ void
|
||||
gtk_column_view_row_widget_remove_child (GtkColumnViewRowWidget *self,
|
||||
GtkWidget *child)
|
||||
{
|
||||
if (GTK_IS_COLUMN_VIEW_CELL_WIDGET (child))
|
||||
gtk_column_view_cell_widget_unset_column (GTK_COLUMN_VIEW_CELL_WIDGET (child));
|
||||
|
||||
gtk_widget_unparent (child);
|
||||
}
|
||||
|
||||
|
||||
+7
-4
@@ -1803,16 +1803,19 @@ typedef enum { /*< prefix=GTK_ACCESSIBLE_SORT >*/
|
||||
|
||||
/**
|
||||
* GtkPopoverMenuFlags:
|
||||
* @GTK_POPOVER_MENU_NESTED: Create submenus as nested
|
||||
* popovers. Without this flag, submenus are created as
|
||||
* sliding pages that replace the main menu.
|
||||
* @GTK_POPOVER_MENU_SLIDING: Submenus are presented as sliding submenus that
|
||||
* replace the main menu.
|
||||
* @GTK_POPOVER_MENU_NESTED: Submenus are presented as traditional, nested
|
||||
* popovers.
|
||||
*
|
||||
* Flags that affect how [class@Gtk.PopoverMenu] widgets built from
|
||||
* a [class@Gio.MenuModel] are created and displayed.
|
||||
*
|
||||
* Since: 4.14
|
||||
*/
|
||||
typedef enum { /*< prefix=GTK_POPOVER_MENU >*/
|
||||
GTK_POPOVER_MENU_SLIDING = 0,
|
||||
GTK_POPOVER_MENU_NESTED = 1 << 0
|
||||
} GtkPopoverMenuFlags;
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
+164
-41
@@ -162,6 +162,45 @@
|
||||
* ```
|
||||
*/
|
||||
|
||||
typedef struct _WeakRefGuard WeakRefGuard;
|
||||
|
||||
struct _WeakRefGuard
|
||||
{
|
||||
gatomicrefcount ref_count;
|
||||
gpointer data;
|
||||
};
|
||||
|
||||
static WeakRefGuard *
|
||||
weak_ref_guard_new (gpointer data)
|
||||
{
|
||||
WeakRefGuard *guard;
|
||||
|
||||
guard = g_new0 (WeakRefGuard, 1);
|
||||
g_atomic_ref_count_init (&guard->ref_count);
|
||||
guard->data = data;
|
||||
|
||||
return guard;
|
||||
}
|
||||
|
||||
static WeakRefGuard *
|
||||
weak_ref_guard_ref (WeakRefGuard *guard)
|
||||
{
|
||||
g_atomic_ref_count_inc (&guard->ref_count);
|
||||
return guard;
|
||||
}
|
||||
|
||||
static void
|
||||
weak_ref_guard_unref (WeakRefGuard *guard)
|
||||
{
|
||||
/* Always clear data pointer after first unref so that it
|
||||
* cannot be accessed unless both the expression/watch is
|
||||
* valid _and_ the weak ref is still active.
|
||||
*/
|
||||
guard->data = NULL;
|
||||
|
||||
if (g_atomic_ref_count_dec (&guard->ref_count))
|
||||
g_free (guard);
|
||||
}
|
||||
|
||||
typedef struct _GtkExpressionClass GtkExpressionClass;
|
||||
typedef struct _GtkExpressionSubWatch GtkExpressionSubWatch;
|
||||
@@ -230,7 +269,8 @@ struct _GtkExpressionTypeInfo
|
||||
struct _GtkExpressionWatch
|
||||
{
|
||||
GtkExpression *expression;
|
||||
GObject *this;
|
||||
WeakRefGuard *guard;
|
||||
GWeakRef this_wr;
|
||||
GDestroyNotify user_destroy;
|
||||
GtkExpressionNotify notify;
|
||||
gpointer user_data;
|
||||
@@ -903,7 +943,8 @@ struct _GtkObjectExpression
|
||||
{
|
||||
GtkExpression parent;
|
||||
|
||||
GObject *object;
|
||||
WeakRefGuard *guard;
|
||||
GWeakRef object_wr;
|
||||
GSList *watches;
|
||||
};
|
||||
|
||||
@@ -917,26 +958,50 @@ static void
|
||||
gtk_object_expression_weak_ref_cb (gpointer data,
|
||||
GObject *object)
|
||||
{
|
||||
GtkObjectExpression *self = (GtkObjectExpression *) data;
|
||||
GSList *l;
|
||||
WeakRefGuard *guard = data;
|
||||
GtkObjectExpression *self = guard->data;
|
||||
|
||||
self->object = NULL;
|
||||
|
||||
for (l = self->watches; l; l = l->next)
|
||||
if (self != NULL)
|
||||
{
|
||||
GtkObjectExpressionWatch *owatch = l->data;
|
||||
GSList *iter = self->watches;
|
||||
|
||||
owatch->notify (owatch->user_data);
|
||||
while (iter)
|
||||
{
|
||||
GtkObjectExpressionWatch *owatch = iter->data;
|
||||
iter = iter->next;
|
||||
owatch->notify (owatch->user_data);
|
||||
}
|
||||
}
|
||||
|
||||
weak_ref_guard_unref (guard);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_object_expression_finalize (GtkExpression *expr)
|
||||
{
|
||||
GtkObjectExpression *self = (GtkObjectExpression *) expr;
|
||||
GObject *object;
|
||||
|
||||
if (self->object)
|
||||
g_object_weak_unref (self->object, gtk_object_expression_weak_ref_cb, self);
|
||||
object = g_weak_ref_get (&self->object_wr);
|
||||
|
||||
if (object != NULL)
|
||||
{
|
||||
g_object_weak_unref (object, gtk_object_expression_weak_ref_cb, self->guard);
|
||||
weak_ref_guard_unref (self->guard);
|
||||
g_object_unref (object);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* @object has been disposed. Which means that either our
|
||||
* gtk_object_expression_weak_ref_cb has been called or we
|
||||
* can expect it to be called shortly after this. No need to
|
||||
* call g_object_weak_unref() or unref the handle which will
|
||||
* be unref'ed by that callback.
|
||||
*/
|
||||
}
|
||||
|
||||
g_clear_pointer (&self->guard, weak_ref_guard_unref);
|
||||
g_weak_ref_clear (&self->object_wr);
|
||||
|
||||
g_assert (self->watches == NULL);
|
||||
|
||||
@@ -955,12 +1020,14 @@ gtk_object_expression_evaluate (GtkExpression *expr,
|
||||
GValue *value)
|
||||
{
|
||||
GtkObjectExpression *self = (GtkObjectExpression *) expr;
|
||||
GObject *object;
|
||||
|
||||
if (self->object == NULL)
|
||||
object = g_weak_ref_get (&self->object_wr);
|
||||
if (object == NULL)
|
||||
return FALSE;
|
||||
|
||||
g_value_init (value, gtk_expression_get_value_type (expr));
|
||||
g_value_set_object (value, self->object);
|
||||
g_value_take_object (value, object);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -1033,10 +1100,14 @@ gtk_object_expression_new (GObject *object)
|
||||
g_return_val_if_fail (G_IS_OBJECT (object), NULL);
|
||||
|
||||
result = gtk_expression_alloc (GTK_TYPE_OBJECT_EXPRESSION, G_OBJECT_TYPE (object));
|
||||
self = (GtkObjectExpression *) result;
|
||||
|
||||
self->object = object;
|
||||
g_object_weak_ref (object, gtk_object_expression_weak_ref_cb, self);
|
||||
self = (GtkObjectExpression *) result;
|
||||
g_weak_ref_init (&self->object_wr, object);
|
||||
self->guard = weak_ref_guard_new (self);
|
||||
|
||||
g_object_weak_ref (object,
|
||||
gtk_object_expression_weak_ref_cb,
|
||||
weak_ref_guard_ref (self->guard));
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -1053,10 +1124,17 @@ GObject *
|
||||
gtk_object_expression_get_object (GtkExpression *expression)
|
||||
{
|
||||
GtkObjectExpression *self = (GtkObjectExpression *) expression;
|
||||
GObject *object;
|
||||
|
||||
g_return_val_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (expression, GTK_TYPE_OBJECT_EXPRESSION), NULL);
|
||||
|
||||
return self->object;
|
||||
object = g_weak_ref_get (&self->object_wr);
|
||||
|
||||
/* Return a borrowed instance */
|
||||
if (object != NULL)
|
||||
g_object_unref (object);
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
@@ -1852,12 +1930,19 @@ static void
|
||||
gtk_expression_watch_this_cb (gpointer data,
|
||||
GObject *this)
|
||||
{
|
||||
GtkExpressionWatch *watch = data;
|
||||
WeakRefGuard *guard = data;
|
||||
GtkExpressionWatch *watch = guard->data;
|
||||
|
||||
watch->this = NULL;
|
||||
if (watch != NULL)
|
||||
{
|
||||
g_weak_ref_set (&watch->this_wr, NULL);
|
||||
|
||||
watch->notify (watch->user_data);
|
||||
gtk_expression_watch_unwatch (watch);
|
||||
watch->notify (watch->user_data);
|
||||
|
||||
gtk_expression_watch_unwatch (watch);
|
||||
}
|
||||
|
||||
weak_ref_guard_unref (guard);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1911,9 +1996,12 @@ gtk_expression_watch (GtkExpression *self,
|
||||
watch = g_atomic_rc_box_alloc0 (sizeof (GtkExpressionWatch) + gtk_expression_watch_size (self));
|
||||
|
||||
watch->expression = gtk_expression_ref (self);
|
||||
watch->this = this_;
|
||||
watch->guard = weak_ref_guard_new (watch);
|
||||
g_weak_ref_init (&watch->this_wr, this_);
|
||||
if (this_)
|
||||
g_object_weak_ref (this_, gtk_expression_watch_this_cb, watch);
|
||||
g_object_weak_ref (this_,
|
||||
gtk_expression_watch_this_cb,
|
||||
weak_ref_guard_ref (watch->guard));
|
||||
watch->notify = notify;
|
||||
watch->user_data = user_data;
|
||||
watch->user_destroy = user_destroy;
|
||||
@@ -1947,6 +2035,10 @@ gtk_expression_watch_finalize (gpointer data)
|
||||
GtkExpressionWatch *watch G_GNUC_UNUSED = data;
|
||||
|
||||
g_assert (!gtk_expression_watch_is_watching (data));
|
||||
|
||||
weak_ref_guard_unref (watch->guard);
|
||||
|
||||
g_weak_ref_clear (&watch->this_wr);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1976,17 +2068,27 @@ gtk_expression_watch_unref (GtkExpressionWatch *watch)
|
||||
void
|
||||
gtk_expression_watch_unwatch (GtkExpressionWatch *watch)
|
||||
{
|
||||
GObject *this;
|
||||
|
||||
if (!gtk_expression_watch_is_watching (watch))
|
||||
return;
|
||||
|
||||
gtk_expression_subwatch_finish (watch->expression, (GtkExpressionSubWatch *) watch->sub);
|
||||
|
||||
if (watch->this)
|
||||
g_object_weak_unref (watch->this, gtk_expression_watch_this_cb, watch);
|
||||
this = g_weak_ref_get (&watch->this_wr);
|
||||
|
||||
if (this)
|
||||
{
|
||||
g_object_weak_unref (this, gtk_expression_watch_this_cb, watch->guard);
|
||||
weak_ref_guard_unref (watch->guard);
|
||||
g_weak_ref_set (&watch->this_wr, NULL);
|
||||
}
|
||||
|
||||
if (watch->user_destroy)
|
||||
watch->user_destroy (watch->user_data);
|
||||
|
||||
g_clear_object (&this);
|
||||
|
||||
g_clear_pointer (&watch->expression, gtk_expression_unref);
|
||||
|
||||
gtk_expression_watch_unref (watch);
|
||||
@@ -2009,17 +2111,24 @@ gboolean
|
||||
gtk_expression_watch_evaluate (GtkExpressionWatch *watch,
|
||||
GValue *value)
|
||||
{
|
||||
GObject *this;
|
||||
gboolean ret;
|
||||
|
||||
g_return_val_if_fail (watch != NULL, FALSE);
|
||||
|
||||
if (!gtk_expression_watch_is_watching (watch))
|
||||
return FALSE;
|
||||
|
||||
return gtk_expression_evaluate (watch->expression, watch->this, value);
|
||||
this = g_weak_ref_get (&watch->this_wr);
|
||||
ret = gtk_expression_evaluate (watch->expression, this, value);
|
||||
g_clear_object (&this);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
GtkExpressionWatch *watch;
|
||||
GObject *target;
|
||||
GWeakRef target_wr;
|
||||
GParamSpec *pspec;
|
||||
} GtkExpressionBind;
|
||||
|
||||
@@ -2029,34 +2138,39 @@ invalidate_binds (gpointer unused,
|
||||
{
|
||||
GSList *l, *binds;
|
||||
|
||||
binds = g_object_get_data (object, "gtk-expression-binds");
|
||||
for (l = binds; l; l = l->next)
|
||||
l = binds = g_object_get_data (object, "gtk-expression-binds");
|
||||
while (l)
|
||||
{
|
||||
GtkExpressionBind *bind = l->data;
|
||||
|
||||
l = l->next;
|
||||
|
||||
/* This guarantees we neither try to update bindings
|
||||
* (which would wreck havoc because the object is
|
||||
* dispose()ing itself) nor try to destroy bindings
|
||||
* anymore, so destruction can be done in free_binds().
|
||||
*/
|
||||
bind->target = NULL;
|
||||
g_weak_ref_set (&bind->target_wr, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
free_binds (gpointer data)
|
||||
{
|
||||
GSList *l;
|
||||
GSList *l = data;
|
||||
|
||||
for (l = data; l; l = l->next)
|
||||
while (l)
|
||||
{
|
||||
GtkExpressionBind *bind = l->data;
|
||||
|
||||
g_assert (bind->target == NULL);
|
||||
l = l->next;
|
||||
|
||||
if (bind->watch)
|
||||
gtk_expression_watch_unwatch (bind->watch);
|
||||
g_weak_ref_clear (&bind->target_wr);
|
||||
g_free (bind);
|
||||
}
|
||||
|
||||
g_slist_free (data);
|
||||
}
|
||||
|
||||
@@ -2064,17 +2178,21 @@ static void
|
||||
gtk_expression_bind_free (gpointer data)
|
||||
{
|
||||
GtkExpressionBind *bind = data;
|
||||
GObject *target = g_weak_ref_get (&bind->target_wr);
|
||||
|
||||
if (bind->target)
|
||||
g_weak_ref_set (&bind->target_wr, NULL);
|
||||
|
||||
if (target)
|
||||
{
|
||||
GSList *binds;
|
||||
binds = g_object_steal_data (bind->target, "gtk-expression-binds");
|
||||
binds = g_object_steal_data (target, "gtk-expression-binds");
|
||||
binds = g_slist_remove (binds, bind);
|
||||
if (binds)
|
||||
g_object_set_data_full (bind->target, "gtk-expression-binds", binds, free_binds);
|
||||
g_object_set_data_full (target, "gtk-expression-binds", binds, free_binds);
|
||||
else
|
||||
g_object_weak_unref (bind->target, invalidate_binds, NULL);
|
||||
g_object_weak_unref (target, invalidate_binds, NULL);
|
||||
|
||||
g_object_unref (target);
|
||||
g_free (bind);
|
||||
}
|
||||
else
|
||||
@@ -2096,14 +2214,19 @@ gtk_expression_bind_notify (gpointer data)
|
||||
{
|
||||
GValue value = G_VALUE_INIT;
|
||||
GtkExpressionBind *bind = data;
|
||||
GObject *target = g_weak_ref_get (&bind->target_wr);
|
||||
|
||||
if (bind->target == NULL)
|
||||
if (target == NULL)
|
||||
return;
|
||||
|
||||
if (!gtk_expression_watch_evaluate (bind->watch, &value))
|
||||
return;
|
||||
{
|
||||
g_object_unref (target);
|
||||
return;
|
||||
}
|
||||
|
||||
g_object_set_property (bind->target, bind->pspec->name, &value);
|
||||
g_object_set_property (target, bind->pspec->name, &value);
|
||||
g_object_unref (target);
|
||||
g_value_unset (&value);
|
||||
}
|
||||
|
||||
@@ -2163,7 +2286,7 @@ gtk_expression_bind (GtkExpression *self,
|
||||
binds = g_object_steal_data (target, "gtk-expression-binds");
|
||||
if (binds == NULL)
|
||||
g_object_weak_ref (target, invalidate_binds, NULL);
|
||||
bind->target = target;
|
||||
g_weak_ref_init (&bind->target_wr, target);
|
||||
bind->pspec = pspec;
|
||||
bind->watch = gtk_expression_watch (self,
|
||||
this_,
|
||||
|
||||
@@ -47,6 +47,8 @@
|
||||
* `GtkGLArea` sets up its own [class@Gdk.GLContext], and creates a custom
|
||||
* GL framebuffer that the widget will do GL rendering onto. It also ensures
|
||||
* that this framebuffer is the default GL rendering target when rendering.
|
||||
* The completed rendering is integrated into the larger GTK scene graph as
|
||||
* a texture.
|
||||
*
|
||||
* In order to draw, you have to connect to the [signal@Gtk.GLArea::render]
|
||||
* signal, or subclass `GtkGLArea` and override the GtkGLAreaClass.render
|
||||
@@ -64,6 +66,8 @@
|
||||
* The `render()` function will be called when the `GtkGLArea` is ready
|
||||
* for you to draw its content:
|
||||
*
|
||||
* The initial contents of the framebuffer are transparent.
|
||||
*
|
||||
* ```c
|
||||
* static gboolean
|
||||
* render (GtkGLArea *area, GdkGLContext *context)
|
||||
|
||||
@@ -805,6 +805,11 @@ gtk_inscription_set_text (GtkInscription *self,
|
||||
gtk_widget_queue_draw (GTK_WIDGET (self));
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_TEXT]);
|
||||
|
||||
gtk_accessible_update_property (GTK_ACCESSIBLE (self),
|
||||
GTK_ACCESSIBLE_PROPERTY_LABEL,
|
||||
text,
|
||||
-1);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -3086,6 +3086,11 @@ gtk_label_set_label_internal (GtkLabel *self,
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), label_props[PROP_LABEL]);
|
||||
|
||||
gtk_accessible_update_property (GTK_ACCESSIBLE (self),
|
||||
GTK_ACCESSIBLE_PROPERTY_LABEL,
|
||||
self->label,
|
||||
-1);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
+4
-3
@@ -6991,9 +6991,10 @@ gtk_notebook_get_tab_detachable (GtkNotebook *notebook,
|
||||
*
|
||||
* If you want a widget to interact with a notebook through DnD
|
||||
* (i.e.: accept dragged tabs from it) it must be set as a drop
|
||||
* destination and accept the target “GTK_NOTEBOOK_TAB”. The notebook
|
||||
* will fill the selection with a GtkWidget** pointing to the child
|
||||
* widget that corresponds to the dropped tab.
|
||||
* destination by adding to it a [class@Gtk.DropTarget] controller that accepts
|
||||
* the GType `GTK_TYPE_NOTEBOOK_PAGE`. The `:value` of said drop target will be
|
||||
* preloaded with a [class@Gtk.NotebookPage] object that corresponds to the
|
||||
* dropped tab, so you can process the value via `::accept` or `::drop` signals.
|
||||
*
|
||||
* Note that you should use [method@Gtk.Notebook.detach_tab] instead
|
||||
* of [method@Gtk.Notebook.remove_page] if you want to remove the tab
|
||||
|
||||
+1
-1
@@ -53,7 +53,7 @@ _gtk_pango_attr_list_merge (PangoAttrList *into,
|
||||
if (into)
|
||||
pango_attr_list_filter (from, attr_list_merge_filter, into);
|
||||
else
|
||||
return pango_attr_list_ref (from);
|
||||
return pango_attr_list_ref (from);
|
||||
}
|
||||
|
||||
return into;
|
||||
|
||||
@@ -637,7 +637,8 @@ gtk_popover_menu_class_init (GtkPopoverMenuClass *klass)
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_FLAGS,
|
||||
g_param_spec_flags ("flags", NULL, NULL,
|
||||
GTK_TYPE_POPOVER_MENU_FLAGS, 0,
|
||||
GTK_TYPE_POPOVER_MENU_FLAGS,
|
||||
GTK_POPOVER_MENU_SLIDING,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS
|
||||
| G_PARAM_EXPLICIT_NOTIFY));
|
||||
|
||||
@@ -783,7 +784,7 @@ GtkWidget *
|
||||
gtk_popover_menu_new_from_model (GMenuModel *model)
|
||||
|
||||
{
|
||||
return gtk_popover_menu_new_from_model_full (model, 0);
|
||||
return gtk_popover_menu_new_from_model_full (model, GTK_POPOVER_MENU_SLIDING);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -799,10 +800,6 @@ gtk_popover_menu_new_from_model (GMenuModel *model)
|
||||
* belongs. Actions can also be added using [method@Gtk.Widget.insert_action_group]
|
||||
* on the parent widget or on any of its parent widgets.
|
||||
*
|
||||
* The only flag that is supported currently is
|
||||
* %GTK_POPOVER_MENU_NESTED, which makes GTK create traditional,
|
||||
* nested submenus instead of the default sliding submenus.
|
||||
*
|
||||
* Returns: the new `GtkPopoverMenu`
|
||||
*/
|
||||
GtkWidget *
|
||||
|
||||
@@ -671,7 +671,7 @@ gtk_keyval_trigger_class_init (GtkKeyvalTriggerClass *klass)
|
||||
keyval_props[KEYVAL_PROP_MODIFIERS] =
|
||||
g_param_spec_flags (I_("modifiers"), NULL, NULL,
|
||||
GDK_TYPE_MODIFIER_TYPE,
|
||||
0,
|
||||
GDK_NO_MODIFIER_MASK,
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
@@ -179,6 +179,7 @@ GDK_AVAILABLE_IN_ALL
|
||||
GtkSelectionModel * gtk_stack_get_pages (GtkStack *stack);
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkStack, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkStackPage, g_object_unref)
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
+12
-1
@@ -38,6 +38,8 @@
|
||||
#include "gdk/gdkdebugprivate.h"
|
||||
#include "gdk/gdkdisplayprivate.h"
|
||||
|
||||
#include "profile_conf.h"
|
||||
|
||||
#include <epoxy/gl.h>
|
||||
|
||||
#ifdef GDK_WINDOWING_X11
|
||||
@@ -193,7 +195,16 @@ init_version (GtkInspectorGeneral *gen)
|
||||
g_object_unref (gsk_renderer);
|
||||
gdk_surface_destroy (surface);
|
||||
|
||||
gtk_label_set_text (GTK_LABEL (gen->gtk_version), GTK_VERSION);
|
||||
if (g_strcmp0 (PROFILE, "devel") == 0)
|
||||
{
|
||||
char *version = g_strdup_printf ("%s-%s", GTK_VERSION, VCS_TAG);
|
||||
gtk_label_set_text (GTK_LABEL (gen->gtk_version), version);
|
||||
g_free (version);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_label_set_text (GTK_LABEL (gen->gtk_version), GTK_VERSION);
|
||||
}
|
||||
gtk_label_set_text (GTK_LABEL (gen->gdk_backend), backend);
|
||||
gtk_label_set_text (GTK_LABEL (gen->gsk_renderer), renderer);
|
||||
}
|
||||
|
||||
@@ -67,6 +67,7 @@ struct _GtkInspectorLogs
|
||||
GtkWidget *shaders;
|
||||
GtkWidget *surface;
|
||||
GtkWidget *glyphcache;
|
||||
GtkWidget *verbose;
|
||||
|
||||
GtkWidget *actions;
|
||||
GtkWidget *builder;
|
||||
@@ -147,6 +148,7 @@ flag_toggled (GtkWidget *button,
|
||||
update_flag (logs->shaders, &flags, GSK_DEBUG_SHADERS);
|
||||
update_flag (logs->surface, &flags, GSK_DEBUG_SURFACE);
|
||||
update_flag (logs->glyphcache, &flags, GSK_DEBUG_GLYPH_CACHE);
|
||||
update_flag (logs->verbose, &flags, GSK_DEBUG_VERBOSE);
|
||||
gsk_set_debug_flags (flags);
|
||||
|
||||
toplevels = gtk_window_list_toplevels ();
|
||||
@@ -210,6 +212,7 @@ gtk_inspector_logs_class_init (GtkInspectorLogsClass *klass)
|
||||
gtk_widget_class_bind_template_child (widget_class, GtkInspectorLogs, shaders);
|
||||
gtk_widget_class_bind_template_child (widget_class, GtkInspectorLogs, surface);
|
||||
gtk_widget_class_bind_template_child (widget_class, GtkInspectorLogs, glyphcache);
|
||||
gtk_widget_class_bind_template_child (widget_class, GtkInspectorLogs, verbose);
|
||||
|
||||
gtk_widget_class_bind_template_child (widget_class, GtkInspectorLogs, actions);
|
||||
gtk_widget_class_bind_template_child (widget_class, GtkInspectorLogs, builder);
|
||||
|
||||
@@ -158,6 +158,12 @@
|
||||
<signal name="toggled" handler="flag_toggled"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="verboe">
|
||||
<property name="label">Verbose</property>
|
||||
<signal name="toggled" handler="flag_toggled"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
|
||||
@@ -1028,6 +1028,7 @@ gtk_deps = [
|
||||
epoxy_dep,
|
||||
libm,
|
||||
graphene_dep,
|
||||
profile_conf_h,
|
||||
]
|
||||
|
||||
if x11_enabled
|
||||
|
||||
+21
@@ -785,6 +785,27 @@ project_build_root = meson.current_build_dir()
|
||||
|
||||
gen_visibility_macros = find_program('build-aux/meson/gen-visibility-macros.py')
|
||||
|
||||
gen_profile_conf = find_program('build-aux/meson/gen-profile-conf.py')
|
||||
|
||||
profile = get_option('profile')
|
||||
if profile == 'auto'
|
||||
if gtk_minor_version.is_even()
|
||||
profile = 'default'
|
||||
else
|
||||
profile = 'devel'
|
||||
endif
|
||||
endif
|
||||
|
||||
profile_conf_h = declare_dependency(
|
||||
sources: custom_target('profile-conf',
|
||||
command: [gen_profile_conf, meson.project_source_root(), profile],
|
||||
capture: true,
|
||||
output: 'profile_conf.h',
|
||||
build_by_default: true,
|
||||
build_always_stale: true,
|
||||
)
|
||||
)
|
||||
|
||||
subdir('gdk/version')
|
||||
subdir('gtk/css')
|
||||
subdir('gdk')
|
||||
|
||||
+6
-6
@@ -124,15 +124,15 @@ option('man-pages',
|
||||
|
||||
option('demo-profile',
|
||||
type: 'combo',
|
||||
choices: [ 'default', 'devel' ],
|
||||
value: 'default',
|
||||
description : 'Profile to use for demos')
|
||||
choices: [ 'auto', 'default', 'devel' ],
|
||||
value: 'auto',
|
||||
deprecated: 'profile')
|
||||
|
||||
option('profile',
|
||||
type: 'combo',
|
||||
choices: [ 'default', 'devel' ],
|
||||
value: 'default',
|
||||
deprecated: 'demo-profile')
|
||||
choices: [ 'auto', 'default', 'devel' ],
|
||||
value: 'auto',
|
||||
description : 'Profile to use for demos')
|
||||
|
||||
option('build-demos',
|
||||
type: 'boolean',
|
||||
|
||||
@@ -58,6 +58,7 @@ gdk/x11/gdkmain-x11.c
|
||||
gdk/x11/gdkselectioninputstream-x11.c
|
||||
gdk/x11/gdktextlistconverter-x11.c
|
||||
gsk/gl/gskglrenderer.c
|
||||
gsk/gpu/gskgldevice.c
|
||||
gsk/gskrendernodeimpl.c
|
||||
gtk/a11y/gtkatspiaction.c
|
||||
gtk/a11y/gtkatspiroot.c
|
||||
|
||||
@@ -6,14 +6,14 @@
|
||||
# Mahyar Moghimi <mahyar.moqimi@gmail.com>, 2010.
|
||||
# Ali Yousefi Sabzevar <aysabzevar@gmail.com>, 2010.
|
||||
# Arash Mousavi <mousavi.arash@gmail.com>, 2011-2017.
|
||||
# Danial Behzadi <dani.behzi@ubuntu.com>, 2018-2023.
|
||||
# Danial Behzadi <dani.behzi@ubuntu.com>, 2018-2024.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gtk+ 2.6\n"
|
||||
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gtk/-/issues/\n"
|
||||
"POT-Creation-Date: 2023-11-27 21:52+0000\n"
|
||||
"PO-Revision-Date: 2023-11-28 12:17+0330\n"
|
||||
"POT-Creation-Date: 2024-01-20 11:14+0000\n"
|
||||
"PO-Revision-Date: 2024-01-20 14:52+0330\n"
|
||||
"Last-Translator: Danial Behzadi <dani.behzi@ubuntu.com>\n"
|
||||
"Language-Team: Persian <>\n"
|
||||
"Language: fa\n"
|
||||
@@ -23,7 +23,7 @@ msgstr ""
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
"X-Poedit-Bookmarks: 133,-1,-1,-1,-1,-1,-1,-1,-1,-1\n"
|
||||
"X-Poedit-SourceCharset: utf-8\n"
|
||||
"X-Generator: Poedit 3.4.1\n"
|
||||
"X-Generator: Poedit 3.4.2\n"
|
||||
|
||||
#: gdk/broadway/gdkbroadway-server.c:135
|
||||
#, c-format
|
||||
@@ -34,11 +34,11 @@ msgstr "نوع نمایشگر broadway پشتیبانی نمیشود: %s"
|
||||
msgid "This clipboard cannot store data."
|
||||
msgstr "این تختهگیره نمیتواند داده ذخیره کند."
|
||||
|
||||
#: gdk/gdkclipboard.c:287 gdk/gdkclipboard.c:785 gdk/gdkclipboard.c:1085
|
||||
#: gdk/gdkclipboard.c:287 gdk/gdkclipboard.c:786 gdk/gdkclipboard.c:1086
|
||||
msgid "Cannot read from empty clipboard."
|
||||
msgstr "نمیتوان از تختهگیرهٔ خالی خواند."
|
||||
|
||||
#: gdk/gdkclipboard.c:318 gdk/gdkclipboard.c:1135 gdk/gdkdrag.c:618
|
||||
#: gdk/gdkclipboard.c:318 gdk/gdkclipboard.c:1136 gdk/gdkdrag.c:618
|
||||
msgid "No compatible formats to transfer clipboard contents."
|
||||
msgstr "هیچ قالب سازگاری برای انتقال محتویات تختهگیره وجود ندارد."
|
||||
|
||||
@@ -53,57 +53,57 @@ msgstr "نمیتوان محتوا را به شکل «%s» فراهم کرد"
|
||||
msgid "Cannot provide contents as %s"
|
||||
msgstr "نمیتوان محتوا را به شکل %s فراهم کرد"
|
||||
|
||||
#: gdk/gdkdisplay.c:169 gdk/gdkglcontext.c:455
|
||||
#: gdk/gdkdisplay.c:170 gdk/gdkglcontext.c:462
|
||||
msgid "The current backend does not support OpenGL"
|
||||
msgstr "پسانه در حال حاضر از OpenGL پشتیبانی نمیکند"
|
||||
|
||||
#: gdk/gdkdisplay.c:1268 gdk/gdksurface.c:1268 gdk/gdkvulkancontext.c:1479
|
||||
#: gdk/gdkdisplay.c:1296 gdk/gdkvulkancontext.c:1581
|
||||
msgid "Vulkan support disabled via GDK_DEBUG"
|
||||
msgstr "پشتیبانی از ولکان به دست GDK_DEBUG از کار افتاده"
|
||||
|
||||
#: gdk/gdkdisplay.c:1300
|
||||
#: gdk/gdkdisplay.c:1350
|
||||
msgid "GL support disabled via GDK_DEBUG"
|
||||
msgstr "پشتیبانی از GL به دست GDK_DEBUG از کار افتاده"
|
||||
|
||||
#: gdk/gdkdisplay.c:1596
|
||||
#: gdk/gdkdisplay.c:1646
|
||||
msgid "No EGL configuration available"
|
||||
msgstr "هیچ پیکربندیای برای EGL موجود نیست"
|
||||
|
||||
#: gdk/gdkdisplay.c:1604
|
||||
#: gdk/gdkdisplay.c:1654
|
||||
msgid "Failed to get EGL configurations"
|
||||
msgstr "شکست در گرفتن پیکربندی EGL"
|
||||
|
||||
#: gdk/gdkdisplay.c:1634
|
||||
#: gdk/gdkdisplay.c:1684
|
||||
msgid "No EGL configuration with required features found"
|
||||
msgstr "هیچ پیکربندیای با ویژگیهای موردنیاز برای EGL موجود نیست"
|
||||
|
||||
#: gdk/gdkdisplay.c:1641
|
||||
#: gdk/gdkdisplay.c:1691
|
||||
msgid "No perfect EGL configuration found"
|
||||
msgstr "هیچ پیکربندی بینظیری برایEGL موجود نیست"
|
||||
|
||||
#: gdk/gdkdisplay.c:1683
|
||||
#: gdk/gdkdisplay.c:1733
|
||||
#, c-format
|
||||
msgid "EGL implementation is missing extension %s"
|
||||
msgid_plural "EGL implementation is missing %2$d extensions: %1$s"
|
||||
msgstr[0] "پیاده سازی EGL %2$Id افزونه کم دارد: %1$s"
|
||||
|
||||
#: gdk/gdkdisplay.c:1733
|
||||
#: gdk/gdkdisplay.c:1783
|
||||
msgid "libEGL not available in this sandbox"
|
||||
msgstr "libEGL در این قرنطینه موجود نیست"
|
||||
|
||||
#: gdk/gdkdisplay.c:1734
|
||||
#: gdk/gdkdisplay.c:1784
|
||||
msgid "libEGL not available"
|
||||
msgstr "libEGL موجود نیست"
|
||||
|
||||
#: gdk/gdkdisplay.c:1744
|
||||
#: gdk/gdkdisplay.c:1794
|
||||
msgid "Failed to create EGL display"
|
||||
msgstr "شکست در ایجاد نمایشگر EGL"
|
||||
|
||||
#: gdk/gdkdisplay.c:1754
|
||||
#: gdk/gdkdisplay.c:1804
|
||||
msgid "Could not initialize EGL display"
|
||||
msgstr "نتوانست نمایشگر EGL را راهاندازی کند"
|
||||
|
||||
#: gdk/gdkdisplay.c:1765
|
||||
#: gdk/gdkdisplay.c:1815
|
||||
#, c-format
|
||||
msgid "EGL version %d.%d is too old. GTK requires %d.%d"
|
||||
msgstr "EGL نگارش %Id. %Id بیش از حد قدیمی است. GTK به %Id.%Id نیاز دارد"
|
||||
@@ -116,37 +116,37 @@ msgstr "کشیدن و رها کردن از دیگر برنامهها پشتی
|
||||
msgid "No compatible formats to transfer contents."
|
||||
msgstr "هیچ قالب سازگاری برای انتقال محتویات وجود ندارد."
|
||||
|
||||
#: gdk/gdkglcontext.c:415 gdk/x11/gdkglcontext-glx.c:642
|
||||
#: gdk/gdkglcontext.c:422 gdk/x11/gdkglcontext-glx.c:642
|
||||
msgid "No GL API allowed."
|
||||
msgstr "هیچ رابط برنامهنویسی GLای مجاز نیست."
|
||||
|
||||
#: gdk/gdkglcontext.c:438 gdk/win32/gdkglcontext-win32-wgl.c:385
|
||||
#: gdk/win32/gdkglcontext-win32-wgl.c:528 gdk/win32/gdkglcontext-win32-wgl.c:572
|
||||
#: gdk/gdkglcontext.c:445 gdk/win32/gdkglcontext-win32-wgl.c:381
|
||||
#: gdk/win32/gdkglcontext-win32-wgl.c:524 gdk/win32/gdkglcontext-win32-wgl.c:568
|
||||
#: gdk/x11/gdkglcontext-glx.c:688
|
||||
msgid "Unable to create a GL context"
|
||||
msgstr "امکان ساخت زمینه مناسب برای GL نبود"
|
||||
|
||||
#: gdk/gdkglcontext.c:1299
|
||||
#: gdk/gdkglcontext.c:1306
|
||||
msgid "OpenGL ES disabled via GDK_DEBUG"
|
||||
msgstr "OpenGL ES به دست GDK_DEBUG از کار افتاد"
|
||||
|
||||
#: gdk/gdkglcontext.c:1311
|
||||
#: gdk/gdkglcontext.c:1318
|
||||
msgid "OpenGL disabled via GDK_DEBUG"
|
||||
msgstr "OpenGL به دست GDK_DEBUG از کار افتاد"
|
||||
|
||||
#: gdk/gdkglcontext.c:1322
|
||||
#: gdk/gdkglcontext.c:1329
|
||||
#, c-format
|
||||
msgid "Application does not support %s API"
|
||||
msgstr "برنامه از API مربوط به %s پشتبانی نمیکند"
|
||||
|
||||
#. translators: This is about OpenGL backend names, like
|
||||
#. * "Trying to use X11 GLX, but EGL is already in use"
|
||||
#: gdk/gdkglcontext.c:1979
|
||||
#: gdk/gdkglcontext.c:2124
|
||||
#, c-format
|
||||
msgid "Trying to use %s, but %s is already in use"
|
||||
msgstr "تلاش شد از %s استفاده شود، ولی %s از پیش در حال استفاده است"
|
||||
|
||||
#: gdk/gdktexture.c:530
|
||||
#: gdk/gdktexture.c:580
|
||||
msgid "Unknown image format."
|
||||
msgstr "قالب تصویر ناشناخته."
|
||||
|
||||
@@ -537,7 +537,7 @@ msgstr "خطا در تفسیر پروندهٔ JPEG (%s)"
|
||||
msgid "Unsupported JPEG colorspace (%d)"
|
||||
msgstr "فضای رنگ JPEG پشتیبانی نشده (%Id)"
|
||||
|
||||
#: gdk/loaders/gdkjpeg.c:203 gdk/loaders/gdkpng.c:280 gdk/loaders/gdktiff.c:472
|
||||
#: gdk/loaders/gdkjpeg.c:203 gdk/loaders/gdkpng.c:286 gdk/loaders/gdktiff.c:472
|
||||
#, c-format
|
||||
msgid "Not enough memory for image size %ux%u"
|
||||
msgstr "حافظهٔ ناکافی برای اندازهٔ تصویر %Iu×%Iu"
|
||||
@@ -547,16 +547,21 @@ msgstr "حافظهٔ ناکافی برای اندازهٔ تصویر %Iu×%Iu"
|
||||
msgid "Error reading png (%s)"
|
||||
msgstr "خطای خواندن png) %s)"
|
||||
|
||||
#: gdk/loaders/gdkpng.c:211
|
||||
#: gdk/loaders/gdkpng.c:212
|
||||
#, c-format
|
||||
msgid "Unsupported depth %u in png image"
|
||||
msgstr "عمق پشتیبانینشدهٔ %Iu در تصویر png"
|
||||
|
||||
#: gdk/loaders/gdkpng.c:261
|
||||
#: gdk/loaders/gdkpng.c:262
|
||||
#, c-format
|
||||
msgid "Unsupported color type %u in png image"
|
||||
msgstr "گونهٔ رنگ پشتیبانی نشدهٔ %Iu در تصویر png"
|
||||
|
||||
#: gdk/loaders/gdkpng.c:272
|
||||
#, c-format
|
||||
msgid "Image stride too large for image size %ux%u"
|
||||
msgstr "گام تصویر بیش از حد بزرگ برای اندازهٔ تصویر %Iu×%Iu"
|
||||
|
||||
#: gdk/loaders/gdktiff.c:358
|
||||
msgid "Failed to load RGB data from TIFF file"
|
||||
msgstr "نمیتوان دادههای RGB را از پروندهٔ TIFF بار کرد"
|
||||
@@ -699,21 +704,21 @@ msgstr "IDataObject_GetData (0x%x) شکست خورد. 0x%lx را برگردان
|
||||
msgid "Failed to transmute DnD data W32 format 0x%x to %p (%s)"
|
||||
msgstr "شکست در تغییر شکل قالب W32 دادهٔ کور 0x%x به %p (%s)"
|
||||
|
||||
#: gdk/win32/gdkglcontext-win32-wgl.c:319
|
||||
#: gdk/win32/gdkglcontext-win32-wgl.c:315
|
||||
msgid "No GL implementation is available"
|
||||
msgstr "هیچ پیاده سازی GLای پیدا نشد"
|
||||
|
||||
#: gdk/win32/gdkglcontext-win32-wgl.c:394
|
||||
#: gdk/win32/gdkglcontext-win32-wgl.c:390
|
||||
#, c-format
|
||||
msgid "WGL version %d.%d is too low, need at least %d.%d"
|
||||
msgstr "WGL نگارش %Id. %Id بیش از حد قدیمی است. کمینه به %Id.%Id نیاز است"
|
||||
|
||||
#: gdk/win32/gdkglcontext-win32-wgl.c:412
|
||||
#: gdk/win32/gdkglcontext-win32-wgl.c:408
|
||||
#, c-format
|
||||
msgid "GL implementation cannot share GL contexts"
|
||||
msgstr "پیادهسازی GL نمیتواند بافتارهای GL را همرساند"
|
||||
|
||||
#: gdk/win32/gdkglcontext-win32-wgl.c:692
|
||||
#: gdk/win32/gdkglcontext-win32-wgl.c:688
|
||||
msgid "No available configurations for the given pixel format"
|
||||
msgstr "هیچ پیکربندی برای قالب نقطهای ارائه شده موجود نیست"
|
||||
|
||||
@@ -813,11 +818,16 @@ msgstr "قالب نامعتبر در تبدیل متن ترکیبی."
|
||||
msgid "Unsupported encoding “%s”"
|
||||
msgstr "رمزنگاری پشتیبانینشدهٔ %s"
|
||||
|
||||
#: gsk/gl/gskglrenderer.c:135
|
||||
#: gsk/gl/gskglrenderer.c:204
|
||||
#, c-format
|
||||
msgid "This GLES %d.%d implementation does not support half-float vertex data"
|
||||
msgstr "این پشتیبانی EGL %Id.%Id از دادههای رأس نیمشناور پیشتیبانی نمیکند"
|
||||
|
||||
#: gsk/gpu/gskgldevice.c:238
|
||||
#, c-format
|
||||
msgid "OpenGL ES 2.0 is not supported by this renderer."
|
||||
msgstr "نگارش ۲٫۰ OpenGL ES به دست این پرداختگر پشتیبانی نمیشود."
|
||||
|
||||
#: gtk/a11y/gtkatspiaction.c:239
|
||||
msgctxt "accessibility"
|
||||
msgid "Click"
|
||||
@@ -1014,7 +1024,7 @@ msgid "Invalid"
|
||||
msgstr "نامعتبر"
|
||||
|
||||
#. This label is displayed in a treeview cell displaying an accelerator
|
||||
#. * when the cell is clicked to change the acelerator.
|
||||
#. * when the cell is clicked to change the accelerator.
|
||||
#.
|
||||
#: gtk/deprecated/gtkcellrendereraccel.c:436
|
||||
#: gtk/deprecated/gtkcellrendereraccel.c:729
|
||||
@@ -1193,35 +1203,39 @@ msgstr "نگارش ۲٫۰ پروانهٔ آپاچی"
|
||||
msgid "Mozilla Public License 2.0"
|
||||
msgstr "پروانهٔ عمومی موزیلا ۲٫۰"
|
||||
|
||||
#: gtk/gtkaboutdialog.c:963
|
||||
#: gtk/gtkaboutdialog.c:137
|
||||
msgid "BSD Zero-Clause License"
|
||||
msgstr "پروانهٔ بیبند BSD"
|
||||
|
||||
#: gtk/gtkaboutdialog.c:964
|
||||
msgid "Website"
|
||||
msgstr "پایگاه وب"
|
||||
|
||||
#: gtk/gtkaboutdialog.c:999 gtk/ui/gtkapplication-quartz.ui:6
|
||||
#: gtk/gtkaboutdialog.c:1000 gtk/ui/gtkapplication-quartz.ui:6
|
||||
#, c-format
|
||||
msgid "About %s"
|
||||
msgstr "دربارهٔ %s"
|
||||
|
||||
#: gtk/gtkaboutdialog.c:2089
|
||||
#: gtk/gtkaboutdialog.c:2090
|
||||
msgid "Created by"
|
||||
msgstr "ایجاد شده به دست"
|
||||
|
||||
#: gtk/gtkaboutdialog.c:2092
|
||||
#: gtk/gtkaboutdialog.c:2093
|
||||
msgid "Documented by"
|
||||
msgstr "مستند شده به دست"
|
||||
|
||||
#: gtk/gtkaboutdialog.c:2102
|
||||
#: gtk/gtkaboutdialog.c:2103
|
||||
msgid "Translated by"
|
||||
msgstr "بازگردانی به دست"
|
||||
|
||||
#: gtk/gtkaboutdialog.c:2107
|
||||
#: gtk/gtkaboutdialog.c:2108
|
||||
msgid "Design by"
|
||||
msgstr "طرّاحی به دست"
|
||||
|
||||
#. Translators: this is the license preamble; the string at the end
|
||||
#. * contains the name of the license as link text.
|
||||
#.
|
||||
#: gtk/gtkaboutdialog.c:2272
|
||||
#: gtk/gtkaboutdialog.c:2273
|
||||
#, c-format
|
||||
msgid ""
|
||||
"This program comes with absolutely no warranty.\n"
|
||||
@@ -1714,6 +1728,16 @@ msgctxt "accessibility"
|
||||
msgid "block quote"
|
||||
msgstr "نقلقول مستقیم"
|
||||
|
||||
#: gtk/gtkaccessible.c:837
|
||||
msgctxt "accessibility"
|
||||
msgid "article"
|
||||
msgstr "حرف تعریف"
|
||||
|
||||
#: gtk/gtkaccessible.c:838
|
||||
msgctxt "accessibility"
|
||||
msgid "comment"
|
||||
msgstr "نظر"
|
||||
|
||||
#: gtk/gtkalertdialog.c:668 gtk/print/gtkcustompaperunixdialog.c:322
|
||||
#: gtk/gtkmessagedialog.c:166 gtk/ui/gtkassistant.ui:40
|
||||
msgid "_Close"
|
||||
@@ -1723,7 +1747,7 @@ msgstr "_بستن"
|
||||
#. * suspend or screen locking, and the caller hasn't specified
|
||||
#. * a reason.
|
||||
#.
|
||||
#: gtk/gtkapplication-dbus.c:721
|
||||
#: gtk/gtkapplication-dbus.c:721 gtk/gtkapplication-dbus.c:763
|
||||
msgid "Reason not specified"
|
||||
msgstr "دلیل مشخّص نشده"
|
||||
|
||||
@@ -2196,7 +2220,7 @@ msgstr "یک پرونده با همان نام در حال حاضر وجود د
|
||||
#: gtk/gtkfiledialog.c:843 gtk/gtkmessagedialog.c:170 gtk/gtkmessagedialog.c:179
|
||||
#: gtk/gtkmountoperation.c:608 gtk/print/gtkpagesetupunixdialog.c:282
|
||||
#: gtk/print/gtkprintbackend.c:638 gtk/print/gtkprintunixdialog.c:682
|
||||
#: gtk/print/gtkprintunixdialog.c:839 gtk/gtkwindow.c:6234
|
||||
#: gtk/print/gtkprintunixdialog.c:839 gtk/gtkwindow.c:6253
|
||||
#: gtk/ui/gtkappchooserdialog.ui:48 gtk/ui/gtkassistant.ui:52
|
||||
#: gtk/ui/gtkcolorchooserdialog.ui:36 gtk/ui/gtkfontchooserdialog.ui:27
|
||||
msgid "_Cancel"
|
||||
@@ -2284,7 +2308,7 @@ msgid "If you delete an item, it will be permanently lost."
|
||||
msgstr "اگر موردی را پاک کنید، برای همیشه از دست خواهد رفت."
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:1183 gtk/gtkfilechooserwidget.c:1781
|
||||
#: gtk/gtklabel.c:5695 gtk/gtktext.c:6147 gtk/gtktextview.c:9018
|
||||
#: gtk/gtklabel.c:5702 gtk/gtktext.c:6147 gtk/gtktextview.c:9018
|
||||
msgid "_Delete"
|
||||
msgstr "_حذف"
|
||||
|
||||
@@ -2609,7 +2633,7 @@ msgstr "دگرگونههای سبک"
|
||||
msgid "Character Variations"
|
||||
msgstr "دگرگونههای نویسه"
|
||||
|
||||
#: gtk/gtkglarea.c:305
|
||||
#: gtk/gtkglarea.c:309
|
||||
msgid "OpenGL context creation failed"
|
||||
msgstr "ساخت زمینه OpenGL شکست خورد"
|
||||
|
||||
@@ -2622,31 +2646,31 @@ msgstr "بستن"
|
||||
msgid "Close the infobar"
|
||||
msgstr "بستن نوار اطّلاعات"
|
||||
|
||||
#: gtk/gtklabel.c:5692 gtk/gtktext.c:6135 gtk/gtktextview.c:9006
|
||||
#: gtk/gtklabel.c:5699 gtk/gtktext.c:6135 gtk/gtktextview.c:9006
|
||||
msgid "Cu_t"
|
||||
msgstr "_برش"
|
||||
|
||||
#: gtk/gtklabel.c:5693 gtk/gtktext.c:6139 gtk/gtktextview.c:9010
|
||||
#: gtk/gtklabel.c:5700 gtk/gtktext.c:6139 gtk/gtktextview.c:9010
|
||||
msgid "_Copy"
|
||||
msgstr "_رونوشت"
|
||||
|
||||
#: gtk/gtklabel.c:5694 gtk/gtktext.c:6143 gtk/gtktextview.c:9014
|
||||
#: gtk/gtklabel.c:5701 gtk/gtktext.c:6143 gtk/gtktextview.c:9014
|
||||
msgid "_Paste"
|
||||
msgstr "_چسباندن"
|
||||
|
||||
#: gtk/gtklabel.c:5700 gtk/gtktext.c:6156 gtk/gtktextview.c:9039
|
||||
#: gtk/gtklabel.c:5707 gtk/gtktext.c:6156 gtk/gtktextview.c:9039
|
||||
msgid "Select _All"
|
||||
msgstr "انتخاب _همه"
|
||||
|
||||
#: gtk/gtklabel.c:5705
|
||||
#: gtk/gtklabel.c:5712
|
||||
msgid "_Open Link"
|
||||
msgstr "_گشودن پیوند"
|
||||
|
||||
#: gtk/gtklabel.c:5709
|
||||
#: gtk/gtklabel.c:5716
|
||||
msgid "Copy _Link Address"
|
||||
msgstr "_رونوشت از نشانی پیوند"
|
||||
|
||||
#: gtk/gtklabel.c:5753 gtk/gtktext.c:2716 gtk/gtktextview.c:9088
|
||||
#: gtk/gtklabel.c:5760 gtk/gtktext.c:2716 gtk/gtktextview.c:9088
|
||||
msgid "Context menu"
|
||||
msgstr "فهرست بافتاری"
|
||||
|
||||
@@ -2717,7 +2741,7 @@ msgid "Play"
|
||||
msgstr "پخش"
|
||||
|
||||
#: gtk/gtkmessagedialog.c:162 gtk/gtkmessagedialog.c:180
|
||||
#: gtk/print/gtkprintbackend.c:639 gtk/gtkwindow.c:6235
|
||||
#: gtk/print/gtkprintbackend.c:639 gtk/gtkwindow.c:6254
|
||||
msgid "_OK"
|
||||
msgstr "_تأیید"
|
||||
|
||||
@@ -3542,7 +3566,7 @@ msgstr "کشیدن به راست"
|
||||
|
||||
#. Translators: This is placeholder text for the search entry in the shortcuts window
|
||||
#: gtk/gtkshortcutswindow.c:879 gtk/gtkshortcutswindow.c:946
|
||||
#: gtk/gtkshortcutswindow.c:951
|
||||
#: gtk/gtkshortcutswindow.c:952
|
||||
msgid "Search Shortcuts"
|
||||
msgstr "جستوجوی میانبرها"
|
||||
|
||||
@@ -3556,12 +3580,12 @@ msgstr "میانبرها"
|
||||
msgid "Search Results"
|
||||
msgstr "نتایج جستوجو"
|
||||
|
||||
#: gtk/gtkshortcutswindow.c:1013 gtk/ui/gtkemojichooser.ui:349
|
||||
#: gtk/gtkshortcutswindow.c:1014 gtk/ui/gtkemojichooser.ui:349
|
||||
#: gtk/ui/gtkfilechooserwidget.ui:239
|
||||
msgid "No Results Found"
|
||||
msgstr "هیچ نتیجهای پیدا نشد"
|
||||
|
||||
#: gtk/gtkshortcutswindow.c:1024 gtk/ui/gtkemojichooser.ui:362
|
||||
#: gtk/gtkshortcutswindow.c:1025 gtk/ui/gtkemojichooser.ui:362
|
||||
#: gtk/ui/gtkfilechooserwidget.ui:252 gtk/ui/gtkplacesview.ui:218
|
||||
msgid "Try a different search"
|
||||
msgstr "جستوجو دیگری را امتحان کنید"
|
||||
@@ -3583,12 +3607,12 @@ msgstr "بر_گردان"
|
||||
msgid "_Redo"
|
||||
msgstr "_انجام دوباره"
|
||||
|
||||
#: gtk/gtkwindow.c:6223
|
||||
#: gtk/gtkwindow.c:6242
|
||||
#, c-format
|
||||
msgid "Do you want to use GTK Inspector?"
|
||||
msgstr "میخواهید از بازرس +GTK استفاده کنید؟"
|
||||
|
||||
#: gtk/gtkwindow.c:6225
|
||||
#: gtk/gtkwindow.c:6244
|
||||
#, c-format
|
||||
msgid ""
|
||||
"GTK Inspector is an interactive debugger that lets you explore and modify the "
|
||||
@@ -3598,7 +3622,7 @@ msgstr ""
|
||||
"بازرس +GTK یک بازرس تعاملی است که به شما اجازه پیمایش و تغییر هسته برنامههای +GTK "
|
||||
"را میدهد. استفاده از آن ممکن است باعث شود که برنامهها قفل کنند یا از هم بپاشند."
|
||||
|
||||
#: gtk/gtkwindow.c:6230
|
||||
#: gtk/gtkwindow.c:6249
|
||||
msgid "Don’t show this message again"
|
||||
msgstr "این پیام را دوباره نشان نده"
|
||||
|
||||
@@ -3777,39 +3801,39 @@ msgid "CSS Property"
|
||||
msgstr "مشخصه CSS"
|
||||
|
||||
# farmaan
|
||||
#: gtk/inspector/general.c:349
|
||||
#: gtk/inspector/general.c:363
|
||||
msgctxt "GL version"
|
||||
msgid "None"
|
||||
msgstr "هیچکدام"
|
||||
|
||||
#: gtk/inspector/general.c:426
|
||||
#: gtk/inspector/general.c:441
|
||||
msgctxt "GL version"
|
||||
msgid "Unknown"
|
||||
msgstr "ناشناخته"
|
||||
|
||||
#: gtk/inspector/general.c:491
|
||||
#: gtk/inspector/general.c:503
|
||||
msgctxt "Vulkan device"
|
||||
msgid "Disabled"
|
||||
msgstr "از کار افتاده"
|
||||
|
||||
#: gtk/inspector/general.c:492 gtk/inspector/general.c:493
|
||||
#: gtk/inspector/general.c:504 gtk/inspector/general.c:505
|
||||
msgctxt "Vulkan version"
|
||||
msgid "Disabled"
|
||||
msgstr "از کار افتاده"
|
||||
|
||||
# farmaan
|
||||
#: gtk/inspector/general.c:549
|
||||
#: gtk/inspector/general.c:555
|
||||
msgctxt "Vulkan device"
|
||||
msgid "None"
|
||||
msgstr "هیچکدام"
|
||||
|
||||
# farmaan
|
||||
#: gtk/inspector/general.c:550 gtk/inspector/general.c:551
|
||||
#: gtk/inspector/general.c:556 gtk/inspector/general.c:557
|
||||
msgctxt "Vulkan version"
|
||||
msgid "None"
|
||||
msgstr "هیچکدام"
|
||||
|
||||
#: gtk/inspector/general.c:882
|
||||
#: gtk/inspector/general.c:895
|
||||
msgid "IM Context is hardcoded by GTK_IM_MODULE"
|
||||
msgstr "بافتار IM به دست GTK_IM_MODULE به صورت سخت رمز شده است"
|
||||
|
||||
@@ -3861,43 +3885,51 @@ msgstr "RGBA بصری"
|
||||
msgid "Composited"
|
||||
msgstr "مرکب"
|
||||
|
||||
#: gtk/inspector/general.ui:559
|
||||
#: gtk/inspector/general.ui:538
|
||||
msgid "Protocols"
|
||||
msgstr "شیوهنامهها"
|
||||
|
||||
#: gtk/inspector/general.ui:594
|
||||
msgid "GL Version"
|
||||
msgstr "نسخهٔ GL"
|
||||
|
||||
#: gtk/inspector/general.ui:586
|
||||
#: gtk/inspector/general.ui:621
|
||||
msgid "GL Backend Version"
|
||||
msgstr "نگارش پسانهٔ GL"
|
||||
|
||||
#: gtk/inspector/general.ui:636
|
||||
#: gtk/inspector/general.ui:671
|
||||
msgid "GL Backend Vendor"
|
||||
msgstr "سازندهٔ پسانهٔ GL"
|
||||
|
||||
#: gtk/inspector/general.ui:663
|
||||
#: gtk/inspector/general.ui:698
|
||||
msgid "GL_VENDOR"
|
||||
msgstr "GL_VENDOR"
|
||||
|
||||
#: gtk/inspector/general.ui:692
|
||||
#: gtk/inspector/general.ui:727
|
||||
msgid "GL_RENDERER"
|
||||
msgstr "GL_RENDERER"
|
||||
|
||||
#: gtk/inspector/general.ui:721
|
||||
#: gtk/inspector/general.ui:756
|
||||
msgid "GL_VERSION"
|
||||
msgstr "GL_VERSION"
|
||||
|
||||
#: gtk/inspector/general.ui:750
|
||||
#: gtk/inspector/general.ui:785
|
||||
msgid "GL_SHADING_LANGUAGE_VERSION"
|
||||
msgstr "GL_SHADING_LANGUAGE_VERSION"
|
||||
|
||||
#: gtk/inspector/general.ui:789
|
||||
#: gtk/inspector/general.ui:813 gtk/inspector/general.ui:929
|
||||
msgid "Extensions"
|
||||
msgstr "افزونهها"
|
||||
|
||||
#: gtk/inspector/general.ui:849
|
||||
msgid "Vulkan Device"
|
||||
msgstr "افزارهٔ ولکان"
|
||||
|
||||
#: gtk/inspector/general.ui:816
|
||||
#: gtk/inspector/general.ui:876
|
||||
msgid "Vulkan API version"
|
||||
msgstr "نگارش API ولکان"
|
||||
|
||||
#: gtk/inspector/general.ui:843
|
||||
#: gtk/inspector/general.ui:903
|
||||
msgid "Vulkan driver version"
|
||||
msgstr "نگارش راهانداز ولکان"
|
||||
|
||||
@@ -4315,49 +4347,52 @@ msgstr "نمایش آهنگ قاب"
|
||||
msgid "Show Graphic Updates"
|
||||
msgstr "نمایش بروزرسانیهای گرافیکی"
|
||||
|
||||
#: gtk/inspector/visual.ui:435
|
||||
msgid "Show Fallback Rendering"
|
||||
msgstr "نمایش پرداخت جایگزین"
|
||||
#: gtk/inspector/visual.ui:430
|
||||
msgid ""
|
||||
"Tints all the places where the current renderer uses Cairo instead of the GPU."
|
||||
msgstr "تیره کردن تمام جاهایی که پرداختگر کنونی به جای GPU از کایرو استفاده میکند."
|
||||
|
||||
#: gtk/inspector/visual.ui:460
|
||||
#: gtk/inspector/visual.ui:436
|
||||
msgid "Show Cairo Rendering"
|
||||
msgstr "نمایش پرداخت کایرو"
|
||||
|
||||
#: gtk/inspector/visual.ui:461
|
||||
msgid "Show Baselines"
|
||||
msgstr "نمایش مبناها"
|
||||
|
||||
#: gtk/inspector/visual.ui:488
|
||||
#: gtk/inspector/visual.ui:489
|
||||
msgid "Show Layout Borders"
|
||||
msgstr "نمایش حاشیههای چیدمان"
|
||||
|
||||
#: gtk/inspector/visual.ui:545
|
||||
#: gtk/inspector/visual.ui:546
|
||||
msgid "CSS Padding"
|
||||
msgstr "فاصلهدهی CSS"
|
||||
|
||||
#: gtk/inspector/visual.ui:555
|
||||
#: gtk/inspector/visual.ui:556
|
||||
msgid "CSS Border"
|
||||
msgstr "لبهٔ CSS"
|
||||
|
||||
#: gtk/inspector/visual.ui:565
|
||||
#: gtk/inspector/visual.ui:566
|
||||
msgid "CSS Margin"
|
||||
msgstr "حاشیهٔ CSS"
|
||||
|
||||
#: gtk/inspector/visual.ui:575
|
||||
#: gtk/inspector/visual.ui:576
|
||||
msgid "Widget Margin"
|
||||
msgstr "حاشیهٔ ابزارک"
|
||||
|
||||
#: gtk/inspector/visual.ui:610
|
||||
#: gtk/inspector/visual.ui:611
|
||||
msgid "Show Focus"
|
||||
msgstr "نمایش تمرکز"
|
||||
|
||||
#: gtk/inspector/visual.ui:635
|
||||
#: gtk/inspector/visual.ui:636
|
||||
msgid "Show Accessibility warnings"
|
||||
msgstr "شنمایش هشدارهای دسترسیپذیری"
|
||||
|
||||
#: gtk/inspector/visual.ui:660
|
||||
#, fuzzy
|
||||
#| msgid "Show Graphic Updates"
|
||||
#: gtk/inspector/visual.ui:661
|
||||
msgid "Show Graphics Offload"
|
||||
msgstr "نمایش بروزرسانیهای گرافیکی"
|
||||
msgstr "نمایش تخلیهٔ گرافیکی"
|
||||
|
||||
#: gtk/inspector/visual.ui:692
|
||||
#: gtk/inspector/visual.ui:693
|
||||
msgid "Inspect Inspector"
|
||||
msgstr "بازرسی بازرس"
|
||||
|
||||
@@ -7187,7 +7222,7 @@ msgid "Use style from CSS file"
|
||||
msgstr "استفادهٔ سبک از پروندهٔ CSS"
|
||||
|
||||
#: tools/gtk-builder-tool-preview.c:187 tools/gtk-builder-tool-screenshot.c:370
|
||||
#: tools/gtk-builder-tool-validate.c:268 tools/gtk-rendernode-tool-render.c:204
|
||||
#: tools/gtk-builder-tool-validate.c:268 tools/gtk-rendernode-tool-render.c:203
|
||||
#: tools/gtk-rendernode-tool-show.c:113
|
||||
#, c-format
|
||||
msgid "Could not initialize windowing system\n"
|
||||
@@ -7232,12 +7267,12 @@ msgstr ""
|
||||
"پروندهٔ %s موجود است.\n"
|
||||
"برای پایکالی از --force استفاده کنید.\n"
|
||||
|
||||
#: tools/gtk-builder-tool-screenshot.c:332 tools/gtk-rendernode-tool-render.c:172
|
||||
#: tools/gtk-builder-tool-screenshot.c:332 tools/gtk-rendernode-tool-render.c:171
|
||||
#, c-format
|
||||
msgid "Output written to %s.\n"
|
||||
msgstr "خروجی در %s نوشته شد.\n"
|
||||
|
||||
#: tools/gtk-builder-tool-screenshot.c:336 tools/gtk-rendernode-tool-render.c:176
|
||||
#: tools/gtk-builder-tool-screenshot.c:336 tools/gtk-rendernode-tool-render.c:175
|
||||
#, c-format
|
||||
msgid "Failed to save %s: %s\n"
|
||||
msgstr "شکست در ذخیرهٔ %s: %s\n"
|
||||
@@ -7254,7 +7289,7 @@ msgstr "ذخیره به شکل پروندهٔ گره بهجای png"
|
||||
msgid "Overwrite existing file"
|
||||
msgstr "رونویسی پروندهٔ موجود"
|
||||
|
||||
#: tools/gtk-builder-tool-screenshot.c:363 tools/gtk-rendernode-tool-render.c:197
|
||||
#: tools/gtk-builder-tool-screenshot.c:363 tools/gtk-rendernode-tool-render.c:196
|
||||
msgid "FILE…"
|
||||
msgstr "پرونده…"
|
||||
|
||||
@@ -7452,10 +7487,8 @@ msgid "Allow cubic Bézier curves"
|
||||
msgstr "اجازه به منحیهای درجه سوم بزیه"
|
||||
|
||||
#: tools/gtk-path-tool-decompose.c:86
|
||||
#, fuzzy
|
||||
#| msgid "Allow cubic Bézier curves"
|
||||
msgid "Allow conic Bézier curves"
|
||||
msgstr "اجازه به منحیهای درجه سوم بزیه"
|
||||
msgstr "اجازه به منحیهای مخروطی بزیه"
|
||||
|
||||
#: tools/gtk-path-tool-decompose.c:87 tools/gtk-path-tool-info.c:88
|
||||
#: tools/gtk-path-tool-render.c:125 tools/gtk-path-tool-restrict.c:38
|
||||
@@ -7519,10 +7552,9 @@ msgid "%d cubics"
|
||||
msgstr "%Id درجه سوم"
|
||||
|
||||
#: tools/gtk-path-tool-info.c:159
|
||||
#, fuzzy, c-format
|
||||
#| msgid "%d cubics"
|
||||
#, c-format
|
||||
msgid "%d conics"
|
||||
msgstr "%Id درجه سوم"
|
||||
msgstr "%Id مخروطی"
|
||||
|
||||
#: tools/gtk-path-tool-render.c:117 tools/gtk-path-tool-show.c:140
|
||||
msgid "Fill the path (the default)"
|
||||
@@ -7729,23 +7761,23 @@ msgid ""
|
||||
"Perform various tasks on GTK render nodes.\n"
|
||||
"\n"
|
||||
"Commands:\n"
|
||||
" benchmark Benchmark rendering of a node\n"
|
||||
" info Provide information about the node\n"
|
||||
" show Show the node\n"
|
||||
" render Take a screenshot of the node\n"
|
||||
"\n"
|
||||
msgstr ""
|
||||
"استفاده:\n"
|
||||
" gtk4-builder-tool [دستور] [گزینه…] FILE\n"
|
||||
" gtk4-rendermode-tool [دستور] [گزینه…] پرونده\n"
|
||||
"\n"
|
||||
"انجام وظایف مختلف روی پروندههای .ui مربوط به GtkBuilder.\n"
|
||||
"انجام وظایف مختلف روی گرههای پرداخت GTK\n"
|
||||
"\n"
|
||||
"دستورها:\n"
|
||||
" validate تصدیق پرونده\n"
|
||||
" simplify ساده سازی پرونده\n"
|
||||
" enumerate فهرست کردن تمام اشیای نامدار\n"
|
||||
" preview پیشنمایش پرونده\n"
|
||||
"\n"
|
||||
" screenshot نماگرفت از پرونده\n"
|
||||
" benchmark محک پرداخت یک گره\n"
|
||||
" info فراهم کردن اطَلاعات دربارهٔ گره\n"
|
||||
" show نمایش گره\n"
|
||||
" render نماگرفت از گره\n"
|
||||
"\n"
|
||||
|
||||
#: tools/gtk-rendernode-tool-info.c:191
|
||||
@@ -7772,7 +7804,7 @@ msgstr "خاستگاه: %g × %g\n"
|
||||
msgid "Provide information about the render node."
|
||||
msgstr "اطّلاعاتی دربارهٔ گره پرداختگر فراهم میکند."
|
||||
|
||||
#: tools/gtk-rendernode-tool-info.c:236 tools/gtk-rendernode-tool-render.c:225
|
||||
#: tools/gtk-rendernode-tool-info.c:236 tools/gtk-rendernode-tool-render.c:224
|
||||
#: tools/gtk-rendernode-tool-show.c:134
|
||||
#, c-format
|
||||
msgid "No .node file specified\n"
|
||||
@@ -7797,19 +7829,24 @@ msgstr ""
|
||||
msgid "Failed to generate SVG: %s\n"
|
||||
msgstr "شکست در ایجاد SVG: %s\n"
|
||||
|
||||
#: tools/gtk-rendernode-tool-render.c:196
|
||||
#: tools/gtk-rendernode-tool-render.c:150
|
||||
#, c-format
|
||||
msgid "Failed to create renderer: %s\n"
|
||||
msgstr "شکست در ایجاد پرداختگر: %s\n"
|
||||
|
||||
#: tools/gtk-rendernode-tool-render.c:195
|
||||
msgid "Renderer to use"
|
||||
msgstr "پرداختگر مورد استفاده"
|
||||
|
||||
#: tools/gtk-rendernode-tool-render.c:196
|
||||
#: tools/gtk-rendernode-tool-render.c:195
|
||||
msgid "RENDERER"
|
||||
msgstr "RENDERER"
|
||||
|
||||
#: tools/gtk-rendernode-tool-render.c:212
|
||||
#: tools/gtk-rendernode-tool-render.c:211
|
||||
msgid "Render a .node file to an image."
|
||||
msgstr "پرداخت یک پروندهٔ .node در یک تصویر."
|
||||
|
||||
#: tools/gtk-rendernode-tool-render.c:231
|
||||
#: tools/gtk-rendernode-tool-render.c:230
|
||||
#, c-format
|
||||
msgid "Can only render a single .node file to a single output file\n"
|
||||
msgstr "تنها میتواند یک تکپروندهٔ .noide را در یک پروندهٔ خروحی پرداخت کند\n"
|
||||
@@ -7827,12 +7864,12 @@ msgstr "نمایش گره پرداختگر."
|
||||
msgid "Can only preview a single .node file\n"
|
||||
msgstr "تنها میتواند یک تکپروندهٔ .node را پیشنمایش دهد\n"
|
||||
|
||||
#: tools/gtk-rendernode-tool-utils.c:51
|
||||
#: tools/gtk-rendernode-tool-utils.c:54
|
||||
#, c-format
|
||||
msgid "Error at %s: %s\n"
|
||||
msgstr "خطا در %s: %s\n"
|
||||
|
||||
#: tools/gtk-rendernode-tool-utils.c:69
|
||||
#: tools/gtk-rendernode-tool-utils.c:72
|
||||
#, c-format
|
||||
msgid "Failed to load node file: %s\n"
|
||||
msgstr "شکست در بار کردن پروندهٔ گره: %s\n"
|
||||
|
||||
@@ -5,14 +5,14 @@
|
||||
# Joern v. Kattchee <kattchee@cs.tu-berlin.de>, 2000-2002.
|
||||
# Nguyễn Thái Ngọc Duy <pclouds@gmail.com>, 2002-2004,2007-2009,2011-2013.
|
||||
# Clytie Siddall <clytie@riverland.net.au>, 2005-2010.
|
||||
# Trần Ngọc Quân <vnwildman@gmail.com>, 2013-2015, 2023
|
||||
# Trần Ngọc Quân <vnwildman@gmail.com>, 2013-2024.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gtk main\n"
|
||||
"Project-Id-Version: gtk.po-ui main\n"
|
||||
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gtk/-/issues/\n"
|
||||
"POT-Creation-Date: 2023-07-22 08:17+0000\n"
|
||||
"PO-Revision-Date: 2023-07-22 15:52+0700\n"
|
||||
"POT-Creation-Date: 2024-01-12 11:17+0000\n"
|
||||
"PO-Revision-Date: 2024-01-13 14:17+0700\n"
|
||||
"Last-Translator: Trần Ngọc Quân <vnwildman@gmail.com>\n"
|
||||
"Language-Team: Vietnamese <gnome-vi-list@gnome.org>\n"
|
||||
"Language: vi\n"
|
||||
@@ -20,6 +20,7 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
"X-Generator: Gtranslator 42.0\n"
|
||||
|
||||
#: gdk/broadway/gdkbroadway-server.c:135
|
||||
#, c-format
|
||||
@@ -49,57 +50,57 @@ msgstr "Không thể cung cấp nội dung dạng “%s”"
|
||||
msgid "Cannot provide contents as %s"
|
||||
msgstr "Không thể cung cấp nội dung dạng %s"
|
||||
|
||||
#: gdk/gdkdisplay.c:156 gdk/gdkglcontext.c:442
|
||||
#: gdk/gdkdisplay.c:156 gdk/gdkglcontext.c:443
|
||||
msgid "The current backend does not support OpenGL"
|
||||
msgstr "Ứng dụng chạy phía sau không hỗ trợ OpenGL"
|
||||
|
||||
#: gdk/gdkdisplay.c:1245 gdk/gdksurface.c:1252
|
||||
#: gdk/gdkdisplay.c:1244 gdk/gdksurface.c:1252
|
||||
msgid "Vulkan support disabled via GDK_DEBUG"
|
||||
msgstr "Vulkan hỗ trợ tắt thông qua GDK_DEBUG"
|
||||
|
||||
#: gdk/gdkdisplay.c:1277
|
||||
#: gdk/gdkdisplay.c:1276
|
||||
msgid "GL support disabled via GDK_DEBUG"
|
||||
msgstr "GL hỗ trợ tắt thông qua GDK_DEBUG"
|
||||
|
||||
#: gdk/gdkdisplay.c:1575
|
||||
#: gdk/gdkdisplay.c:1574
|
||||
msgid "No EGL configuration available"
|
||||
msgstr "Không có cấu hình EGL nào"
|
||||
|
||||
#: gdk/gdkdisplay.c:1583
|
||||
#: gdk/gdkdisplay.c:1582
|
||||
msgid "Failed to get EGL configurations"
|
||||
msgstr "Gặp lỗi khi lấy cấu hình EGL"
|
||||
|
||||
#: gdk/gdkdisplay.c:1613
|
||||
#: gdk/gdkdisplay.c:1612
|
||||
msgid "No EGL configuration with required features found"
|
||||
msgstr "Không tìm thấy cấu hình EGL với các tính năng cần thiết"
|
||||
|
||||
#: gdk/gdkdisplay.c:1620
|
||||
#: gdk/gdkdisplay.c:1619
|
||||
msgid "No perfect EGL configuration found"
|
||||
msgstr "Không tìm thấy cấu hình EGL hoàn hảo"
|
||||
|
||||
#: gdk/gdkdisplay.c:1662
|
||||
#: gdk/gdkdisplay.c:1661
|
||||
#, c-format
|
||||
msgid "EGL implementation is missing extension %s"
|
||||
msgid_plural "EGL implementation is missing %2$d extensions: %1$s"
|
||||
msgstr[0] "Phần mã thực thi EGL thiếu tiện %2$d ích mở rộng: %1$s"
|
||||
|
||||
#: gdk/gdkdisplay.c:1695
|
||||
#: gdk/gdkdisplay.c:1694
|
||||
msgid "libEGL not available in this sandbox"
|
||||
msgstr "libEGL không khả dụng trong sandbox này"
|
||||
|
||||
#: gdk/gdkdisplay.c:1696
|
||||
#: gdk/gdkdisplay.c:1695
|
||||
msgid "libEGL not available"
|
||||
msgstr "libEGL không sẵn có"
|
||||
|
||||
#: gdk/gdkdisplay.c:1706
|
||||
#: gdk/gdkdisplay.c:1705
|
||||
msgid "Failed to create EGL display"
|
||||
msgstr "Gặp lỗi khi tạo bộ hiển thị EGL"
|
||||
|
||||
#: gdk/gdkdisplay.c:1716
|
||||
#: gdk/gdkdisplay.c:1715
|
||||
msgid "Could not initialize EGL display"
|
||||
msgstr "Không thể khởi tạo bộ hiển thị EGL"
|
||||
|
||||
#: gdk/gdkdisplay.c:1727
|
||||
#: gdk/gdkdisplay.c:1726
|
||||
#, c-format
|
||||
msgid "EGL version %d.%d is too old. GTK requires %d.%d"
|
||||
msgstr "Phiên bản EGL %d.%d quá cũ. GTK yêu cầu %d.%d"
|
||||
@@ -112,33 +113,33 @@ msgstr "Kéo và thả từ các ứng dụng khác không được hỗ trợ."
|
||||
msgid "No compatible formats to transfer contents."
|
||||
msgstr "Không có định dạng tương thích để chuyển nội dung."
|
||||
|
||||
#: gdk/gdkglcontext.c:401 gdk/x11/gdkglcontext-glx.c:642
|
||||
#: gdk/gdkglcontext.c:402 gdk/x11/gdkglcontext-glx.c:642
|
||||
msgid "No GL API allowed."
|
||||
msgstr "Không cho phép API GL."
|
||||
|
||||
#: gdk/gdkglcontext.c:425 gdk/win32/gdkglcontext-win32-wgl.c:387
|
||||
#: gdk/gdkglcontext.c:426 gdk/win32/gdkglcontext-win32-wgl.c:387
|
||||
#: gdk/win32/gdkglcontext-win32-wgl.c:530
|
||||
#: gdk/win32/gdkglcontext-win32-wgl.c:574 gdk/x11/gdkglcontext-glx.c:691
|
||||
msgid "Unable to create a GL context"
|
||||
msgstr "Không thể tạo ngữ cảnh GL"
|
||||
|
||||
#: gdk/gdkglcontext.c:1280
|
||||
#: gdk/gdkglcontext.c:1281
|
||||
msgid "Anything but OpenGL ES disabled via GDK_DEBUG"
|
||||
msgstr "Mọi thứ trừ OpenGL ES bị vô hiệu hóa qua GDK_DEBUG"
|
||||
|
||||
#: gdk/gdkglcontext.c:1289
|
||||
#: gdk/gdkglcontext.c:1290
|
||||
#, c-format
|
||||
msgid "Application does not support %s API"
|
||||
msgstr "Ứng dụng không hỗ trợ %s API"
|
||||
|
||||
#. translators: This is about OpenGL backend names, like
|
||||
#. * "Trying to use X11 GLX, but EGL is already in use"
|
||||
#: gdk/gdkglcontext.c:1863
|
||||
#: gdk/gdkglcontext.c:1899
|
||||
#, c-format
|
||||
msgid "Trying to use %s, but %s is already in use"
|
||||
msgstr "Đang cố dùng %s, nhưng %s đã được sử dụng rồi"
|
||||
|
||||
#: gdk/gdktexture.c:528
|
||||
#: gdk/gdktexture.c:530
|
||||
msgid "Unknown image format."
|
||||
msgstr "Định dạng ảnh chưa biết."
|
||||
|
||||
@@ -565,7 +566,7 @@ msgstr "Gặp lỗi khi đang đọc dữ liệu tại dòng %d"
|
||||
#: gdk/macos/gdkmacospasteboard.c:211 gdk/wayland/gdkclipboard-wayland.c:240
|
||||
#: gdk/wayland/gdkdrop-wayland.c:207 gdk/wayland/gdkprimary-wayland.c:343
|
||||
#: gdk/win32/gdkdrop-win32.c:1018 gdk/win32/gdkdrop-win32.c:1063
|
||||
#: gdk/x11/gdkclipboard-x11.c:805 gdk/x11/gdkdrop-x11.c:235
|
||||
#: gdk/x11/gdkclipboard-x11.c:807 gdk/x11/gdkdrop-x11.c:235
|
||||
msgid "No compatible transfer format found"
|
||||
msgstr "Không tìm thấy định dạng chuyển tương thích"
|
||||
|
||||
@@ -574,60 +575,60 @@ msgstr "Không tìm thấy định dạng chuyển tương thích"
|
||||
msgid "Failed to decode contents with mime-type of '%s'"
|
||||
msgstr "Gặp lỗi khi giải mã các nội dung với kiểu mine của '%s'"
|
||||
|
||||
#: gdk/win32/gdkclipdrop-win32.c:721
|
||||
#: gdk/win32/gdkclipdrop-win32.c:719
|
||||
#, c-format
|
||||
msgid "Cannot claim clipboard ownership. OpenClipboard() timed out."
|
||||
msgstr ""
|
||||
"Không thể yêu cầu quyền sở hữu clipboard. OpenClipboard() đã hết thời gian "
|
||||
"chờ."
|
||||
|
||||
#: gdk/win32/gdkclipdrop-win32.c:731
|
||||
#: gdk/win32/gdkclipdrop-win32.c:729
|
||||
#, c-format
|
||||
msgid "Cannot claim clipboard ownership. Another process claimed it before us."
|
||||
msgstr ""
|
||||
"Không thể yêu cầu quyền sở hữu clipboard. Một tiến trình khác đã tuyên bố nó "
|
||||
"trước chúng ta."
|
||||
|
||||
#: gdk/win32/gdkclipdrop-win32.c:745
|
||||
#: gdk/win32/gdkclipdrop-win32.c:743
|
||||
#, c-format
|
||||
msgid "Cannot claim clipboard ownership. OpenClipboard() failed: 0x%lx."
|
||||
msgstr ""
|
||||
"Không thể yêu cầu quyền sở hữu clipboard. OpenClipboard() gặp lỗi: 0x%lx."
|
||||
|
||||
#: gdk/win32/gdkclipdrop-win32.c:757
|
||||
#: gdk/win32/gdkclipdrop-win32.c:755
|
||||
#, c-format
|
||||
msgid "Cannot claim clipboard ownership. EmptyClipboard() failed: 0x%lx."
|
||||
msgstr ""
|
||||
"Không thể yêu cầu quyền sở hữu clipboard. EmptyClipboard() gặp lỗi: 0x%lx."
|
||||
|
||||
#: gdk/win32/gdkclipdrop-win32.c:800
|
||||
#: gdk/win32/gdkclipdrop-win32.c:798
|
||||
#, c-format
|
||||
msgid "Cannot set clipboard data. OpenClipboard() timed out."
|
||||
msgstr "Không thể đặt dữ liệu clipboard. OpenClipboard() chờ quá lâu."
|
||||
|
||||
#: gdk/win32/gdkclipdrop-win32.c:810 gdk/win32/gdkclipdrop-win32.c:841
|
||||
#: gdk/win32/gdkclipdrop-win32.c:808 gdk/win32/gdkclipdrop-win32.c:839
|
||||
#, c-format
|
||||
msgid "Cannot set clipboard data. Another process claimed clipboard ownership."
|
||||
msgstr ""
|
||||
"Không thể đặt dữ liệu clipboard. Một tiến trình khác đã xác nhận quyền sở "
|
||||
"hữu clipboard."
|
||||
|
||||
#: gdk/win32/gdkclipdrop-win32.c:824
|
||||
#: gdk/win32/gdkclipdrop-win32.c:822
|
||||
#, c-format
|
||||
msgid "Cannot set clipboard data. OpenClipboard() failed: 0x%lx."
|
||||
msgstr "Không thể đặt dữ liệu clipboard. OpenClipboard() gặp lỗi: 0x%lx."
|
||||
|
||||
#: gdk/win32/gdkclipdrop-win32.c:876
|
||||
#: gdk/win32/gdkclipdrop-win32.c:874
|
||||
#, c-format
|
||||
msgid "Cannot get clipboard data. GlobalLock(0x%p) failed: 0x%lx."
|
||||
msgstr "Không thể lấy dữ liệu clipboard. GlobalLock(0x%p) gặp lỗi: 0x%lx."
|
||||
|
||||
#: gdk/win32/gdkclipdrop-win32.c:887
|
||||
#: gdk/win32/gdkclipdrop-win32.c:885
|
||||
#, c-format
|
||||
msgid "Cannot get clipboard data. GlobalSize(0x%p) failed: 0x%lx."
|
||||
msgstr "Không thể lấy dữ liệu clipboard. GlobalSize(0x%p) gặp lỗi: 0x%lx."
|
||||
|
||||
#: gdk/win32/gdkclipdrop-win32.c:900
|
||||
#: gdk/win32/gdkclipdrop-win32.c:898
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Cannot get clipboard data. Failed to allocate %s bytes to store the data."
|
||||
@@ -635,17 +636,17 @@ msgstr ""
|
||||
"Không thể lấy dữ liệu clipboard. Không thể phân bổ %s byte để lưu trữ dữ "
|
||||
"liệu."
|
||||
|
||||
#: gdk/win32/gdkclipdrop-win32.c:932
|
||||
#: gdk/win32/gdkclipdrop-win32.c:930
|
||||
#, c-format
|
||||
msgid "Cannot get clipboard data. OpenClipboard() timed out."
|
||||
msgstr "Không thể lấy dữ liệu clipboard. OpenClipboard() chờ quá lâu."
|
||||
|
||||
#: gdk/win32/gdkclipdrop-win32.c:942
|
||||
#: gdk/win32/gdkclipdrop-win32.c:940
|
||||
#, c-format
|
||||
msgid "Cannot get clipboard data. Clipboard ownership changed."
|
||||
msgstr "Không thể lấy dữ liệu clipboard. Chủ sở hữu clipboard đã thay đổi."
|
||||
|
||||
#: gdk/win32/gdkclipdrop-win32.c:952
|
||||
#: gdk/win32/gdkclipdrop-win32.c:950
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Cannot get clipboard data. Clipboard data changed before we could get it."
|
||||
@@ -653,18 +654,18 @@ msgstr ""
|
||||
"Không thể lấy dữ liệu clipboard. Dữ liệu clipboard đã thay đổi trước khi "
|
||||
"chúng ta có thể lấy được."
|
||||
|
||||
#: gdk/win32/gdkclipdrop-win32.c:969
|
||||
#: gdk/win32/gdkclipdrop-win32.c:967
|
||||
#, c-format
|
||||
msgid "Cannot get clipboard data. OpenClipboard() failed: 0x%lx."
|
||||
msgstr "Không thể lấy dữ liệu clipboard. OpenClipboard() gặp lỗi: 0x%lx."
|
||||
|
||||
#: gdk/win32/gdkclipdrop-win32.c:994
|
||||
#: gdk/win32/gdkclipdrop-win32.c:992
|
||||
#, c-format
|
||||
msgid "Cannot get clipboard data. No compatible transfer format found."
|
||||
msgstr ""
|
||||
"Không thể lấy dữ liệu clipboard. Không tìm thấy định dạng tương thích nào."
|
||||
|
||||
#: gdk/win32/gdkclipdrop-win32.c:1004
|
||||
#: gdk/win32/gdkclipdrop-win32.c:1002
|
||||
#, c-format
|
||||
msgid "Cannot get clipboard data. GetClipboardData() failed: 0x%lx."
|
||||
msgstr "Không thể lấy dữ liệu clipboard. GetClipboardData() gặp lỗi: 0x%lx."
|
||||
@@ -773,11 +774,11 @@ msgid "Opening %d Item"
|
||||
msgid_plural "Opening %d Items"
|
||||
msgstr[0] "Đang mở %d mục"
|
||||
|
||||
#: gdk/x11/gdkclipboard-x11.c:475
|
||||
#: gdk/x11/gdkclipboard-x11.c:477
|
||||
msgid "Clipboard manager could not store selection."
|
||||
msgstr "Trình quản lý clipboard không thể lưu trữ phần lựa chọn."
|
||||
|
||||
#: gdk/x11/gdkclipboard-x11.c:655
|
||||
#: gdk/x11/gdkclipboard-x11.c:657
|
||||
msgid "Cannot store clipboard. No clipboard manager is active."
|
||||
msgstr ""
|
||||
"Không thể lưu trữ clipboard. Không có trình quản lý clipboard nào đang được "
|
||||
@@ -1039,19 +1040,19 @@ msgctxt "progress bar label"
|
||||
msgid "%d %%"
|
||||
msgstr "%d %%"
|
||||
|
||||
#: gtk/deprecated/gtkcolorbutton.c:183 gtk/deprecated/gtkcolorbutton.c:311
|
||||
#: gtk/deprecated/gtkcolorbutton.c:183 gtk/deprecated/gtkcolorbutton.c:314
|
||||
#: gtk/gtkcolordialog.c:411
|
||||
msgid "Pick a Color"
|
||||
msgstr "Chọn màu"
|
||||
|
||||
#: gtk/deprecated/gtkcolorbutton.c:502 gtk/gtkcolorchooserwidget.c:313
|
||||
#: gtk/gtkcolordialogbutton.c:302
|
||||
#: gtk/deprecated/gtkcolorbutton.c:505 gtk/gtkcolorchooserwidget.c:313
|
||||
#: gtk/gtkcolordialogbutton.c:335
|
||||
#, c-format
|
||||
msgid "Red %d%%, Green %d%%, Blue %d%%, Alpha %d%%"
|
||||
msgstr "Đỏ %d%%, Xanh %d%%, Lục %d%%, Trong suốt %d%%"
|
||||
|
||||
#: gtk/deprecated/gtkcolorbutton.c:508 gtk/gtkcolorchooserwidget.c:319
|
||||
#: gtk/gtkcolordialogbutton.c:308
|
||||
#: gtk/deprecated/gtkcolorbutton.c:511 gtk/gtkcolorchooserwidget.c:319
|
||||
#: gtk/gtkcolordialogbutton.c:341
|
||||
#, c-format
|
||||
msgid "Red %d%%, Green %d%%, Blue %d%%"
|
||||
msgstr "Đỏ %d%%, Xanh %d%%, Lục %d%%"
|
||||
@@ -1060,17 +1061,17 @@ msgstr "Đỏ %d%%, Xanh %d%%, Lục %d%%"
|
||||
msgid "Sans 12"
|
||||
msgstr "Sans 12"
|
||||
|
||||
#: gtk/deprecated/gtkfontbutton.c:507 gtk/deprecated/gtkfontbutton.c:621
|
||||
#: gtk/deprecated/gtkfontbutton.c:507 gtk/deprecated/gtkfontbutton.c:624
|
||||
#: gtk/gtkfontdialog.c:596
|
||||
msgid "Pick a Font"
|
||||
msgstr "Chọn phông chữ"
|
||||
|
||||
#: gtk/deprecated/gtkfontbutton.c:597 gtk/gtkfilechooserwidget.c:3871
|
||||
#: gtk/gtkfontdialogbutton.c:115 gtk/inspector/visual.ui:169
|
||||
#: gtk/deprecated/gtkfontbutton.c:600 gtk/gtkfilechooserwidget.c:3871
|
||||
#: gtk/gtkfontdialogbutton.c:126 gtk/inspector/visual.ui:169
|
||||
msgid "Font"
|
||||
msgstr "Phông chữ"
|
||||
|
||||
#: gtk/deprecated/gtkfontbutton.c:1152 gtk/gtkfontdialogbutton.c:614
|
||||
#: gtk/deprecated/gtkfontbutton.c:1155 gtk/gtkfontdialogbutton.c:652
|
||||
msgctxt "font"
|
||||
msgid "None"
|
||||
msgstr "Không"
|
||||
@@ -1728,7 +1729,7 @@ msgstr "Đón_g"
|
||||
#. * suspend or screen locking, and the caller hasn't specified
|
||||
#. * a reason.
|
||||
#.
|
||||
#: gtk/gtkapplication-dbus.c:713
|
||||
#: gtk/gtkapplication-dbus.c:721
|
||||
msgid "Reason not specified"
|
||||
msgstr "Không cung cấp lý do"
|
||||
|
||||
@@ -2134,7 +2135,7 @@ msgstr "_Phải:"
|
||||
msgid "Paper Margins"
|
||||
msgstr "Lề giấy"
|
||||
|
||||
#: gtk/gtkentry.c:3673
|
||||
#: gtk/gtkentry.c:3685
|
||||
msgid "Insert Emoji"
|
||||
msgstr "Chèn Emoji"
|
||||
|
||||
@@ -2204,7 +2205,7 @@ msgstr "Một tập tin mang tên đó đã có rồi"
|
||||
#: gtk/gtkmessagedialog.c:179 gtk/gtkmountoperation.c:608
|
||||
#: gtk/print/gtkpagesetupunixdialog.c:282 gtk/print/gtkprintbackend.c:638
|
||||
#: gtk/print/gtkprintunixdialog.c:682 gtk/print/gtkprintunixdialog.c:839
|
||||
#: gtk/gtkwindow.c:6193 gtk/ui/gtkappchooserdialog.ui:48
|
||||
#: gtk/gtkwindow.c:6233 gtk/ui/gtkappchooserdialog.ui:48
|
||||
#: gtk/ui/gtkassistant.ui:52 gtk/ui/gtkcolorchooserdialog.ui:36
|
||||
#: gtk/ui/gtkfontchooserdialog.ui:27
|
||||
msgid "_Cancel"
|
||||
@@ -2220,7 +2221,7 @@ msgstr "_Mở"
|
||||
msgid "_Save"
|
||||
msgstr "_Lưu"
|
||||
|
||||
#: gtk/gtkfilechoosernativequartz.c:340 gtk/ui/gtkfilechooserwidget.ui:288
|
||||
#: gtk/gtkfilechoosernativequartz.c:344 gtk/ui/gtkfilechooserwidget.ui:288
|
||||
msgid "Select which types of files are shown"
|
||||
msgstr "Chọn hiển thị những kiểu tập tin nào"
|
||||
|
||||
@@ -2292,7 +2293,7 @@ msgid "If you delete an item, it will be permanently lost."
|
||||
msgstr "Nếu bạn xóa bỏ một mục, nó sẽ bị mất vĩnh viễn."
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:1185 gtk/gtkfilechooserwidget.c:1815
|
||||
#: gtk/gtklabel.c:5693 gtk/gtktext.c:6127 gtk/gtktextview.c:9024
|
||||
#: gtk/gtklabel.c:5695 gtk/gtktext.c:6147 gtk/gtktextview.c:9018
|
||||
msgid "_Delete"
|
||||
msgstr "_Xóa bỏ"
|
||||
|
||||
@@ -2433,7 +2434,7 @@ msgstr "Chương trình"
|
||||
msgid "Audio"
|
||||
msgstr "Âm thanh"
|
||||
|
||||
#: gtk/gtkfilechooserwidget.c:3872 gtk/gtkfilefilter.c:1035
|
||||
#: gtk/gtkfilechooserwidget.c:3872 gtk/gtkfilefilter.c:1032
|
||||
msgid "Image"
|
||||
msgstr "Ảnh"
|
||||
|
||||
@@ -2543,7 +2544,7 @@ msgstr "Chọn nhiều thư mục"
|
||||
msgid "Select a Folder"
|
||||
msgstr "Chọn thư mục"
|
||||
|
||||
#: gtk/gtkfilefilter.c:1048
|
||||
#: gtk/gtkfilefilter.c:1045
|
||||
msgid "Unspecified"
|
||||
msgstr "Chưa xác định"
|
||||
|
||||
@@ -2631,31 +2632,31 @@ msgstr "Đóng"
|
||||
msgid "Close the infobar"
|
||||
msgstr "Đóng infobar"
|
||||
|
||||
#: gtk/gtklabel.c:5690 gtk/gtktext.c:6115 gtk/gtktextview.c:9012
|
||||
#: gtk/gtklabel.c:5692 gtk/gtktext.c:6135 gtk/gtktextview.c:9006
|
||||
msgid "Cu_t"
|
||||
msgstr "Cắ_t"
|
||||
|
||||
#: gtk/gtklabel.c:5691 gtk/gtktext.c:6119 gtk/gtktextview.c:9016
|
||||
#: gtk/gtklabel.c:5693 gtk/gtktext.c:6139 gtk/gtktextview.c:9010
|
||||
msgid "_Copy"
|
||||
msgstr "_Chép"
|
||||
|
||||
#: gtk/gtklabel.c:5692 gtk/gtktext.c:6123 gtk/gtktextview.c:9020
|
||||
#: gtk/gtklabel.c:5694 gtk/gtktext.c:6143 gtk/gtktextview.c:9014
|
||||
msgid "_Paste"
|
||||
msgstr "_Dán"
|
||||
|
||||
#: gtk/gtklabel.c:5698 gtk/gtktext.c:6136 gtk/gtktextview.c:9045
|
||||
#: gtk/gtklabel.c:5700 gtk/gtktext.c:6156 gtk/gtktextview.c:9039
|
||||
msgid "Select _All"
|
||||
msgstr "Chọn tất _cả"
|
||||
|
||||
#: gtk/gtklabel.c:5703
|
||||
#: gtk/gtklabel.c:5705
|
||||
msgid "_Open Link"
|
||||
msgstr "_Mở liên kết"
|
||||
|
||||
#: gtk/gtklabel.c:5707
|
||||
#: gtk/gtklabel.c:5709
|
||||
msgid "Copy _Link Address"
|
||||
msgstr "Chép địa chỉ _liên kết"
|
||||
|
||||
#: gtk/gtklabel.c:5751 gtk/gtktext.c:2716 gtk/gtktextview.c:9094
|
||||
#: gtk/gtklabel.c:5753 gtk/gtktext.c:2716 gtk/gtktextview.c:9088
|
||||
msgid "Context menu"
|
||||
msgstr "Trình đơn ngữ cảnh"
|
||||
|
||||
@@ -2726,7 +2727,7 @@ msgid "Play"
|
||||
msgstr "Phát"
|
||||
|
||||
#: gtk/gtkmessagedialog.c:162 gtk/gtkmessagedialog.c:180
|
||||
#: gtk/print/gtkprintbackend.c:639 gtk/gtkwindow.c:6194
|
||||
#: gtk/print/gtkprintbackend.c:639 gtk/gtkwindow.c:6234
|
||||
msgid "_OK"
|
||||
msgstr "_OK"
|
||||
|
||||
@@ -2792,7 +2793,7 @@ msgstr "_Nhớ mật khẩu cho đến khi bạn đăng xuất"
|
||||
|
||||
#: gtk/gtkmountoperation.c:781
|
||||
msgid "Remember _forever"
|
||||
msgstr "_Nhớ mãi mãi"
|
||||
msgstr "Nhớ _mãi mãi"
|
||||
|
||||
#: gtk/gtkmountoperation.c:1251
|
||||
#, c-format
|
||||
@@ -2858,7 +2859,7 @@ msgstr "Thẻ kế trước"
|
||||
msgid "Next tab"
|
||||
msgstr "Thẻ kế tiếp"
|
||||
|
||||
#: gtk/gtknotebook.c:4331 gtk/gtknotebook.c:6539
|
||||
#: gtk/gtknotebook.c:4331 gtk/gtknotebook.c:6541
|
||||
#, c-format
|
||||
msgid "Page %u"
|
||||
msgstr "Trang %u"
|
||||
@@ -3326,8 +3327,8 @@ msgstr "Lý do thường là không thể tạo tập tin tạm."
|
||||
|
||||
#. window
|
||||
#: gtk/print/gtkprintoperation-portal.c:264
|
||||
#: gtk/print/gtkprintoperation-portal.c:584
|
||||
#: gtk/print/gtkprintoperation-portal.c:653 gtk/print/gtkprintunixdialog.c:3008
|
||||
#: gtk/print/gtkprintoperation-portal.c:594
|
||||
#: gtk/print/gtkprintoperation-portal.c:663 gtk/print/gtkprintunixdialog.c:3008
|
||||
msgid "Print"
|
||||
msgstr "In"
|
||||
|
||||
@@ -3499,7 +3500,7 @@ msgstr "Không thể di chuyển mục có URI “%s” đến “%s”"
|
||||
msgid "No registered application with name “%s” for item with URI “%s” found"
|
||||
msgstr "Không tìm thấy ứng dụng nào đăng ký tên “%s” cho mục có URI “%s”"
|
||||
|
||||
#: gtk/gtksearchentry.c:758
|
||||
#: gtk/gtksearchentry.c:767
|
||||
msgid "Clear Entry"
|
||||
msgstr "Xóa mục tin"
|
||||
|
||||
@@ -3590,24 +3591,24 @@ msgctxt "accessibility"
|
||||
msgid "Sidebar"
|
||||
msgstr "Thanh bên"
|
||||
|
||||
#: gtk/gtktext.c:6141 gtk/gtktextview.c:9050
|
||||
#: gtk/gtktext.c:6161 gtk/gtktextview.c:9044
|
||||
msgid "Insert _Emoji"
|
||||
msgstr "Chèn _Emoji"
|
||||
|
||||
#: gtk/gtktextview.c:9032
|
||||
#: gtk/gtktextview.c:9026
|
||||
msgid "_Undo"
|
||||
msgstr "_Hoàn tác"
|
||||
|
||||
#: gtk/gtktextview.c:9036
|
||||
#: gtk/gtktextview.c:9030
|
||||
msgid "_Redo"
|
||||
msgstr "Làm _lại"
|
||||
|
||||
#: gtk/gtkwindow.c:6182
|
||||
#: gtk/gtkwindow.c:6222
|
||||
#, c-format
|
||||
msgid "Do you want to use GTK Inspector?"
|
||||
msgstr "Bạn có muốn dùng GTK Inspector?"
|
||||
|
||||
#: gtk/gtkwindow.c:6184
|
||||
#: gtk/gtkwindow.c:6224
|
||||
#, c-format
|
||||
msgid ""
|
||||
"GTK Inspector is an interactive debugger that lets you explore and modify "
|
||||
@@ -3617,7 +3618,7 @@ msgstr ""
|
||||
"Bộ điều tra GTK là một bộ gỡ lỗi tương tác, nó giúp bạn dò tìm và sửa bên "
|
||||
"trong bất kỳ ứng dụng GTK nào. Dùng nó có thể gây ra sự đổ vỡ của ứng dụng."
|
||||
|
||||
#: gtk/gtkwindow.c:6189
|
||||
#: gtk/gtkwindow.c:6229
|
||||
msgid "Don’t show this message again"
|
||||
msgstr "Đừng hiện lời nhắc này nữa"
|
||||
|
||||
@@ -3653,7 +3654,7 @@ msgstr "Vai trò"
|
||||
msgid "Description"
|
||||
msgstr "Mô tả"
|
||||
|
||||
#: gtk/inspector/a11y.ui:99 gtk/inspector/misc-info.ui:297
|
||||
#: gtk/inspector/a11y.ui:99 gtk/inspector/misc-info.ui:296
|
||||
msgid "Bounds"
|
||||
msgstr "Giới hạn"
|
||||
|
||||
@@ -3955,61 +3956,61 @@ msgstr "Chế độ yêu cầu"
|
||||
msgid "Measure map"
|
||||
msgstr "Bản đồ đo lường"
|
||||
|
||||
#: gtk/inspector/misc-info.ui:254
|
||||
#: gtk/inspector/misc-info.ui:253
|
||||
msgid "Expand"
|
||||
msgstr "Mở rộng"
|
||||
|
||||
#: gtk/inspector/misc-info.ui:322
|
||||
#: gtk/inspector/misc-info.ui:321
|
||||
msgid "Baseline"
|
||||
msgstr "Đường cơ sở"
|
||||
|
||||
#: gtk/inspector/misc-info.ui:347
|
||||
#: gtk/inspector/misc-info.ui:346
|
||||
msgid "Surface"
|
||||
msgstr "Bề mặt"
|
||||
|
||||
#: gtk/inspector/misc-info.ui:366 gtk/inspector/misc-info.ui:401
|
||||
#: gtk/inspector/misc-info.ui:436 gtk/inspector/prop-editor.c:1150
|
||||
#: gtk/inspector/prop-editor.c:1533 gtk/inspector/window.ui:396
|
||||
#: gtk/inspector/misc-info.ui:365 gtk/inspector/misc-info.ui:400
|
||||
#: gtk/inspector/misc-info.ui:435 gtk/inspector/prop-editor.c:1153
|
||||
#: gtk/inspector/prop-editor.c:1536 gtk/inspector/window.ui:396
|
||||
msgid "Properties"
|
||||
msgstr "Thuộc tính"
|
||||
|
||||
#: gtk/inspector/misc-info.ui:382
|
||||
#: gtk/inspector/misc-info.ui:381
|
||||
msgid "Renderer"
|
||||
msgstr "Bộ vẽ"
|
||||
|
||||
#: gtk/inspector/misc-info.ui:417
|
||||
#: gtk/inspector/misc-info.ui:416
|
||||
msgid "Frame Clock"
|
||||
msgstr "Đồng hồ khung"
|
||||
|
||||
#: gtk/inspector/misc-info.ui:452
|
||||
#: gtk/inspector/misc-info.ui:451
|
||||
msgid "Tick Callback"
|
||||
msgstr "Gọi ngược tick"
|
||||
|
||||
#: gtk/inspector/misc-info.ui:478
|
||||
#: gtk/inspector/misc-info.ui:477
|
||||
msgid "Frame Count"
|
||||
msgstr "Số lượng khung hình"
|
||||
|
||||
#: gtk/inspector/misc-info.ui:503
|
||||
#: gtk/inspector/misc-info.ui:502
|
||||
msgid "Frame Rate"
|
||||
msgstr "Tốc độ khung hình"
|
||||
|
||||
#: gtk/inspector/misc-info.ui:528
|
||||
#: gtk/inspector/misc-info.ui:527
|
||||
msgid "Scale"
|
||||
msgstr "Tỷ lệ"
|
||||
|
||||
#: gtk/inspector/misc-info.ui:553
|
||||
#: gtk/inspector/misc-info.ui:552
|
||||
msgid "Mapped"
|
||||
msgstr "Đã ánh xạ"
|
||||
|
||||
#: gtk/inspector/misc-info.ui:579
|
||||
#: gtk/inspector/misc-info.ui:578
|
||||
msgid "Realized"
|
||||
msgstr "Hiện thực hóa"
|
||||
|
||||
#: gtk/inspector/misc-info.ui:605
|
||||
#: gtk/inspector/misc-info.ui:604
|
||||
msgid "Is Toplevel"
|
||||
msgstr "Là mức đỉnh"
|
||||
|
||||
#: gtk/inspector/misc-info.ui:631
|
||||
#: gtk/inspector/misc-info.ui:630
|
||||
msgid "Child Visible"
|
||||
msgstr "Con khả kiến"
|
||||
|
||||
@@ -4021,7 +4022,7 @@ msgstr "Con trỏ: %p"
|
||||
#. Translators: %s is a type name, for example
|
||||
#. * GtkPropertyExpression with value \"2.5\"
|
||||
#.
|
||||
#: gtk/inspector/prop-editor.c:824
|
||||
#: gtk/inspector/prop-editor.c:827
|
||||
#, c-format
|
||||
msgid "%s with value \"%s\""
|
||||
msgstr "%s với giá trị \"%s\""
|
||||
@@ -4029,7 +4030,7 @@ msgstr "%s với giá trị \"%s\""
|
||||
#. Translators: Both %s are type names, for example
|
||||
#. * GtkPropertyExpression with type GObject
|
||||
#.
|
||||
#: gtk/inspector/prop-editor.c:835
|
||||
#: gtk/inspector/prop-editor.c:838
|
||||
#, c-format
|
||||
msgid "%s with type %s"
|
||||
msgstr "%s với kiểu %s"
|
||||
@@ -4037,7 +4038,7 @@ msgstr "%s với kiểu %s"
|
||||
#. Translators: Both %s are type names, for example
|
||||
#. * GtkObjectExpression for GtkStringObject 0x23456789
|
||||
#.
|
||||
#: gtk/inspector/prop-editor.c:848
|
||||
#: gtk/inspector/prop-editor.c:851
|
||||
#, c-format
|
||||
msgid "%s for %s %p"
|
||||
msgstr "%s cho %s %p"
|
||||
@@ -4045,71 +4046,71 @@ msgstr "%s cho %s %p"
|
||||
#. Translators: Both %s are type names, for example
|
||||
#. * GtkPropertyExpression with value type: gchararray
|
||||
#.
|
||||
#: gtk/inspector/prop-editor.c:878
|
||||
#: gtk/inspector/prop-editor.c:881
|
||||
#, c-format
|
||||
msgid "%s with value type %s"
|
||||
msgstr "%s với kiểu giá trị %s"
|
||||
|
||||
#: gtk/inspector/prop-editor.c:1227
|
||||
#: gtk/inspector/prop-editor.c:1230
|
||||
#, c-format
|
||||
msgid "Uneditable property type: %s"
|
||||
msgstr "Kiểu thuộc tính không thể chỉnh sửa: %s"
|
||||
|
||||
#: gtk/inspector/prop-editor.c:1385
|
||||
#: gtk/inspector/prop-editor.c:1388
|
||||
msgctxt "column number"
|
||||
msgid "None"
|
||||
msgstr "Không"
|
||||
|
||||
#: gtk/inspector/prop-editor.c:1422
|
||||
#: gtk/inspector/prop-editor.c:1425
|
||||
msgid "Attribute:"
|
||||
msgstr "Thuộc tính:"
|
||||
|
||||
#: gtk/inspector/prop-editor.c:1425
|
||||
#: gtk/inspector/prop-editor.c:1428
|
||||
msgid "Model"
|
||||
msgstr "Mô hình"
|
||||
|
||||
#: gtk/inspector/prop-editor.c:1430
|
||||
#: gtk/inspector/prop-editor.c:1433
|
||||
msgid "Column:"
|
||||
msgstr "Cột:"
|
||||
|
||||
#. Translators: %s is a type name, for example
|
||||
#. * Action from 0x2345678 (GtkApplicationWindow)
|
||||
#.
|
||||
#: gtk/inspector/prop-editor.c:1529
|
||||
#: gtk/inspector/prop-editor.c:1532
|
||||
#, c-format
|
||||
msgid "Action from: %p (%s)"
|
||||
msgstr "Thao tác từ: %p (%s)"
|
||||
|
||||
#: gtk/inspector/prop-editor.c:1584
|
||||
#: gtk/inspector/prop-editor.c:1587
|
||||
msgid "Reset"
|
||||
msgstr "Đặt lại"
|
||||
|
||||
#: gtk/inspector/prop-editor.c:1592
|
||||
#: gtk/inspector/prop-editor.c:1595
|
||||
msgctxt "GtkSettings source"
|
||||
msgid "Default"
|
||||
msgstr "Mặc định"
|
||||
|
||||
#: gtk/inspector/prop-editor.c:1595
|
||||
#: gtk/inspector/prop-editor.c:1598
|
||||
msgctxt "GtkSettings source"
|
||||
msgid "Theme"
|
||||
msgstr "Chủ đề"
|
||||
|
||||
#: gtk/inspector/prop-editor.c:1598
|
||||
#: gtk/inspector/prop-editor.c:1601
|
||||
msgctxt "GtkSettings source"
|
||||
msgid "XSettings"
|
||||
msgstr "Cài đặt X"
|
||||
|
||||
#: gtk/inspector/prop-editor.c:1602
|
||||
#: gtk/inspector/prop-editor.c:1605
|
||||
msgctxt "GtkSettings source"
|
||||
msgid "Application"
|
||||
msgstr "Ứng dụng"
|
||||
|
||||
#: gtk/inspector/prop-editor.c:1605
|
||||
#: gtk/inspector/prop-editor.c:1608
|
||||
msgctxt "GtkSettings source"
|
||||
msgid "Unknown"
|
||||
msgstr "Không rõ"
|
||||
|
||||
#: gtk/inspector/prop-editor.c:1608
|
||||
#: gtk/inspector/prop-editor.c:1611
|
||||
msgid "Source:"
|
||||
msgstr "Nguồn:"
|
||||
|
||||
@@ -4255,11 +4256,11 @@ msgstr "Thứ bậc"
|
||||
msgid "Implements"
|
||||
msgstr "Thực hiện"
|
||||
|
||||
#: gtk/inspector/visual.c:640 gtk/inspector/visual.c:659
|
||||
#: gtk/inspector/visual.c:637 gtk/inspector/visual.c:656
|
||||
msgid "Theme is hardcoded by GTK_THEME"
|
||||
msgstr "Chủ đề bị có định do GTK_THEME"
|
||||
|
||||
#: gtk/inspector/visual.c:908
|
||||
#: gtk/inspector/visual.c:905
|
||||
msgid "Backend does not support window scaling"
|
||||
msgstr "Phần ứng dụng chạy phía sau không hỗ trợ co dãn cửa sổ"
|
||||
|
||||
@@ -4355,11 +4356,7 @@ msgstr "Hiển thị tiêu điểm"
|
||||
msgid "Show Accessibility warnings"
|
||||
msgstr "Hiện cảnh báo hỗ trợ Truy cập"
|
||||
|
||||
#: gtk/inspector/visual.ui:670
|
||||
msgid "Simulate Touchscreen"
|
||||
msgstr "Mô phỏng màn hình cảm ứng"
|
||||
|
||||
#: gtk/inspector/visual.ui:701
|
||||
#: gtk/inspector/visual.ui:667
|
||||
msgid "Inspect Inspector"
|
||||
msgstr "Xem xét Inspector"
|
||||
|
||||
@@ -4970,7 +4967,7 @@ msgstr "Chữ hoa nhỏ"
|
||||
#: gtk/open-type-layout.h:110
|
||||
msgctxt "OpenType layout"
|
||||
msgid "Simplified Forms"
|
||||
msgstr "Simplified Forms"
|
||||
msgstr "Mẫu đơn giản hóa"
|
||||
|
||||
#: gtk/open-type-layout.h:111
|
||||
msgctxt "OpenType layout"
|
||||
@@ -5726,17 +5723,17 @@ msgstr "f"
|
||||
#: gtk/print/paper_names_offsets.c:131
|
||||
msgctxt "paper size"
|
||||
msgid "Fan-Fold European"
|
||||
msgstr "Gấp quạt Âu"
|
||||
msgstr "Âu Gấp-quạt"
|
||||
|
||||
#: gtk/print/paper_names_offsets.c:132
|
||||
msgctxt "paper size"
|
||||
msgid "Fan-Fold US"
|
||||
msgstr "Gấp quạt Mỹ"
|
||||
msgstr "Mỹ Gấp-quạt"
|
||||
|
||||
#: gtk/print/paper_names_offsets.c:133
|
||||
msgctxt "paper size"
|
||||
msgid "Fan-Fold German Legal"
|
||||
msgstr "Gấp quạt Đức hành pháp"
|
||||
msgstr "Hành pháp Đức Gấp-quạt"
|
||||
|
||||
#: gtk/print/paper_names_offsets.c:134
|
||||
msgctxt "paper size"
|
||||
@@ -6182,11 +6179,11 @@ msgstr "_Tạo"
|
||||
|
||||
#: gtk/ui/gtkfontchooserdialog.ui:4
|
||||
msgid "Select Font"
|
||||
msgstr "Chọn phông"
|
||||
msgstr "Chọn phông chữ"
|
||||
|
||||
#: gtk/ui/gtkfontchooserwidget.ui:64
|
||||
msgid "Search font name"
|
||||
msgstr "Tìm tên phông"
|
||||
msgstr "Tìm kiếm tên phông chữ"
|
||||
|
||||
#: gtk/ui/gtkfontchooserwidget.ui:77
|
||||
msgid "Filters"
|
||||
@@ -6489,7 +6486,7 @@ msgstr "Một số cài đặt trong trường hợp xung đột hộp thoại"
|
||||
#: modules/media/gtkffmediafile.c:253
|
||||
#, c-format
|
||||
msgid "Unspecified error decoding media"
|
||||
msgstr "ặp lỗi khi giải mã chưa biết"
|
||||
msgstr "Gặp lỗi khi giải mã chưa biết"
|
||||
|
||||
#: modules/media/gtkffmediafile.c:286
|
||||
#, c-format
|
||||
@@ -7168,7 +7165,7 @@ msgstr ""
|
||||
#: tools/gtk-builder-tool-enumerate.c:56 tools/gtk-builder-tool-preview.c:179
|
||||
#: tools/gtk-builder-tool-preview.c:180 tools/gtk-builder-tool-screenshot.c:360
|
||||
#: tools/gtk-builder-tool-simplify.c:2529 tools/gtk-builder-tool-validate.c:261
|
||||
#: tools/gtk-rendernode-tool-info.c:200 tools/gtk-rendernode-tool-show.c:102
|
||||
#: tools/gtk-rendernode-tool-info.c:202 tools/gtk-rendernode-tool-show.c:106
|
||||
msgid "FILE"
|
||||
msgstr "TẬP_TIN"
|
||||
|
||||
@@ -7200,8 +7197,8 @@ msgid "Use style from CSS file"
|
||||
msgstr "Dùng kiểu dáng từ tập tin CSS"
|
||||
|
||||
#: tools/gtk-builder-tool-preview.c:187 tools/gtk-builder-tool-screenshot.c:370
|
||||
#: tools/gtk-builder-tool-validate.c:268 tools/gtk-rendernode-tool-show.c:109
|
||||
#: tools/gtk-rendernode-tool-render.c:131
|
||||
#: tools/gtk-builder-tool-validate.c:268 tools/gtk-rendernode-tool-show.c:113
|
||||
#: tools/gtk-rendernode-tool-render.c:204
|
||||
#, c-format
|
||||
msgid "Could not initialize windowing system\n"
|
||||
msgstr "Không thể khởi tạo hệ thống cửa sổ\n"
|
||||
@@ -7237,7 +7234,6 @@ msgid "Failed to take a screenshot\n"
|
||||
msgstr "Gặp lỗi khi chụp màn hình\n"
|
||||
|
||||
#: tools/gtk-builder-tool-screenshot.c:309
|
||||
#: tools/gtk-rendernode-tool-render.c:83
|
||||
#, c-format
|
||||
msgid ""
|
||||
"File %s exists.\n"
|
||||
@@ -7247,13 +7243,13 @@ msgstr ""
|
||||
"Dùng tùy chọn --force để ghi đè.\n"
|
||||
|
||||
#: tools/gtk-builder-tool-screenshot.c:332
|
||||
#: tools/gtk-rendernode-tool-render.c:96
|
||||
#: tools/gtk-rendernode-tool-render.c:172
|
||||
#, c-format
|
||||
msgid "Output written to %s.\n"
|
||||
msgstr "Đầu ra ghi vào %s.\n"
|
||||
|
||||
#: tools/gtk-builder-tool-screenshot.c:336
|
||||
#: tools/gtk-rendernode-tool-render.c:100
|
||||
#: tools/gtk-rendernode-tool-render.c:176
|
||||
#, c-format
|
||||
msgid "Failed to save %s: %s\n"
|
||||
msgstr "Gặp lỗi khi lưu %s: %s\n"
|
||||
@@ -7267,12 +7263,11 @@ msgid "Save as node file instead of png"
|
||||
msgstr "Lưu dạng tập tin nút thay vì png"
|
||||
|
||||
#: tools/gtk-builder-tool-screenshot.c:362
|
||||
#: tools/gtk-rendernode-tool-render.c:123
|
||||
msgid "Overwrite existing file"
|
||||
msgstr "Ghi đè lên tập tin sẵn có"
|
||||
|
||||
#: tools/gtk-builder-tool-screenshot.c:363
|
||||
#: tools/gtk-rendernode-tool-render.c:124
|
||||
#: tools/gtk-rendernode-tool-render.c:197
|
||||
msgid "FILE…"
|
||||
msgstr "TẬP_TIN…"
|
||||
|
||||
@@ -7472,63 +7467,81 @@ msgstr ""
|
||||
" render Chụp màn hình nút\n"
|
||||
"\n"
|
||||
|
||||
#: tools/gtk-rendernode-tool-info.c:177
|
||||
#: tools/gtk-rendernode-tool-info.c:179
|
||||
#, c-format
|
||||
msgid "Number of nodes: %u\n"
|
||||
msgstr "Số lượng nút: %u\n"
|
||||
|
||||
#: tools/gtk-rendernode-tool-info.c:184
|
||||
#: tools/gtk-rendernode-tool-info.c:186
|
||||
#, c-format
|
||||
msgid "Depth: %u\n"
|
||||
msgstr "Độ sâu: %u\n"
|
||||
|
||||
#: tools/gtk-rendernode-tool-info.c:187
|
||||
#: tools/gtk-rendernode-tool-info.c:189
|
||||
#, c-format
|
||||
msgid "Bounds: %g x %g\n"
|
||||
msgstr "Giới hạn: %g x %g\n"
|
||||
|
||||
#: tools/gtk-rendernode-tool-info.c:188
|
||||
#: tools/gtk-rendernode-tool-info.c:190
|
||||
#, c-format
|
||||
msgid "Origin: %g %g\n"
|
||||
msgstr "Gốc: %g %g\n"
|
||||
|
||||
#: tools/gtk-rendernode-tool-info.c:209
|
||||
#: tools/gtk-rendernode-tool-info.c:211
|
||||
msgid "Provide information about the render node."
|
||||
msgstr "Cung cấp thông tin về nút bộ vẽ."
|
||||
|
||||
#: tools/gtk-rendernode-tool-info.c:222 tools/gtk-rendernode-tool-show.c:130
|
||||
#: tools/gtk-rendernode-tool-render.c:152
|
||||
#: tools/gtk-rendernode-tool-info.c:224 tools/gtk-rendernode-tool-show.c:134
|
||||
#: tools/gtk-rendernode-tool-render.c:225
|
||||
#, c-format
|
||||
msgid "No .node file specified\n"
|
||||
msgstr "Chưa chỉ ra tập tin .node\n"
|
||||
|
||||
#: tools/gtk-rendernode-tool-info.c:228
|
||||
#: tools/gtk-rendernode-tool-info.c:230
|
||||
#, c-format
|
||||
msgid "Can only accept a single .node file\n"
|
||||
msgstr "Chỉ có thể chấp nhận một tập tin nút đơn\n"
|
||||
|
||||
#: tools/gtk-rendernode-tool-show.c:117
|
||||
#: tools/gtk-rendernode-tool-show.c:105
|
||||
msgid "Don't add a titlebar"
|
||||
msgstr "Đừng thêm thanh tựa đề"
|
||||
|
||||
#: tools/gtk-rendernode-tool-show.c:121
|
||||
msgid "Show the render node."
|
||||
msgstr "Hiện nút bộ vẽ."
|
||||
|
||||
#: tools/gtk-rendernode-tool-show.c:136
|
||||
#: tools/gtk-rendernode-tool-show.c:140
|
||||
#, c-format
|
||||
msgid "Can only preview a single .node file\n"
|
||||
msgstr "Chỉ có thể xem trước một tập tin nút đơn\n"
|
||||
|
||||
#: tools/gtk-rendernode-tool-render.c:122
|
||||
#: tools/gtk-rendernode-tool-render.c:123
|
||||
#, c-format
|
||||
msgid ""
|
||||
"File %s exists.\n"
|
||||
"If you want to overwrite, specify the filename.\n"
|
||||
msgstr ""
|
||||
"Tập tin %s sẵn có.\n"
|
||||
"Nếu bạn muốn đè hãy chỉ định tên tập tin.\n"
|
||||
|
||||
#: tools/gtk-rendernode-tool-render.c:137
|
||||
#, c-format
|
||||
msgid "Failed to generate SVG: %s\n"
|
||||
msgstr "Gặp lỗi khi tạo SVG: %s\n"
|
||||
|
||||
#: tools/gtk-rendernode-tool-render.c:196
|
||||
msgid "Renderer to use"
|
||||
msgstr "Bộ vẽ được dùng"
|
||||
|
||||
#: tools/gtk-rendernode-tool-render.c:122
|
||||
#: tools/gtk-rendernode-tool-render.c:196
|
||||
msgid "RENDERER"
|
||||
msgstr "BỘ_VẼ"
|
||||
|
||||
#: tools/gtk-rendernode-tool-render.c:139
|
||||
#: tools/gtk-rendernode-tool-render.c:212
|
||||
msgid "Render a .node file to an image."
|
||||
msgstr "Vẽ một tập tin .node ra một ảnh."
|
||||
|
||||
#: tools/gtk-rendernode-tool-render.c:158
|
||||
#: tools/gtk-rendernode-tool-render.c:231
|
||||
#, c-format
|
||||
msgid "Can only render a single .node file to a single output file\n"
|
||||
msgstr "Chỉ có thể vẽ một tập tin .node đơn ra một tập tin đầu ra đơn\n"
|
||||
@@ -7538,6 +7551,11 @@ msgstr "Chỉ có thể vẽ một tập tin .node đơn ra một tập tin đ
|
||||
msgid "Error at %s: %s\n"
|
||||
msgstr "Lỗi tại %s: %s\n"
|
||||
|
||||
#: tools/gtk-rendernode-tool-utils.c:69
|
||||
#, c-format
|
||||
msgid "Failed to load node file: %s\n"
|
||||
msgstr "Gặp lỗi khi tải tập tin nút: %s\n"
|
||||
|
||||
#: tools/updateiconcache.c:1391
|
||||
#, c-format
|
||||
msgid "Failed to write header\n"
|
||||
@@ -7646,6 +7664,9 @@ msgstr ""
|
||||
"Nếu bạn thật muốn tạo một bộ nhớ biểu tượng ở đây, hãy dùng --ignore-theme-"
|
||||
"index.\n"
|
||||
|
||||
#~ msgid "Simulate Touchscreen"
|
||||
#~ msgstr "Mô phỏng màn hình cảm ứng"
|
||||
|
||||
#~ msgid "Tab list"
|
||||
#~ msgstr "Danh sách tab"
|
||||
|
||||
|
||||
@@ -119,10 +119,15 @@ row_data_update_info (RowData *data,
|
||||
icon = g_file_icon_new (thumbnail_file);
|
||||
g_object_unref (thumbnail_file);
|
||||
}
|
||||
else
|
||||
else if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_ICON))
|
||||
{
|
||||
icon = g_file_info_get_icon (info);
|
||||
}
|
||||
else
|
||||
{
|
||||
icon = NULL;
|
||||
}
|
||||
|
||||
|
||||
gtk_widget_set_visible (data->icon, icon != NULL);
|
||||
gtk_image_set_from_gicon (GTK_IMAGE (data->icon), icon);
|
||||
|
||||
@@ -376,10 +376,14 @@ row_data_update_info (RowData *data,
|
||||
icon = g_file_icon_new (thumbnail_file);
|
||||
g_object_unref (thumbnail_file);
|
||||
}
|
||||
else
|
||||
else if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_ICON))
|
||||
{
|
||||
icon = g_file_info_get_icon (info);
|
||||
}
|
||||
else
|
||||
{
|
||||
icon = NULL;
|
||||
}
|
||||
|
||||
gtk_widget_set_visible (data->icon, icon != NULL);
|
||||
gtk_image_set_from_gicon (GTK_IMAGE (data->icon), icon);
|
||||
|
||||
@@ -5,10 +5,6 @@
|
||||
#include <stdlib.h>
|
||||
#include "../reftests/reftest-compare.h"
|
||||
|
||||
#ifdef HAVE_PANGOFT
|
||||
#include <pango/pangofc-fontmap.h>
|
||||
#endif
|
||||
|
||||
|
||||
static char *arg_output_dir = NULL;
|
||||
static gboolean flip = FALSE;
|
||||
@@ -238,22 +234,6 @@ apply_mask_to_pixbuf (GdkPixbuf *pixbuf)
|
||||
return copy;
|
||||
}
|
||||
|
||||
static void
|
||||
maybe_add_test_fonts (void)
|
||||
{
|
||||
#ifdef HAVE_PANGOFT
|
||||
const char *dir;
|
||||
|
||||
dir = g_getenv ("TEST_FONT_DIR");
|
||||
|
||||
if (dir && g_file_test (dir, G_FILE_TEST_EXISTS))
|
||||
{
|
||||
FcConfig *config = FcConfigGetCurrent ();
|
||||
FcConfigAppFontAddDir (config, (const FcChar8 *) dir);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Non-option arguments:
|
||||
* 1) .node file to compare
|
||||
@@ -274,8 +254,6 @@ main (int argc, char **argv)
|
||||
GOptionContext *context;
|
||||
GdkTexture *diff_texture;
|
||||
|
||||
maybe_add_test_fonts ();
|
||||
|
||||
(g_test_init) (&argc, &argv, NULL);
|
||||
|
||||
context = g_option_context_new ("NODE REF - run GSK node tests");
|
||||
|
||||
@@ -1,7 +1,21 @@
|
||||
transform {
|
||||
transform: scale(30);
|
||||
child: text {
|
||||
font: "text-mixed-color 7.5";
|
||||
font: "text-mixed-color 7.5" url("data:font/ttf;base64,\
|
||||
AAEAAAAKAIAAAwAgQ09MUgATAEEAAAJ8AAAALENQQUwB/wATAAACqAAAABpjbWFwAHcAPQAAATwA\
|
||||
AAA0Z2x5Zu8g4kAAAAGEAAAA0mhlYWQmofyJAAAArAAAADZoaGVhDAEEAgAAAOQAAAAkaG10eAQA\
|
||||
AQAAAAEoAAAAFGxvY2EAyAD5AAABcAAAABRtYXhwAAwACQAAAQgAAAAgbmFtZX7VdrQAAAJYAAAA\
|
||||
IgABAAAAARmajs74k18PPPUAAggAAAAAAOHCPQAAAAAA4cpY+QAAAAAEAAgAAAAAAQACAAAAAAAA\
|
||||
AAEAAAgAAAAAAAQAAAAAAAQAAAEAAAAAAAAAAAAAAAAAAAABAAEAAAAJAAgAAgAAAAAAAQAAAAAA\
|
||||
AAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAABAAAAAAEAAAADAAAADAAEACgAAAAGAAQAAQAC\
|
||||
ACAASP//AAAAIABB////4P/AAAEAAAAAAAAAAAAAAAwAGAAkADAAPABIAFwAaQABAAAAAAQACAAA\
|
||||
AwAAMSERIQQA/AAIAAABAAAAAAQACAAAAwAAMSERIQQA/AAIAAABAAAAAAQACAAAAwAAMSERIQQA\
|
||||
/AAIAAABAAAAAAQACAAAAwAAMSERIQQA/AAIAAABAAAAAAQACAAAAwAAMSERIQQA/AAIAAABAAAA\
|
||||
AAQACAAAAwAAMSERIQQA/AAIAAACAAAAAAQACAAAAwAHAAAxIREhExEhEQQA/AAFA/YIAPgFB/b4\
|
||||
CgAAAQEAAAADAAgAAAMAACEhESEBAAIA/gAIAAAAAAAAAQASAAEAAAAAAAEAEAAAdGV4dC1taXhl\
|
||||
ZC1jb2xvcgAAAAAAAwAAAA4AAAAgAAMABAAAAAEABQABAAEABgACAAEAAgAAAAMAAQADAAIAAAAD\
|
||||
AAEAAwAAAA4AAAAA//8A/wD//wAA/wAA\
|
||||
");
|
||||
glyphs: 7 10;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
transform {
|
||||
transform: scale(30);
|
||||
child: text {
|
||||
font: "text-mixed-color 7.5" url("data:font/ttf;base64,\
|
||||
AAEAAAAKAIAAAwAgQ09MUgATAEEAAAJ8AAAALENQQUwB/wATAAACqAAAABpjbWFwAHcAPQAAATwA\
|
||||
AAA0Z2x5Zu8g4kAAAAGEAAAA0mhlYWQmofyJAAAArAAAADZoaGVhDAEEAgAAAOQAAAAkaG10eAQA\
|
||||
AQAAAAEoAAAAFGxvY2EAyAD5AAABcAAAABRtYXhwAAwACQAAAQgAAAAgbmFtZX7VdrQAAAJYAAAA\
|
||||
IgABAAAAARmajs74k18PPPUAAggAAAAAAOHCPQAAAAAA4cpY+QAAAAAEAAgAAAAAAQACAAAAAAAA\
|
||||
AAEAAAgAAAAAAAQAAAAAAAQAAAEAAAAAAAAAAAAAAAAAAAABAAEAAAAJAAgAAgAAAAAAAQAAAAAA\
|
||||
AAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAABAAAAAAEAAAADAAAADAAEACgAAAAGAAQAAQAC\
|
||||
ACAASP//AAAAIABB////4P/AAAEAAAAAAAAAAAAAAAwAGAAkADAAPABIAFwAaQABAAAAAAQACAAA\
|
||||
AwAAMSERIQQA/AAIAAABAAAAAAQACAAAAwAAMSERIQQA/AAIAAABAAAAAAQACAAAAwAAMSERIQQA\
|
||||
/AAIAAABAAAAAAQACAAAAwAAMSERIQQA/AAIAAABAAAAAAQACAAAAwAAMSERIQQA/AAIAAABAAAA\
|
||||
AAQACAAAAwAAMSERIQQA/AAIAAACAAAAAAQACAAAAwAHAAAxIREhExEhEQQA/AAFA/YIAPgFB/b4\
|
||||
CgAAAQEAAAADAAgAAAMAACEhESEBAAIA/gAIAAAAAAAAAQASAAEAAAAAAAEAEAAAdGV4dC1taXhl\
|
||||
ZC1jb2xvcgAAAAAAAwAAAA4AAAAgAAMABAAAAAEABQABAAEABgACAAEAAgAAAAMAAQADAAIAAAAD\
|
||||
AAEAAwAAAA4AAAAA//8A/wD//wAA/wAA\
|
||||
");
|
||||
glyphs: 7 10;
|
||||
}
|
||||
}
|
||||
color {
|
||||
bounds: 144 -305 10 10;
|
||||
color: rgb(0,0,0);
|
||||
}
|
||||
color {
|
||||
bounds: 144 -5 10 10;
|
||||
color: rgb(0,0,0);
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
repeat {
|
||||
bounds: 0 0 4000 4000;
|
||||
bounds: 0 0 200 200;
|
||||
child: container {
|
||||
color {
|
||||
bounds: 0 0 1 1;
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 594 B |
@@ -0,0 +1,18 @@
|
||||
text {
|
||||
font: "text-mixed-color 30" url("data:font/ttf;base64,\
|
||||
AAEAAAAKAIAAAwAgQ09MUgATAEEAAAJ8AAAALENQQUwB/wATAAACqAAAABpjbWFwAHcAPQAAATwA\
|
||||
AAA0Z2x5Zu8g4kAAAAGEAAAA0mhlYWQmofyJAAAArAAAADZoaGVhDAEEAgAAAOQAAAAkaG10eAQA\
|
||||
AQAAAAEoAAAAFGxvY2EAyAD5AAABcAAAABRtYXhwAAwACQAAAQgAAAAgbmFtZX7VdrQAAAJYAAAA\
|
||||
IgABAAAAARmajs74k18PPPUAAggAAAAAAOHCPQAAAAAA4cpY+QAAAAAEAAgAAAAAAQACAAAAAAAA\
|
||||
AAEAAAgAAAAAAAQAAAAAAAQAAAEAAAAAAAAAAAAAAAAAAAABAAEAAAAJAAgAAgAAAAAAAQAAAAAA\
|
||||
AAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAABAAAAAAEAAAADAAAADAAEACgAAAAGAAQAAQAC\
|
||||
ACAASP//AAAAIABB////4P/AAAEAAAAAAAAAAAAAAAwAGAAkADAAPABIAFwAaQABAAAAAAQACAAA\
|
||||
AwAAMSERIQQA/AAIAAABAAAAAAQACAAAAwAAMSERIQQA/AAIAAABAAAAAAQACAAAAwAAMSERIQQA\
|
||||
/AAIAAABAAAAAAQACAAAAwAAMSERIQQA/AAIAAABAAAAAAQACAAAAwAAMSERIQQA/AAIAAABAAAA\
|
||||
AAQACAAAAwAAMSERIQQA/AAIAAACAAAAAAQACAAAAwAHAAAxIREhExEhEQQA/AAFA/YIAPgFB/b4\
|
||||
CgAAAQEAAAADAAgAAAMAACEhESEBAAIA/gAIAAAAAAAAAQASAAEAAAAAAAEAEAAAdGV4dC1taXhl\
|
||||
ZC1jb2xvcgAAAAAAAwAAAA4AAAAgAAMABAAAAAEABQABAAEABgACAAEAAgAAAAMAAQADAAIAAAAD\
|
||||
AAEAAwAAAA4AAAAA//8A/wD//wAA/wAA\
|
||||
");
|
||||
glyphs: 1 40, 1 40, 8 40, 1 40;
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 205 B |
@@ -1,4 +1,18 @@
|
||||
text {
|
||||
font: "text-mixed-color-colrv1 15";
|
||||
font: "text-mixed-color-colrv1 15" url("data:font/ttf;base64,\
|
||||
AAEAAAAKAIAAAwAgQ09MUhc9T40AAAI4AAAAe0NQQUwB/wATAAACtAAAABpjbWFwAHUAPQAAATgA\
|
||||
AAA0Z2x5Zn7NhtgAAAF8AAAAkGhlYWQmof0NAAAArAAAADZoaGVhDAEEAgAAAOQAAAAkaG10eAQA\
|
||||
AAAAAAEoAAAAEGxvY2EAbACQAAABbAAAABBtYXhwAAkABQAAAQgAAAAgbmFtZR9CFpQAAAIMAAAA\
|
||||
KQABAAAAARmaAQnTZV8PPPUAAggAAAAAAOHCPQAAAAAA4cpZfQAAAAAEAAgAAAAAAQACAAAAAAAA\
|
||||
AAEAAAgAAAAAAAQAAAAAAAQAAAEAAAAAAAAAAAAAAAAAAAABAAEAAAAHAAQAAQAAAAAAAQAAAAAA\
|
||||
AAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAMAAAAMAAQAKAAAAAYABAABAAIAIABG\
|
||||
//8AAAAgAEH////g/8AAAQAAAAAAAAAAAAAADAAYACQAMAA8AEgAAQAAAAAEAAgAAAMAADEhESEE\
|
||||
APwACAAAAQAAAAAEAAgAAAMAADEhESEEAPwACAAAAQAAAAAEAAgAAAMAADEhESEEAPwACAAAAQAA\
|
||||
AAAEAAgAAAMAADEhESEEAPwACAAAAQAAAAAEAAgAAAMAADEhESEEAPwACAAAAQAAAAAEAAgAAAMA\
|
||||
ADEhESEEAPwACAAAAAABABIAAQAAAAAAAQAXAAB0ZXh0LW1peGVkLWNvbG9yLWNvbHJ2MQAAAAAB\
|
||||
AAAAAAAAAAAAAAAAAAAAIgAAAEoAAAAAAAAAAAAAAAAAAAADAAQAAAAWAAUAAAAcAAYAAAAiAQEA\
|
||||
AAAAAQEAAAABAQEAAAACAAAAAwAAABAAAAAbAAAAJgoAAAYAAQIAAEAACgAABgACAgABQAAKAAAG\
|
||||
AAMCAAJAAAAAAAADAAEAAwAAAA4AAAAA//8A/wD//wAA/wAA\
|
||||
");
|
||||
glyphs: 1 20, 2 20, 3 20, 4 20 0 0 color, 5 20 0 0 color, 6 20 0 0 color;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,21 @@
|
||||
transform {
|
||||
transform: translate(0, 100);
|
||||
child: text {
|
||||
font: "text-mixed-color 20";
|
||||
font: "text-mixed-color 20" url("data:font/ttf;base64,\
|
||||
AAEAAAAKAIAAAwAgQ09MUgATAEEAAAJ8AAAALENQQUwB/wATAAACqAAAABpjbWFwAHcAPQAAATwA\
|
||||
AAA0Z2x5Zu8g4kAAAAGEAAAA0mhlYWQmofyJAAAArAAAADZoaGVhDAEEAgAAAOQAAAAkaG10eAQA\
|
||||
AQAAAAEoAAAAFGxvY2EAyAD5AAABcAAAABRtYXhwAAwACQAAAQgAAAAgbmFtZX7VdrQAAAJYAAAA\
|
||||
IgABAAAAARmajs74k18PPPUAAggAAAAAAOHCPQAAAAAA4cpY+QAAAAAEAAgAAAAAAQACAAAAAAAA\
|
||||
AAEAAAgAAAAAAAQAAAAAAAQAAAEAAAAAAAAAAAAAAAAAAAABAAEAAAAJAAgAAgAAAAAAAQAAAAAA\
|
||||
AAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAABAAAAAAEAAAADAAAADAAEACgAAAAGAAQAAQAC\
|
||||
ACAASP//AAAAIABB////4P/AAAEAAAAAAAAAAAAAAAwAGAAkADAAPABIAFwAaQABAAAAAAQACAAA\
|
||||
AwAAMSERIQQA/AAIAAABAAAAAAQACAAAAwAAMSERIQQA/AAIAAABAAAAAAQACAAAAwAAMSERIQQA\
|
||||
/AAIAAABAAAAAAQACAAAAwAAMSERIQQA/AAIAAABAAAAAAQACAAAAwAAMSERIQQA/AAIAAABAAAA\
|
||||
AAQACAAAAwAAMSERIQQA/AAIAAACAAAAAAQACAAAAwAHAAAxIREhExEhEQQA/AAFA/YIAPgFB/b4\
|
||||
CgAAAQEAAAADAAgAAAMAACEhESEBAAIA/gAIAAAAAAAAAQASAAEAAAAAAAEAEAAAdGV4dC1taXhl\
|
||||
ZC1jb2xvcgAAAAAAAwAAAA4AAAAgAAMABAAAAAEABQABAAEABgACAAEAAgAAAAMAAQADAAIAAAAD\
|
||||
AAEAAwAAAA4AAAAA//8A/wD//wAA/wAA\
|
||||
");
|
||||
glyphs: 1 20, 2 20, 3 20, 4 20 0 0 color, 5 20 0 0 color, 6 20 0 0 color;
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -204,7 +204,7 @@
|
||||
</CPAL>
|
||||
|
||||
<name>
|
||||
<namerecord nameID="0" platformID="1" platEncID="0" langID="0x0" unicode="True">
|
||||
<namerecord nameID="1" platformID="1" platEncID="0" langID="0x0" unicode="True">
|
||||
text-mixed-color-colrv1
|
||||
</namerecord>
|
||||
</name>
|
||||
|
||||
Binary file not shown.
@@ -11,6 +11,7 @@
|
||||
<GlyphID id="5" name="E"/>
|
||||
<GlyphID id="6" name="F"/>
|
||||
<GlyphID id="7" name="G"/>
|
||||
<GlyphID id="8" name="H"/>
|
||||
</GlyphOrder>
|
||||
|
||||
<head>
|
||||
@@ -82,12 +83,13 @@
|
||||
<mtx name="E" width="1024" lsb="0"/>
|
||||
<mtx name="F" width="1024" lsb="0"/>
|
||||
<mtx name="G" width="1024" lsb="0"/>
|
||||
<mtx name="H" width="1024" lsb="256" rsb="256"/>
|
||||
</hmtx>
|
||||
|
||||
<loca>
|
||||
</loca>
|
||||
|
||||
<glyf> <!-- Will result in empty table -->
|
||||
<glyf>
|
||||
<TTGlyph name=".notdef"/>
|
||||
<TTGlyph name="A">
|
||||
<contour>
|
||||
@@ -158,6 +160,15 @@
|
||||
</contour>
|
||||
<instructions><assembly></assembly></instructions>
|
||||
</TTGlyph>
|
||||
<TTGlyph name="H">
|
||||
<contour>
|
||||
<pt x="256" y="0" on="1"/>
|
||||
<pt x="768" y="0" on="1"/>
|
||||
<pt x="768" y="2048" on="1"/>
|
||||
<pt x="256" y="2048" on="1"/>
|
||||
</contour>
|
||||
<instructions><assembly></assembly></instructions>
|
||||
</TTGlyph>
|
||||
</glyf>
|
||||
|
||||
<COLR>
|
||||
@@ -184,7 +195,7 @@
|
||||
</CPAL>
|
||||
|
||||
<name>
|
||||
<namerecord nameID="0" platformID="1" platEncID="0" langID="0x0" unicode="True">
|
||||
<namerecord nameID="1" platformID="1" platEncID="0" langID="0x0" unicode="True">
|
||||
text-mixed-color
|
||||
</namerecord>
|
||||
</name>
|
||||
@@ -200,6 +211,7 @@
|
||||
<map code="0x45" name="E"/>
|
||||
<map code="0x46" name="F"/>
|
||||
<map code="0x47" name="G"/>
|
||||
<map code="0x48" name="H"/>
|
||||
</cmap_format_4>
|
||||
</cmap>
|
||||
|
||||
|
||||
@@ -136,6 +136,7 @@ compare_render_tests = [
|
||||
'stroke-fractional-translate-nogl',
|
||||
'stroke-opacity',
|
||||
'stroke-with-3d-contents-nogl-nocairo',
|
||||
'text-glyph-lsb',
|
||||
'text-mixed-color-nocairo',
|
||||
'text-mixed-color-colrv1',
|
||||
'texture-coords',
|
||||
@@ -384,10 +385,15 @@ node_parser_tests = [
|
||||
'text-fail.node',
|
||||
'text-fail.ref.node',
|
||||
'text-fail.errors',
|
||||
'text-font-blob.node',
|
||||
'text-font-blob.ref.node',
|
||||
'text-font-errors.node',
|
||||
'text-font-errors.ref.node',
|
||||
'text-font-errors.errors',
|
||||
'text-no-color.node',
|
||||
'texture-fail.node',
|
||||
'texture-fail.ref.node',
|
||||
'texture-fail.ref.errors',
|
||||
'texture-fail.errors',
|
||||
'texture-names.node',
|
||||
'texture-scale-filters.node',
|
||||
'texture-scale-filters.ref.node',
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
<data>:4:3-7: error: GTK_CSS_PARSER_WARNING_SYNTAX
|
||||
<data>:3:11-12: error: GTK_CSS_PARSER_ERROR_UNKNOWN_VALUE
|
||||
<data>:4:11-12: error: GTK_CSS_PARSER_ERROR_UNKNOWN_VALUE
|
||||
<data>:6:3-9: error: GTK_CSS_PARSER_WARNING_SYNTAX
|
||||
<data>:8:1-2: error: GTK_CSS_PARSER_ERROR_UNKNOWN_VALUE
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
color {
|
||||
bounds: 0 0 50 50;
|
||||
color: rgb(255,0,204);
|
||||
text {
|
||||
color: rgb(50,50,50);
|
||||
font: "Cantarell 11";
|
||||
glyphs: "N";
|
||||
offset: 0 32.0186;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
text {
|
||||
font: "text-mixed-color 7.5" url("data:font/ttf;base64,\
|
||||
AAEAAAAKAIAAAwAgQ09MUgATAEEAAAJ8AAAALENQQUwB/wATAAACqAAAABpjbWFwAHcAPQAAATwA\
|
||||
AAA0Z2x5Zu8g4kAAAAGEAAAA0mhlYWQmofyJAAAArAAAADZoaGVhDAEEAgAAAOQAAAAkaG10eAQA\
|
||||
AQAAAAEoAAAAFGxvY2EAyAD5AAABcAAAABRtYXhwAAwACQAAAQgAAAAgbmFtZX7VdrQAAAJYAAAA\
|
||||
IgABAAAAARmajs74k18PPPUAAggAAAAAAOHCPQAAAAAA4cpY+QAAAAAEAAgAAAAAAQACAAAAAAAA\
|
||||
AAEAAAgAAAAAAAQAAAAAAAQAAAEAAAAAAAAAAAAAAAAAAAABAAEAAAAJAAgAAgAAAAAAAQAAAAAA\
|
||||
AAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAABAAAAAAEAAAADAAAADAAEACgAAAAGAAQAAQAC\
|
||||
ACAASP//AAAAIABB////4P/AAAEAAAAAAAAAAAAAAAwAGAAkADAAPABIAFwAaQABAAAAAAQACAAA\
|
||||
AwAAMSERIQQA/AAIAAABAAAAAAQACAAAAwAAMSERIQQA/AAIAAABAAAAAAQACAAAAwAAMSERIQQA\
|
||||
/AAIAAABAAAAAAQACAAAAwAAMSERIQQA/AAIAAABAAAAAAQACAAAAwAAMSERIQQA/AAIAAABAAAA\
|
||||
AAQACAAAAwAAMSERIQQA/AAIAAACAAAAAAQACAAAAwAHAAAxIREhExEhEQQA/AAFA/YIAPgFB/b4\
|
||||
CgAAAQEAAAADAAgAAAMAACEhESEBAAIA/gAIAAAAAAAAAQASAAEAAAAAAAEAEAAAdGV4dC1taXhl\
|
||||
ZC1jb2xvcgAAAAAAAwAAAA4AAAAgAAMABAAAAAEABQABAAEABgACAAEAAgAAAAMAAQADAAIAAAAD\
|
||||
AAEAAwAAAA4AAAAA//8A/wD//wAA/wAA\
|
||||
");
|
||||
glyphs: 7 10;
|
||||
}
|
||||
|
||||
text {
|
||||
font: "Cantarell 11";
|
||||
glyphs: "Hello";
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
text {
|
||||
font: "text-mixed-color 7.5" url("data:font/ttf;base64,AAEAAAAKAIAAAwAgQ09MUgATAEEAAAJ8AAAALENQQUwB/wATAAACqAAAABpjbWFwAHcAPQAAATwA\
|
||||
AAA0Z2x5Zu8g4kAAAAGEAAAA0mhlYWQmofyJAAAArAAAADZoaGVhDAEEAgAAAOQAAAAkaG10eAQA\
|
||||
AQAAAAEoAAAAFGxvY2EAyAD5AAABcAAAABRtYXhwAAwACQAAAQgAAAAgbmFtZX7VdrQAAAJYAAAA\
|
||||
IgABAAAAARmajs74k18PPPUAAggAAAAAAOHCPQAAAAAA4cpY+QAAAAAEAAgAAAAAAQACAAAAAAAA\
|
||||
AAEAAAgAAAAAAAQAAAAAAAQAAAEAAAAAAAAAAAAAAAAAAAABAAEAAAAJAAgAAgAAAAAAAQAAAAAA\
|
||||
AAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAABAAAAAAEAAAADAAAADAAEACgAAAAGAAQAAQAC\
|
||||
ACAASP//AAAAIABB////4P/AAAEAAAAAAAAAAAAAAAwAGAAkADAAPABIAFwAaQABAAAAAAQACAAA\
|
||||
AwAAMSERIQQA/AAIAAABAAAAAAQACAAAAwAAMSERIQQA/AAIAAABAAAAAAQACAAAAwAAMSERIQQA\
|
||||
/AAIAAABAAAAAAQACAAAAwAAMSERIQQA/AAIAAABAAAAAAQACAAAAwAAMSERIQQA/AAIAAABAAAA\
|
||||
AAQACAAAAwAAMSERIQQA/AAIAAACAAAAAAQACAAAAwAHAAAxIREhExEhEQQA/AAFA/YIAPgFB/b4\
|
||||
CgAAAQEAAAADAAgAAAMAACEhESEBAAIA/gAIAAAAAAAAAQASAAEAAAAAAAEAEAAAdGV4dC1taXhl\
|
||||
ZC1jb2xvcgAAAAAAAwAAAA4AAAAgAAMABAAAAAEABQABAAEABgACAAEAAgAAAAMAAQADAAIAAAAD\
|
||||
AAEAAwAAAA4AAAAA//8A/wD//wAA/wAA\
|
||||
");
|
||||
glyphs: 7 10;
|
||||
}
|
||||
text {
|
||||
font: "Cantarell 11";
|
||||
glyphs: "Hello";
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
<data>:21:32-36: error: GTK_CSS_PARSER_ERROR_UNKNOWN_VALUE
|
||||
<data>:50:23-24: error: GTK_CSS_PARSER_ERROR_UNKNOWN_VALUE
|
||||
@@ -0,0 +1,52 @@
|
||||
text {
|
||||
font: "text-mixed-color 7.5" url("data:font/ttf;base64,\
|
||||
AAEAAAAKAIAAAwAgQ09MUgATAEEAAAJ8AAAALENQQUwB/wATAAACqAAAABpjbWFwAHcAPQAAATwA\
|
||||
AAA0Z2x5Zu8g4kAAAAGEAAAA0mhlYWQmofyJAAAArAAAADZoaGVhDAEEAgAAAOQAAAAkaG10eAQA\
|
||||
AQAAAAEoAAAAFGxvY2EAyAD5AAABcAAAABRtYXhwAAwACQAAAQgAAAAgbmFtZX7VdrQAAAJYAAAA\
|
||||
IgABAAAAARmajs74k18PPPUAAggAAAAAAOHCPQAAAAAA4cpY+QAAAAAEAAgAAAAAAQACAAAAAAAA\
|
||||
AAEAAAgAAAAAAAQAAAAAAAQAAAEAAAAAAAAAAAAAAAAAAAABAAEAAAAJAAgAAgAAAAAAAQAAAAAA\
|
||||
AAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAABAAAAAAEAAAADAAAADAAEACgAAAAGAAQAAQAC\
|
||||
ACAASP//AAAAIABB////4P/AAAEAAAAAAAAAAAAAAAwAGAAkADAAPABIAFwAaQABAAAAAAQACAAA\
|
||||
AwAAMSERIQQA/AAIAAABAAAAAAQACAAAAwAAMSERIQQA/AAIAAABAAAAAAQACAAAAwAAMSERIQQA\
|
||||
/AAIAAABAAAAAAQACAAAAwAAMSERIQQA/AAIAAABAAAAAAQACAAAAwAAMSERIQQA/AAIAAABAAAA\
|
||||
AAQACAAAAwAAMSERIQQA/AAIAAACAAAAAAQACAAAAwAHAAAxIREhExEhEQQA/AAFA/YIAPgFB/b4\
|
||||
CgAAAQEAAAADAAgAAAMAACEhESEBAAIA/gAIAAAAAAAAAQASAAEAAAAAAAEAEAAAdGV4dC1taXhl\
|
||||
ZC1jb2xvcgAAAAAAAwAAAA4AAAAgAAMABAAAAAEABQABAAEABgACAAEAAgAAAAMAAQADAAIAAAAD\
|
||||
AAEAAwAAAA4AAAAA//8A/wD//wAA/wAA\
|
||||
");
|
||||
glyphs: 7 10;
|
||||
}
|
||||
|
||||
text {
|
||||
font: "text-mixed-color 7.5" url("data:font/ttf;base64,\
|
||||
AAEAAAAKAIAAAwAgQ09MUgATAEEAAAJ8AAAALENQQUwB/wATAAACqAAAABpjbWFwAHcAPQAAATwA\
|
||||
AAA0Z2x5Zu8g4kAAAAGEAAAA0mhlYWQmofyJAAAArAAAADZoaGVhDAEEAgAAAOQAAAAkaG10eAQA\
|
||||
AQAAAAEoAAAAFGxvY2EAyAD5AAABcAAAABRtYXhwAAwACQAAAQgAAAAgbmFtZX7VdrQAAAJYAAAA\
|
||||
IgABAAAAARmajs74k18PPPUAAggAAAAAAOHCPQAAAAAA4cpY+QAAAAAEAAgAAAAAAQACAAAAAAAA\
|
||||
AAEAAAgAAAAAAAQAAAAAAAQAAAEAAAAAAAAAAAAAAAAAAAABAAEAAAAJAAgAAgAAAAAAAQAAAAAA\
|
||||
AAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAABAAAAAAEAAAADAAAADAAEACgAAAAGAAQAAQAC\
|
||||
ACAASP//AAAAIABB////4P/AAAEAAAAAAAAAAAAAAAwAGAAkADAAPABIAFwAaQABAAAAAAQACAAA\
|
||||
AwAAMSERIQQA/AAIAAABAAAAAAQACAAAAwAAMSERIQQA/AAIAAABAAAAAAQACAAAAwAAMSERIQQA\
|
||||
/AAIAAABAAAAAAQACAAAAwAAMSERIQQA/AAIAAABAAAAAAQACAAAAwAAMSERIQQA/AAIAAABAAAA\
|
||||
AAQACAAAAwAAMSERIQQA/AAIAAACAAAAAAQACAAAAwAHAAAxIREhExEhEQQA/AAFA/YIAPgFB/b4\
|
||||
CgAAAQEAAAADAAgAAAMAACEhESEBAAIA/gAIAAAAAAAAAQASAAEAAAAAAAEAEAAAdGV4dC1taXhl\
|
||||
ZC1jb2xvcgAAAAAAAwAAAA4AAAAgAAMABAAAAAEABQABAAEABgACAAEAAgAAAAMAAQADAAIAAAAD\
|
||||
AAEAAwAAAA4AAAAA//8A/wD//wAA/wAA\
|
||||
");
|
||||
glyphs: 7 10;
|
||||
}
|
||||
|
||||
text {
|
||||
font: "text-mixed-color 7.5";
|
||||
glyphs: 7 10;
|
||||
}
|
||||
|
||||
text {
|
||||
font: "Cantarell 11";
|
||||
glyphs: "Hello";
|
||||
}
|
||||
|
||||
text {
|
||||
font: "Demon Cat 11";
|
||||
glyphs: "Hello";
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
text {
|
||||
font: "text-mixed-color 7.5" url("data:font/ttf;base64,AAEAAAAKAIAAAwAgQ09MUgATAEEAAAJ8AAAALENQQUwB/wATAAACqAAAABpjbWFwAHcAPQAAATwA\
|
||||
AAA0Z2x5Zu8g4kAAAAGEAAAA0mhlYWQmofyJAAAArAAAADZoaGVhDAEEAgAAAOQAAAAkaG10eAQA\
|
||||
AQAAAAEoAAAAFGxvY2EAyAD5AAABcAAAABRtYXhwAAwACQAAAQgAAAAgbmFtZX7VdrQAAAJYAAAA\
|
||||
IgABAAAAARmajs74k18PPPUAAggAAAAAAOHCPQAAAAAA4cpY+QAAAAAEAAgAAAAAAQACAAAAAAAA\
|
||||
AAEAAAgAAAAAAAQAAAAAAAQAAAEAAAAAAAAAAAAAAAAAAAABAAEAAAAJAAgAAgAAAAAAAQAAAAAA\
|
||||
AAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAABAAAAAAEAAAADAAAADAAEACgAAAAGAAQAAQAC\
|
||||
ACAASP//AAAAIABB////4P/AAAEAAAAAAAAAAAAAAAwAGAAkADAAPABIAFwAaQABAAAAAAQACAAA\
|
||||
AwAAMSERIQQA/AAIAAABAAAAAAQACAAAAwAAMSERIQQA/AAIAAABAAAAAAQACAAAAwAAMSERIQQA\
|
||||
/AAIAAABAAAAAAQACAAAAwAAMSERIQQA/AAIAAABAAAAAAQACAAAAwAAMSERIQQA/AAIAAABAAAA\
|
||||
AAQACAAAAwAAMSERIQQA/AAIAAACAAAAAAQACAAAAwAHAAAxIREhExEhEQQA/AAFA/YIAPgFB/b4\
|
||||
CgAAAQEAAAADAAgAAAMAACEhESEBAAIA/gAIAAAAAAAAAQASAAEAAAAAAAEAEAAAdGV4dC1taXhl\
|
||||
ZC1jb2xvcgAAAAAAAwAAAA4AAAAgAAMABAAAAAEABQABAAEABgACAAEAAgAAAAMAAQADAAIAAAAD\
|
||||
AAEAAwAAAA4AAAAA//8A/wD//wAA/wAA\
|
||||
");
|
||||
glyphs: 7 10;
|
||||
}
|
||||
text {
|
||||
font: "Cantarell 11";
|
||||
glyphs: 7 10;
|
||||
}
|
||||
text {
|
||||
font: "text-mixed-color 7.5";
|
||||
glyphs: 7 10;
|
||||
}
|
||||
text {
|
||||
font: "Cantarell 11";
|
||||
glyphs: "Hello";
|
||||
}
|
||||
text {
|
||||
font: "Cantarell 11";
|
||||
glyphs: "Hello";
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
/* Copyright 2024 Red Hat, Inc.
|
||||
*
|
||||
* GTK is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* GTK is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with GTK; see the file COPYING. If not,
|
||||
* see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Benjamin Otte
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <glib/gi18n-lib.h>
|
||||
#include <glib/gprintf.h>
|
||||
#include <glib/gstdio.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include "gtk-rendernode-tool.h"
|
||||
|
||||
static void
|
||||
benchmark_node (GskRenderNode *node,
|
||||
const char *renderer_name,
|
||||
guint runs,
|
||||
gboolean download)
|
||||
{
|
||||
GError *error = NULL;
|
||||
GskRenderer *renderer;
|
||||
guint i;
|
||||
|
||||
renderer = create_renderer (renderer_name, &error);
|
||||
if (renderer == NULL)
|
||||
{
|
||||
g_printerr ("Could not benchmark renderer \"%s\": %s\n", renderer_name, error->message);
|
||||
g_clear_error (&error);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < runs; i++)
|
||||
{
|
||||
GdkTexture *texture;
|
||||
gint64 start_time, end_time, duration;
|
||||
|
||||
start_time = g_get_monotonic_time ();
|
||||
|
||||
texture = gsk_renderer_render_texture (renderer, node, NULL);
|
||||
if (download)
|
||||
{
|
||||
GdkTextureDownloader *downloader;
|
||||
GBytes *bytes;
|
||||
gsize stride;
|
||||
|
||||
downloader = gdk_texture_downloader_new (texture);
|
||||
bytes = gdk_texture_downloader_download_bytes (downloader, &stride);
|
||||
g_bytes_unref (bytes);
|
||||
gdk_texture_downloader_free (downloader);
|
||||
}
|
||||
|
||||
end_time = g_get_monotonic_time ();
|
||||
|
||||
duration = end_time - start_time;
|
||||
g_print ("%s\t%lld.%03ds\n",
|
||||
renderer_name,
|
||||
(long long) duration / G_USEC_PER_SEC,
|
||||
(int) ((duration * 1000 / G_USEC_PER_SEC) % 1000));
|
||||
g_object_unref (texture);
|
||||
}
|
||||
|
||||
gsk_renderer_unrealize (renderer);
|
||||
g_object_unref (renderer);
|
||||
}
|
||||
|
||||
void
|
||||
do_benchmark (int *argc,
|
||||
const char ***argv)
|
||||
{
|
||||
GOptionContext *context;
|
||||
char **filenames = NULL;
|
||||
char **renderers = NULL;
|
||||
gboolean nodownload = FALSE;
|
||||
int runs = 3;
|
||||
const GOptionEntry entries[] = {
|
||||
{ "renderer", 0, 0, G_OPTION_ARG_STRING_ARRAY, &renderers, N_("Add renderer to benchmark"), N_("RENDERER") },
|
||||
{ "runs", 0, 0, G_OPTION_ARG_INT, &runs, N_("Number of runs with each renderer"), N_("RUNS") },
|
||||
{ "no-download", 0, 0, G_OPTION_ARG_NONE, &nodownload, N_("Dont download result/wait for GPU to finish"), NULL },
|
||||
{ G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &filenames, NULL, N_("FILE…") },
|
||||
{ NULL, }
|
||||
};
|
||||
GskRenderNode *node;
|
||||
GError *error = NULL;
|
||||
gsize i;
|
||||
|
||||
if (gdk_display_get_default () == NULL)
|
||||
{
|
||||
g_printerr (_("Could not initialize windowing system\n"));
|
||||
exit (1);
|
||||
}
|
||||
|
||||
g_set_prgname ("gtk4-rendernode-tool benchmark");
|
||||
context = g_option_context_new (NULL);
|
||||
g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);
|
||||
g_option_context_add_main_entries (context, entries, NULL);
|
||||
g_option_context_set_summary (context, _("Benchmark rendering of a .node file."));
|
||||
|
||||
if (!g_option_context_parse (context, argc, (char ***)argv, &error))
|
||||
{
|
||||
g_printerr ("%s\n", error->message);
|
||||
g_error_free (error);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
g_option_context_free (context);
|
||||
|
||||
if (filenames == NULL)
|
||||
{
|
||||
g_printerr (_("No .node file specified\n"));
|
||||
exit (1);
|
||||
}
|
||||
|
||||
if (g_strv_length (filenames) > 1)
|
||||
{
|
||||
g_printerr (_("Can only benchmark a single .node file\n"));
|
||||
exit (1);
|
||||
}
|
||||
|
||||
if (renderers == NULL || renderers[0] == NULL)
|
||||
renderers = g_strdupv ((char **) (const char *[]) { "gl", "ngl", "vulkan", "cairo", NULL });
|
||||
|
||||
node = load_node_file (filenames[0]);
|
||||
|
||||
for (i = 0; renderers[i] != NULL; i++)
|
||||
{
|
||||
benchmark_node (node, renderers[i], runs, !nodownload);
|
||||
}
|
||||
|
||||
gsk_render_node_unref (node);
|
||||
|
||||
g_strfreev (filenames);
|
||||
g_strfreev (renderers);
|
||||
}
|
||||
@@ -143,14 +143,13 @@ render_file (const char *filename,
|
||||
{
|
||||
GdkTexture *texture;
|
||||
GskRenderer *renderer;
|
||||
GdkSurface *window;
|
||||
|
||||
if (renderer_name)
|
||||
g_object_set_data_full (G_OBJECT (gdk_display_get_default ()), "gsk-renderer",
|
||||
g_strdup (renderer_name), g_free);
|
||||
|
||||
window = gdk_surface_new_toplevel (gdk_display_get_default ());
|
||||
renderer = gsk_renderer_new_for_surface (window);
|
||||
renderer = create_renderer (renderer_name, &error);
|
||||
if (renderer == NULL)
|
||||
{
|
||||
g_printerr (_("Failed to create renderer: %s\n"), error->message);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
texture = gsk_renderer_render_texture (renderer, node, NULL);
|
||||
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
#include <gtk/gtk.h>
|
||||
#include "gtk-rendernode-tool.h"
|
||||
|
||||
#ifdef GDK_WINDOWING_BROADWAY
|
||||
#include <gsk/broadway/gskbroadwayrenderer.h>
|
||||
#endif
|
||||
|
||||
static void
|
||||
deserialize_error_func (const GskParseLocation *start,
|
||||
@@ -73,3 +76,62 @@ load_node_file (const char *filename)
|
||||
|
||||
return gsk_render_node_deserialize (bytes, deserialize_error_func, NULL);
|
||||
}
|
||||
|
||||
/* keep in sync with gsk/gskrenderer.c */
|
||||
static GskRenderer *
|
||||
get_renderer_for_name (const char *renderer_name)
|
||||
{
|
||||
if (renderer_name == NULL)
|
||||
return NULL;
|
||||
#ifdef GDK_WINDOWING_BROADWAY
|
||||
else if (g_ascii_strcasecmp (renderer_name, "broadway") == 0)
|
||||
return gsk_broadway_renderer_new ();
|
||||
#endif
|
||||
else if (g_ascii_strcasecmp (renderer_name, "cairo") == 0)
|
||||
return gsk_cairo_renderer_new ();
|
||||
else if (g_ascii_strcasecmp (renderer_name, "opengl") == 0 ||
|
||||
g_ascii_strcasecmp (renderer_name, "gl") == 0)
|
||||
return gsk_gl_renderer_new ();
|
||||
else if (g_ascii_strcasecmp (renderer_name, "ngl") == 0)
|
||||
return gsk_ngl_renderer_new ();
|
||||
#ifdef GDK_RENDERING_VULKAN
|
||||
else if (g_ascii_strcasecmp (renderer_name, "vulkan") == 0)
|
||||
return gsk_vulkan_renderer_new ();
|
||||
#endif
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GskRenderer *
|
||||
create_renderer (const char *name, GError **error)
|
||||
{
|
||||
GskRenderer *renderer;
|
||||
|
||||
if (name == NULL)
|
||||
{
|
||||
/* awwwwwkward - there should be code to get the
|
||||
* default renderer without a surface */
|
||||
static GdkSurface *window = NULL;
|
||||
|
||||
if (window == NULL)
|
||||
window = gdk_surface_new_toplevel (gdk_display_get_default ());
|
||||
return gsk_renderer_new_for_surface (window);
|
||||
}
|
||||
|
||||
renderer = get_renderer_for_name (name);
|
||||
|
||||
if (renderer == NULL)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
|
||||
"No renderer named \"%s\"", name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!gsk_renderer_realize_for_display (renderer, gdk_display_get_default (), error))
|
||||
{
|
||||
g_object_unref (renderer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return renderer;
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ usage (void)
|
||||
"Perform various tasks on GTK render nodes.\n"
|
||||
"\n"
|
||||
"Commands:\n"
|
||||
" benchmark Benchmark rendering of a node\n"
|
||||
" info Provide information about the node\n"
|
||||
" show Show the node\n"
|
||||
" render Take a screenshot of the node\n"
|
||||
@@ -113,6 +114,8 @@ main (int argc, const char *argv[])
|
||||
do_render (&argc, &argv);
|
||||
else if (strcmp (argv[0], "info") == 0)
|
||||
do_info (&argc, &argv);
|
||||
else if (strcmp (argv[0], "benchmark") == 0)
|
||||
do_benchmark (&argc, &argv);
|
||||
else
|
||||
usage ();
|
||||
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
void do_show (int *argc, const char ***argv);
|
||||
void do_render (int *argc, const char ***argv);
|
||||
void do_info (int *argc, const char ***argv);
|
||||
void do_benchmark (int *argc, const char ***argv);
|
||||
void do_info (int *argc, const char ***argv);
|
||||
void do_show (int *argc, const char ***argv);
|
||||
void do_render (int *argc, const char ***argv);
|
||||
|
||||
GskRenderNode *load_node_file (const char *filename);
|
||||
GskRenderer *create_renderer (const char *name, GError **error);
|
||||
|
||||
@@ -41,6 +41,7 @@ gtk_tools = [
|
||||
'gtk-builder-tool-preview.c',
|
||||
'fake-scope.c'], [libgtk_dep] ],
|
||||
['gtk4-rendernode-tool', ['gtk-rendernode-tool.c',
|
||||
'gtk-rendernode-tool-benchmark.c',
|
||||
'gtk-rendernode-tool-info.c',
|
||||
'gtk-rendernode-tool-render.c',
|
||||
'gtk-rendernode-tool-show.c',
|
||||
|
||||
Reference in New Issue
Block a user