[gnome-builder/wip/gtk4-port: 425/736] libide/sourceview: add font-desc property
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/wip/gtk4-port: 425/736] libide/sourceview: add font-desc property
- Date: Tue, 26 Apr 2022 01:46:26 +0000 (UTC)
commit 99179a151af3afbb75b14dc68975e2cd0bc03a6f
Author: Christian Hergert <chergert redhat com>
Date: Tue Apr 5 18:50:16 2022 -0700
libide/sourceview: add font-desc property
The goal here is to make things easier to bind for settings from the
new preferences window.
src/libide/sourceview/ide-source-view.c | 253 ++++++++++++++++++++++++++++++++
src/libide/sourceview/ide-source-view.h | 19 ++-
2 files changed, 266 insertions(+), 6 deletions(-)
---
diff --git a/src/libide/sourceview/ide-source-view.c b/src/libide/sourceview/ide-source-view.c
index f851cc0b3..0642624bb 100644
--- a/src/libide/sourceview/ide-source-view.c
+++ b/src/libide/sourceview/ide-source-view.c
@@ -23,16 +23,27 @@
#include "config.h"
#include <glib/gi18n.h>
+#include <math.h>
+
+#include <libide-gtk.h>
#include "ide-source-view.h"
struct _IdeSourceView
{
GtkSourceView source_view;
+ GtkCssProvider *css_provider;
+ PangoFontDescription *font_desc;
+ int font_scale;
+ double line_height;
};
enum {
PROP_0,
+ PROP_FONT_DESC,
+ PROP_FONT_SCALE,
+ PROP_LINE_HEIGHT,
+ PROP_ZOOM_LEVEL,
N_PROPS
};
@@ -40,9 +51,126 @@ G_DEFINE_TYPE (IdeSourceView, ide_source_view, GTK_SOURCE_TYPE_VIEW)
static GParamSpec *properties [N_PROPS];
+static void
+ide_source_view_update_css (IdeSourceView *self)
+{
+ const PangoFontDescription *font_desc;
+ PangoFontDescription *scaled = NULL;
+ PangoFontDescription *system_font = NULL;
+ GtkSourceStyleScheme *scheme;
+ GtkSourceStyle *style;
+ GtkTextBuffer *buffer;
+ g_autoptr(GString) str = NULL;
+ g_autofree char *font_css = NULL;
+ int size = 11; /* 11pt */
+ char line_height_str[G_ASCII_DTOSTR_BUF_SIZE];
+
+ g_assert (IDE_IS_SOURCE_VIEW (self));
+
+ str = g_string_new (NULL);
+
+ /* Get information for search bubbles */
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (self));
+ if ((scheme = gtk_source_buffer_get_style_scheme (GTK_SOURCE_BUFFER (buffer))) &&
+ (style = gtk_source_style_scheme_get_style (scheme, "search-match")))
+ {
+ g_autofree char *background = NULL;
+ gboolean background_set = FALSE;
+
+ g_object_get (style,
+ "background", &background,
+ "background-set", &background_set,
+ NULL);
+
+ if (background != NULL && background_set)
+ g_string_append_printf (str,
+ ".search-match {"
+ " background:mix(%s,currentColor,0.0125);"
+ " border-radius:7px;"
+ " box-shadow: 0 1px 3px mix(%s,currentColor,.2);"
+ "}\n",
+ background, background);
+ }
+
+ g_string_append (str, "textview {\n");
+
+ /* Get font information to adjust line height and font changes */
+ if ((font_desc = self->font_desc) == NULL)
+ {
+ g_object_get (g_application_get_default (),
+ "system-font", &system_font,
+ NULL);
+ font_desc = system_font;
+ }
+
+ if (font_desc != NULL &&
+ pango_font_description_get_set_fields (font_desc) & PANGO_FONT_MASK_SIZE)
+ size = pango_font_description_get_size (font_desc) / PANGO_SCALE;
+
+ if (size + self->font_scale < 1)
+ self->font_scale = -size + 1;
+
+ size = MAX (1, size + self->font_scale);
+
+ if (size != 0)
+ {
+ if (font_desc)
+ scaled = pango_font_description_copy (font_desc);
+ else
+ scaled = pango_font_description_new ();
+ pango_font_description_set_size (scaled, size * PANGO_SCALE);
+ font_desc = scaled;
+ }
+
+ if (font_desc)
+ {
+ font_css = ide_font_description_to_css (font_desc);
+ g_string_append (str, font_css);
+ }
+
+ g_ascii_dtostr (line_height_str, sizeof line_height_str, self->line_height);
+ line_height_str[6] = 0;
+ g_string_append_printf (str, "\nline-height: %s;\n", line_height_str);
+
+ g_string_append (str, "}\n");
+
+ gtk_css_provider_load_from_data (self->css_provider, str->str, -1);
+
+ g_clear_pointer (&scaled, pango_font_description_free);
+ g_clear_pointer (&system_font, pango_font_description_free);
+}
+
+static void
+tweak_gutter_spacing (GtkSourceView *view)
+{
+ GtkSourceGutter *gutter;
+ GtkWidget *child;
+ guint n = 0;
+
+ g_assert (GTK_SOURCE_IS_VIEW (view));
+
+ /* Ensure we have a line gutter renderer to tweak */
+ gutter = gtk_source_view_get_gutter (view, GTK_TEXT_WINDOW_LEFT);
+ gtk_source_view_set_show_line_numbers (view, TRUE);
+
+ /* Add margin to first gutter renderer */
+ for (child = gtk_widget_get_first_child (GTK_WIDGET (gutter));
+ child != NULL;
+ child = gtk_widget_get_next_sibling (child), n++)
+ {
+ if (GTK_SOURCE_IS_GUTTER_RENDERER (child))
+ gtk_widget_set_margin_start (child, n == 0 ? 4 : 0);
+ }
+}
+
static void
ide_source_view_dispose (GObject *object)
{
+ IdeSourceView *self = (IdeSourceView *)object;
+
+ g_clear_object (&self->css_provider);
+ g_clear_pointer (&self->font_desc, pango_font_description_free);
+
G_OBJECT_CLASS (ide_source_view_parent_class)->dispose (object);
}
@@ -62,6 +190,21 @@ ide_source_view_get_property (GObject *object,
switch (prop_id)
{
+ case PROP_FONT_DESC:
+ g_value_set_boxed (value, ide_source_view_get_font_desc (self));
+ break;
+
+ case PROP_FONT_SCALE:
+ g_value_set_int (value, self->font_scale);
+ break;
+
+ case PROP_LINE_HEIGHT:
+ g_value_set_double (value, self->line_height);
+ break;
+
+ case PROP_ZOOM_LEVEL:
+ g_value_set_double (value, ide_source_view_get_zoom_level (self));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@@ -77,6 +220,21 @@ ide_source_view_set_property (GObject *object,
switch (prop_id)
{
+ case PROP_FONT_DESC:
+ ide_source_view_set_font_desc (self, g_value_get_boxed (value));
+ break;
+
+ case PROP_FONT_SCALE:
+ self->font_scale = g_value_get_int (value);
+ ide_source_view_update_css (self);
+ g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_ZOOM_LEVEL]);
+ break;
+
+ case PROP_LINE_HEIGHT:
+ self->line_height = g_value_get_double (value);
+ ide_source_view_update_css (self);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@@ -91,11 +249,56 @@ ide_source_view_class_init (IdeSourceViewClass *klass)
object_class->finalize = ide_source_view_finalize;
object_class->get_property = ide_source_view_get_property;
object_class->set_property = ide_source_view_set_property;
+
+ properties [PROP_LINE_HEIGHT] =
+ g_param_spec_double ("line-height",
+ "Line height",
+ "The line height of all lines",
+ 0.5, 10.0, 1.2,
+ (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+ properties [PROP_FONT_DESC] =
+ g_param_spec_boxed ("font-desc",
+ "Font Description",
+ "The font to use for text within the editor",
+ PANGO_TYPE_FONT_DESCRIPTION,
+ (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+ properties [PROP_FONT_SCALE] =
+ g_param_spec_int ("font-scale",
+ "Font Scale",
+ "The font scale",
+ G_MININT, G_MAXINT, 0,
+ (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+ properties [PROP_ZOOM_LEVEL] =
+ g_param_spec_double ("zoom-level",
+ "Zoom Level",
+ "Zoom Level",
+ -G_MAXDOUBLE, G_MAXDOUBLE, 1.0,
+ (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_properties (object_class, N_PROPS, properties);
}
static void
ide_source_view_init (IdeSourceView *self)
{
+ GtkStyleContext *style_context;
+
+ g_signal_connect_object (g_application_get_default (),
+ "notify::system-font-name",
+ G_CALLBACK (ide_source_view_update_css),
+ self,
+ G_CONNECT_SWAPPED);
+
+ self->css_provider = gtk_css_provider_new ();
+ style_context = gtk_widget_get_style_context (GTK_WIDGET (self));
+ gtk_style_context_add_provider (style_context,
+ GTK_STYLE_PROVIDER (self->css_provider),
+ GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
+
+ tweak_gutter_spacing (GTK_SOURCE_VIEW (self));
}
void
@@ -149,3 +352,53 @@ ide_source_view_dup_position_label (IdeSourceView *self)
return g_strdup_printf (_("Ln %u, Col %u"), line + 1, column + 1);
}
+
+const PangoFontDescription *
+ide_source_view_get_font_desc (IdeSourceView *self)
+{
+ g_return_val_if_fail (IDE_IS_SOURCE_VIEW (self), NULL);
+
+ return self->font_desc;
+}
+
+void
+ide_source_view_set_font_desc (IdeSourceView *self,
+ const PangoFontDescription *font_desc)
+{
+ g_return_if_fail (IDE_IS_SOURCE_VIEW (self));
+
+ if (self->font_desc == font_desc ||
+ (self->font_desc != NULL && font_desc != NULL &&
+ pango_font_description_equal (self->font_desc, font_desc)))
+ return;
+
+ g_clear_pointer (&self->font_desc, pango_font_description_free);
+
+ if (font_desc)
+ self->font_desc = pango_font_description_copy (font_desc);
+
+ self->font_scale = 0;
+
+ ide_source_view_update_css (self);
+
+ g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_FONT_DESC]);
+ g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_FONT_SCALE]);
+ g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_ZOOM_LEVEL]);
+}
+
+double
+ide_source_view_get_zoom_level (IdeSourceView *self)
+{
+ int alt_size;
+ int size = 11; /* 11pt */
+
+ g_return_val_if_fail (IDE_IS_SOURCE_VIEW (self), 0);
+
+ if (self->font_desc != NULL &&
+ pango_font_description_get_set_fields (self->font_desc) & PANGO_FONT_MASK_SIZE)
+ size = pango_font_description_get_size (self->font_desc) / PANGO_SCALE;
+
+ alt_size = MAX (1, size + self->font_scale);
+
+ return (double)alt_size / (double)size;
+}
diff --git a/src/libide/sourceview/ide-source-view.h b/src/libide/sourceview/ide-source-view.h
index e21f744da..cf7d48108 100644
--- a/src/libide/sourceview/ide-source-view.h
+++ b/src/libide/sourceview/ide-source-view.h
@@ -36,14 +36,21 @@ IDE_AVAILABLE_IN_ALL
G_DECLARE_FINAL_TYPE (IdeSourceView, ide_source_view, IDE, SOURCE_VIEW, GtkSourceView)
IDE_AVAILABLE_IN_ALL
-GtkWidget *ide_source_view_new (void);
+GtkWidget *ide_source_view_new (void);
IDE_AVAILABLE_IN_ALL
-void ide_source_view_scroll_to_insert (IdeSourceView *self);
+void ide_source_view_scroll_to_insert (IdeSourceView *self);
IDE_AVAILABLE_IN_ALL
-char *ide_source_view_dup_position_label (IdeSourceView *self);
+char *ide_source_view_dup_position_label (IdeSourceView *self);
IDE_AVAILABLE_IN_ALL
-void ide_source_view_get_visual_position (IdeSourceView *self,
- guint *line,
- guint *line_column);
+void ide_source_view_get_visual_position (IdeSourceView *self,
+ guint *line,
+ guint *line_column);
+IDE_AVAILABLE_IN_ALL
+double ide_source_view_get_zoom_level (IdeSourceView *self);
+IDE_AVAILABLE_IN_ALL
+void ide_source_view_set_font_desc (IdeSourceView *self,
+ const PangoFontDescription *font_desc);
+IDE_AVAILABLE_IN_ALL
+const PangoFontDescription *ide_source_view_get_font_desc (IdeSourceView *self);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]