Compare commits

..

15 Commits

Author SHA1 Message Date
Matthias Clasen c5988a22a4 gpu: Add a front cache
This copies the approach taken in the gl renderer to avoid much
of the hash table lookup overhead by means of a front cache.
2024-01-20 11:19:23 -05:00
Matthias Clasen 498bf67cec gpu: Print more detailed cache statistics
Print out stale glyphs and dead pixel ratios.
2024-01-20 08:50:50 -05:00
Matthias Clasen 65455cdb91 gpu: Rework glyph aging
Instead of counting atlas occupancy by itesm, count how many
dead pixels we have, and free the atlas if more than half of its
pixels are dead. This matches what the GL renderer does.

As part of this, change when glyphs are freed. We now keep them
in the hash table until their atlas is freed and we only do dead
pixel accounting when should_collect is called. This keeps the
glyphs available for use from the cache as long as are in the atlas.

If a stale glyph is sused, we 'revive' itby removing its pixels
from the dead.

This matches more closely what the gl renderer does.
2024-01-20 08:48:33 -05:00
Matthias Clasen d4963ba2e5 gpu: Make cache freeing more robust
Currently, we only free an atlas when all its glyphs are gone,
but we might revisit that in the future, so be prepared for it.
2024-01-20 08:05:38 -05:00
Matthias Clasen ec5fed6cc4 gpu: Fix atlas allocation logic
The code wasn't careful enough, and could make the last slice
higher than the atlas, or put the image into a too-narrow slice.

