#include "gtkwidget.h"
#include "gtkwindow.h"
#include "gtknative.h"
+#include "gtkmain.h"
/* duration before we start fading in us */
#define GDK_FPS_OVERLAY_LINGER_DURATION (1000 * 1000)
GtkInspectorOverlay parent_instance;
GHashTable *infos; /* GtkWidget => GtkFpsInfo */
+
+ PangoFont *font;
+ PangoGlyphString *glyphs;
+ PangoGlyphString *digits;
+ int width, height, baseline;
};
struct _GtkFpsOverlayClass
{
GtkFpsOverlay *self = GTK_FPS_OVERLAY (overlay);
GtkFpsInfo *info;
- PangoLayout *layout;
- PangoAttrList *attrs;
gint64 now;
double fps;
- char *fps_string;
graphene_rect_t bounds;
gboolean has_bounds;
- int width, height;
double overlay_opacity;
+ PangoGlyphString *glyphs;
+ GskRenderNode *fps_node;
now = gdk_frame_clock_get_frame_time (gtk_widget_get_frame_clock (widget));
info = g_hash_table_lookup (self->infos, widget);
}
}
- fps = gtk_fps_overlay_get_fps (widget);
- if (fps == 0.0)
- fps_string = g_strdup ("--- fps");
- else
- fps_string = g_strdup_printf ("%.2f fps", fps);
-
if (GTK_IS_WINDOW (widget))
{
GtkWidget *child = gtk_window_get_child (GTK_WINDOW (widget));
else
has_bounds = gtk_widget_compute_bounds (child, widget, &bounds);
}
- else
+ else
{
has_bounds = gtk_widget_compute_bounds (widget, widget, &bounds);
}
- layout = gtk_widget_create_pango_layout (widget, fps_string);
- attrs = pango_attr_list_new ();
- pango_attr_list_insert (attrs, pango_attr_font_features_new ("tnum=1"));
- pango_layout_set_attributes (layout, attrs);
- pango_attr_list_unref (attrs);
- pango_layout_get_pixel_size (layout, &width, &height);
+ glyphs = pango_glyph_string_copy (self->glyphs);
+
+ fps = gtk_fps_overlay_get_fps (widget);
+ if (fps == 0.0)
+ {
+ for (int i = 0; i < 7; i++)
+ glyphs->glyphs[i].glyph = PANGO_GLYPH_EMPTY;
+ }
+ else
+ {
+ char *fps_string = g_strdup_printf ("%7.2f fps", fps);
+ for (int i = 0; i < 7; i++)
+ {
+ if (g_ascii_isdigit (fps_string[i]))
+ glyphs->glyphs[i].glyph = self->digits->glyphs[fps_string[i] - '0'].glyph;
+ else if (fps_string[i] == ' ')
+ glyphs->glyphs[i].glyph = PANGO_GLYPH_EMPTY;
+ }
+ g_free (fps_string);
+ }
gtk_snapshot_save (snapshot);
if (has_bounds)
- gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (bounds.origin.x + bounds.size.width - width, bounds.origin.y));
+ gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (bounds.origin.x + bounds.size.width - self->width, bounds.origin.y));
+
if (overlay_opacity < 1.0)
gtk_snapshot_push_opacity (snapshot, overlay_opacity);
gtk_snapshot_append_color (snapshot,
&(GdkRGBA) { 0, 0, 0, 0.5 },
- &GRAPHENE_RECT_INIT (-1, -1, width + 2, height + 2));
- gtk_snapshot_append_layout (snapshot,
- layout,
- &(GdkRGBA) { 1, 1, 1, 1 });
+ &GRAPHENE_RECT_INIT (-1, -1, self->width + 2, self->height + 2));
+ fps_node = gsk_text_node_new (self->font,
+ glyphs,
+ &(GdkRGBA) { 1, 1, 1, 1 },
+ &GRAPHENE_POINT_INIT (0, self->baseline));
+ gtk_snapshot_append_node (snapshot, fps_node);
+ gsk_render_node_unref (fps_node);
if (overlay_opacity < 1.0)
gtk_snapshot_pop (snapshot);
gtk_snapshot_restore (snapshot);
- g_free (fps_string);
gtk_widget_add_tick_callback (widget, gtk_fps_overlay_force_redraw, NULL, NULL);
}
g_hash_table_unref (self->infos);
+ g_clear_pointer (&self->glyphs, pango_glyph_string_free);
+ g_clear_pointer (&self->digits, pango_glyph_string_free);
+ g_clear_object (&self->font);
+
G_OBJECT_CLASS (gtk_fps_overlay_parent_class)->dispose (object);
}
static void
gtk_fps_overlay_init (GtkFpsOverlay *self)
{
+ PangoContext *context;
+ PangoLayout *layout;
+ PangoLayoutIter *iter;
+ PangoLayoutRun *run;
+ PangoAttrList *attrs;
+
self->infos = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, gtk_fps_info_free);
+
+ context = pango_font_map_create_context (pango_cairo_font_map_get_default ());
+ pango_context_set_language (context, gtk_get_default_language ());
+
+ layout = pango_layout_new (context);
+ pango_layout_set_text (layout, "0000.00 fps", -1);
+ attrs = pango_attr_list_new ();
+ pango_attr_list_insert (attrs, pango_attr_font_features_new ("tnum=1"));
+ pango_layout_set_attributes (layout, attrs);
+ pango_attr_list_unref (attrs);
+ pango_layout_get_pixel_size (layout, &self->width, &self->height);
+
+ iter = pango_layout_get_iter (layout);
+ self->baseline = pango_layout_iter_get_baseline (iter) / (double) PANGO_SCALE;
+ run = pango_layout_iter_get_run_readonly (iter);
+
+ self->glyphs = pango_glyph_string_copy (run->glyphs);
+ self->font = g_object_ref (run->item->analysis.font);
+
+ pango_layout_iter_free (iter);
+
+ pango_layout_set_text (layout, "0123456789", -1);
+
+ iter = pango_layout_get_iter (layout);
+ run = pango_layout_iter_get_run_readonly (iter);
+
+ self->digits = pango_glyph_string_copy (run->glyphs);
+
+ pango_layout_iter_free (iter);
+ g_object_unref (layout);
+ g_object_unref (context);
}
GtkInspectorOverlay *