Add more assertions.
2024-01-20 08:05:38 -05:00
Matthias Clasen b7ae5404a3 gsk: Reshuffle code a bit
Move the atlas allocation to the atlas section in the code.
2024-01-20 08:05:38 -05:00
Matthias Clasen fb4f210430 gpu: Fix ordering problem in clear_cache()
We must free the glyphs before their atlases, since we now maintain
the item count of the atlas when glyphs are freed.
2024-01-20 08:05:30 -05:00
Matthias Clasen 82df109444 gpu: Fix atlas freeing
We need to unset current_atlas if we free that one.
2024-01-20 08:05:30 -05:00
Matthias Clasen bd84142f43 gpu: Evict stale atlases from the cache
We evict atlases when they are old and unused.
2024-01-20 08:05:30 -05:00
Matthias Clasen 65074bbbac gpu: Count glyphs on atlases
That is the only way to know when its safe to gc an atlas. We can't
do that if there's still glyphs living on it.
2024-01-20 08:05:30 -05:00
Matthias Clasen 21fb5ec0b2 gpu: Evict stale glyphs from the cache 2024-01-20 08:05:30 -05:00
Matthias Clasen e57f92b7e9 gpu: Fix texture eviction
If we gc a cached texture for which the GdkTexture is still alive,
the cached texture object will remain accessible via the render
data, so need to make sure not to leave a dangling pointer behind
here.
2024-01-20 08:05:30 -05:00
Matthias Clasen e94e348ad5 gpu: Evict stale textures from the cache
Fixes: #6346
2024-01-20 08:05:30 -05:00
Matthias Clasen 91234e75f8 gpu: Start doing gc
Call gc periodically from a timeout.
2024-01-20 08:05:30 -05:00
Matthias Clasen 212e9a6957 gpu: Print some cache stats
This reuses the GLYPHCACHE debug flag that is used for the same
purpose in the gl renderer.
2024-01-20 08:05:30 -05:00
76 changed files with 1052 additions and 8223 deletions
+19
View File
@@ -1567,6 +1567,23 @@ 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,
@@ -1643,6 +1660,8 @@ 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);
+3 -1
View File
@@ -222,6 +222,7 @@ gdk_parse_debug_var (const char *variable,
}
else
{
char *val = g_strndup (p, q - p);
for (i = 0; i < nkeys; i++)
{
if (strlen (keys[i].key) == q - p &&
@@ -232,7 +233,8 @@ gdk_parse_debug_var (const char *variable,
}
}
if (i == nkeys)
fprintf (stderr, "Unrecognized value \"%.*s\". Try %s=help\n", (int) (q - p), p, variable);
fprintf (stderr, "Unrecognized value \"%s\". Try %s=help\n", val, variable);
g_free (val);
}
p = q;
+6 -3
View File
@@ -1363,7 +1363,7 @@ gdk_display_init_gl (GdkDisplay *self)
return;
}
gdk_profiler_end_mark (before2, "Realize OpenGL context", NULL);
gdk_profiler_end_mark (before2, "realize OpenGL context", NULL);
/* Only assign after realize, so GdkGLContext::realize() can use
* gdk_display_get_gl_context() == NULL to differentiate between
@@ -1373,7 +1373,7 @@ gdk_display_init_gl (GdkDisplay *self)
gdk_gl_backend_use (GDK_GL_CONTEXT_GET_CLASS (context)->backend_type);
gdk_profiler_end_mark (before, "Init OpenGL", NULL);
gdk_profiler_end_mark (before, "initialize OpenGL", NULL);
}
/**
@@ -1768,6 +1768,7 @@ gdk_display_init_egl (GdkDisplay *self,
{
GdkDisplayPrivate *priv = gdk_display_get_instance_private (self);
G_GNUC_UNUSED gint64 start_time = GDK_PROFILER_CURRENT_TIME;
G_GNUC_UNUSED gint64 start_time2;
int major, minor;
if (!gdk_gl_backend_can_be_used (GDK_GL_EGL, error))
@@ -1794,6 +1795,7 @@ gdk_display_init_egl (GdkDisplay *self,
return FALSE;
}
start_time2 = GDK_PROFILER_CURRENT_TIME;
if (!eglInitialize (priv->egl_display, &major, &minor))
{
priv->egl_display = NULL;
@@ -1802,6 +1804,7 @@ gdk_display_init_egl (GdkDisplay *self,
_("Could not initialize EGL display"));
return FALSE;
}
gdk_profiler_end_mark (start_time2, "eglInitialize", NULL);
if (major < GDK_EGL_MIN_VERSION_MAJOR ||
(major == GDK_EGL_MIN_VERSION_MAJOR && minor < GDK_EGL_MIN_VERSION_MINOR))
@@ -1891,7 +1894,7 @@ gdk_display_init_egl (GdkDisplay *self,
g_free (ext);
}
gdk_profiler_end_mark (start_time, "Init EGL", NULL);
gdk_profiler_end_mark (start_time, "init EGL", NULL);
return TRUE;
}
+5 -5
View File
@@ -687,7 +687,7 @@ _gdk_frame_clock_emit_update (GdkFrameClock *frame_clock)
g_signal_emit (frame_clock, signals[UPDATE], 0);
gdk_profiler_end_mark (before, "Frameclock update", NULL);
gdk_profiler_end_mark (before, "frameclock update", NULL);
}
void
@@ -699,7 +699,7 @@ _gdk_frame_clock_emit_layout (GdkFrameClock *frame_clock)
g_signal_emit (frame_clock, signals[LAYOUT], 0);
gdk_profiler_end_mark (before, "Frameclock layout", NULL);
gdk_profiler_end_mark (before, "frameclock layout", NULL);
}
void
@@ -711,7 +711,7 @@ _gdk_frame_clock_emit_paint (GdkFrameClock *frame_clock)
g_signal_emit (frame_clock, signals[PAINT], 0);
gdk_profiler_end_mark (before, "Frameclock paint", NULL);
gdk_profiler_end_mark (before, "frameclock paint", NULL);
}
void
@@ -811,12 +811,12 @@ _gdk_frame_clock_add_timings_to_profiler (GdkFrameClock *clock,
{
if (timings->drawn_time != 0)
{
gdk_profiler_add_mark (1000 * timings->drawn_time, 0, "Drawn window", NULL);
gdk_profiler_add_mark (1000 * timings->drawn_time, 0, "drawn window", NULL);
}
if (timings->presentation_time != 0)
{
gdk_profiler_add_mark (1000 * timings->presentation_time, 0, "Presented window", NULL);
gdk_profiler_add_mark (1000 * timings->presentation_time, 0, "presented window", NULL);
}
gdk_profiler_set_counter (fps_counter, gdk_frame_clock_get_fps (clock));
+1 -1
View File
@@ -694,7 +694,7 @@ gdk_frame_clock_paint_idle (void *data)
if (!gdk_frame_clock_idle_is_frozen (clock_idle))
priv->sleep_serial = get_sleep_serial ();
gdk_profiler_end_mark (before, "Frameclock cycle", NULL);
gdk_profiler_end_mark (before, "frameclock cycle", NULL);
return FALSE;
}
+11 -2
View File
@@ -386,7 +386,7 @@ gdk_gl_context_create_egl_context (GdkGLContext *context,
else if (epoxy_has_egl_extension (egl_display, "EGL_EXT_swap_buffers_with_damage"))
priv->eglSwapBuffersWithDamage = (gpointer) epoxy_eglGetProcAddress ("eglSwapBuffersWithDamageEXT");
gdk_profiler_end_mark (start_time, "Create EGL context", NULL);
gdk_profiler_end_mark (start_time, "realize GdkWaylandGLContext", NULL);
return api;
}
@@ -669,7 +669,7 @@ gdk_gl_context_real_end_frame (GdkDrawContext *draw_context,
egl_surface = gdk_surface_get_egl_surface (surface);
gdk_profiler_add_mark (GDK_PROFILER_CURRENT_TIME, 0, "EGL swap buffers", NULL);
gdk_profiler_add_mark (GDK_PROFILER_CURRENT_TIME, 0, "EGL", "swap buffers");
if (priv->eglSwapBuffersWithDamage)
{
@@ -2042,6 +2042,15 @@ gdk_gl_context_has_sync (GdkGLContext *self)
return priv->has_sync;
}
/* Return if GL_BGRA works with glTexImage2D */
gboolean
gdk_gl_context_has_bgra (GdkGLContext *self)
{
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (self);
return priv->has_bgra;
}
/* Return if glGenVertexArrays, glBindVertexArray and glDeleteVertexArrays
* can be used
*/
+2
View File
@@ -171,6 +171,8 @@ gboolean gdk_gl_context_has_vertex_half_float (GdkGLContext
gboolean gdk_gl_context_has_sync (GdkGLContext *self) G_GNUC_PURE;
gboolean gdk_gl_context_has_bgra (GdkGLContext *self) G_GNUC_PURE;
gboolean gdk_gl_context_has_vertex_arrays (GdkGLContext *self) G_GNUC_PURE;
double gdk_gl_context_get_scale (GdkGLContext *self);
+6 -7
View File
@@ -32,7 +32,6 @@
#include "version/gdkversionmacros.h"
#include "gdkframeclockprivate.h"
#define CATEGORY "GTK"
gboolean
gdk_profiler_is_running (void)
@@ -51,7 +50,7 @@ void
const char *message)
{
#ifdef HAVE_SYSPROF
sysprof_collector_mark (begin_time, duration, CATEGORY, name, message);
sysprof_collector_mark (begin_time, duration, "gtk", name, message);
#endif
}
@@ -61,7 +60,7 @@ void
const char *message)
{
#ifdef HAVE_SYSPROF
sysprof_collector_mark (begin_time, GDK_PROFILER_CURRENT_TIME - begin_time, CATEGORY, name, message);
sysprof_collector_mark (begin_time, GDK_PROFILER_CURRENT_TIME - begin_time, "gtk", name, message);
#endif
}
@@ -75,7 +74,7 @@ void
#ifdef HAVE_SYSPROF
va_list args;
va_start (args, message_format);
sysprof_collector_mark_vprintf (begin_time, duration, CATEGORY, name, message_format, args);
sysprof_collector_mark_vprintf (begin_time, duration, "gtk", name, message_format, args);
va_end (args);
#endif /* HAVE_SYSPROF */
}
@@ -89,7 +88,7 @@ void
#ifdef HAVE_SYSPROF
va_list args;
va_start (args, message_format);
sysprof_collector_mark_vprintf (begin_time, GDK_PROFILER_CURRENT_TIME - begin_time, CATEGORY, name, message_format, args);
sysprof_collector_mark_vprintf (begin_time, GDK_PROFILER_CURRENT_TIME - begin_time, "gtk", name, message_format, args);
va_end (args);
#endif /* HAVE_SYSPROF */
}
@@ -104,7 +103,7 @@ guint
counter.id = sysprof_collector_request_counters (1);
counter.type = SYSPROF_CAPTURE_COUNTER_DOUBLE;
counter.value.vdbl = 0.0;
g_strlcpy (counter.category, CATEGORY, sizeof counter.category);
g_strlcpy (counter.category, "gtk", sizeof counter.category);
g_strlcpy (counter.name, name, sizeof counter.name);
g_strlcpy (counter.description, description, sizeof counter.name);
@@ -126,7 +125,7 @@ guint
counter.id = sysprof_collector_request_counters (1);
counter.type = SYSPROF_CAPTURE_COUNTER_INT64;
counter.value.v64 = 0;
g_strlcpy (counter.category, CATEGORY, sizeof counter.category);
g_strlcpy (counter.category, "gtk", sizeof counter.category);
g_strlcpy (counter.name, name, sizeof counter.name);
g_strlcpy (counter.description, description, sizeof counter.name);
+2 -2
View File
@@ -2839,7 +2839,7 @@ add_event_mark (GdkEvent *event,
class = g_type_class_ref (GDK_TYPE_EVENT_TYPE);
value = g_enum_get_value (class, event_type);
g_type_class_unref (class);
kind = value ? value->value_nick : "Event";
kind = value ? value->value_nick : "event";
switch ((int) event_type)
{
@@ -2909,7 +2909,7 @@ add_event_mark (GdkEvent *event,
break;
}
gdk_profiler_add_mark (time, end_time - time, "Event", message ? message : kind);
gdk_profiler_add_mark (time, end_time - time, "event", message ? message : kind);
g_free (message);
#endif
+1 -1
View File
@@ -237,7 +237,7 @@ gdk_load_jpeg (GBytes *input_bytes,
g_bytes_unref (bytes);
gdk_profiler_end_mark (before, "Load jpeg", NULL);
gdk_profiler_end_mark (before, "jpeg load", NULL);
return texture;
}
+1 -1
View File
@@ -304,7 +304,7 @@ gdk_load_png (GBytes *bytes,
{
gint64 end = GDK_PROFILER_CURRENT_TIME;
if (end - before > 500000)
gdk_profiler_add_mark (before, end - before, "Load png", NULL);
gdk_profiler_add_mark (before, end - before, "png load", NULL);
}
return texture;
+1 -1
View File
@@ -504,7 +504,7 @@ gdk_load_tiff (GBytes *input_bytes,
{
gint64 end = GDK_PROFILER_CURRENT_TIME;
if (end - before > 500000)
gdk_profiler_add_mark (before, end - before, "Load tiff", NULL);
gdk_profiler_add_mark (before, end - before, "tiff load", NULL);
}
return texture;
+2 -2
View File
@@ -186,7 +186,7 @@ gdk_wayland_cairo_context_end_frame (GdkDrawContext *draw_context,
gdk_wayland_surface_attach_image (surface, self->paint_surface, painted);
gdk_wayland_surface_request_frame (surface);
gdk_profiler_add_mark (GDK_PROFILER_CURRENT_TIME, 0, "Wayland surface commit", NULL);
gdk_profiler_add_mark (GDK_PROFILER_CURRENT_TIME, 0, "wayland", "surface commit");
gdk_wayland_surface_commit (surface);
gdk_wayland_surface_notify_committed (surface);
@@ -206,7 +206,7 @@ gdk_wayland_cairo_context_empty_frame (GdkDrawContext *draw_context)
gdk_wayland_surface_sync (surface);
gdk_wayland_surface_request_frame (surface);
gdk_profiler_add_mark (GDK_PROFILER_CURRENT_TIME, 0, "Wayland surface commit", NULL);
gdk_profiler_add_mark (GDK_PROFILER_CURRENT_TIME, 0, "wayland", "surface commit");
gdk_wayland_surface_commit (surface);
gdk_wayland_surface_notify_committed (surface);
}
+1 -1
View File
@@ -1253,7 +1253,7 @@ _gdk_wayland_display_load_cursor_theme (GdkWaylandDisplay *display_wayland)
gdk_wayland_display_set_cursor_theme (GDK_DISPLAY (display_wayland), name, size);
g_value_unset (&v);
gdk_profiler_end_mark (before, "Wayland cursor theme load", NULL);
gdk_profiler_end_mark (before, "wayland", "load cursor theme");
}
+1 -1
View File
@@ -1012,7 +1012,7 @@ gdk_wayland_surface_create_xdg_popup (GdkWaylandPopup *wayland_popup,
}
}
gdk_profiler_add_mark (GDK_PROFILER_CURRENT_TIME, 0, "Wayland surface commit", NULL);
gdk_profiler_add_mark (GDK_PROFILER_CURRENT_TIME, 0, "wayland", "surface commit");
wl_surface_commit (impl->display_server.wl_surface);
if (GDK_IS_POPUP (surface))
+1 -1
View File
@@ -274,7 +274,7 @@ gdk_wayland_surface_frame_callback (GdkSurface *surface,
GdkFrameClock *clock = gdk_surface_get_frame_clock (surface);
GdkFrameTimings *timings;
gdk_profiler_add_mark (GDK_PROFILER_CURRENT_TIME, 0, "Wayland frame event", NULL);
gdk_profiler_add_mark (GDK_PROFILER_CURRENT_TIME, 0, "wayland", "frame event");
GDK_DISPLAY_DEBUG (GDK_DISPLAY (display_wayland), EVENTS, "frame %p", surface);
g_clear_pointer (&impl->frame_callback, wl_callback_destroy);
+1 -1
View File
@@ -830,7 +830,7 @@ gdk_wayland_surface_create_xdg_toplevel (GdkWaylandToplevel *wayland_toplevel)
maybe_set_gtk_surface_dbus_properties (wayland_toplevel);
maybe_set_gtk_surface_modal (wayland_toplevel);
gdk_profiler_add_mark (GDK_PROFILER_CURRENT_TIME, 0, "Wayland surface commit", NULL);
gdk_profiler_add_mark (GDK_PROFILER_CURRENT_TIME, 0, "wayland", "surface commit");
wl_surface_commit (wayland_surface->display_server.wl_surface);
}
-479
View File
@@ -1,479 +0,0 @@
#pragma once
#include <graphene.h>
#include <math.h>
#include "gsktypesprivate.h"
#include "scaleprivate.h"
#include "pointprivate.h"
#ifndef USE_SIMD
struct _Box
{
float x0, y0, x1, y1;
};
static inline float
box_x0 (const Box box)
{
return box.x0;
}
static inline float
box_y0 (const Box box)
{
return box.y0;
}
static inline float
box_x1 (const Box box)
{
return box.x1;
}
static inline float
box_y1 (const Box box)
{
return box.y1;
}
static inline float
box_width (const Box box)
{
return box.x1 - box.x0;
}
static inline float
box_height (const Box box)
{
return box.y1 - box.y0;
}
/* Assumes x0 <= x1 && y0 <= y1 */
static inline Box
box (float x0,
float y0,
float x1,
float y1)
{
return (Box) { .x0 = x0, .y0 = y0, .x1 = x1, .y1 = y1 };
}
static inline Box
box_from_rect (float x,
float y,
float w,
float h)
{
return box (x, y, x + w, y + h);
}
static inline Box
box_from_graphene (const graphene_rect_t *rect)
{
return box_from_rect (rect->origin.x,
rect->origin.y,
rect->size.width,
rect->size.height);
}
/* Assumes p0.x <= p1.x && p0.y <= p1.y */
static inline Box
box_from_points (Point p0,
Point p1)
{
return box (p0.x, p0.y, p1.x, p1.y);
}
static inline Point
box_origin (const Box box)
{
return point (box.x0, box.y0);
}
static inline Point
box_opposite (const Box box)
{
return point (box.x1, box.y1);
}
static inline void
box_to_float (const Box box,
float v[4])
{
v[0] = box.x0;
v[1] = box.y0;
v[2] = box.x1 - box.x0;
v[3] = box.y1 - box.y0;
}
static inline Box
box_inset (const Box box,
float dx,
float dy)
{
return (Box) { .x0 = box.x0 + dx, .y0 = box.y0 + dy,
.x1 = box.x1 - dx, .y1 = box.y1 - dy };
}
static inline gboolean
box_intersect (const Box box1,
const Box box2,
Box *box)
{
Box b;
b.x0 = MAX (box1.x0, box2.x0);
b.y0 = MAX (box1.y0, box2.y0);
b.x1 = MIN (box1.x1, box2.x1);
b.y1 = MIN (box1.y1, box2.y1);
if (b.x0 <= b.x1 && b.y0 <= b.x1)
{
if (box)
*box = b;
return TRUE;
}
return FALSE;
}
static inline gboolean
box_equal (const Box box1,
const Box box2)
{
return memcmp (&box1, &box2, sizeof (Box)) == 0;
}
static inline gboolean
box_contains (const Box box1,
const Box box2)
{
Box box;
if (box_intersect (box1, box2, &box))
return box_equal (box, box2);
return FALSE;
}
static inline gboolean
box_empty (const Box box)
{
return box.x0 == box.x1 || box.y0 == box.y1;
}
static inline Box
box_add (const Box box,
const Point offset)
{
return (Box) { .x0 = box.x0 + offset.x, .y0 = box.y0 + offset.y,
.x1 = box.x1 + offset.x, .y1 = box.y1 + offset.y };
}
static inline Box
box_sub (const Box box,
const Point offset)
{
return (Box) { .x0 = box.x0 - offset.x, .y0 = box.y0 - offset.y,
.x1 = box.x1 - offset.x, .y1 = box.y1 - offset.y };
}
static inline Box
box_mul (const Box box,
const Scale scale)
{
Box b = (Box) { .x0 = box.x0 * scale.x, .y0 = box.y0 * scale.y,
.x1 = box.x1 * scale.x, .y1 = box.y1 * scale.y };
if (G_UNLIKELY (scale.x < 0 || scale.y < 0))
return (Box) { .x0 = MIN (b.x0, b.x1), .y0 = MIN (b.y0, b.y1),
.x1 = MAX (b.x0, b.x1), .y1 = MAX (b.y0, b.y1) };
return b;
}
static inline Box
box_div (const Box box,
const Scale scale)
{
return box_mul (box, scale_inv (scale));
}
static inline void
box_offset_to_float (const Box box,
const Point offset,
float v[4])
{
box_to_float (box_add (box, offset), v);
}
static inline Box
box_round_larger (const Box box)
{
return (Box) { .x0 = floorf (box.x0), .y0 = floorf (box.y0),
.x1 = ceilf (box.x1), .y1 = ceilf (box.y1) };
}
static inline Box
box_round_to_pixels (const Box box,
const Scale scale,
const Point offset)
{
return box_sub (box_div (box_round_larger (box_mul (box_add (box, offset), scale)), scale), offset);
}
#else /* USE_SIMD */
struct _Box
{
GRAPHENE_ALIGNED_DECL (graphene_simd4f_t v, 16);
};
static inline float
box_x0 (const Box box)
{
return graphene_simd4f_get_x (box.v);
}
static inline float
box_y0 (const Box box)
{
return graphene_simd4f_get_y (box.v);
}
static inline float
box_x1 (const Box box)
{
return graphene_simd4f_get_z (box.v);
}
static inline float
box_y1 (const Box box)
{
return graphene_simd4f_get_w (box.v);
}
static inline float
box_width (const Box box)
{
return box_x1 (box) - box_x0 (box);
}
static inline float
box_height (const Box box)
{
return box_y1 (box) - box_y0 (box);
}
static inline Box
box (float x0,
float y0,
float x1,
float y1)
{
return (Box) { .v = graphene_simd4f_init (x0, y0, x1, y1) };
}
static inline Box
box_from_rect (float x,
float y,
float w,
float h)
{
return box (x, y, x + w, y + h);
}
static inline Box
box_from_graphene (const graphene_rect_t *rect)
{
return box_from_rect (rect->origin.x,
rect->origin.y,
rect->size.width,
rect->size.height);
}
/* { a[0], a[1], b[0], b[1] } */
# define graphene_simd4f_splat_xyxy(a,b) \
(__extension__ ({ \
(graphene_simd4f_t) _mm_shuffle_ps ((a), (b), _MM_SHUFFLE (1, 0, 1, 0)); \
}))
static inline Box
box_from_points (Point p0,
Point p1)
{
return (Box) { .v = graphene_simd4f_splat_xyxy (p0.v, p1.v) };
}
static inline Point
box_origin (const Box box)
{
return (Point) { .v = graphene_simd4f_zero_zw (box.v) };
}
static inline Point
box_opposite (const Box box)
{
return (Point) { .v = graphene_simd4f_zero_zw (graphene_simd4f_shuffle_zwxy (box.v)) };
}
static inline void
box_to_float (const Box box,
float v[4])
{
graphene_simd4f_dup_4f (box.v, v);
v[2] -= v[0];
v[3] -= v[1];
}
static inline Box
box_inset (const Box box,
float dx,
float dy)
{
return (Box) { .v = graphene_simd4f_add (box.v, graphene_simd4f_init (dx, dy, -dx, -dy)) };
}
/* return a[0] < b[0] && a[1] < b[1] */
#ifndef graphene_simd4f_cmple_xy
# define graphene_simd4f_cmple_xy(a,b) \
(__extension__ ({ \
__m128i __res = (__m128i) _mm_cmple_ps ((a), (b)); \
(bool) ((_mm_movemask_epi8 (__res) & 0xff) == 0xff); \
}))
#endif
static inline gboolean
box_intersect (const Box box1,
const Box box2,
Box *box)
{
graphene_simd4f_t s, t, t1;
s = graphene_simd4f_max (box1.v, box2.v);
t = graphene_simd4f_min (box1.v, box2.v);
t1 = graphene_simd4f_shuffle_zwxy (t);
if (graphene_simd4f_cmple_xy (s, t1))
{
if (box)
box->v = graphene_simd4f_splat_xyxy (s, t);
return TRUE;
}
return FALSE;
}
static inline gboolean
box_equal (const Box box1,
const Box box2)
{
return (gboolean) !!graphene_simd4f_cmp_eq (box1.v, box2.v);
}
static inline gboolean
box_contains (const Box box1,
const Box box2)
{
Box box;
if (box_intersect (box1, box2, &box))
return box_equal (box, box2);
return FALSE;
}
static inline gboolean
box_empty (const Box box)
{
/* FIXME simd */
return box_x0 (box) == box_x1 (box) || box_y0 (box) == box_y1 (box);
}
/* a splat variation */
#ifndef graphene_simd4f_shuffle_xyxy
# define graphene_simd4f_shuffle_xyxy(v) \
(__extension__ ({ \
(graphene_simd4f_t) _mm_shuffle_ps ((v), (v), _MM_SHUFFLE (1, 0, 1, 0)); \
}))
#endif
static inline Box
box_add (const Box box,
const Point offset)
{
return (Box) { .v = graphene_simd4f_add (box.v, graphene_simd4f_shuffle_xyxy (offset.v)) };
}
static inline Box
box_sub (const Box box,
const Point offset)
{
return (Box) { .v = graphene_simd4f_sub (box.v, graphene_simd4f_shuffle_xyxy (offset.v)) };
}
static inline Box
box_mul (const Box box,
const Scale scale)
{
Box b = (Box) { .v = graphene_simd4f_mul (box.v, graphene_simd4f_shuffle_xyxy (scale.v)) };
if (G_UNLIKELY (!graphene_simd4f_cmple_xy (graphene_simd4f_init (0, 0, 0, 0), scale.v)))
{
graphene_simd4f_t v = graphene_simd4f_shuffle_zwxy (b.v);
graphene_simd4f_t s = graphene_simd4f_min (b.v, v);
graphene_simd4f_t t = graphene_simd4f_max (b.v, v);
return (Box) { .v = graphene_simd4f_splat_xyxy (s, t) };
}
return b;
}
static inline Box
box_div (const Box box,
const Scale scale)
{
return box_mul (box, scale_inv (scale));
}
static inline void
box_offset_to_float (const Box box,
const Point offset,
float v[4])
{
box_to_float (box_add (box, offset), v);
}
#ifdef __SSE4_1__
static inline Box
box_round_larger (const Box box)
{
return { (Box) .v = graphene_simd4f_splat_xyxy (graphene_simd4f_floor (b.v), graphene_simd4f_ceil (b.v)) };
}
#else
static inline Box
box_round_larger (const Box b)
{
return box (floorf (box_x0 (b)),
floorf (box_y0 (b)),
ceilf (box_x1 (b)),
ceilf (box_y1 (b)));
}
#endif
static inline Box
box_round_to_pixels (const Box box,
const Scale scale,
const Point offset)
{
return box_sub (box_div (box_round_larger (box_mul (box_add (box, offset), scale)), scale), offset);
}
#endif
+4 -4
View File
@@ -1608,8 +1608,8 @@ gsk_gl_command_queue_do_upload_texture_chunk (GskGLCommandQueue *self,
if (gdk_profiler_is_running ())
{
gdk_profiler_end_markf (start_time,
"Download texture chunk",
gdk_profiler_add_markf (start_time, GDK_PROFILER_CURRENT_TIME-start_time,
"Download Texture chunk",
"Tile %dx%d Size %dx%d", x, y, width, height);
start_time = GDK_PROFILER_CURRENT_TIME;
}
@@ -1654,8 +1654,8 @@ gsk_gl_command_queue_do_upload_texture_chunk (GskGLCommandQueue *self,
g_bytes_unref (bytes);
if (gdk_profiler_is_running ())
gdk_profiler_end_markf (start_time,
"Upload texture chunk",
gdk_profiler_add_markf (start_time, GDK_PROFILER_CURRENT_TIME-start_time,
"Upload Texture chunk",
"Tile %dx%d Size %dx%d", x, y, width, height);
}
+2 -2
View File
@@ -424,7 +424,7 @@ gsk_gl_driver_load_programs (GskGLDriver *self,
failure:
g_clear_object (&compiler);
gdk_profiler_end_mark (start_time, "Load GL programs", NULL);
gdk_profiler_end_mark (start_time, "load programs", NULL);
return ret;
}
@@ -477,7 +477,7 @@ gsk_gl_driver_new (GskGLCommandQueue *command_queue,
self->icons_library = gsk_gl_icon_library_new (self);
self->shadows_library = gsk_gl_shadow_library_new (self);
gdk_profiler_end_mark (before, "Create GL driver", NULL);
gdk_profiler_end_mark (before, "create GskGLDriver", NULL);
return g_steal_pointer (&self);
}
+6 -2
View File
@@ -119,7 +119,11 @@ gsk_gl_glyph_library_init_atlas (GskGLTextureLibrary *self,
memset (pixel_data, 255, sizeof pixel_data);
if (gdk_gl_context_get_use_es (gdk_gl_context_get_current ()))
if (!gdk_gl_context_has_bgra (gdk_gl_context_get_current ())
#if G_BYTE_ORDER == G_BIG_ENDIAN
|| gdk_gl_context_get_use_es (gdk_gl_context_get_current ())
#endif
)
{
gl_format = GL_RGBA;
gl_type = GL_UNSIGNED_BYTE;
@@ -376,7 +380,7 @@ gsk_gl_glyph_library_upload_glyph (GskGLGlyphLibrary *self,
{
char message[64];
g_snprintf (message, sizeof message, "Size %dx%d", width, height);
gdk_profiler_add_mark (start_time, GDK_PROFILER_CURRENT_TIME-start_time, "Upload glyph", message);
gdk_profiler_add_mark (start_time, GDK_PROFILER_CURRENT_TIME-start_time, "Upload Glyph", message);
}
}
+1 -1
View File
@@ -211,6 +211,6 @@ gsk_gl_icon_library_add (GskGLIconLibrary *self,
{
char message[64];
g_snprintf (message, sizeof message, "Size %dx%d", width, height);
gdk_profiler_add_mark (start_time, GDK_PROFILER_CURRENT_TIME-start_time, "Upload icon", message);
gdk_profiler_add_mark (start_time, GDK_PROFILER_CURRENT_TIME-start_time, "Upload Icon", message);
}
}
+31 -31
View File
@@ -830,8 +830,8 @@ rounded_rect_scale_corners (const GskRoundedRect *rect,
{
for (guint i = 0; i < G_N_ELEMENTS (out_rect->corner); i++)
{
out_rect->corner[i].width = rect->corner[i].width * fabsf (scale_x);
out_rect->corner[i].height = rect->corner[i].height * fabsf (scale_y);
out_rect->corner[i].width = rect->corner[i].width * fabs (scale_x);
out_rect->corner[i].height = rect->corner[i].height * fabs (scale_y);
}
if (scale_x < 0)
@@ -1173,8 +1173,8 @@ gsk_gl_render_job_visit_as_fallback (GskGLRenderJob *job,
{
float scale_x = job->scale_x;
float scale_y = job->scale_y;
int surface_width = ceilf (node->bounds.size.width * fabsf (scale_x));
int surface_height = ceilf (node->bounds.size.height * fabsf (scale_y));
int surface_width = ceilf (node->bounds.size.width * fabs (scale_x));
int surface_height = ceilf (node->bounds.size.height * fabs (scale_y));
GdkTexture *texture;
cairo_surface_t *surface;
cairo_surface_t *rendered_surface;
@@ -1203,7 +1203,7 @@ gsk_gl_render_job_visit_as_fallback (GskGLRenderJob *job,
surface_width,
surface_height);
cairo_surface_set_device_scale (rendered_surface, fabsf (scale_x), fabsf (scale_y));
cairo_surface_set_device_scale (rendered_surface, fabs (scale_x), fabs (scale_y));
cr = cairo_create (rendered_surface);
cairo_save (cr);
@@ -1217,16 +1217,16 @@ gsk_gl_render_job_visit_as_fallback (GskGLRenderJob *job,
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
surface_width,
surface_height);
cairo_surface_set_device_scale (surface, fabsf (scale_x), fabsf (scale_y));
cairo_surface_set_device_scale (surface, fabs (scale_x), fabs (scale_y));
cr = cairo_create (surface);
/* We draw upside down here, so it matches what GL does. */
cairo_save (cr);
cairo_scale (cr, scale_x < 0 ? -1 : 1, scale_y < 0 ? 1 : -1);
cairo_translate (cr, scale_x < 0 ? - surface_width / fabsf (scale_x) : 0,
scale_y < 0 ? 0 : - surface_height / fabsf (scale_y));
cairo_translate (cr, scale_x < 0 ? - surface_width / fabs (scale_x) : 0,
scale_y < 0 ? 0 : - surface_height / fabs (scale_y));
cairo_set_source_surface (cr, rendered_surface, 0, 0);
cairo_rectangle (cr, 0, 0, surface_width / fabsf (scale_x), surface_height / fabsf (scale_y));
cairo_rectangle (cr, 0, 0, surface_width / fabs (scale_x), surface_height / fabs (scale_y));
cairo_fill (cr);
cairo_restore (cr);
cairo_destroy (cr);
@@ -1432,10 +1432,10 @@ blur_node (GskGLRenderJob *job,
offscreen->texture_id = blur_offscreen (job,
offscreen,
texture_width * fabsf (scale_x),
texture_height * fabsf (scale_y),
blur_radius * fabsf (scale_x),
blur_radius * fabsf (scale_y));
texture_width * fabs (scale_x),
texture_height * fabs (scale_y),
blur_radius * fabs (scale_x),
blur_radius * fabs (scale_y));
init_full_texture_region (offscreen);
}
@@ -2019,9 +2019,9 @@ result_is_axis_aligned (GskTransform *transform,
for (guint i = 0; i < 4; i++)
{
p = graphene_quad_get_point (&q, i);
if (fabsf (p->x - b1.x) > FLT_EPSILON && fabsf (p->x - b2.x) > FLT_EPSILON)
if (fabs (p->x - b1.x) > FLT_EPSILON && fabs (p->x - b2.x) > FLT_EPSILON)
return FALSE;
if (fabsf (p->y - b1.y) > FLT_EPSILON && fabsf (p->y - b2.y) > FLT_EPSILON)
if (fabs (p->y - b1.y) > FLT_EPSILON && fabs (p->y - b2.y) > FLT_EPSILON)
return FALSE;
}
@@ -2304,8 +2304,8 @@ gsk_gl_render_job_visit_blurred_inset_shadow_node (GskGLRenderJob *job,
&offscreen,
texture_width,
texture_height,
blur_radius * fabsf (scale_x),
blur_radius * fabsf (scale_y));
blur_radius * fabs (scale_x),
blur_radius * fabs (scale_y));
gsk_gl_driver_release_render_target (job->driver, render_target, TRUE);
@@ -2501,8 +2501,8 @@ gsk_gl_render_job_visit_blurred_outset_shadow_node (GskGLRenderJob *job,
do_slicing = TRUE;
}
texture_width = (int)ceilf ((scaled_outline.bounds.size.width + blur_extra) * scale_x);
texture_height = (int)ceilf ((scaled_outline.bounds.size.height + blur_extra) * scale_y);
texture_width = (int)ceil ((scaled_outline.bounds.size.width + blur_extra) * scale_x);
texture_height = (int)ceil ((scaled_outline.bounds.size.height + blur_extra) * scale_y);
scaled_outline.bounds.origin.x = extra_blur_pixels_x;
scaled_outline.bounds.origin.y = extra_blur_pixels_y;
@@ -2577,8 +2577,8 @@ gsk_gl_render_job_visit_blurred_outset_shadow_node (GskGLRenderJob *job,
&offscreen,
texture_width,
texture_height,
blur_radius * fabsf (scale_x),
blur_radius * fabsf (scale_y));
blur_radius * fabs (scale_x),
blur_radius * fabs (scale_y));
gsk_gl_shadow_library_insert (job->driver->shadows_library,
&scaled_outline,
@@ -2834,7 +2834,7 @@ gsk_gl_render_job_visit_cross_fade_node (GskGLRenderJob *job,
offscreen_end.reset_clip = TRUE;
offscreen_end.bounds = &node->bounds;
gsk_gl_render_job_set_modelview (job, gsk_transform_scale (NULL, fabsf (job->scale_x), fabsf (job->scale_y)));
gsk_gl_render_job_set_modelview (job, gsk_transform_scale (NULL, fabs (job->scale_x), fabs (job->scale_y)));
if (!gsk_gl_render_job_visit_node_with_offscreen (job, start_node, &offscreen_start))
{
@@ -2964,7 +2964,7 @@ gsk_gl_render_job_visit_text_node (GskGLRenderJob *job,
const PangoFont *font = gsk_text_node_get_font (node);
const PangoGlyphInfo *glyphs = gsk_text_node_get_glyphs (node, NULL);
const graphene_point_t *offset = gsk_text_node_get_offset (node);
float text_scale = MAX (fabsf (job->scale_x), fabsf (job->scale_y)); /* TODO: Fix for uneven scales? */
float text_scale = MAX (fabs (job->scale_x), fabs (job->scale_y)); /* TODO: Fix for uneven scales? */
guint num_glyphs = gsk_text_node_get_num_glyphs (node);
float x = offset->x + job->offset_x;
float y = offset->y + job->offset_y;
@@ -3263,7 +3263,7 @@ gsk_gl_render_job_visit_blend_node (GskGLRenderJob *job,
bottom_offscreen.force_offscreen = TRUE;
bottom_offscreen.reset_clip = TRUE;
gsk_gl_render_job_set_modelview (job, gsk_transform_scale (NULL, fabsf (job->scale_x), fabsf (job->scale_y)));
gsk_gl_render_job_set_modelview (job, gsk_transform_scale (NULL, fabs (job->scale_x), fabs (job->scale_y)));
/* TODO: We create 2 textures here as big as the blend node, but both the
* start and the end node might be a lot smaller than that. */
@@ -3344,8 +3344,8 @@ gsk_gl_render_job_texture_mask_for_color (GskGLRenderJob *job,
gboolean use_mipmap;
guint16 cc[4];
use_mipmap = (scale_x * fabsf (job->scale_x)) < 0.5 ||
(scale_y * fabsf (job->scale_y)) < 0.5;
use_mipmap = (scale_x * fabs (job->scale_x)) < 0.5 ||
(scale_y * fabs (job->scale_y)) < 0.5;
rgba_to_half (rgba, cc);
gsk_gl_render_job_upload_texture (job, texture, use_mipmap, &offscreen);
@@ -3396,7 +3396,7 @@ gsk_gl_render_job_visit_mask_node (GskGLRenderJob *job,
mask_offscreen.reset_clip = TRUE;
mask_offscreen.do_not_cache = TRUE;
gsk_gl_render_job_set_modelview (job, gsk_transform_scale (NULL, fabsf (job->scale_x), fabsf (job->scale_y)));
gsk_gl_render_job_set_modelview (job, gsk_transform_scale (NULL, fabs (job->scale_x), fabs (job->scale_y)));
/* TODO: We create 2 textures here as big as the mask node, but both
* nodes might be a lot smaller than that.
@@ -3664,8 +3664,8 @@ gsk_gl_render_job_visit_texture (GskGLRenderJob *job,
float scale_y = bounds->size.height / texture->height;
gboolean use_mipmap;
use_mipmap = (scale_x * fabsf (job->scale_x)) < 0.5 ||
(scale_y * fabsf (job->scale_y)) < 0.5;
use_mipmap = (scale_x * fabs (job->scale_x)) < 0.5 ||
(scale_y * fabs (job->scale_y)) < 0.5;
if G_LIKELY (texture->width <= max_texture_size &&
texture->height <= max_texture_size)
@@ -4544,7 +4544,7 @@ gsk_gl_render_job_render (GskGLRenderJob *job,
gsk_gl_render_job_visit_node (job, root);
gdk_gl_context_pop_debug_group (job->command_queue->context);
gdk_profiler_end_mark (start_time, "Build GL command queue", "");
gdk_profiler_add_mark (start_time, GDK_PROFILER_CURRENT_TIME-start_time, "Build GL command queue", "");
#if 0
/* At this point the atlases have uploaded content while we processed
@@ -4562,7 +4562,7 @@ gsk_gl_render_job_render (GskGLRenderJob *job,
gdk_gl_context_push_debug_group (job->command_queue->context, "Executing command queue");
gsk_gl_command_queue_execute (job->command_queue, surface_height, scale, job->region, job->default_framebuffer);
gdk_gl_context_pop_debug_group (job->command_queue->context);
gdk_profiler_end_mark (start_time, "Execute GL command queue", "");
gdk_profiler_add_mark (start_time, GDK_PROFILER_CURRENT_TIME-start_time, "Execute GL command queue", "");
}
static int
+4 -2
View File
@@ -117,8 +117,9 @@ gsk_gl_texture_library_real_compact (GskGLTextureLibrary *self,
g_hash_table_iter_remove (&iter);
dropped++;
}
else if (periodic_scan)
entry->accessed = FALSE;
if (periodic_scan)
entry->accessed = FALSE;
}
}
@@ -439,6 +440,7 @@ gsk_gl_texture_library_pack (GskGLTextureLibrary *self,
entry->texture = texture;
entry->is_atlased = FALSE;
entry->accessed = TRUE;
entry->area.x = padding / (float) (padding + width + padding);
entry->area.y = padding / (float) (padding + height + padding);
entry->area.x2 = (padding + width) / (float) (padding + width + padding);
-39
View File
@@ -301,42 +301,3 @@ gsk_gpu_clip_get_shader_clip (const GskGpuClip *self,
return GSK_GPU_SHADER_CLIP_ROUNDED;
}
gboolean
gsk_gpu_clip_contains_box (const GskGpuClip *self,
const Point *offset,
const Box *box)
{
Box b = box_add (*box, *offset);
switch (self->type)
{
default:
g_assert_not_reached();
case GSK_GPU_CLIP_ALL_CLIPPED:
return FALSE;
case GSK_GPU_CLIP_NONE:
case GSK_GPU_CLIP_CONTAINED:
case GSK_GPU_CLIP_RECT:
return box_contains (box_from_graphene (&self->rect.bounds), b);
case GSK_GPU_CLIP_ROUNDED:
return gsk_rounded_rect_contains_rect (&self->rect, &GRAPHENE_RECT_INIT (box_x0 (b), box_y0 (b), box_width (b), box_height (b)));
}
}
GskGpuShaderClip
gsk_gpu_clip_get_shader_clip2 (const GskGpuClip *self,
const Point *offset,
const Box *box)
{
if (self->type == GSK_GPU_CLIP_NONE ||
self->type == GSK_GPU_CLIP_CONTAINED ||
gsk_gpu_clip_contains_box (self, offset, box))
return GSK_GPU_SHADER_CLIP_NONE;
else if (self->type == GSK_GPU_CLIP_RECT)
return GSK_GPU_SHADER_CLIP_RECT;
else
return GSK_GPU_SHADER_CLIP_ROUNDED;
}
+1 -9
View File
@@ -5,7 +5,6 @@
#include <gdk/gdk.h>
#include <graphene.h>
#include <gsk/gskroundedrect.h>
#include "boxprivate.h"
G_BEGIN_DECLS
@@ -66,16 +65,9 @@ gboolean gsk_gpu_clip_contains_rect (const G
gboolean gsk_gpu_clip_may_intersect_rect (const GskGpuClip *self,
const graphene_point_t *offset,
const graphene_rect_t *rect) G_GNUC_WARN_UNUSED_RESULT;
GskGpuShaderClip gsk_gpu_clip_get_shader_clip (const GskGpuClip *self,
GskGpuShaderClip gsk_gpu_clip_get_shader_clip (const GskGpuClip *self,
const graphene_point_t *offset,
const graphene_rect_t *rect);
gboolean gsk_gpu_clip_contains_box (const GskGpuClip *self,
const Point *offset,
const Box *box) G_GNUC_WARN_UNUSED_RESULT;
GskGpuShaderClip gsk_gpu_clip_get_shader_clip2 (const GskGpuClip *self,
const Point *offset,
const Box *box);
G_END_DECLS
+291 -143
View File
@@ -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)
@@ -54,12 +79,34 @@ struct _GskGpuCachedClass
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,6 +233,91 @@ gsk_gpu_cached_atlas_new (GskGpuDevice *device)
return self;
}
/* 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
*/
static gsize
round_up_atlas_size (gsize num)
{
gsize storage = g_bit_storage (num);
num = num + (((1 << storage) - 1) >> 2);
num &= (((gsize) 7) << storage) >> 2;
return num;
}
static gboolean
gsk_gpu_cached_atlas_allocate (GskGpuCachedAtlas *atlas,
gsize width,
gsize height,
gsize *out_x,
gsize *out_y)
{
gsize i;
gsize waste, slice_waste;
gsize best_slice;
gsize y, best_y;
gboolean can_add_slice;
best_y = 0;
best_slice = G_MAXSIZE;
can_add_slice = atlas->n_slices < MAX_SLICES_PER_ATLAS;
if (can_add_slice)
waste = height; /* Require less than 100% waste */
else
waste = G_MAXSIZE; /* Accept any slice, we can't make better ones */
for (i = 0, y = 0; i < atlas->n_slices; y += atlas->slices[i].height, i++)
{
if (atlas->slices[i].height < height || ATLAS_SIZE - atlas->slices[i].width < width)
continue;
slice_waste = atlas->slices[i].height - height;
if (slice_waste < waste)
{
waste = slice_waste;
best_slice = i;
best_y = y;
if (waste == 0)
break;
}
}
if (best_slice >= i && i == atlas->n_slices)
{
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 = 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 */
@@ -190,8 +337,8 @@ gsk_gpu_cached_texture_free (GskGpuDevice *device,
gboolean texture_still_alive;
texture_still_alive = g_atomic_pointer_exchange (&self->texture, NULL) != NULL;
g_object_unref (self->image);
g_clear_object (&self->image);
if (!texture_still_alive)
g_free (self);
}
@@ -201,8 +348,7 @@ gsk_gpu_cached_texture_should_collect (GskGpuDevice *device,
GskGpuCached *cached,
gint64 timestamp)
{
/* FIXME */
return FALSE;
return timestamp - cached->timestamp > CACHE_MAX_AGE;
}
static const GskGpuCachedClass GSK_GPU_CACHED_TEXTURE_CLASS =
@@ -260,10 +406,7 @@ struct _GskGpuCachedGlyph
{
GskGpuCached parent;
PangoFont *font;
PangoGlyph glyph;
GskGpuGlyphLookupFlags flags;
float scale;
GlyphKey key;
GskGpuImage *image;
graphene_rect_t bounds;
@@ -274,9 +417,12 @@ 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_object_unref (self->font);
g_hash_table_remove (priv->glyph_cache, self);
g_object_unref (self->key.font);
g_object_unref (self->image);
g_free (self);
@@ -287,7 +433,10 @@ gsk_gpu_cached_glyph_should_collect (GskGpuDevice *device,
GskGpuCached *cached,
gint64 timestamp)
{
/* FIXME */
if (timestamp - cached->timestamp > CACHE_MAX_AGE)
mark_as_stale (cached, TRUE);
/* Glyphs are only collected when their atlas is freed */
return FALSE;
}
@@ -296,10 +445,10 @@ 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);
return GPOINTER_TO_UINT (glyph->key.font) ^
glyph->key.glyph ^
(glyph->key.flags << 24) ^
((guint) glyph->key.scale * PANGO_SCALE);
}
static gboolean
@@ -309,10 +458,10 @@ gsk_gpu_cached_glyph_equal (gconstpointer v1,
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;
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 =
@@ -325,19 +474,74 @@ static const GskGpuCachedClass GSK_GPU_CACHED_GLYPH_CLASS =
/* }}} */
/* {{{ 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, *next;
GskGpuCached *cached, *prev;
for (cached = priv->first_cached; cached != NULL; cached = next)
/* 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)
{
next = cached->next;
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
@@ -357,8 +561,9 @@ gsk_gpu_device_clear_cache (GskGpuDevice *self)
g_assert (cached->next->prev == cached);
}
while (priv->first_cached)
gsk_gpu_cached_free (self, priv->first_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);
}
@@ -372,6 +577,7 @@ gsk_gpu_device_dispose (GObject *object)
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);
}
@@ -407,6 +613,16 @@ gsk_gpu_device_init (GskGpuDevice *self)
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,
@@ -416,6 +632,8 @@ gsk_gpu_device_setup (GskGpuDevice *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 *
@@ -463,88 +681,6 @@ gsk_gpu_device_create_download_image (GskGpuDevice *self,
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
*/
static gsize
round_up_atlas_size (gsize num)
{
gsize storage = g_bit_storage (num);
num = num + (((1 << storage) - 1) >> 2);
num &= (((gsize) 7) << storage) >> 2;
return num;
}
static gboolean
gsk_gpu_cached_atlas_allocate (GskGpuCachedAtlas *atlas,
gsize width,
gsize height,
gsize *out_x,
gsize *out_y)
{
gsize i;
gsize waste, slice_waste;
gsize best_slice;
gsize y, best_y;
gboolean can_add_slice;
best_y = 0;
best_slice = G_MAXSIZE;
can_add_slice = atlas->n_slices < MAX_SLICES_PER_ATLAS;
if (can_add_slice)
waste = height; /* Require less than 100% waste */
else
waste = G_MAXSIZE; /* Accept any slice, we can't make better ones */
for (i = 0, y = 0; i < atlas->n_slices; y += atlas->slices[i].height, i++)
{
if (atlas->slices[i].height < height || ATLAS_SIZE - atlas->slices[i].width < width)
continue;
slice_waste = atlas->slices[i].height - height;
if (slice_waste < waste)
{
waste = slice_waste;
best_slice = i;
best_y = y;
if (waste == 0)
break;
}
}
if (best_slice >= i && i == atlas->n_slices)
{
gsize slice_height;
if (!can_add_slice)
return FALSE;
slice_height = round_up_atlas_size (MAX (height, 4));
if (slice_height > ATLAS_SIZE - y)
return FALSE;
atlas->n_slices++;
if (atlas->n_slices == MAX_SLICES_PER_ATLAS)
slice_height = ATLAS_SIZE - y;
atlas->slices[i].width = 0;
atlas->slices[i].height = slice_height;
best_y = y;
best_slice = i;
}
*out_x = atlas->slices[best_slice].width;
*out_y = best_y;
atlas->slices[best_slice].width += width;
g_assert (atlas->slices[best_slice].width <= ATLAS_SIZE);
return TRUE;
}
static void
gsk_gpu_device_ensure_atlas (GskGpuDevice *self,
gboolean recreate,
@@ -582,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;
}
@@ -612,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;
}
@@ -645,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;
@@ -656,29 +784,44 @@ gsk_gpu_device_lookup_glyph_image (GskGpuDevice *self,
graphene_point_t origin;
GskGpuImage *image;
gsize atlas_x, atlas_y, padding;
float subpixel_x, subpixel_y;
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;
}
subpixel_x = (flags & 3) / 4.f;
subpixel_y = ((flags >> 2) & 3) / 4.f;
pango_font_get_glyph_extents (font, glyph, &ink_rect, NULL);
origin.x = floor (ink_rect.x * scale / PANGO_SCALE + subpixel_x);
origin.y = floor (ink_rect.y * scale / PANGO_SCALE + subpixel_y);
rect.size.width = ceil ((ink_rect.x + ink_rect.width) * scale / PANGO_SCALE + subpixel_x) - origin.x;
rect.size.height = ceil ((ink_rect.y + ink_rect.height) * scale / PANGO_SCALE + subpixel_y) - origin.y;
origin.x = floor (ink_rect.x * scale / PANGO_SCALE);
origin.y = floor (ink_rect.y * scale / PANGO_SCALE);
rect.size.width = ceil ((ink_rect.x + ink_rect.width) * scale / PANGO_SCALE) - origin.x;
rect.size.height = ceil ((ink_rect.y + ink_rect.height) * scale / PANGO_SCALE) - origin.y;
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)
@@ -697,14 +840,15 @@ 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,
cache->origin = GRAPHENE_POINT_INIT (- origin.x + subpixel_x,
- origin.y + subpixel_y);
((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);
gsk_gpu_upload_glyph_op (frame,
cache->image,
@@ -721,10 +865,14 @@ 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;
}
+69 -99
View File
@@ -43,10 +43,6 @@
#include "gdk/gdkrgbaprivate.h"
#include "scaleprivate.h"
#include "pointprivate.h"
#include "boxprivate.h"
/* A note about coordinate systems
*
* The rendering code keeps track of multiple coordinate systems to optimize rendering as
@@ -326,8 +322,8 @@ rect_round_to_pixels (const graphene_rect_t *src,
*dest = GRAPHENE_RECT_INIT (
x * inv_xscale - pixel_offset->x,
y * inv_yscale - pixel_offset->y,
(ceilf ((src->origin.x + pixel_offset->x + src->size.width) * xscale) - x) * inv_xscale,
(ceilf ((src->origin.y + pixel_offset->y + src->size.height) * yscale) - y) * inv_yscale);
(ceil ((src->origin.x + pixel_offset->x + src->size.width) * xscale) - x) * inv_xscale,
(ceil ((src->origin.y + pixel_offset->y + src->size.height) * yscale) - y) * inv_yscale);
}
static GskGpuImage *
@@ -342,8 +338,8 @@ gsk_gpu_node_processor_init_draw (GskGpuNodeProcessor *self,
area.x = 0;
area.y = 0;
area.width = ceilf (graphene_vec2_get_x (scale) * viewport->size.width);
area.height = ceilf (graphene_vec2_get_y (scale) * viewport->size.height);
area.width = ceil (graphene_vec2_get_x (scale) * viewport->size.width);
area.height = ceil (graphene_vec2_get_y (scale) * viewport->size.height);
image = gsk_gpu_device_create_offscreen_image (gsk_gpu_frame_get_device (frame),
FALSE,
@@ -502,18 +498,6 @@ gsk_gpu_pattern_writer_append_rect (GskGpuPatternWriter *self,
gsk_gpu_pattern_writer_append (self, G_ALIGNOF (float), (guchar *) f, sizeof (f));
}
static void
gsk_gpu_pattern_writer_append_box (GskGpuPatternWriter *self,
const Box box,
const Point offset)
{
float f[4];
box_offset_to_float (box, offset, f);
gsk_gpu_pattern_writer_append (self, G_ALIGNOF (float), (guchar *) f, sizeof (f));
}
static void
gsk_gpu_pattern_writer_append_rgba (GskGpuPatternWriter *self,
const GdkRGBA *rgba)
@@ -1010,8 +994,8 @@ gsk_gpu_node_processor_blur_op (GskGpuNodeProcessor *self,
if (!gsk_rect_intersection (rect, &clip_rect, &intermediate_rect))
return;
width = ceilf (graphene_vec2_get_x (&self->scale) * intermediate_rect.size.width);
height = ceilf (graphene_vec2_get_y (&self->scale) * intermediate_rect.size.height);
width = ceil (graphene_vec2_get_x (&self->scale) * intermediate_rect.size.width);
height = ceil (graphene_vec2_get_y (&self->scale) * intermediate_rect.size.height);
intermediate = gsk_gpu_device_create_offscreen_image (gsk_gpu_frame_get_device (self->frame),
FALSE,
@@ -1830,10 +1814,10 @@ gsk_gpu_node_processor_add_color_node (GskGpuNodeProcessor *self,
if (shader_clip != GSK_GPU_SHADER_CLIP_NONE)
{
gsk_rounded_rect_get_largest_cover (&self->clip.rect, &clipped, &cover);
int_clipped.x = ceilf (cover.origin.x * scale_x);
int_clipped.y = ceilf (cover.origin.y * scale_y);
int_clipped.width = floorf ((cover.origin.x + cover.size.width) * scale_x) - int_clipped.x;
int_clipped.height = floorf ((cover.origin.y + cover.size.height) * scale_y) - int_clipped.y;
int_clipped.x = ceil (cover.origin.x * scale_x);
int_clipped.y = ceil (cover.origin.y * scale_y);
int_clipped.width = floor ((cover.origin.x + cover.size.width) * scale_x) - int_clipped.x;
int_clipped.height = floor ((cover.origin.y + cover.size.height) * scale_y) - int_clipped.y;
if (int_clipped.width == 0 || int_clipped.height == 0)
{
gsk_gpu_color_op (self->frame,
@@ -2990,11 +2974,10 @@ gsk_gpu_node_processor_add_glyph_node (GskGpuNodeProcessor *self,
GskGpuDevice *device;
const PangoGlyphInfo *glyphs;
PangoFont *font;
Point offset;
Scale scale, s4, pango_scale;
graphene_point_t offset;
guint i, num_glyphs;
float scale, inv_scale;
GdkRGBA color;
gboolean glyph_align;
if (self->opacity < 1.0 &&
gsk_text_node_has_color_glyphs (node))
@@ -3003,83 +2986,59 @@ gsk_gpu_node_processor_add_glyph_node (GskGpuNodeProcessor *self,
return;
}
glyph_align = gsk_gpu_frame_should_optimize (self->frame, GSK_GPU_OPTIMIZE_GLYPH_ALIGN) &&
gsk_transform_get_category (self->modelview) >= GSK_TRANSFORM_CATEGORY_2D;
device = gsk_gpu_frame_get_device (self->frame);
color = *gsk_text_node_get_color (node);
color.alpha *= self->opacity;
num_glyphs = gsk_text_node_get_num_glyphs (node);
glyphs = gsk_text_node_get_glyphs (node, NULL);
font = gsk_text_node_get_font (node);
offset = *gsk_text_node_get_offset (node);
offset.x += self->offset.x;
offset.y += self->offset.y;
offset = point_add (point_from_graphene (gsk_text_node_get_offset (node)),
point_from_graphene (&self->offset));
scale = scale_max (scale_from_graphene (&self->scale));
s4 = scale_mul (scale, scale_from_float (4));
pango_scale = scale_from_float (PANGO_SCALE);
scale = MAX (graphene_vec2_get_x (&self->scale), graphene_vec2_get_y (&self->scale));
inv_scale = 1.f / scale;
for (i = 0; i < num_glyphs; i++)
{
GskGpuImage *image;
graphene_rect_t glyph_bds;
graphene_point_t glyph_ofs;
Box glyph_bounds, glyph_tex_rect;
Point g_ofs, glyph_origin;
graphene_rect_t glyph_bounds, glyph_tex_rect;
graphene_point_t glyph_offset;
guint32 descriptor;
GskGpuGlyphLookupFlags flags;
glyph_origin = point_add (offset, point_div (point (glyphs[i].geometry.x_offset, glyphs[i].geometry.y_offset), pango_scale));
if (glyph_align)
{
glyph_origin = point_round (point_mul (glyph_origin, s4));
flags = ((int) point_x (glyph_origin) & 3) |
(((int) point_y (glyph_origin) & 3) << 2);
glyph_origin = point_div (glyph_origin, s4);
}
else
{
flags = 0;
}
image = gsk_gpu_device_lookup_glyph_image (device,
self->frame,
font,
glyphs[i].glyph,
flags,
scale_x (scale),
&glyph_bds,
&glyph_ofs);
glyph_tex_rect = box_div (box_from_rect (-glyph_bds.origin.x, -glyph_bds.origin.y, gsk_gpu_image_get_width (image), gsk_gpu_image_get_height (image)), scale);
glyph_bounds = box_div (box_from_rect (0, 0, glyph_bds.size.width, glyph_bds.size.height), scale);
g_ofs = point_from_graphene (&glyph_ofs);
glyph_origin = point_sub (glyph_origin, point_div (g_ofs, scale));
0,
scale,
&glyph_bounds,
&glyph_offset);
graphene_rect_scale (&GRAPHENE_RECT_INIT (-glyph_bounds.origin.x, -glyph_bounds.origin.y, gsk_gpu_image_get_width (image), gsk_gpu_image_get_height (image)), inv_scale, inv_scale, &glyph_tex_rect);
graphene_rect_scale (&GRAPHENE_RECT_INIT(0, 0, glyph_bounds.size.width, glyph_bounds.size.height), inv_scale, inv_scale, &glyph_bounds);
glyph_offset = GRAPHENE_POINT_INIT (offset.x - glyph_offset.x * inv_scale + (float) glyphs[i].geometry.x_offset / PANGO_SCALE,
offset.y - glyph_offset.y * inv_scale + (float) glyphs[i].geometry.y_offset / PANGO_SCALE);
descriptor = gsk_gpu_node_processor_add_image (self, image, GSK_GPU_SAMPLER_DEFAULT);
if (glyphs[i].attr.is_color)
gsk_gpu_texture_op (self->frame,
gsk_gpu_clip_get_shader_clip2 (&self->clip, &g_ofs, &glyph_bounds),
gsk_gpu_clip_get_shader_clip (&self->clip, &glyph_offset, &glyph_bounds),
self->desc,
descriptor,
&GRAPHENE_RECT_INIT (box_x0 (glyph_bounds), box_y0 (glyph_bounds), box_width (glyph_bounds), box_height (glyph_bounds)),
&GRAPHENE_POINT_INIT (point_x (glyph_origin), point_y (glyph_origin)),
&GRAPHENE_RECT_INIT (box_x0 (glyph_tex_rect), box_y0 (glyph_tex_rect), box_width (glyph_tex_rect), box_height (glyph_tex_rect)));
&glyph_bounds,
&glyph_offset,
&glyph_tex_rect);
else
gsk_gpu_colorize_op (self->frame,
gsk_gpu_clip_get_shader_clip2 (&self->clip, &g_ofs, &glyph_bounds),
gsk_gpu_clip_get_shader_clip (&self->clip, &glyph_offset, &glyph_bounds),
self->desc,
descriptor,
&GRAPHENE_RECT_INIT (box_x0 (glyph_bounds), box_y0 (glyph_bounds), box_width (glyph_bounds), box_height (glyph_bounds)),
&GRAPHENE_POINT_INIT (point_x (glyph_origin), point_y (glyph_origin)),
&GRAPHENE_RECT_INIT (box_x0 (glyph_tex_rect), box_y0 (glyph_tex_rect), box_width (glyph_tex_rect), box_height (glyph_tex_rect)),
&glyph_bounds,
&glyph_offset,
&glyph_tex_rect,
&color);
offset = point_add (offset, point (glyphs[i].geometry.width / (float)PANGO_SCALE, 0));
offset.x += (float) glyphs[i].geometry.width / PANGO_SCALE;
}
}
@@ -3092,10 +3051,10 @@ gsk_gpu_node_processor_create_glyph_pattern (GskGpuPatternWriter *self,
PangoFont *font;
guint num_glyphs;
gsize i;
Scale scale, pango_scale;
float scale, inv_scale;
guint32 tex_id;
GskGpuImage *last_image;
Point offset;
graphene_point_t offset;
if (gsk_text_node_has_color_glyphs (node))
return FALSE;
@@ -3104,11 +3063,12 @@ gsk_gpu_node_processor_create_glyph_pattern (GskGpuPatternWriter *self,
num_glyphs = gsk_text_node_get_num_glyphs (node);
glyphs = gsk_text_node_get_glyphs (node, NULL);
font = gsk_text_node_get_font (node);
offset = *gsk_text_node_get_offset (node);
offset.x += self->offset.x;
offset.y += self->offset.y;
offset = point_add (point_from_graphene (gsk_text_node_get_offset (node)),
point_from_graphene (&self->offset));
scale = scale_max (scale_from_graphene (&self->scale));
pango_scale = scale_from_float (PANGO_SCALE);
scale = MAX (graphene_vec2_get_x (&self->scale), graphene_vec2_get_y (&self->scale));
inv_scale = 1.f / scale;
gsk_gpu_pattern_writer_append_uint (self, GSK_GPU_PATTERN_GLYPHS);
gsk_gpu_pattern_writer_append_rgba (self, gsk_text_node_get_color (node));
@@ -3118,20 +3078,17 @@ gsk_gpu_node_processor_create_glyph_pattern (GskGpuPatternWriter *self,
for (i = 0; i < num_glyphs; i++)
{
GskGpuImage *image;
graphene_rect_t glyph_bds;
graphene_point_t glyph_ofs;
Point glyph_offset;
Box glyph_bounds;
Box glyph_tex_rect;
graphene_rect_t glyph_bounds;
graphene_point_t glyph_offset;
image = gsk_gpu_device_lookup_glyph_image (device,
self->frame,
font,
glyphs[i].glyph,
0,
scale_x (scale),
&glyph_bds,
&glyph_ofs);
scale,
&glyph_bounds,
&glyph_offset);
if (image != last_image)
{
@@ -3141,15 +3098,28 @@ gsk_gpu_node_processor_create_glyph_pattern (GskGpuPatternWriter *self,
last_image = image;
}
glyph_offset = point_add (point_sub (offset, point_div (glyph_offset, scale)), point_div (point (glyphs[i].geometry.x_offset, glyphs[i].geometry.y_offset), pango_scale));
glyph_offset = GRAPHENE_POINT_INIT (offset.x - glyph_offset.x * inv_scale + (float) glyphs[i].geometry.x_offset / PANGO_SCALE,
offset.y - glyph_offset.y * inv_scale + (float) glyphs[i].geometry.y_offset / PANGO_SCALE);
glyph_bounds = box_div (box_from_rect (0, 0, glyph_bds.size.width, glyph_bds.size.height), scale);
glyph_tex_rect = box_div (box_from_rect (-glyph_bds.origin.x, - glyph_bds.origin.y, gsk_gpu_image_get_width (image), gsk_gpu_image_get_height (image)), scale);
gsk_gpu_pattern_writer_append_uint (self, tex_id);
gsk_gpu_pattern_writer_append_box (self, glyph_bounds, glyph_offset);
gsk_gpu_pattern_writer_append_box (self, glyph_tex_rect, glyph_offset);
gsk_gpu_pattern_writer_append_rect (self,
&GRAPHENE_RECT_INIT (
0,
0,
glyph_bounds.size.width * inv_scale,
glyph_bounds.size.height * inv_scale
),
&glyph_offset);
gsk_gpu_pattern_writer_append_rect (self,
&GRAPHENE_RECT_INIT (
- glyph_bounds.origin.x * inv_scale,
- glyph_bounds.origin.y * inv_scale,
gsk_gpu_image_get_width (image) * inv_scale,
gsk_gpu_image_get_height (image) * inv_scale
),
&glyph_offset);
offset = point_add (offset, point (glyphs[i].geometry.width / (float)PANGO_SCALE, 0));
offset.x += (float) glyphs[i].geometry.width / PANGO_SCALE;
}
return TRUE;
@@ -3277,8 +3247,8 @@ gsk_gpu_node_processor_repeat_tile (GskGpuNodeProcessor *self,
rect,
&self->offset,
&GRAPHENE_RECT_INIT (
clipped_child_bounds.origin.x + x * child_bounds->size.width,
clipped_child_bounds.origin.y + y * child_bounds->size.height,
clipped_child_bounds.origin.x - x * child_bounds->size.width,
clipped_child_bounds.origin.y - y * child_bounds->size.height,
clipped_child_bounds.size.width,
clipped_child_bounds.size.height
));
-1
View File
@@ -30,7 +30,6 @@ static const GdkDebugKey gsk_gpu_optimization_keys[] = {
{ "blit", GSK_GPU_OPTIMIZE_BLIT, "Use shaders instead of vkCmdBlit()/glBlitFramebuffer()" },
{ "gradients", GSK_GPU_OPTIMIZE_GRADIENTS, "Don't supersample gradients" },
{ "mipmap", GSK_GPU_OPTIMIZE_MIPMAP, "Avoid creating mipmaps" },
{ "glyph-align", GSK_GPU_OPTIMIZE_GLYPH_ALIGN, "Never align glyphs to the subpixel grid" },
{ "gl-baseinstance", GSK_GPU_OPTIMIZE_GL_BASE_INSTANCE, "Assume no ARB/EXT_base_instance support" },
};
+1 -2
View File
@@ -117,8 +117,7 @@ typedef enum {
GSK_GPU_OPTIMIZE_BLIT = 1 << 3,
GSK_GPU_OPTIMIZE_GRADIENTS = 1 << 4,
GSK_GPU_OPTIMIZE_MIPMAP = 1 << 5,
GSK_GPU_OPTIMIZE_GLYPH_ALIGN = 1 << 6,
/* These require hardware support */
GSK_GPU_OPTIMIZE_GL_BASE_INSTANCE = 1 << 7,
GSK_GPU_OPTIMIZE_GL_BASE_INSTANCE = 1 << 6,
} GskGpuOptimizations;
-17
View File
@@ -132,20 +132,3 @@ gsk_rect_round_larger (graphene_rect_t *rect)
ceil (rect->origin.y + rect->size.height) - y);
}
static inline void
gsk_rect_scale (const graphene_rect_t *r,
float sx,
float sy,
graphene_rect_t *res)
{
if (G_UNLIKELY (sx < 0 || sy < 0))
{
graphene_rect_scale (r, sx, sy, res);
return;
}
res->origin.x = r->origin.x * sx;
res->origin.y = r->origin.y * sy;
res->size.width = r->size.width * sx;
res->size.height = r->size.height * sy;
}
-7
View File
@@ -3335,7 +3335,6 @@ gsk_container_node_new (GskRenderNode **children,
self->children = g_malloc_n (n_children, sizeof (GskRenderNode *));
self->children[0] = gsk_render_node_ref (children[0]);
node->offscreen_for_opacity = children[0]->offscreen_for_opacity;
gsk_rect_init_from_rect (&bounds, &(children[0]->bounds));
node->preferred_depth = gdk_memory_depth_merge (node->preferred_depth,
gsk_render_node_get_preferred_depth (children[0]));
@@ -4092,7 +4091,6 @@ gsk_repeat_node_draw_tiled (cairo_t *cr,
const graphene_rect_t *child_bounds)
{
cairo_pattern_t *pattern;
cairo_matrix_t matrix;
cairo_save (cr);
/* reset the clip so we get an unclipped pattern for repeating */
@@ -4109,11 +4107,6 @@ gsk_repeat_node_draw_tiled (cairo_t *cr,
cairo_restore (cr);
cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
cairo_pattern_get_matrix (pattern, &matrix);
cairo_matrix_translate (&matrix,
- x * child_bounds->size.width,
- y * child_bounds->size.height);
cairo_pattern_set_matrix (pattern, &matrix);
cairo_set_source (cr, pattern);
cairo_pattern_destroy (pattern);
+73 -90
View File
@@ -981,7 +981,7 @@ ensure_fontmap (Context *context)
g_object_set_data_full (G_OBJECT (context->fontmap), "font-files", files, (GDestroyNotify) g_ptr_array_unref);
}
static gboolean
static void
add_font_from_file (Context *context,
const char *path,
GError **error)
@@ -997,7 +997,7 @@ add_font_from_file (Context *context,
GTK_CSS_PARSER_ERROR,
GTK_CSS_PARSER_ERROR_FAILED,
"Custom fonts are not implemented for %s", G_OBJECT_TYPE_NAME (context->fontmap));
return FALSE;
return;
}
config = pango_fc_font_map_get_config (PANGO_FC_FONT_MAP (context->fontmap));
@@ -1006,20 +1006,18 @@ add_font_from_file (Context *context,
{
g_set_error (error,
GTK_CSS_PARSER_ERROR,
GTK_CSS_PARSER_ERROR_UNKNOWN_VALUE,
"Failed to load font");
return FALSE;
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));
return TRUE;
}
static gboolean
static void
add_font_from_bytes (Context *context,
GBytes *bytes,
GError **error)
@@ -1027,11 +1025,10 @@ add_font_from_bytes (Context *context,
GFile *file;
GIOStream *iostream;
GOutputStream *ostream;
gboolean result;
file = g_file_new_tmp ("gtk4-font-XXXXXX.ttf", (GFileIOStream **) &iostream, error);
if (!file)
return FALSE;
return;
ostream = g_io_stream_get_output_stream (iostream);
if (g_output_stream_write_bytes (ostream, bytes, NULL, error) == -1)
@@ -1039,22 +1036,20 @@ add_font_from_bytes (Context *context,
g_object_unref (file);
g_object_unref (iostream);
return FALSE;
return;
}
g_io_stream_close (iostream, NULL, NULL);
g_object_unref (iostream);
result = add_font_from_file (context, g_file_peek_path (file), error);
add_font_from_file (context, g_file_peek_path (file), error);
g_object_unref (file);
return result;
}
#else /* !HAVE_PANGOFT */
static gboolean
static void
add_font_from_bytes (Context *context,
GBytes *bytes,
GError **error)
@@ -1063,7 +1058,6 @@ add_font_from_bytes (Context *context,
GTK_CSS_PARSER_ERROR,
GTK_CSS_PARSER_ERROR_FAILED,
"Not implemented");
return FALSE;
}
#endif
@@ -1074,105 +1068,94 @@ parse_font (GtkCssParser *parser,
gpointer out_font)
{
PangoFont *font = NULL;
char *font_name;
char *s;
GtkCssLocation start_location;
PangoFontMap *fontmap;
font_name = gtk_css_parser_consume_string (parser);
if (font_name == NULL)
fontmap = pango_cairo_font_map_get_default ();
s = gtk_css_parser_consume_string (parser);
if (s == NULL)
return FALSE;
if (context->fontmap)
font = font_from_string (context->fontmap, font_name);
start_location = *gtk_css_parser_get_start_location (parser);
if (gtk_css_parser_has_url (parser))
if (gtk_css_parser_try_token (parser, GTK_CSS_TOKEN_URL) ||
gtk_css_parser_has_function (parser, "url"))
{
char *url;
char *scheme;
GBytes *bytes = NULL;
GError *error = NULL;
if (font != NULL)
/* If we have a url, it is a bug if the font already exists in our custom fontmap */
if (context->fontmap)
{
gtk_css_parser_error_value (parser, "A font with this name already exists.");
/* consume the url to avoid more errors */
url = gtk_css_parser_consume_url (parser);
g_free (url);
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
{
char *scheme;
GBytes *bytes;
GError *error = NULL;
GtkCssLocation start_location;
gboolean success = FALSE;
GFile *file;
start_location = *gtk_css_parser_get_start_location (parser);
url = gtk_css_parser_consume_url (parser);
file = g_file_new_for_uri (url);
bytes = g_file_load_bytes (file, NULL, NULL, &error);
g_object_unref (file);
}
if (url != NULL)
{
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;
g_free (scheme);
g_free (url);
file = g_file_new_for_uri (url);
bytes = g_file_load_bytes (file, NULL, NULL, &error);
g_object_unref (file);
}
if (bytes)
{
add_font_from_bytes (context, bytes, &error);
g_bytes_unref (bytes);
g_free (scheme);
g_free (url);
if (bytes != NULL)
{
success = add_font_from_bytes (context, bytes, &error);
g_bytes_unref (bytes);
}
fontmap = context->fontmap;
}
else
{
g_assert (error != NULL);
if (!success)
{
gtk_css_parser_emit_error (parser,
&start_location,
gtk_css_parser_get_end_location (parser),
error);
}
}
gtk_css_parser_emit_error (parser,
&start_location,
gtk_css_parser_get_end_location (parser),
error);
g_clear_error (&error);
if (success)
{
font = font_from_string (context->fontmap, font_name);
if (!font)
{
gtk_css_parser_error (parser,
GTK_CSS_PARSER_ERROR_UNKNOWN_VALUE,
&start_location,
gtk_css_parser_get_end_location (parser),
"The given url does not define a font named \"%s\"",
font_name);
}
}
return FALSE;
}
}
else
{
if (!font)
font = font_from_string (pango_cairo_font_map_get_default (), font_name);
if (!font)
gtk_css_parser_error_value (parser, "The font \"%s\" does not exist", font_name);
}
font = font_from_string (fontmap, s);
g_free (font_name);
if (!font && context->fontmap && fontmap != context->fontmap)
font = font_from_string (context->fontmap, s);
if (font)
{
*((PangoFont**)out_font) = font;
return TRUE;
}
else
if (!font)
{
gtk_css_parser_error_value (parser, "This font does not exist.");
return FALSE;
}
*((PangoFont**)out_font) = font;
g_free (s);
return TRUE;
}
static void
+2 -2
View File
@@ -311,8 +311,8 @@ gsk_rounded_rect_scale_affine (GskRoundedRect *dest,
graphene_rect_scale (&src->bounds, scale_x, scale_y, &dest->bounds);
graphene_rect_offset (&dest->bounds, dx, dy);
scale_x = fabsf (scale_x);
scale_y = fabsf (scale_y);
scale_x = fabs (scale_x);
scale_y = fabs (scale_y);
for (guint i = 0; i < 4; i++)
{
-22
View File
@@ -1,22 +0,0 @@
/* GSK - The GTK Scene Kit
* Copyright 2024 Red Hat, Inc.
*
* This library 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.
*
* This library 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 this library. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
typedef struct _Scale Scale;
typedef struct _Point Point;
typedef struct _Box Box;
-252
View File
@@ -1,252 +0,0 @@
#pragma once
#include "gsktypesprivate.h"
#include <graphene.h>
#include <math.h>
#include <smmintrin.h>
#include "scaleprivate.h"
#ifndef USE_SIMD
struct _Point
{
float x, y;
};
static inline float
point_x (const Point p)
{
return p.x;
}
static inline float
point_y (const Point p)
{
return p.y;
}
static inline Point
point (float x,
float y)
{
return (Point) { .x = x, .y = y };
}
static inline Point
point_from_graphene (const graphene_point_t *p)
{
return point (p->x, p->y);
}
static inline void
point_to_float (const Point p,
float v[2])
{
v[0] = p.x;
v[1] = p.y;
}
static inline Point
point_zero (void)
{
return point (0, 0);
}
static inline Point
point_neg (const Point p)
{
return (Point) { .x = -p.x, .y = -p.y };
}
static inline Point
point_mul (const Point p,
const Scale s)
{
return (Point) { .x = p.x * s.x, .y = p.y * s.y };
}
static inline Point
point_div (const Point p,
const Scale s)
{
return (Point) { .x = p.x / s.x, .y = p.y / s.y };
}
static inline Point
point_add (const Point p1,
const Point p2)
{
return (Point) { .x = p1.x + p2.x, .y = p1.y + p2.y };
}
static inline Point
point_sub (const Point p1,
const Point p2)
{
return (Point) { .x = p1.x - p2.x, .y = p1.y - p2.y };
}
static inline Point
point_floor (const Point p)
{
return (Point) { .x = floorf (p.x), .y = floorf (p.y) };
}
static inline Point
point_ceil (const Point p)
{
return (Point) { .x = ceilf (p.x), .y = ceilf (p.y) };
}
static inline Point
point_round (const Point p)
{
return (Point) { .x = roundf (p.x), .y = roundf (p.y) };
}
#else /* USE_SIMD */
#include <smmintrin.h>
struct _Point
{
GRAPHENE_ALIGNED_DECL (graphene_simd4f_t v, 16);
};
static inline float
point_x (const Point p)
{
return graphene_simd4f_get_x (p.v);
}
static inline float
point_y (const Point p)
{
return graphene_simd4f_get_y (p.v);
}
static inline Point
point (float x,
float y)
{
return (Point) { .v = graphene_simd4f_init (x, y, 0.f, 0.f) };
}
static inline Point
point_from_graphene (const graphene_point_t *p)
{
return point (p->x, p->y);
}
static inline void
point_to_float (const Point p,
float v[2])
{
graphene_simd4f_dup_2f (p.v, v);
}
static inline Point
point_zero (void)
{
return point (0, 0);
}
static inline Point
point_neg (const Point p)
{
return (Point) { .v = graphene_simd4f_neg (p.v) };
}
static inline Point
point_mul (const Point p,
const Scale s)
{
return (Point) { .v = graphene_simd4f_mul (p.v, s.v) };
}
static inline Point
point_div (const Point p,
const Scale s)
{
return (Point) { .v = graphene_simd4f_div (p.v, s.v) };
}
static inline Point
point_add (const Point p1,
const Point p2)
{
return (Point) { .v = graphene_simd4f_add (p1.v, p2.v) };
}
static inline Point
point_sub (const Point p1,
const Point p2)
{
return (Point) { .v = graphene_simd4f_sub (p1.v, p2.v) };
}
#ifdef __SSE4_1__
#ifndef graphene_simd4f_floor
# define graphene_simd4f_floor(v) \
(__extension__ ({ \
(graphene_simd4f_t) _mm_floor_ps ((v)); \
}))
#endif
#ifndef graphene_simd4f_ceil
# define graphene_simd4f_ceil(v) \
(__extension__ ({ \
(graphene_simd4f_t) _mm_ceil_ps ((v)); \
}))
#endif
#ifndef graphene_simd4f_round
# define graphene_simd4f_round(v) \
(__extension__ ({ \
(graphene_simd4f_t) _mm_round_ps ((v)); \
}))
#endif
static inline Point
point_floor (const Point p)
{
return (Point) { .v = graphene_simd4f_floor (p.v) };
}
static inline Point
point_ceil (const Point p)
{
return (Point) { .v = graphene_simd4f_ceil (p.v) };
}
static inline Point
point_round (const Point p)
{
return (Point) { .v = graphene_simd4f_round (p.v) };
}
#else
static inline Point
point_floor (const Point p)
{
return point (floorf (point_x (p)), floorf (point_y (p)));
}
static inline Point
point_ceil (const Point p)
{
return point (ceilf (point_x (p)), ceilf (point_y (p)));
}
static inline Point
point_round (const Point p)
{
return point (roundf (point_x (p)), roundf (point_y (p)));
}
#endif
#endif
-183
View File
@@ -1,183 +0,0 @@
#pragma once
#include "gsktypesprivate.h"
#include <graphene.h>
#include <math.h>
#ifndef USE_SIMD
struct _Scale
{
float x, y;
};
static inline float
scale_x (const Scale s)
{
return s.x;
}
static inline float
scale_y (const Scale s)
{
return s.y;
}
static inline Scale
scale (float x,
float y)
{
return (Scale) { .x = x, .y = y };
}
static inline Scale
scale_from_float (float s)
{
return scale (s, s);
}
static inline Scale
scale_from_graphene (const graphene_vec2_t *v)
{
return (Scale) { .x = graphene_vec2_get_x (v), .y = graphene_vec2_get_y (v) };
}
static inline void
scale_to_float (const Scale s,
float v[2])
{
v[0] = s.x;
v[1] = s.y;
}
static inline gboolean
scale_equal (const Scale s1,
const Scale s2)
{
return (gboolean) (s1.x == s2.x && s1.y == s2.y);
}
static inline Scale
scale_one (void)
{
return scale (1, 1);
}
static inline Scale
scale_inv (const Scale s)
{
return (Scale) { .x = 1 / s.x, .y = 1 / s.y };
}
static inline Scale
scale_mul (const Scale s1,
const Scale s2)
{
return (Scale) { .x = s1.x * s2.x, .y = s1.y * s2.y };
}
static inline Scale
scale_div (const Scale s1,
const Scale s2)
{
return (Scale) { .x = s1.x / s2.x, .y = s1.y / s2.y };
}
static inline Scale
scale_max (const Scale s)
{
return (Scale) { .x = MAX (s.x, s.y), .y = MAX (s.x, s.y) };
}
#else /* USE_SIMD */
struct _Scale
{
GRAPHENE_ALIGNED_DECL (graphene_simd4f_t v, 16);
};
static inline float
scale_x (const Scale s)
{
return graphene_simd4f_get_x (s.v);
}
static inline float
scale_y (const Scale s)
{
return graphene_simd4f_get_y (s.v);
}
static inline Scale
scale (float x,
float y)
{
return (Scale) { .v = graphene_simd4f_init (x, y, 0.f, 0.f) };
}
static inline Scale
scale_from_float (float s)
{
return scale (s, s);
}
static inline Scale
scale_from_graphene (const graphene_vec2_t *v)
{
return (Scale) { .v = v->__graphene_private_value };
}
static inline void
scale_to_float (const Scale s,
float v[2])
{
graphene_simd4f_dup_2f (s.v, v);
}
static inline gboolean
scale_equal (const Scale s1,
const Scale s2)
{
return (gboolean) graphene_simd4f_cmp_eq (s1.v, s2.v);
}
static inline Scale
scale_one (void)
{
return scale (1, 1);
}
static inline Scale
scale_inv (const Scale s)
{
return (Scale) { .v = graphene_simd4f_reciprocal (s.v) };
}
static inline Scale
scale_mul (const Scale s1,
const Scale s2)
{
return (Scale) { .v = graphene_simd4f_mul (s1.v, s2.v) };
}
static inline Scale
scale_div (const Scale s1,
const Scale s2)
{
return (Scale) { .v = graphene_simd4f_div (s1.v, s2.v) };
}
#ifndef graphene_simd4f_shuffle_yxzw
# define graphene_simd4f_shuffle_yxzw(v) \
(__extension__ ({ \
(graphene_simd4f_t) _mm_shuffle_ps ((v), (v), _MM_SHUFFLE (3, 2, 0, 1)); \
}))
#endif
static inline Scale
scale_max (const Scale s)
{
return (Scale) { .v = graphene_simd4f_max (graphene_simd4f_shuffle_yxzw (s.v), s.v) };
}
#endif
-8
View File
@@ -957,14 +957,6 @@ gtk_css_parser_parse_url_arg (GtkCssParser *parser,
return 1;
}
gboolean
gtk_css_parser_has_url (GtkCssParser *self)
{
return gtk_css_parser_has_token (self, GTK_CSS_TOKEN_URL)
|| gtk_css_parser_has_token (self, GTK_CSS_TOKEN_BAD_URL)
|| gtk_css_parser_has_function (self, "url");
}
/**
* gtk_css_parser_consume_url:
* @self: a `GtkCssParser`
-1
View File
@@ -116,7 +116,6 @@ gboolean gtk_css_parser_has_token (GtkCssParser
GtkCssTokenType token_type);
gboolean gtk_css_parser_has_ident (GtkCssParser *self,
const char *ident);
gboolean gtk_css_parser_has_url (GtkCssParser *self);
gboolean gtk_css_parser_has_number (GtkCssParser *self);
gboolean gtk_css_parser_has_integer (GtkCssParser *self);
gboolean gtk_css_parser_has_function (GtkCssParser *self,
+1 -1
View File
@@ -403,7 +403,7 @@ gtk_file_chooser_set_current_folder (GtkFileChooser *chooser,
GError **error)
{
g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), FALSE);
g_return_val_if_fail (file == NULL || G_IS_FILE (file), FALSE);
g_return_val_if_fail (G_IS_FILE (file), FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
return GTK_FILE_CHOOSER_GET_IFACE (chooser)->set_current_folder (chooser, file, error);
+2 -2
View File
@@ -257,14 +257,14 @@ gtk_application_startup (GApplication *g_application)
before2 = GDK_PROFILER_CURRENT_TIME;
gtk_init ();
gdk_profiler_end_mark (before2, "gtk_init", NULL);
gdk_profiler_end_mark (before2, "gtk init", NULL);
priv->impl = gtk_application_impl_new (application, gdk_display_get_default ());
gtk_application_impl_startup (priv->impl, priv->register_session);
gtk_application_load_resources (application);
gdk_profiler_end_mark (before, "Application startup", NULL);
gdk_profiler_end_mark (before, "gtk application startup", NULL);
}
static void
+1 -1
View File
@@ -2251,7 +2251,7 @@ _gtk_builder_parser_parse_buffer (GtkBuilder *builder,
guint64 after = GDK_PROFILER_CURRENT_TIME;
if (after - before > 500000) /* half a millisecond */
{
gdk_profiler_add_mark (before, after - before, "Builder load", filename);
gdk_profiler_add_mark (before, after - before, "builder load", filename);
}
}
}
+1 -1
View File
@@ -1363,7 +1363,7 @@ gtk_css_node_validate (GtkCssNode *cssnode)
if (GDK_PROFILER_IS_RUNNING)
{
gdk_profiler_end_mark (before, "Validate CSS", "");
gdk_profiler_end_mark (before, "css validation", "");
gdk_profiler_set_int_counter (invalidated_nodes_counter, invalidated_nodes);
gdk_profiler_set_int_counter (created_styles_counter, created_styles);
invalidated_nodes = 0;
+2 -2
View File
@@ -1016,7 +1016,7 @@ gtk_css_provider_postprocess (GtkCssProvider *css_provider)
}
#endif
gdk_profiler_end_mark (before, "Create CSS selector tree", NULL);
gdk_profiler_end_mark (before, "create selector tree", NULL);
}
static void
@@ -1081,7 +1081,7 @@ gtk_css_provider_load_internal (GtkCssProvider *self,
if (GDK_PROFILER_IS_RUNNING)
{
char *uri = g_file_get_uri (file);
gdk_profiler_end_mark (before, "CSS theme load", uri);
gdk_profiler_end_mark (before, "theme load", uri);
g_free (uri);
}
}
+2 -2
View File
@@ -75,7 +75,7 @@
*
* // This widget accepts two types of drop types: GFile objects
* // and GdkPixbuf objects
* gtk_drop_target_set_gtypes (target, (GType [2]) {
* gtk_drop_target_set_gtypes (target, (GTypes [2]) {
* G_TYPE_FILE,
* GDK_TYPE_PIXBUF,
* }, 2);
@@ -935,7 +935,7 @@ gtk_drop_target_get_formats (GtkDropTarget *self)
* that can be dropped on the target
* @n_types: number of @types
*
* Sets the supported `GType`s for this drop target.
* Sets the supported `GTypes` for this drop target.
*/
void
gtk_drop_target_set_gtypes (GtkDropTarget *self,
+2 -2
View File
@@ -761,7 +761,7 @@ populate_emoji_chooser (gpointer data)
now = g_get_monotonic_time ();
if (now > start + 200) /* 2 ms */
{
gdk_profiler_add_mark (start * 1000, (now - start) * 1000, "Emojichooser populate", NULL);
gdk_profiler_add_mark (start * 1000, (now - start) * 1000, "emojichooser", "populate");
return G_SOURCE_CONTINUE;
}
}
@@ -771,7 +771,7 @@ populate_emoji_chooser (gpointer data)
chooser->box = NULL;
chooser->populate_idle = 0;
gdk_profiler_end_mark (start, "Emojichooser populate (finish)", NULL);
gdk_profiler_end_mark (start, "emojichooser", "populate (finish)");
return G_SOURCE_REMOVE;
}
-9
View File
@@ -44,15 +44,6 @@ void gtk_graphics_offload_set_child (GtkGraphicsOffload *
GDK_AVAILABLE_IN_4_14
GtkWidget * gtk_graphics_offload_get_child (GtkGraphicsOffload *self);
/**
* GtkGraphicsOffloadEnabled:
* @GTK_GRAPHICS_OFFLOAD_ENABLED: Graphics offloading is enabled.
* @GTK_GRAPHICS_OFFLOAD_DISABLED: Graphics offloading is disabled.
*
* Represents the state of graphics offlodading.
*
* Since: 4.14
*/
typedef enum
{
GTK_GRAPHICS_OFFLOAD_ENABLED,
+2 -2
View File
@@ -2069,7 +2069,7 @@ ensure_valid_themes (GtkIconTheme *self,
load_themes (self);
gdk_profiler_end_mark (before, "Icon theme load", self->current_theme);
gdk_profiler_end_mark (before, "icon theme load", self->current_theme);
if (was_valid)
queue_theme_changed (self);
@@ -3822,7 +3822,7 @@ icon_ensure_texture__locked (GtkIconPaintable *icon,
/* Don't report quick (< 0.5 msec) parses */
if (end - before > 500000 || !in_thread)
{
gdk_profiler_add_markf (before, (end - before), in_thread ? "Icon load (thread)" : "Icon load" ,
gdk_profiler_add_markf (before, (end - before), in_thread ? "icon load (thread)" : "icon load" ,
"%s size %d@%d", icon->filename, icon->desired_size, icon->desired_scale);
}
}
+1 -1
View File
@@ -353,7 +353,7 @@ init_compose_table_thread_cb (GTask *task,
g_task_return_boolean (task, TRUE);
gdk_profiler_end_mark (before, "Compose table load (thread)", NULL);
gdk_profiler_end_mark (before, "im compose table load (thread)", NULL);
}
static void
+3 -3
View File
@@ -549,7 +549,7 @@ do_post_parse_initialization (void)
gsk_render_node_init_types ();
_gtk_ensure_resources ();
gdk_profiler_end_mark (before, "Basic initialization", NULL);
gdk_profiler_end_mark (before, "basic initialization", NULL);
gtk_initialized = TRUE;
@@ -559,13 +559,13 @@ do_post_parse_initialization (void)
#endif
gtk_im_modules_init ();
gtk_media_file_extension_init ();
gdk_profiler_end_mark (before, "Init modules", NULL);
gdk_profiler_end_mark (before, "init modules", NULL);
before = GDK_PROFILER_CURRENT_TIME;
display_manager = gdk_display_manager_get ();
if (gdk_display_manager_get_default_display (display_manager) != NULL)
default_display_notify_cb (display_manager);
gdk_profiler_end_mark (before, "Create display", NULL);
gdk_profiler_end_mark (before, "create display", NULL);
g_signal_connect (display_manager, "notify::default-display",
G_CALLBACK (default_display_notify_cb),
+2 -2
View File
@@ -11956,7 +11956,7 @@ gtk_widget_render (GtkWidget *widget,
if (GDK_PROFILER_IS_RUNNING)
{
before_render = GDK_PROFILER_CURRENT_TIME;
gdk_profiler_add_mark (before_snapshot, (before_render - before_snapshot), "Widget snapshot", "");
gdk_profiler_add_mark (before_snapshot, (before_render - before_snapshot), "widget snapshot", "");
}
if (root != NULL)
@@ -11972,7 +11972,7 @@ gtk_widget_render (GtkWidget *widget,
gsk_render_node_unref (root);
gdk_profiler_end_mark (before_render, "Widget render", "");
gdk_profiler_end_mark (before_render, "widget render", "");
}
}
+1 -1
View File
@@ -159,7 +159,7 @@
</object>
</child>
<child>
<object class="GtkCheckButton" id="verbose">
<object class="GtkCheckButton" id="verboe">
<property name="label">Verbose</property>
<signal name="toggled" handler="flag_toggled"/>
</object>
+78 -86
View File
@@ -22,9 +22,9 @@ msgid ""
msgstr ""
"Project-Id-Version: gtk master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gtk/-/issues/\n"
"POT-Creation-Date: 2023-11-18 03:13+0000\n"
"POT-Creation-Date: 2023-09-19 01:36+0000\n"
"PO-Revision-Date: 2023-09-19 18:38+0200\n"
"Last-Translator: AesirIvy <aesir.ivy@gmx.com>\n"
"Last-Translator: Guillaume Bernard <associations@guillaume-bernard.fr>\n"
"Language-Team: GNOME French Team <gnomefr@traduc.org>\n"
"Language: fr\n"
"MIME-Version: 1.0\n"
@@ -61,59 +61,59 @@ msgstr "Impossible de fournir le contenu comme « %s »"
msgid "Cannot provide contents as %s"
msgstr "Impossible de fournir le contenu comme %s"
#: gdk/gdkdisplay.c:156 gdk/gdkglcontext.c:443
#: gdk/gdkdisplay.c:156 gdk/gdkglcontext.c:442
msgid "The current backend does not support OpenGL"
msgstr "Le moteur actuel ne gère pas OpenGL"
#: gdk/gdkdisplay.c:1244 gdk/gdksurface.c:1252
#: gdk/gdkdisplay.c:1245 gdk/gdksurface.c:1252
msgid "Vulkan support disabled via GDK_DEBUG"
msgstr "Prise en charge de Vulkan désactivée via GDK_DEBUG"
#: gdk/gdkdisplay.c:1276
#: gdk/gdkdisplay.c:1277
msgid "GL support disabled via GDK_DEBUG"
msgstr "Prise en charge de GL désactivée via GDK_DEBUG"
#: gdk/gdkdisplay.c:1574
#: gdk/gdkdisplay.c:1575
msgid "No EGL configuration available"
msgstr "Aucune configuration EGL disponible"
#: gdk/gdkdisplay.c:1582
#: gdk/gdkdisplay.c:1583
msgid "Failed to get EGL configurations"
msgstr "Impossible dobtenir les configurations EGL"
#: gdk/gdkdisplay.c:1612
#: gdk/gdkdisplay.c:1613
msgid "No EGL configuration with required features found"
msgstr ""
"Aucune configuration EGL avec les fonctionnalités requises na été trouvée"
#: gdk/gdkdisplay.c:1619
#: gdk/gdkdisplay.c:1620
msgid "No perfect EGL configuration found"
msgstr "Aucune configuration EGL idéale trouvée"
#: gdk/gdkdisplay.c:1661
#: gdk/gdkdisplay.c:1662
#, c-format
msgid "EGL implementation is missing extension %s"
msgid_plural "EGL implementation is missing %2$d extensions: %1$s"
msgstr[0] "Lextension %s manque dans limplémentation EGL"
msgstr[1] "%2$d extensions manquent dans limplémentation EGL : %1$s"
#: gdk/gdkdisplay.c:1694
#: gdk/gdkdisplay.c:1695
msgid "libEGL not available in this sandbox"
msgstr "libEGL nest pas disponible dans ce bac à sable"
#: gdk/gdkdisplay.c:1695
#: gdk/gdkdisplay.c:1696
msgid "libEGL not available"
msgstr "libEGL non disponible"
#: gdk/gdkdisplay.c:1705
#: gdk/gdkdisplay.c:1706
msgid "Failed to create EGL display"
msgstr "Impossible de créer laffichage EGL"
#: gdk/gdkdisplay.c:1715
#: gdk/gdkdisplay.c:1716
msgid "Could not initialize EGL display"
msgstr "Impossible dinitialiser laffichage EGL"
#: gdk/gdkdisplay.c:1726
#: gdk/gdkdisplay.c:1727
#, c-format
msgid "EGL version %d.%d is too old. GTK requires %d.%d"
msgstr "La version %d.%d dEGL est trop ancienne. GTK requiert %d.%d"
@@ -127,33 +127,33 @@ msgstr ""
msgid "No compatible formats to transfer contents."
msgstr "Aucun format compatible pour le transfert du contenu."
#: gdk/gdkglcontext.c:402 gdk/x11/gdkglcontext-glx.c:642
#: gdk/gdkglcontext.c:401 gdk/x11/gdkglcontext-glx.c:642
msgid "No GL API allowed."
msgstr "Aucune API GL autorisée."
#: gdk/gdkglcontext.c:426 gdk/win32/gdkglcontext-win32-wgl.c:387
#: gdk/gdkglcontext.c:425 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 "Impossible de créer un contexte GL"
#: gdk/gdkglcontext.c:1281
#: gdk/gdkglcontext.c:1280
msgid "Anything but OpenGL ES disabled via GDK_DEBUG"
msgstr "Tout sauf OpenGL ES est désactivé via GTK_DEBUG"
#: gdk/gdkglcontext.c:1290
#: gdk/gdkglcontext.c:1289
#, c-format
msgid "Application does not support %s API"
msgstr "Lapplication ne prend pas en charge lAPI %s"
#. translators: This is about OpenGL backend names, like
#. * "Trying to use X11 GLX, but EGL is already in use"
#: gdk/gdkglcontext.c:1899
#: gdk/gdkglcontext.c:1864
#, c-format
msgid "Trying to use %s, but %s is already in use"
msgstr "Tentative dutilisation de %s, mais %s est déjà utilisé"
#: gdk/gdktexture.c:530
#: gdk/gdktexture.c:528
msgid "Unknown image format."
msgstr "Format dimage inconnu."
@@ -752,7 +752,8 @@ msgstr "Aucune implémentation GL disponible"
#: gdk/win32/gdkglcontext-win32-wgl.c:396
#, c-format
msgid "WGL version %d.%d is too low, need at least %d.%d"
msgstr "La version %d.%d dEGL est trop basse, elle doit être au moins à %d.%d"
msgstr ""
"La version %d.%d dEGL est trop basse, elle doit être au moins à %d.%d"
#: gdk/win32/gdkglcontext-win32-wgl.c:414
#, c-format
@@ -1083,18 +1084,18 @@ msgctxt "progress bar label"
msgid "%d%%"
msgstr "%d %%"
#: gtk/deprecated/gtkcolorbutton.c:183 gtk/deprecated/gtkcolorbutton.c:314
#: gtk/deprecated/gtkcolorbutton.c:183 gtk/deprecated/gtkcolorbutton.c:311
#: gtk/gtkcolordialog.c:411
msgid "Pick a Color"
msgstr "Choisissez une couleur"
#: gtk/deprecated/gtkcolorbutton.c:505 gtk/gtkcolorchooserwidget.c:313
#: gtk/deprecated/gtkcolorbutton.c:502 gtk/gtkcolorchooserwidget.c:313
#: gtk/gtkcolordialogbutton.c:335
#, c-format
msgid "Red %d%%, Green %d%%, Blue %d%%, Alpha %d%%"
msgstr "Rouge %d%%, Vert %d%%, Bleu %d%%, Alpha %d%%"
#: gtk/deprecated/gtkcolorbutton.c:511 gtk/gtkcolorchooserwidget.c:319
#: gtk/deprecated/gtkcolorbutton.c:508 gtk/gtkcolorchooserwidget.c:319
#: gtk/gtkcolordialogbutton.c:341
#, c-format
msgid "Red %d%%, Green %d%%, Blue %d%%"
@@ -1104,17 +1105,17 @@ msgstr "Rouge %d%%, Vert %d%%, Bleu %d%%"
msgid "Sans 12"
msgstr "Sans 12"
#: gtk/deprecated/gtkfontbutton.c:507 gtk/deprecated/gtkfontbutton.c:624
#: gtk/deprecated/gtkfontbutton.c:507 gtk/deprecated/gtkfontbutton.c:621
#: gtk/gtkfontdialog.c:596
msgid "Pick a Font"
msgstr "Choisissez une police"
#: gtk/deprecated/gtkfontbutton.c:600 gtk/gtkfilechooserwidget.c:3871
#: gtk/deprecated/gtkfontbutton.c:597 gtk/gtkfilechooserwidget.c:3871
#: gtk/gtkfontdialogbutton.c:126 gtk/inspector/visual.ui:169
msgid "Font"
msgstr "Police"
#: gtk/deprecated/gtkfontbutton.c:1155 gtk/gtkfontdialogbutton.c:652
#: gtk/deprecated/gtkfontbutton.c:1152 gtk/gtkfontdialogbutton.c:652
msgctxt "font"
msgid "None"
msgstr "Aucune"
@@ -2178,7 +2179,7 @@ msgstr "_Droite :"
msgid "Paper Margins"
msgstr "Marges du papier"
#: gtk/gtkentry.c:3685
#: gtk/gtkentry.c:3673
msgid "Insert Emoji"
msgstr "Insérer un émoji"
@@ -2248,7 +2249,7 @@ msgstr "Un fichier avec ce nom existe déjà"
#: 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:6233 gtk/ui/gtkappchooserdialog.ui:48
#: gtk/gtkwindow.c:6242 gtk/ui/gtkappchooserdialog.ui:48
#: gtk/ui/gtkassistant.ui:52 gtk/ui/gtkcolorchooserdialog.ui:36
#: gtk/ui/gtkfontchooserdialog.ui:27
msgid "_Cancel"
@@ -2338,7 +2339,7 @@ msgid "If you delete an item, it will be permanently lost."
msgstr "Si vous supprimez un élément, il sera définitivement perdu."
#: gtk/gtkfilechooserwidget.c:1185 gtk/gtkfilechooserwidget.c:1815
#: gtk/gtklabel.c:5695 gtk/gtktext.c:6147 gtk/gtktextview.c:9018
#: gtk/gtklabel.c:5695 gtk/gtktext.c:6145 gtk/gtktextview.c:9018
msgid "_Delete"
msgstr "_Supprimer"
@@ -2464,7 +2465,6 @@ msgid "Yesterday"
msgstr "Hier"
#: gtk/gtkfilechooserwidget.c:3823
#, c-format
msgid "%-e %b"
msgstr "%-e %b"
@@ -2677,19 +2677,19 @@ msgstr "Fermer"
msgid "Close the infobar"
msgstr "Fermer la barre dinformation"
#: gtk/gtklabel.c:5692 gtk/gtktext.c:6135 gtk/gtktextview.c:9006
#: gtk/gtklabel.c:5692 gtk/gtktext.c:6133 gtk/gtktextview.c:9006
msgid "Cu_t"
msgstr "Co_uper"
#: gtk/gtklabel.c:5693 gtk/gtktext.c:6139 gtk/gtktextview.c:9010
#: gtk/gtklabel.c:5693 gtk/gtktext.c:6137 gtk/gtktextview.c:9010
msgid "_Copy"
msgstr "_Copier"
#: gtk/gtklabel.c:5694 gtk/gtktext.c:6143 gtk/gtktextview.c:9014
#: gtk/gtklabel.c:5694 gtk/gtktext.c:6141 gtk/gtktextview.c:9014
msgid "_Paste"
msgstr "C_oller"
#: gtk/gtklabel.c:5700 gtk/gtktext.c:6156 gtk/gtktextview.c:9039
#: gtk/gtklabel.c:5700 gtk/gtktext.c:6154 gtk/gtktextview.c:9039
msgid "Select _All"
msgstr "_Tout sélectionner"
@@ -2772,7 +2772,7 @@ msgid "Play"
msgstr "Lecture"
#: gtk/gtkmessagedialog.c:162 gtk/gtkmessagedialog.c:180
#: gtk/print/gtkprintbackend.c:639 gtk/gtkwindow.c:6234
#: gtk/print/gtkprintbackend.c:639 gtk/gtkwindow.c:6243
msgid "_OK"
msgstr "_Valider"
@@ -3377,8 +3377,8 @@ msgstr ""
#. window
#: gtk/print/gtkprintoperation-portal.c:264
#: gtk/print/gtkprintoperation-portal.c:594
#: gtk/print/gtkprintoperation-portal.c:663 gtk/print/gtkprintunixdialog.c:3008
#: gtk/print/gtkprintoperation-portal.c:584
#: gtk/print/gtkprintoperation-portal.c:653 gtk/print/gtkprintunixdialog.c:3008
msgid "Print"
msgstr "Imprimer"
@@ -3553,7 +3553,7 @@ msgstr ""
"Impossible de trouver une application enregistrée sous le nom « %s » pour "
"l’élément dont lURI est « %s »"
#: gtk/gtksearchentry.c:767
#: gtk/gtksearchentry.c:758
msgid "Clear Entry"
msgstr "Efface la saisie"
@@ -3644,7 +3644,7 @@ msgctxt "accessibility"
msgid "Sidebar"
msgstr "Panneau latéral"
#: gtk/gtktext.c:6161 gtk/gtktextview.c:9044
#: gtk/gtktext.c:6159 gtk/gtktextview.c:9044
msgid "Insert _Emoji"
msgstr "Insérer un _émoji"
@@ -3656,12 +3656,12 @@ msgstr "Ann_uler"
msgid "_Redo"
msgstr "_Rétablir"
#: gtk/gtkwindow.c:6222
#: gtk/gtkwindow.c:6231
#, c-format
msgid "Do you want to use GTK Inspector?"
msgstr "Voulez-vous utiliser lInspecteur GTK ?"
#: gtk/gtkwindow.c:6224
#: gtk/gtkwindow.c:6233
#, c-format
msgid ""
"GTK Inspector is an interactive debugger that lets you explore and modify "
@@ -3672,7 +3672,7 @@ msgstr ""
"modifier les éléments internes de toute application GTK. Son utilisation "
"peut causer une interruption ou un plantage de lapplication."
#: gtk/gtkwindow.c:6229
#: gtk/gtkwindow.c:6238
msgid "Dont show this message again"
msgstr "Ne plus afficher ce message"
@@ -4024,8 +4024,8 @@ msgid "Surface"
msgstr "Surface"
#: 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
#: gtk/inspector/misc-info.ui:435 gtk/inspector/prop-editor.c:1150
#: gtk/inspector/prop-editor.c:1533 gtk/inspector/window.ui:396
msgid "Properties"
msgstr "Propriétés"
@@ -4077,7 +4077,7 @@ msgstr "Pointeur : %p"
#. Translators: %s is a type name, for example
#. * GtkPropertyExpression with value \"2.5\"
#.
#: gtk/inspector/prop-editor.c:827
#: gtk/inspector/prop-editor.c:824
#, c-format
msgid "%s with value \"%s\""
msgstr "%s avec valeur « %s »"
@@ -4085,7 +4085,7 @@ msgstr "%s avec valeur « %s »"
#. Translators: Both %s are type names, for example
#. * GtkPropertyExpression with type GObject
#.
#: gtk/inspector/prop-editor.c:838
#: gtk/inspector/prop-editor.c:835
#, c-format
msgid "%s with type %s"
msgstr "%s de type %s"
@@ -4093,7 +4093,7 @@ msgstr "%s de type %s"
#. Translators: Both %s are type names, for example
#. * GtkObjectExpression for GtkStringObject 0x23456789
#.
#: gtk/inspector/prop-editor.c:851
#: gtk/inspector/prop-editor.c:848
#, c-format
msgid "%s for %s %p"
msgstr "%s pour %s %p"
@@ -4101,71 +4101,71 @@ msgstr "%s pour %s %p"
#. Translators: Both %s are type names, for example
#. * GtkPropertyExpression with value type: gchararray
#.
#: gtk/inspector/prop-editor.c:881
#: gtk/inspector/prop-editor.c:878
#, c-format
msgid "%s with value type %s"
msgstr "%s avec type de valeur %s"
#: gtk/inspector/prop-editor.c:1230
#: gtk/inspector/prop-editor.c:1227
#, c-format
msgid "Uneditable property type: %s"
msgstr "Type de propriété non éditable : %s"
#: gtk/inspector/prop-editor.c:1388
#: gtk/inspector/prop-editor.c:1385
msgctxt "column number"
msgid "None"
msgstr "Aucun"
#: gtk/inspector/prop-editor.c:1425
#: gtk/inspector/prop-editor.c:1422
msgid "Attribute:"
msgstr "Attribut :"
#: gtk/inspector/prop-editor.c:1428
#: gtk/inspector/prop-editor.c:1425
msgid "Model"
msgstr "Modèle"
#: gtk/inspector/prop-editor.c:1433
#: gtk/inspector/prop-editor.c:1430
msgid "Column:"
msgstr "Colonne :"
#. Translators: %s is a type name, for example
#. * Action from 0x2345678 (GtkApplicationWindow)
#.
#: gtk/inspector/prop-editor.c:1532
#: gtk/inspector/prop-editor.c:1529
#, c-format
msgid "Action from: %p (%s)"
msgstr "Action de : %p (%s)"
#: gtk/inspector/prop-editor.c:1587
#: gtk/inspector/prop-editor.c:1584
msgid "Reset"
msgstr "Réinitialiser"
#: gtk/inspector/prop-editor.c:1595
#: gtk/inspector/prop-editor.c:1592
msgctxt "GtkSettings source"
msgid "Default"
msgstr "Par défaut"
#: gtk/inspector/prop-editor.c:1598
#: gtk/inspector/prop-editor.c:1595
msgctxt "GtkSettings source"
msgid "Theme"
msgstr "Thème"
#: gtk/inspector/prop-editor.c:1601
#: gtk/inspector/prop-editor.c:1598
msgctxt "GtkSettings source"
msgid "XSettings"
msgstr "Paramètres X"
#: gtk/inspector/prop-editor.c:1605
#: gtk/inspector/prop-editor.c:1602
msgctxt "GtkSettings source"
msgid "Application"
msgstr "Application"
#: gtk/inspector/prop-editor.c:1608
#: gtk/inspector/prop-editor.c:1605
msgctxt "GtkSettings source"
msgid "Unknown"
msgstr "Inconnue"
#: gtk/inspector/prop-editor.c:1611
#: gtk/inspector/prop-editor.c:1608
msgid "Source:"
msgstr "Source :"
@@ -7228,7 +7228,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:202 tools/gtk-rendernode-tool-show.c:106
#: tools/gtk-rendernode-tool-info.c:200 tools/gtk-rendernode-tool-show.c:102
msgid "FILE"
msgstr "FICHIER"
@@ -7260,7 +7260,7 @@ msgid "Use style from CSS file"
msgstr "Utiliser le style dun fichier 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:113
#: tools/gtk-builder-tool-validate.c:268 tools/gtk-rendernode-tool-show.c:109
#: tools/gtk-rendernode-tool-render.c:204
#, c-format
msgid "Could not initialize windowing system\n"
@@ -7515,50 +7515,47 @@ msgstr ""
" render Prendre une capture d’écran du nœud\n"
"\n"
#: tools/gtk-rendernode-tool-info.c:179
#: tools/gtk-rendernode-tool-info.c:177
#, c-format
msgid "Number of nodes: %u\n"
msgstr "Nombre de nœuds : %u\n"
#: tools/gtk-rendernode-tool-info.c:186
#: tools/gtk-rendernode-tool-info.c:184
#, c-format
msgid "Depth: %u\n"
msgstr "Profondeur : %u\n"
#: tools/gtk-rendernode-tool-info.c:189
#: tools/gtk-rendernode-tool-info.c:187
#, c-format
msgid "Bounds: %g x %g\n"
msgstr "Limites : %g × %g\n"
#: tools/gtk-rendernode-tool-info.c:190
#: tools/gtk-rendernode-tool-info.c:188
#, c-format
msgid "Origin: %g %g\n"
msgstr "Origine : %g %g\n"
#: tools/gtk-rendernode-tool-info.c:211
#: tools/gtk-rendernode-tool-info.c:209
msgid "Provide information about the render node."
msgstr "Fournir des informations sur le nœud de rendu."
#: tools/gtk-rendernode-tool-info.c:224 tools/gtk-rendernode-tool-show.c:134
#: tools/gtk-rendernode-tool-info.c:222 tools/gtk-rendernode-tool-show.c:130
#: tools/gtk-rendernode-tool-render.c:225
#, c-format
msgid "No .node file specified\n"
msgstr "Aucun fichier .node indiqué\n"
#: tools/gtk-rendernode-tool-info.c:230
#: tools/gtk-rendernode-tool-info.c:228
#, c-format
msgid "Can only accept a single .node file\n"
msgstr "Naccepte quun unique fichier .node\n"
msgstr ""
"Naccepte quun unique fichier .node\n"
#: tools/gtk-rendernode-tool-show.c:105
msgid "Don't add a titlebar"
msgstr "Ne pas ajouter de barre de titre"
#: tools/gtk-rendernode-tool-show.c:121
#: tools/gtk-rendernode-tool-show.c:117
msgid "Show the render node."
msgstr "Afficher le nœud de rendu."
#: tools/gtk-rendernode-tool-show.c:140
#: tools/gtk-rendernode-tool-show.c:136
#, c-format
msgid "Can only preview a single .node file\n"
msgstr "Ne peut afficher laperçu que dun unique fichier .node\n"
@@ -7593,19 +7590,14 @@ msgstr "Réaliser le rendu du fichier .node vers une image."
#, c-format
msgid "Can only render a single .node file to a single output file\n"
msgstr ""
"Ne peut effectuer le rendu que dun unique fichier .node vers un seul "
"fichier de sortie\n"
"Ne peut effectuer le rendu que dun unique fichier .node vers un seul fichier "
"de sortie\n"
#: tools/gtk-rendernode-tool-utils.c:51
#, c-format
msgid "Error at %s: %s\n"
msgstr "Erreur à %s : %s\n"
#: tools/gtk-rendernode-tool-utils.c:69
#, c-format
msgid "Failed to load node file: %s\n"
msgstr "Impossible de charger le fichier de nœud : %s\n"
#: tools/updateiconcache.c:1391
#, c-format
msgid "Failed to write header\n"
+389 -507
View File
File diff suppressed because it is too large Load Diff
+14 -26
View File
@@ -22,8 +22,8 @@ msgid ""
msgstr ""
"Project-Id-Version: gtk+.master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gtk/-/issues/\n"
"POT-Creation-Date: 2024-01-16 17:25+0000\n"
"PO-Revision-Date: 2024-01-16 22:49+0300\n"
"POT-Creation-Date: 2024-01-08 02:46+0000\n"
"PO-Revision-Date: 2024-01-08 15:00+0300\n"
"Last-Translator: Artur So <arturios2005@mail.ru>\n"
"Language-Team: Русский <gnome-cyr@gnome.org>\n"
"Language: ru\n"
@@ -867,11 +867,6 @@ msgid "This GLES %d.%d implementation does not support half-float vertex data"
msgstr ""
"Данная реализация GLES %d.%d не поддерживает полуплавающие вершинные данные"
#: gsk/gpu/gskgldevice.c:238
#, c-format
msgid "OpenGL ES 2.0 is not supported by this renderer."
msgstr "OpenGL ES 2.0 не поддерживается этим рендерером."
#: gtk/a11y/gtkatspiaction.c:239
msgctxt "accessibility"
msgid "Click"
@@ -2690,7 +2685,7 @@ msgstr "Вариации стилей"
msgid "Character Variations"
msgstr "Вариации символов"
#: gtk/gtkglarea.c:309
#: gtk/gtkglarea.c:305
msgid "OpenGL context creation failed"
msgstr "Не удалось создать контекст OpenGL"
@@ -7308,7 +7303,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:203
#: tools/gtk-builder-tool-validate.c:268 tools/gtk-rendernode-tool-render.c:204
#: tools/gtk-rendernode-tool-show.c:113
#, c-format
msgid "Could not initialize windowing system\n"
@@ -7354,13 +7349,13 @@ msgstr ""
"Используйте --force для перезаписи.\n"
#: tools/gtk-builder-tool-screenshot.c:332
#: tools/gtk-rendernode-tool-render.c:171
#: tools/gtk-rendernode-tool-render.c:172
#, c-format
msgid "Output written to %s.\n"
msgstr "Выход записывается в %s.\n"
#: tools/gtk-builder-tool-screenshot.c:336
#: tools/gtk-rendernode-tool-render.c:175
#: tools/gtk-rendernode-tool-render.c:176
#, c-format
msgid "Failed to save %s: %s\n"
msgstr "Не удалось сохранить %s: %s\n"
@@ -7378,7 +7373,7 @@ msgid "Overwrite existing file"
msgstr "Перезаписать существующий файл"
#: tools/gtk-builder-tool-screenshot.c:363
#: tools/gtk-rendernode-tool-render.c:196
#: tools/gtk-rendernode-tool-render.c:197
msgid "FILE…"
msgstr "ФАЙЛ…"
@@ -7849,7 +7844,6 @@ 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"
@@ -7861,7 +7855,6 @@ msgstr ""
"Выполнение различных задач на узлах рендеринга GTK.\n"
"\n"
"Команды:\n"
" benchmark Тест рендеринга узла\n"
" info Предоставить информацию об узле\n"
" show Показать узел\n"
" render Сделать снимок узла\n"
@@ -7891,7 +7884,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:224
#: tools/gtk-rendernode-tool-info.c:236 tools/gtk-rendernode-tool-render.c:225
#: tools/gtk-rendernode-tool-show.c:134
#, c-format
msgid "No .node file specified\n"
@@ -7916,24 +7909,19 @@ msgstr ""
msgid "Failed to generate SVG: %s\n"
msgstr "Не удалось сгенерировать SVG: %s\n"
#: 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
#: tools/gtk-rendernode-tool-render.c:196
msgid "Renderer to use"
msgstr "Используемый рендерер"
#: tools/gtk-rendernode-tool-render.c:195
#: tools/gtk-rendernode-tool-render.c:196
msgid "RENDERER"
msgstr "РЕНДЕРЕР"
#: tools/gtk-rendernode-tool-render.c:211
#: tools/gtk-rendernode-tool-render.c:212
msgid "Render a .node file to an image."
msgstr "Преобразование .node файла в изображение."
#: tools/gtk-rendernode-tool-render.c:230
#: tools/gtk-rendernode-tool-render.c:231
#, c-format
msgid "Can only render a single .node file to a single output file\n"
msgstr "Можно вывести только один файл .node в один выходной файл\n"
@@ -7951,12 +7939,12 @@ msgstr "Показать узел рендеринга."
msgid "Can only preview a single .node file\n"
msgstr "Можно предварительно просмотреть только один .node файл\n"
#: tools/gtk-rendernode-tool-utils.c:54
#: tools/gtk-rendernode-tool-utils.c:51
#, c-format
msgid "Error at %s: %s\n"
msgstr "Ошибка в %s: %s\n"
#: tools/gtk-rendernode-tool-utils.c:72
#: tools/gtk-rendernode-tool-utils.c:69
#, c-format
msgid "Failed to load node file: %s\n"
msgstr "Не удалось загрузить node файл: %s\n"
@@ -1,15 +0,0 @@
opacity {
opacity: 0.6;
child: container {
container {
color {
bounds: 0 0 40 40;
color: rgb(255,0,0);
}
color {
bounds: 10 10 40 40;
color: rgb(0,255,0);
}
}
}
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 175 B

@@ -1,181 +0,0 @@
clip {
clip: 0 -15 1024 1024;
child: container {
color {
color: black;
bounds: 0 -15 1024 1024;
}
text {
color: red;
font: "Font 13px" url("data://;base64,\
AAEAAAAIAIAAAwAAY21hcAAIAKUAAAIMAAAALGdseWZFxbN2AAACvAAABhZoZWFkvj7BOAAAAIwA\
AAA2aGhlYQFBAXIAAADEAAAAJGhtdHhMoAAAAAABCAAAAQRsb2NhMYAzCwAAAjgAAACEbWF4cABD\
AAUAAADoAAAAIG5hbWVuh0Z1AAAI1AAAABYAAQAAAAEZmoDtU+9fDzz1AAIAEAAAAAB8JbCAAAAA\
AOHTuggAAAAAATAAEAAAAAEAAgAAAAAAAAABAAAAEAAAAAABMAAAAAABMAABAAAAAAAAAAAAAAAA\
AAAAQQABAAAAQQAEAAEAAAAAAAEAAAAAAAAAAAAAAAAAAAAAATAAAAEwAAABMAAAATAAAAEwAAAB\
MAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEw\
AAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAA\
AAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAA\
ATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAAB\
MAAAATAAAACgAAAAAAABAAAAAwAAAAwABAAgAAAABAAEAAEAAABw//8AAAAw////0AABAAAAAAAA\
AAwAGAAkADAAPABIAFQAYABsAHgAhACQAJwAqAC0AMAAzADYAOQA8AD8AQgBFAEgASwBOAFEAVAB\
XAFoAXQBgAGMAZgBpAGwAbwByAHUAeAB7AH4AgQCEAIcAigCNAJAAkwCWAJkAnACfAKIApQCoAKs\
ArgCxALQAtwC6AL0AwADCwABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1\
IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAAB\
AAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAA\
AwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw\
/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAA\
AAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAA\
MSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQ\
AAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEw\
ABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1\
IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAAB\
AAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAA\
AwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw\
/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAA\
AAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAA\
MSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQ\
AAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEw\
ABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1\
IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAAB\
AAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAA\
AwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw\
/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAA\
AAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAA\
MSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQ\
AAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEw\
ABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1\
IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAAB\
AAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAA\
AwAAMSE1IQEw/tAQAAABAAAAAACgABAAAwAAMTM1I6CgEAAAAAAAAAEAEgABAAAAAAABAAQAAEZv\
bnQAAA==");
glyphs: 0 0 1 1, 1 0 257 1, 2 0 513 1, 3 0 769 1,
4 0 1 17, 5 0 257 17, 6 0 513 17, 7 0 769 17,
8 0 1 33, 9 0 257 33, 10 0 513 33, 11 0 769 33,
12 0 1 49, 13 0 257 49, 14 0 513 49, 15 0 769 49,
16 0 1 65, 17 0 257 65, 18 0 513 65, 19 0 769 65,
20 0 1 81, 21 0 257 81, 22 0 513 81, 23 0 769 81,
24 0 1 97, 25 0 257 97, 26 0 513 97, 27 0 769 97,
28 0 1 113, 29 0 257 113, 30 0 513 113, 31 0 769 113,
32 0 1 129, 33 0 257 129, 34 0 513 129, 35 0 769 129,
36 0 1 145, 37 0 257 145, 38 0 513 145, 39 0 769 145,
40 0 1 161, 41 0 257 161, 42 0 513 161, 43 0 769 161,
44 0 1 177, 45 0 257 177, 46 0 513 177, 47 0 769 177,
48 0 1 193, 49 0 257 193, 50 0 513 193, 51 0 769 193,
52 0 1 209, 53 0 257 209, 54 0 513 209, 55 0 769 209,
56 0 1 225, 57 0 257 225, 58 0 513 225, 59 0 769 225,
60 0 1 241, 61 0 257 241, 62 0 513 241, 63 0 769 241;
}
text {
color: red;
font: "Font 12px";
glyphs: 0 0 1 257, 1 0 257 257, 2 0 513 257, 3 0 769 257,
4 0 1 273, 5 0 257 273, 6 0 513 273, 7 0 769 273,
8 0 1 289, 9 0 257 289, 10 0 513 289, 11 0 769 289,
12 0 1 305, 13 0 257 305, 14 0 513 305, 15 0 769 305,
16 0 1 321, 17 0 257 321, 18 0 513 321, 19 0 769 321,
20 0 1 337, 21 0 257 337, 22 0 513 337, 23 0 769 337,
24 0 1 353, 25 0 257 353, 26 0 513 353, 27 0 769 353,
28 0 1 369, 29 0 257 369, 30 0 513 369, 31 0 769 369,
32 0 1 385, 33 0 257 385, 34 0 513 385, 35 0 769 385,
36 0 1 401, 37 0 257 401, 38 0 513 401, 39 0 769 401,
40 0 1 417, 41 0 257 417, 42 0 513 417, 43 0 769 417,
44 0 1 433, 45 0 257 433, 46 0 513 433, 47 0 769 433,
48 0 1 449, 49 0 257 449, 50 0 513 449, 51 0 769 449,
52 0 1 465, 53 0 257 465, 54 0 513 465, 55 0 769 465,
56 0 1 481, 57 0 257 481, 58 0 513 481, 59 0 769 481,
60 0 1 497, 61 0 257 497, 62 0 513 497, 63 0 769 497;
}
text {
color: red;
font: "Font 2 13px" url("data://;base64,\
AAEAAAAIAIAAAwAAY21hcAAIAKUAAAIMAAAALGdseWZFxbN2AAACvAAABhZoZWFkvj7C5QAAAIwA\
AAA2aGhlYQFBAXIAAADEAAAAJGhtdHhMoAAAAAABCAAAAQRsb2NhMYAzCwAAAjgAAACEbWF4cABD\
AAUAAADoAAAAIG5hbWVuh2apAAAI1AAAABgAAQAAAAEZmoDtECtfDzz1AAIAEAAAAAB8JbCAAAAA\
AOHTu7UAAAAAATAAEAAAAAEAAgAAAAAAAAABAAAAEAAAAAABMAAAAAABMAABAAAAAAAAAAAAAAAA\
AAAAQQABAAAAQQAEAAEAAAAAAAEAAAAAAAAAAAAAAAAAAAAAATAAAAEwAAABMAAAATAAAAEwAAAB\
MAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEw\
AAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAA\
AAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAA\
ATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAAB\
MAAAATAAAACgAAAAAAABAAAAAwAAAAwABAAgAAAABAAEAAEAAABw//8AAAAw////0AABAAAAAAAA\
AAwAGAAkADAAPABIAFQAYABsAHgAhACQAJwAqAC0AMAAzADYAOQA8AD8AQgBFAEgASwBOAFEAVAB\
XAFoAXQBgAGMAZgBpAGwAbwByAHUAeAB7AH4AgQCEAIcAigCNAJAAkwCWAJkAnACfAKIApQCoAKs\
ArgCxALQAtwC6AL0AwADCwABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1\
IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAAB\
AAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAA\
AwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw\
/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAA\
AAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAA\
MSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQ\
AAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEw\
ABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1\
IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAAB\
AAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAA\
AwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw\
/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAA\
AAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAA\
MSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQ\
AAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEw\
ABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1\
IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAAB\
AAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAA\
AwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw\
/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAA\
AAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAA\
MSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQ\
AAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEw\
ABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1\
IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAAB\
AAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAAAwAAMSE1IQEw/tAQAAABAAAAAAEwABAA\
AwAAMSE1IQEw/tAQAAABAAAAAACgABAAAwAAMTM1I6CgEAAAAAAAAAEAEgABAAAAAAABAAYAAEZv\
bnQgMg==");
glyphs: 0 0 1 513, 1 0 257 513, 2 0 513 513, 3 0 769 513,
4 0 1 529, 5 0 257 529, 6 0 513 529, 7 0 769 529,
8 0 1 545, 9 0 257 545, 10 0 513 545, 11 0 769 545,
12 0 1 561, 13 0 257 561, 14 0 513 561, 15 0 769 561,
16 0 1 577, 17 0 257 577, 18 0 513 577, 19 0 769 577,
20 0 1 593, 21 0 257 593, 22 0 513 593, 23 0 769 593,
24 0 1 609, 25 0 257 609, 26 0 513 609, 27 0 769 609,
28 0 1 625, 29 0 257 625, 30 0 513 625, 31 0 769 625,
32 0 1 641, 33 0 257 641, 34 0 513 641, 35 0 769 641,
36 0 1 657, 37 0 257 657, 38 0 513 657, 39 0 769 657,
40 0 1 673, 41 0 257 673, 42 0 513 673, 43 0 769 673,
44 0 1 689, 45 0 257 689, 46 0 513 689, 47 0 769 689,
48 0 1 705, 49 0 257 705, 50 0 513 705, 51 0 769 705,
52 0 1 721, 53 0 257 721, 54 0 513 721, 55 0 769 721,
56 0 1 737, 57 0 257 737, 58 0 513 737, 59 0 769 737,
60 0 1 753, 61 0 257 753, 62 0 513 753, 63 0 769 753;
}
text {
color: red;
font: "Font 2 12px";
glyphs: 0 0 1 769, 1 0 257 769, 2 0 513 769, 3 0 769 769,
4 0 1 785, 5 0 257 785, 6 0 513 785, 7 0 769 785,
8 0 1 801, 9 0 257 801, 10 0 513 801, 11 0 769 801,
12 0 1 817, 13 0 257 817, 14 0 513 817, 15 0 769 817,
16 0 1 833, 17 0 257 833, 18 0 513 833, 19 0 769 833,
20 0 1 849, 21 0 257 849, 22 0 513 849, 23 0 769 849,
24 0 1 865, 25 0 257 865, 26 0 513 865, 27 0 769 865,
28 0 1 881, 29 0 257 881, 30 0 513 881, 31 0 769 881,
32 0 1 897, 33 0 257 897, 34 0 513 897, 35 0 769 897,
36 0 1 913, 37 0 257 913, 38 0 513 913, 39 0 769 913,
40 0 1 929, 41 0 257 929, 42 0 513 929, 43 0 769 929,
44 0 1 945, 45 0 257 945, 46 0 513 945, 47 0 769 945,
48 0 1 961, 49 0 257 961, 50 0 513 961, 51 0 769 961,
52 0 1 977, 53 0 257 977, 54 0 513 977, 55 0 769 977,
56 0 1 993, 57 0 257 993, 58 0 513 993, 59 0 769 993;
}
text {
color: red;
font: "Font 15px";
glyphs: 64 0 0 1009;
}
}
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 630 B

@@ -1,508 +0,0 @@
text {
color: red;
font: "BlockBlockBlock 210px" url("data://;base64,\
AAEAAAAIAIAAAwAAY21hcAByAD0AAAEUAAAANGdseWY/ZsNsAAABVAAAAEhoZWFkJqsy2gAAAIwA\
AAA2aGhlYQwBBAIAAADEAAAAJGhtdHgEAAAAAAABCAAAAApsb2NhADAAGAAAAUgAAAAKbWF4cAAG\
AAUAAADoAAAAIG5hbWWJUoCNAAABnAAAACEAAQAAAAEZmmVCT9xfDzz1AAIIAAAAAADhwj0AAAAA\
AOHTj0oAAAAABAAIAAAAAAEAAgAAAAAAAAABAAAIAAAAAAAEAAAAAAAEAAABAAAAAAAAAAAAAAAA\
AAAAAQABAAAABAAEAAEAAAAAAAEAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAQAAAAMA\
AAAMAAQAKAAAAAYABAABAAIAIABD//8AAAAgAEH////g/8AAAQAAAAAAAAAAAAAADAAYACQAAAAB\
AAAAAAQACAAAAwAAMSERIQQA/AAIAAABAAAAAAQACAAAAwAAMSERIQQA/AAIAAABAAAAAAQACAAA\
AwAAMSERIQQA/AAIAAAAAAEAEgABAAAAAAABAA8AAEJsb2NrQmxvY2tCbG9jawAAAA==");
glyphs: 1 150, 2 150, 3 0;
}
text {
color: lime;
font: "BlockBlockBlock 208px";
glyphs: 1 150, 2 151, 3 0;
}
text {
color: blue;
font: "BlockBlockBlock 206px";
glyphs: 1 151, 2 151, 3 0;
}
text {
color: yellow;
font: "BlockBlockBlock 204px";
glyphs: 1 151, 2 152, 3 0;
}
text {
color: magenta;
font: "BlockBlockBlock 202px";
glyphs: 1 152, 2 152, 3 0;
}
text {
color: teal;
font: "BlockBlockBlock 200px";
glyphs: 1 152, 2 153, 3 0;
}
text {
color: red;
font: "BlockBlockBlock 198px";
glyphs: 1 153, 2 153, 3 0;
}
text {
color: lime;
font: "BlockBlockBlock 196px";
glyphs: 1 153, 2 154, 3 0;
}
text {
color: blue;
font: "BlockBlockBlock 194px";
glyphs: 1 154, 2 154, 3 0;
}
text {
color: yellow;
font: "BlockBlockBlock 192px";
glyphs: 1 154, 2 155, 3 0;
}
text {
color: magenta;
font: "BlockBlockBlock 190px";
glyphs: 1 155, 2 155, 3 0;
}
text {
color: teal;
font: "BlockBlockBlock 188px";
glyphs: 1 155, 2 156, 3 0;
}
text {
color: red;
font: "BlockBlockBlock 186px";
glyphs: 1 156, 2 156, 3 0;
}
text {
color: lime;
font: "BlockBlockBlock 184px";
glyphs: 1 156, 2 157, 3 0;
}
text {
color: blue;
font: "BlockBlockBlock 182px";
glyphs: 1 157, 2 157, 3 0;
}
text {
color: yellow;
font: "BlockBlockBlock 180px";
glyphs: 1 157, 2 158, 3 0;
}
text {
color: magenta;
font: "BlockBlockBlock 178px";
glyphs: 1 158, 2 158, 3 0;
}
text {
color: teal;
font: "BlockBlockBlock 176px";
glyphs: 1 158, 2 159, 3 0;
}
text {
color: red;
font: "BlockBlockBlock 174px";
glyphs: 1 159, 2 159, 3 0;
}
text {
color: lime;
font: "BlockBlockBlock 172px";
glyphs: 1 159, 2 160, 3 0;
}
text {
color: blue;
font: "BlockBlockBlock 170px";
glyphs: 1 160, 2 160, 3 0;
}
text {
color: yellow;
font: "BlockBlockBlock 168px";
glyphs: 1 160, 2 161, 3 0;
}
text {
color: magenta;
font: "BlockBlockBlock 166px";
glyphs: 1 161, 2 161, 3 0;
}
text {
color: teal;
font: "BlockBlockBlock 164px";
glyphs: 1 161, 2 162, 3 0;
}
text {
color: red;
font: "BlockBlockBlock 162px";
glyphs: 1 162, 2 162, 3 0;
}
text {
color: lime;
font: "BlockBlockBlock 160px";
glyphs: 1 162, 2 163, 3 0;
}
text {
color: blue;
font: "BlockBlockBlock 158px";
glyphs: 1 163, 2 163, 3 0;
}
text {
color: yellow;
font: "BlockBlockBlock 156px";
glyphs: 1 163, 2 164, 3 0;
}
text {
color: magenta;
font: "BlockBlockBlock 154px";
glyphs: 1 164, 2 164, 3 0;
}
text {
color: teal;
font: "BlockBlockBlock 152px";
glyphs: 1 164, 2 165, 3 0;
}
text {
color: red;
font: "BlockBlockBlock 150px";
glyphs: 1 165, 2 165, 3 0;
}
text {
color: lime;
font: "BlockBlockBlock 148px";
glyphs: 1 165, 2 166, 3 0;
}
text {
color: blue;
font: "BlockBlockBlock 146px";
glyphs: 1 166, 2 166, 3 0;
}
text {
color: yellow;
font: "BlockBlockBlock 144px";
glyphs: 1 166, 2 167, 3 0;
}
text {
color: magenta;
font: "BlockBlockBlock 142px";
glyphs: 1 167, 2 167, 3 0;
}
text {
color: teal;
font: "BlockBlockBlock 140px";
glyphs: 1 167, 2 168, 3 0;
}
text {
color: red;
font: "BlockBlockBlock 138px";
glyphs: 1 168, 2 168, 3 0;
}
text {
color: lime;
font: "BlockBlockBlock 136px";
glyphs: 1 168, 2 169, 3 0;
}
text {
color: blue;
font: "BlockBlockBlock 134px";
glyphs: 1 169, 2 169, 3 0;
}
text {
color: yellow;
font: "BlockBlockBlock 132px";
glyphs: 1 169, 2 170, 3 0;
}
text {
color: magenta;
font: "BlockBlockBlock 130px";
glyphs: 1 170, 2 170, 3 0;
}
text {
color: teal;
font: "BlockBlockBlock 128px";
glyphs: 1 170, 2 171, 3 0;
}
text {
color: red;
font: "BlockBlockBlock 126px";
glyphs: 1 171, 2 171, 3 0;
}
text {
color: lime;
font: "BlockBlockBlock 124px";
glyphs: 1 171, 2 172, 3 0;
}
text {
color: blue;
font: "BlockBlockBlock 122px";
glyphs: 1 172, 2 172, 3 0;
}
text {
color: yellow;
font: "BlockBlockBlock 120px";
glyphs: 1 172, 2 173, 3 0;
}
text {
color: magenta;
font: "BlockBlockBlock 118px";
glyphs: 1 173, 2 173, 3 0;
}
text {
color: teal;
font: "BlockBlockBlock 116px";
glyphs: 1 173, 2 174, 3 0;
}
text {
color: red;
font: "BlockBlockBlock 114px";
glyphs: 1 174, 2 174, 3 0;
}
text {
color: lime;
font: "BlockBlockBlock 112px";
glyphs: 1 174, 2 175, 3 0;
}
text {
color: blue;
font: "BlockBlockBlock 110px";
glyphs: 1 175, 2 175, 3 0;
}
text {
color: yellow;
font: "BlockBlockBlock 108px";
glyphs: 1 175, 2 176, 3 0;
}
text {
color: magenta;
font: "BlockBlockBlock 106px";
glyphs: 1 176, 2 176, 3 0;
}
text {
color: teal;
font: "BlockBlockBlock 104px";
glyphs: 1 176, 2 177, 3 0;
}
text {
color: red;
font: "BlockBlockBlock 102px";
glyphs: 1 177, 2 177, 3 0;
}
text {
color: lime;
font: "BlockBlockBlock 100px";
glyphs: 1 177, 2 178, 3 0;
}
text {
color: blue;
font: "BlockBlockBlock 98px";
glyphs: 1 178, 2 178, 3 0;
}
text {
color: yellow;
font: "BlockBlockBlock 96px";
glyphs: 1 178, 2 179, 3 0;
}
text {
color: magenta;
font: "BlockBlockBlock 94px";
glyphs: 1 179, 2 179, 3 0;
}
text {
color: teal;
font: "BlockBlockBlock 92px";
glyphs: 1 179, 2 180, 3 0;
}
text {
color: red;
font: "BlockBlockBlock 90px";
glyphs: 1 180, 2 180, 3 0;
}
text {
color: lime;
font: "BlockBlockBlock 88px";
glyphs: 1 180, 2 181, 3 0;
}
text {
color: blue;
font: "BlockBlockBlock 86px";
glyphs: 1 181, 2 181, 3 0;
}
text {
color: yellow;
font: "BlockBlockBlock 84px";
glyphs: 1 181, 2 182, 3 0;
}
text {
color: magenta;
font: "BlockBlockBlock 82px";
glyphs: 1 182, 2 182, 3 0;
}
text {
color: teal;
font: "BlockBlockBlock 80px";
glyphs: 1 182, 2 183, 3 0;
}
text {
color: red;
font: "BlockBlockBlock 78px";
glyphs: 1 183, 2 183, 3 0;
}
text {
color: lime;
font: "BlockBlockBlock 76px";
glyphs: 1 183, 2 184, 3 0;
}
text {
color: blue;
font: "BlockBlockBlock 74px";
glyphs: 1 184, 2 184, 3 0;
}
text {
color: yellow;
font: "BlockBlockBlock 72px";
glyphs: 1 184, 2 185, 3 0;
}
text {
color: magenta;
font: "BlockBlockBlock 70px";
glyphs: 1 185, 2 185, 3 0;
}
text {
color: teal;
font: "BlockBlockBlock 68px";
glyphs: 1 185, 2 186, 3 0;
}
text {
color: red;
font: "BlockBlockBlock 66px";
glyphs: 1 186, 2 186, 3 0;
}
text {
color: lime;
font: "BlockBlockBlock 64px";
glyphs: 1 186, 2 187, 3 0;
}
text {
color: blue;
font: "BlockBlockBlock 62px";
glyphs: 1 187, 2 187, 3 0;
}
text {
color: yellow;
font: "BlockBlockBlock 60px";
glyphs: 1 187, 2 188, 3 0;
}
text {
color: magenta;
font: "BlockBlockBlock 58px";
glyphs: 1 188, 2 188, 3 0;
}
text {
color: teal;
font: "BlockBlockBlock 56px";
glyphs: 1 188, 2 189, 3 0;
}
text {
color: red;
font: "BlockBlockBlock 54px";
glyphs: 1 189, 2 189, 3 0;
}
text {
color: lime;
font: "BlockBlockBlock 52px";
glyphs: 1 189, 2 190, 3 0;
}
text {
color: blue;
font: "BlockBlockBlock 50px";
glyphs: 1 190, 2 190, 3 0;
}
text {
color: yellow;
font: "BlockBlockBlock 48px";
glyphs: 1 190, 2 191, 3 0;
}
text {
color: magenta;
font: "BlockBlockBlock 46px";
glyphs: 1 191, 2 191, 3 0;
}
text {
color: teal;
font: "BlockBlockBlock 44px";
glyphs: 1 191, 2 192, 3 0;
}
text {
color: red;
font: "BlockBlockBlock 42px";
glyphs: 1 192, 2 192, 3 0;
}
text {
color: lime;
font: "BlockBlockBlock 40px";
glyphs: 1 192, 2 193, 3 0;
}
text {
color: blue;
font: "BlockBlockBlock 38px";
glyphs: 1 193, 2 193, 3 0;
}
text {
color: yellow;
font: "BlockBlockBlock 36px";
glyphs: 1 193, 2 194, 3 0;
}
text {
color: magenta;
font: "BlockBlockBlock 34px";
glyphs: 1 194, 2 194, 3 0;
}
text {
color: teal;
font: "BlockBlockBlock 32px";
glyphs: 1 194, 2 195, 3 0;
}
text {
color: red;
font: "BlockBlockBlock 30px";
glyphs: 1 195, 2 195, 3 0;
}
text {
color: lime;
font: "BlockBlockBlock 28px";
glyphs: 1 195, 2 196, 3 0;
}
text {
color: blue;
font: "BlockBlockBlock 26px";
glyphs: 1 196, 2 196, 3 0;
}
text {
color: yellow;
font: "BlockBlockBlock 24px";
glyphs: 1 196, 2 197, 3 0;
}
text {
color: magenta;
font: "BlockBlockBlock 22px";
glyphs: 1 197, 2 197, 3 0;
}
text {
color: teal;
font: "BlockBlockBlock 20px";
glyphs: 1 197, 2 198, 3 0;
}
text {
color: red;
font: "BlockBlockBlock 18px";
glyphs: 1 198, 2 198, 3 0;
}
text {
color: lime;
font: "BlockBlockBlock 16px";
glyphs: 1 198, 2 199, 3 0;
}
text {
color: blue;
font: "BlockBlockBlock 14px";
glyphs: 1 199, 2 199, 3 0;
}
text {
color: yellow;
font: "BlockBlockBlock 12px";
glyphs: 1 199, 2 200, 3 0;
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

@@ -1,9 +0,0 @@
repeat {
bounds: 105 0 80 100;
child: linear-gradient {
bounds: 0 0 50 10;
start: 0 0;
end: 50 0;
stops: 0.5 rgb(255,0,0), 0.5 rgb(0,255,0);
}
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 105 B

@@ -1,9 +0,0 @@
repeat {
bounds: 0 105 100 80;
child: linear-gradient {
bounds: 0 0 10 50;
start: 0 0;
end: 0 50;
stops: 0.5 rgb(255,0,0), 0.5 rgb(0,255,0);
}
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 102 B

File diff suppressed because it is too large Load Diff
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

File diff suppressed because it is too large Load Diff
Binary file not shown.

Before

Width:  |  Height:  |  Size: 499 B

-21
View File
@@ -1,21 +0,0 @@
text {
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;
}
color {
bounds: 0 5 20 5;
color: rgb(255,0,0);
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 113 B

-8
View File
@@ -45,7 +45,6 @@ compare_render_tests = [
'color-matrix-merge',
'color-matrix-parsing',
'conic-gradient-with-64-colorstops',
'container-single-child-offscreen-for-opacity',
'crossfade-clip-both-children',
'cross-fade-clipped-with-huge-children-nogl',
'cross-fade-in-opacity',
@@ -78,8 +77,6 @@ compare_render_tests = [
'fill-opacity',
'fill-scaled-up',
'fill-with-3d-contents-nogl-nocairo',
'glyph-cache-overflow',
'glyph-cache-overflow-slices',
'huge-height',
'huge-width',
'inset-shadow-multiple',
@@ -116,8 +113,6 @@ compare_render_tests = [
'repeat-huge-overdraw',
'repeat-negative-coords',
'repeat-no-repeat',
'repeat-node-tiling-horizontal',
'repeat-node-tiling-vertical',
'repeat-repeats',
'repeat-repeats-nested-nogl',
'repeat-scaling',
@@ -141,9 +136,6 @@ compare_render_tests = [
'stroke-fractional-translate-nogl',
'stroke-opacity',
'stroke-with-3d-contents-nogl-nocairo',
'subpixel-positioning',
'subpixel-positioning-hidpi-nogl-nocairo',
'text-color-mix',
'text-glyph-lsb',
'text-mixed-color-nocairo',
'text-mixed-color-colrv1',
+1 -1
View File
@@ -149,7 +149,7 @@ deserialize_error_func (const GskParseLocation *start,
append_error_value (errors, GTK_TYPE_CSS_PARSER_WARNING, error->code);
else
g_string_append_printf (errors,
"%s %u",
"%s %u\n",
g_quark_to_string (error->domain),
error->code);
@@ -1,7 +1,2 @@
<data>:21:32-36: error: GTK_CSS_PARSER_ERROR_UNKNOWN_VALUE
<data>:50:23-24: error: GTK_CSS_PARSER_ERROR_UNKNOWN_VALUE
<data>:55:24-69:3: error: GTK_CSS_PARSER_ERROR_UNKNOWN_VALUE
<data>:74:24-33: error: GTK_CSS_PARSER_ERROR_SYNTAX
<data>:79:24-38: error: g-io-error-quark 15
<data>:84:24-47: error: g-io-error-quark 1
<data>:89:24-62: error: GTK_CSS_PARSER_ERROR_UNKNOWN_VALUE
@@ -50,42 +50,3 @@ text {
font: "Demon Cat 11";
glyphs: "Hello";
}
text {
font: "Demon Cat 11" 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: "Demon Cat 11" url(url());
glyphs: 7 10;
}
text {
font: "Demon Cat 11" url(not-a-url);
glyphs: 7 10;
}
text {
font: "Demon Cat 11" url(file:///not-a-file);
glyphs: 7 10;
}
text {
font: "Demon Cat 11" url("data:font/ttf,Hello, I'm a Font");
glyphs: 7 10;
}
@@ -16,7 +16,7 @@ AAEAAwAAAA4AAAAA//8A/wD//wAA/wAA\
glyphs: 7 10;
}
text {
font: "text-mixed-color 7.5";
font: "Cantarell 11";
glyphs: 7 10;
}
text {
@@ -31,23 +31,3 @@ text {
font: "Cantarell 11";
glyphs: "Hello";
}
text {
font: "Cantarell 11";
glyphs: 7 10;
}
text {
font: "Cantarell 11";
glyphs: 7 10;
}
text {
font: "Cantarell 11";
glyphs: 7 10;
}
text {
font: "Cantarell 11";
glyphs: 7 10;
}
text {
font: "Cantarell 11";
glyphs: 7 10;
}