[gtk/pango2: 8/8] Fontchooser: Add palette support
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/pango2: 8/8] Fontchooser: Add palette support
- Date: Mon, 4 Jul 2022 14:40:16 +0000 (UTC)
commit 646149bc7209db774a5f6b976df94edadc979847
Author: Matthias Clasen <mclasen redhat com>
Date: Sun Jul 3 12:54:15 2022 -0400
Fontchooser: Add palette support
For fonts that have color palettes, optionally
allow the user to select one.
This is behind the new GTK_FONT_CHOOSER_LEVEL_PALETTE
flag. If it is enabled, you can use
gtk_font_chooser_get_palette() to get the
selected palette name.
The testfontchooserdialog test lets you play with
this. Fonts to try tihs with are Amiri Quran Colored
or the Bungee Color family.
gtk/gtkfontbutton.c | 267 ++++-------------------------------------
gtk/gtkfontchooser.c | 31 +++++
gtk/gtkfontchooser.h | 6 +-
gtk/gtkfontchooserdialog.c | 4 +-
gtk/gtkfontchooserutils.c | 3 +
gtk/gtkfontchooserutils.h | 1 +
gtk/gtkfontchooserwidget.c | 213 ++++++++++++++++++++++++++++----
gtk/ui/gtkfontchooserwidget.ui | 6 +
tests/testfontchooserdialog.c | 4 +
9 files changed, 269 insertions(+), 266 deletions(-)
---
diff --git a/gtk/gtkfontbutton.c b/gtk/gtkfontbutton.c
index 135e7c9a02..c4c4cd258c 100644
--- a/gtk/gtkfontbutton.c
+++ b/gtk/gtkfontbutton.c
@@ -96,13 +96,13 @@ struct _GtkFontButton
Pango2FontFamily *font_family;
Pango2FontFace *font_face;
Pango2FontMap *font_map;
- char *font_features;
+ char *font_features;
+ char *palette;
Pango2Language *language;
char *preview_text;
GtkFontFilterFunc font_filter;
gpointer font_filter_data;
GDestroyNotify font_filter_data_destroy;
- GtkCssProvider *provider;
};
struct _GtkFontButtonClass
@@ -200,6 +200,7 @@ clear_font_data (GtkFontButton *font_button)
g_clear_pointer (&font_button->font_desc, pango2_font_description_free);
g_clear_pointer (&font_button->fontname, g_free);
g_clear_pointer (&font_button->font_features, g_free);
+ g_clear_pointer (&font_button->palette, g_free);
}
static void
@@ -623,8 +624,6 @@ gtk_font_button_finalize (GObject *object)
g_free (font_button->preview_text);
- g_clear_object (&font_button->provider);
-
gtk_widget_unparent (font_button->button);
G_OBJECT_CLASS (gtk_font_button_parent_class)->finalize (object);
@@ -704,6 +703,9 @@ gtk_font_button_get_property (GObject *object,
case GTK_FONT_CHOOSER_PROP_FONT_FEATURES:
g_value_set_string (value, font_button->font_features);
break;
+ case GTK_FONT_CHOOSER_PROP_PALETTE:
+ g_value_set_string (value, font_button->palette);
+ break;
case GTK_FONT_CHOOSER_PROP_LANGUAGE:
g_value_set_string (value, pango2_language_to_string (font_button->language));
break;
@@ -1044,6 +1046,8 @@ response_cb (GtkDialog *dialog,
font_button->font_size = gtk_font_chooser_get_font_size (font_chooser);
g_free (font_button->font_features);
font_button->font_features = gtk_font_chooser_get_font_features (font_chooser);
+ g_free (font_button->palette);
+ font_button->palette = gtk_font_chooser_get_palette (font_chooser);
font_button->language = pango2_language_from_string (gtk_font_chooser_get_language (font_chooser));
/* Set label font */
@@ -1052,6 +1056,7 @@ response_cb (GtkDialog *dialog,
g_object_notify (G_OBJECT (font_button), "font");
g_object_notify (G_OBJECT (font_button), "font-desc");
g_object_notify (G_OBJECT (font_button), "font-features");
+ g_object_notify (G_OBJECT (font_button), "palette");
g_object_thaw_notify (object);
@@ -1069,260 +1074,38 @@ dialog_destroy (GtkWidget *widget,
font_button->font_dialog = NULL;
}
-static void
-add_css_variations (GString *s,
- const char *variations)
-{
- const char *p;
- const char *sep = "";
-
- if (variations == NULL || variations[0] == '\0')
- {
- g_string_append (s, "normal");
- return;
- }
-
- p = variations;
- while (p && *p)
- {
- const char *start;
- const char *end, *end2;
- double value;
- char name[5];
-
- while (g_ascii_isspace (*p)) p++;
-
- start = p;
- end = strchr (p, ',');
- if (end && (end - p < 6))
- goto skip;
-
- name[0] = p[0];
- name[1] = p[1];
- name[2] = p[2];
- name[3] = p[3];
- name[4] = '\0';
-
- p += 4;
- while (g_ascii_isspace (*p)) p++;
- if (*p == '=') p++;
-
- if (p - start < 5)
- goto skip;
-
- value = g_ascii_strtod (p, (char **) &end2);
-
- while (end2 && g_ascii_isspace (*end2)) end2++;
-
- if (end2 && (*end2 != ',' && *end2 != '\0'))
- goto skip;
-
- g_string_append_printf (s, "%s\"%s\" %g", sep, name, value);
- sep = ", ";
-
-skip:
- p = end ? end + 1 : NULL;
- }
-}
-
-static char *
-pango2_font_description_to_css (Pango2FontDescription *desc,
- const char *features,
- const char *language)
-{
- GString *s;
- Pango2FontMask set;
-
- s = g_string_new ("* { ");
-
- set = pango2_font_description_get_set_fields (desc);
- if (set & PANGO2_FONT_MASK_FAMILY)
- {
- g_string_append (s, "font-family: \"");
- g_string_append (s, pango2_font_description_get_family (desc));
- g_string_append (s, "\"; ");
- }
- if (set & PANGO2_FONT_MASK_STYLE)
- {
- switch (pango2_font_description_get_style (desc))
- {
- case PANGO2_STYLE_NORMAL:
- g_string_append (s, "font-style: normal; ");
- break;
- case PANGO2_STYLE_OBLIQUE:
- g_string_append (s, "font-style: oblique; ");
- break;
- case PANGO2_STYLE_ITALIC:
- g_string_append (s, "font-style: italic; ");
- break;
- default:
- break;
- }
- }
- if (set & PANGO2_FONT_MASK_VARIANT)
- {
- switch (pango2_font_description_get_variant (desc))
- {
- case PANGO2_VARIANT_NORMAL:
- g_string_append (s, "font-variant: normal; ");
- break;
- case PANGO2_VARIANT_SMALL_CAPS:
- g_string_append (s, "font-variant: small-caps; ");
- break;
- case PANGO2_VARIANT_ALL_SMALL_CAPS:
- g_string_append (s, "font-variant: all-small-caps; ");
- break;
- case PANGO2_VARIANT_PETITE_CAPS:
- g_string_append (s, "font-variant: petite-caps; ");
- break;
- case PANGO2_VARIANT_ALL_PETITE_CAPS:
- g_string_append (s, "font-variant: all-petite-caps; ");
- break;
- case PANGO2_VARIANT_UNICASE:
- g_string_append (s, "font-variant: unicase; ");
- break;
- case PANGO2_VARIANT_TITLE_CAPS:
- g_string_append (s, "font-variant: titling-caps; ");
- break;
- default:
- break;
- }
- }
- if (set & PANGO2_FONT_MASK_WEIGHT)
- {
- switch (pango2_font_description_get_weight (desc))
- {
- case PANGO2_WEIGHT_THIN:
- g_string_append (s, "font-weight: 100; ");
- break;
- case PANGO2_WEIGHT_ULTRALIGHT:
- g_string_append (s, "font-weight: 200; ");
- break;
- case PANGO2_WEIGHT_LIGHT:
- case PANGO2_WEIGHT_SEMILIGHT:
- g_string_append (s, "font-weight: 300; ");
- break;
- case PANGO2_WEIGHT_BOOK:
- case PANGO2_WEIGHT_NORMAL:
- g_string_append (s, "font-weight: 400; ");
- break;
- case PANGO2_WEIGHT_MEDIUM:
- g_string_append (s, "font-weight: 500; ");
- break;
- case PANGO2_WEIGHT_SEMIBOLD:
- g_string_append (s, "font-weight: 600; ");
- break;
- case PANGO2_WEIGHT_BOLD:
- g_string_append (s, "font-weight: 700; ");
- break;
- case PANGO2_WEIGHT_ULTRABOLD:
- g_string_append (s, "font-weight: 800; ");
- break;
- case PANGO2_WEIGHT_HEAVY:
- case PANGO2_WEIGHT_ULTRAHEAVY:
- g_string_append (s, "font-weight: 900; ");
- break;
- default:
- break;
- }
- }
- if (set & PANGO2_FONT_MASK_STRETCH)
- {
- switch (pango2_font_description_get_stretch (desc))
- {
- case PANGO2_STRETCH_ULTRA_CONDENSED:
- g_string_append (s, "font-stretch: ultra-condensed; ");
- break;
- case PANGO2_STRETCH_EXTRA_CONDENSED:
- g_string_append (s, "font-stretch: extra-condensed; ");
- break;
- case PANGO2_STRETCH_CONDENSED:
- g_string_append (s, "font-stretch: condensed; ");
- break;
- case PANGO2_STRETCH_SEMI_CONDENSED:
- g_string_append (s, "font-stretch: semi-condensed; ");
- break;
- case PANGO2_STRETCH_NORMAL:
- g_string_append (s, "font-stretch: normal; ");
- break;
- case PANGO2_STRETCH_SEMI_EXPANDED:
- g_string_append (s, "font-stretch: semi-expanded; ");
- break;
- case PANGO2_STRETCH_EXPANDED:
- g_string_append (s, "font-stretch: expanded; ");
- break;
- case PANGO2_STRETCH_EXTRA_EXPANDED:
- break;
- case PANGO2_STRETCH_ULTRA_EXPANDED:
- g_string_append (s, "font-stretch: ultra-expanded; ");
- break;
- default:
- break;
- }
- }
- if (set & PANGO2_FONT_MASK_SIZE)
- {
- g_string_append_printf (s, "font-size: %dpt; ", pango2_font_description_get_size (desc) /
PANGO2_SCALE);
- }
-
- if (set & PANGO2_FONT_MASK_VARIATIONS)
- {
- const char *variations;
-
- g_string_append (s, "font-variation-settings: ");
- variations = pango2_font_description_get_variations (desc);
- add_css_variations (s, variations);
- g_string_append (s, "; ");
- }
- if (features)
- {
- g_string_append_printf (s, "font-feature-settings: %s;", features);
- }
-
- g_string_append (s, "}");
-
- return g_string_free (s, FALSE);
-}
-
static void
gtk_font_button_label_use_font (GtkFontButton *font_button)
{
- GtkStyleContext *context;
-
- context = gtk_widget_get_style_context (font_button->font_label);
-
if (!font_button->use_font)
{
- if (font_button->provider)
- {
- gtk_style_context_remove_provider (context, GTK_STYLE_PROVIDER (font_button->provider));
- g_clear_object (&font_button->provider);
- }
+ gtk_label_set_attributes (GTK_LABEL (font_button->font_label), NULL);
}
else
{
Pango2FontDescription *desc;
- char *data;
-
- if (!font_button->provider)
- {
- font_button->provider = gtk_css_provider_new ();
- gtk_style_context_add_provider (context,
- GTK_STYLE_PROVIDER (font_button->provider),
- GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
- }
desc = pango2_font_description_copy (font_button->font_desc);
if (!font_button->use_size)
pango2_font_description_unset_fields (desc, PANGO2_FONT_MASK_SIZE);
- data = pango2_font_description_to_css (desc,
- font_button->font_features,
- pango2_language_to_string (font_button->language));
- gtk_css_provider_load_from_data (font_button->provider, data, -1);
+ Pango2AttrList *attrs = pango2_attr_list_new ();
+
+ if ((font_button->level & GTK_FONT_CHOOSER_LEVEL_FEATURES) != 0 &&
+ font_button->font_features != NULL)
+ pango2_attr_list_insert (attrs, pango2_attr_font_features_new (font_button->font_features));
+
+ if ((font_button->level & GTK_FONT_CHOOSER_LEVEL_PALETTE) != 0 && font_button->palette != NULL)
+ {
+ pango2_attr_list_insert (attrs, pango2_attr_palette_new (font_button->palette));
+ g_print ("using palette %s\n", font_button->palette);
+ }
+
+ pango2_attr_list_insert (attrs, pango2_attr_font_desc_new (desc));
+ gtk_label_set_attributes (GTK_LABEL (font_button->font_label), attrs);
+ pango2_attr_list_unref (attrs);
- g_free (data);
pango2_font_description_free (desc);
}
}
diff --git a/gtk/gtkfontchooser.c b/gtk/gtkfontchooser.c
index b569dfe9de..1ced14b7f3 100644
--- a/gtk/gtkfontchooser.c
+++ b/gtk/gtkfontchooser.c
@@ -123,6 +123,17 @@ gtk_font_chooser_default_init (GtkFontChooserInterface *iface)
"",
GTK_PARAM_READABLE));
+ /**
+ * GtkFontChooser:palette: (attributes org.gtk.Property.get=gtk_font_chooser_get_palette)
+ *
+ * The selected palette.
+ */
+ g_object_interface_install_property
+ (iface,
+ g_param_spec_string ("palette", NULL, NULL,
+ "default",
+ GTK_PARAM_READABLE));
+
/**
* GtkFontChooser:language: (attributes org.gtk.Property.get=gtk_font_chooser_get_language
org.gtk.Property.set=gtk_font_chooser_set_language)
*
@@ -538,6 +549,26 @@ gtk_font_chooser_get_font_features (GtkFontChooser *fontchooser)
return text;
}
+/**
+ * gtk_font_chooser_get_palette: (attributes org.gtk.Method.get_property=palette)
+ * @fontchooser: a `GtkFontChooser`
+ *
+ * Gets the currently-selected palette.
+ *
+ * Returns: the currently selected palette
+ */
+char *
+gtk_font_chooser_get_palette (GtkFontChooser *fontchooser)
+{
+ char *text;
+
+ g_return_val_if_fail (GTK_IS_FONT_CHOOSER (fontchooser), NULL);
+
+ g_object_get (fontchooser, "palette", &text, NULL);
+
+ return text;
+}
+
/**
* gtk_font_chooser_get_language: (attributes org.gtk.Method.get_property=language)
* @fontchooser: a `GtkFontChooser`
diff --git a/gtk/gtkfontchooser.h b/gtk/gtkfontchooser.h
index 44027951a9..d61efed40b 100644
--- a/gtk/gtkfontchooser.h
+++ b/gtk/gtkfontchooser.h
@@ -53,6 +53,7 @@ typedef gboolean (*GtkFontFilterFunc) (const Pango2FontFamily *family,
* @GTK_FONT_CHOOSER_LEVEL_SIZE: Allow selecting a specific font size
* @GTK_FONT_CHOOSER_LEVEL_VARIATIONS: Allow changing OpenType font variation axes
* @GTK_FONT_CHOOSER_LEVEL_FEATURES: Allow selecting specific OpenType font features
+ * @GTK_FONT_CHOOSER_LEVEL_PALETTE: Allow selecting a color palette
*
* Specifies the granularity of font selection
* that is desired in a `GtkFontChooser`.
@@ -65,7 +66,8 @@ typedef enum {
GTK_FONT_CHOOSER_LEVEL_STYLE = 1 << 0,
GTK_FONT_CHOOSER_LEVEL_SIZE = 1 << 1,
GTK_FONT_CHOOSER_LEVEL_VARIATIONS = 1 << 2,
- GTK_FONT_CHOOSER_LEVEL_FEATURES = 1 << 3
+ GTK_FONT_CHOOSER_LEVEL_FEATURES = 1 << 3,
+ GTK_FONT_CHOOSER_LEVEL_PALETTE = 1 << 4,
} GtkFontChooserLevel;
#define GTK_TYPE_FONT_CHOOSER (gtk_font_chooser_get_type ())
@@ -156,6 +158,8 @@ GtkFontChooserLevel
GDK_AVAILABLE_IN_ALL
char * gtk_font_chooser_get_font_features (GtkFontChooser *fontchooser);
GDK_AVAILABLE_IN_ALL
+char * gtk_font_chooser_get_palette (GtkFontChooser *fontchooser);
+GDK_AVAILABLE_IN_ALL
char * gtk_font_chooser_get_language (GtkFontChooser *fontchooser);
GDK_AVAILABLE_IN_ALL
void gtk_font_chooser_set_language (GtkFontChooser *fontchooser,
diff --git a/gtk/gtkfontchooserdialog.c b/gtk/gtkfontchooserdialog.c
index 014091159c..d6c6fa2fa7 100644
--- a/gtk/gtkfontchooserdialog.c
+++ b/gtk/gtkfontchooserdialog.c
@@ -150,7 +150,9 @@ update_tweak_button (GtkFontChooserDialog *dialog)
return;
g_object_get (dialog->fontchooser, "level", &level, NULL);
- if ((level & (GTK_FONT_CHOOSER_LEVEL_FEATURES | GTK_FONT_CHOOSER_LEVEL_VARIATIONS)) != 0)
+ if ((level & (GTK_FONT_CHOOSER_LEVEL_FEATURES |
+ GTK_FONT_CHOOSER_LEVEL_VARIATIONS |
+ GTK_FONT_CHOOSER_LEVEL_PALETTE)) != 0)
gtk_widget_show (dialog->tweak_button);
else
gtk_widget_hide (dialog->tweak_button);
diff --git a/gtk/gtkfontchooserutils.c b/gtk/gtkfontchooserutils.c
index 2d8cc19fae..6da6946810 100644
--- a/gtk/gtkfontchooserutils.c
+++ b/gtk/gtkfontchooserutils.c
@@ -141,6 +141,9 @@ _gtk_font_chooser_install_properties (GObjectClass *klass)
g_object_class_override_property (klass,
GTK_FONT_CHOOSER_PROP_FONT_FEATURES,
"font-features");
+ g_object_class_override_property (klass,
+ GTK_FONT_CHOOSER_PROP_PALETTE,
+ "palette");
g_object_class_override_property (klass,
GTK_FONT_CHOOSER_PROP_LANGUAGE,
"language");
diff --git a/gtk/gtkfontchooserutils.h b/gtk/gtkfontchooserutils.h
index ac7bf18558..7efb33e22e 100644
--- a/gtk/gtkfontchooserutils.h
+++ b/gtk/gtkfontchooserutils.h
@@ -39,6 +39,7 @@ typedef enum {
GTK_FONT_CHOOSER_PROP_SHOW_PREVIEW_ENTRY,
GTK_FONT_CHOOSER_PROP_LEVEL,
GTK_FONT_CHOOSER_PROP_FONT_FEATURES,
+ GTK_FONT_CHOOSER_PROP_PALETTE,
GTK_FONT_CHOOSER_PROP_LANGUAGE,
GTK_FONT_CHOOSER_PROP_LAST
} GtkFontChooserProp;
diff --git a/gtk/gtkfontchooserwidget.c b/gtk/gtkfontchooserwidget.c
index 3370272757..fcdbd169a9 100644
--- a/gtk/gtkfontchooserwidget.c
+++ b/gtk/gtkfontchooserwidget.c
@@ -62,6 +62,8 @@
#include "gtklistview.h"
#include "gtksortlistmodel.h"
#include "gtkstringsorter.h"
+#include "gtkcolorswatchprivate.h"
+#include "gtkpicture.h"
#include <hb-ot.h>
@@ -122,6 +124,7 @@ struct _GtkFontChooserWidget
GtkWidget *axis_grid;
GtkWidget *feature_box;
+ GtkWidget *palette_grid;
GtkFrame *language_button;
GtkFrame *language_frame;
@@ -136,7 +139,8 @@ struct _GtkFontChooserWidget
Pango2FontMap *font_map;
Pango2FontDescription *font_desc;
- char *font_features;
+ char *font_features;
+ char *palette;
Pango2Language *language;
GtkFontFilterFunc filter_func;
@@ -276,6 +280,9 @@ gtk_font_chooser_widget_get_property (GObject *object,
case GTK_FONT_CHOOSER_PROP_FONT_FEATURES:
g_value_set_string (value, fontchooser->font_features);
break;
+ case GTK_FONT_CHOOSER_PROP_PALETTE:
+ g_value_set_string (value, fontchooser->palette);
+ break;
case GTK_FONT_CHOOSER_PROP_LANGUAGE:
g_value_set_string (value, pango2_language_to_string (fontchooser->language));
break;
@@ -718,6 +725,8 @@ gtk_font_chooser_widget_update_preview_attributes (GtkFontChooserWidget *fontcho
pango2_attr_list_insert (attrs, pango2_attr_font_desc_new (fontchooser->font_desc));
if (fontchooser->font_features)
pango2_attr_list_insert (attrs, pango2_attr_font_features_new (fontchooser->font_features));
+ if (fontchooser->palette)
+ pango2_attr_list_insert (attrs, pango2_attr_palette_new (fontchooser->palette));
if (fontchooser->language)
pango2_attr_list_insert (attrs, pango2_attr_language_new (fontchooser->language));
@@ -884,6 +893,7 @@ gtk_font_chooser_widget_class_init (GtkFontChooserWidgetClass *klass)
gtk_widget_class_bind_template_child (widget_class, GtkFontChooserWidget, grid);
gtk_widget_class_bind_template_child (widget_class, GtkFontChooserWidget, font_name_label);
gtk_widget_class_bind_template_child (widget_class, GtkFontChooserWidget, feature_box);
+ gtk_widget_class_bind_template_child (widget_class, GtkFontChooserWidget, palette_grid);
gtk_widget_class_bind_template_child (widget_class, GtkFontChooserWidget, axis_grid);
gtk_widget_class_bind_template_child (widget_class, GtkFontChooserWidget, language_button);
gtk_widget_class_bind_template_child (widget_class, GtkFontChooserWidget, language_frame);
@@ -1285,6 +1295,7 @@ gtk_font_chooser_widget_finalize (GObject *object)
g_hash_table_unref (fontchooser->axes);
g_free (fontchooser->font_features);
+ g_free (fontchooser->palette);
G_OBJECT_CLASS (gtk_font_chooser_widget_parent_class)->finalize (object);
}
@@ -2069,18 +2080,11 @@ font_feature_toggled_cb (GtkCheckButton *check_button,
update_font_features (fontchooser);
}
-static void
-add_check_group (GtkFontChooserWidget *fontchooser,
- const char *title,
- const char **tags)
+static GtkWidget *
+make_title_label (const char *title)
{
GtkWidget *label;
- GtkWidget *group;
Pango2AttrList *attrs;
- int i;
-
- group = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
- gtk_widget_set_halign (group, GTK_ALIGN_FILL);
label = gtk_label_new (title);
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
@@ -2090,7 +2094,22 @@ add_check_group (GtkFontChooserWidget *fontchooser,
pango2_attr_list_insert (attrs, pango2_attr_weight_new (PANGO2_WEIGHT_BOLD));
gtk_label_set_attributes (GTK_LABEL (label), attrs);
pango2_attr_list_unref (attrs);
- gtk_box_append (GTK_BOX (group), label);
+
+ return label;
+}
+
+static void
+add_check_group (GtkFontChooserWidget *fontchooser,
+ const char *title,
+ const char **tags)
+{
+ GtkWidget *group;
+ int i;
+
+ group = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+ gtk_widget_set_halign (group, GTK_ALIGN_FILL);
+
+ gtk_box_append (GTK_BOX (group), make_title_label (title));
for (i = 0; tags[i]; i++)
{
@@ -2144,24 +2163,14 @@ add_radio_group (GtkFontChooserWidget *fontchooser,
const char *title,
const char **tags)
{
- GtkWidget *label;
GtkWidget *group;
int i;
GtkWidget *group_button = NULL;
- Pango2AttrList *attrs;
group = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_widget_set_halign (group, GTK_ALIGN_FILL);
- label = gtk_label_new (title);
- gtk_label_set_xalign (GTK_LABEL (label), 0.0);
- gtk_widget_set_halign (label, GTK_ALIGN_START);
- g_object_set (label, "margin-top", 10, "margin-bottom", 10, NULL);
- attrs = pango2_attr_list_new ();
- pango2_attr_list_insert (attrs, pango2_attr_weight_new (PANGO2_WEIGHT_BOLD));
- gtk_label_set_attributes (GTK_LABEL (label), attrs);
- pango2_attr_list_unref (attrs);
- gtk_box_append (GTK_BOX (group), label);
+ gtk_box_append (GTK_BOX (group), make_title_label (title));
for (i = 0; tags[i]; i++)
{
@@ -2386,6 +2395,164 @@ update_font_features (GtkFontChooserWidget *fontchooser)
gtk_font_chooser_widget_update_preview_attributes (fontchooser);
}
+static void
+palette_changed (GtkCheckButton *button,
+ gpointer data)
+{
+ GtkFontChooserWidget *fontchooser = data;
+ const char *palette;
+
+ palette = (const char *) g_object_get_data (G_OBJECT (button), "palette");
+
+ if (g_strcmp0 (fontchooser->palette, palette) != 0)
+ {
+ g_free (fontchooser->palette);
+ fontchooser->palette = g_strdup (palette);
+ g_object_notify (G_OBJECT (fontchooser), "palette");
+ }
+
+ gtk_font_chooser_widget_update_preview_attributes (fontchooser);
+}
+
+static gboolean
+gtk_font_chooser_widget_update_palettes (GtkFontChooserWidget *fontchooser)
+{
+ GtkWidget *child;
+ Pango2Font *font;
+ Pango2FontFace *face;
+ hb_font_t *hb_font;
+ hb_face_t *hb_face;
+
+ if ((fontchooser->level & GTK_FONT_CHOOSER_LEVEL_PALETTE) == 0)
+ return FALSE;
+
+ while ((child = gtk_widget_get_first_child (fontchooser->palette_grid)))
+ gtk_grid_remove (GTK_GRID (fontchooser->palette_grid), child);
+
+ font = pango2_context_load_font (gtk_widget_get_pango_context (GTK_WIDGET (fontchooser)),
+ fontchooser->font_desc);
+ face = pango2_font_get_face (font);
+
+ hb_font = pango2_font_get_hb_font (font);
+ hb_face = hb_font_get_face (hb_font);
+
+ if (hb_ot_color_has_palettes (hb_face))
+ {
+ GtkWidget *first_palette = NULL;
+ GtkWidget *toggle;
+ GtkWidget *box;
+
+ gtk_grid_attach (GTK_GRID (fontchooser->palette_grid),
+ make_title_label (_("Color Palettes")),
+ 0, -2, 3, 1);
+
+ box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
+ gtk_box_set_homogeneous (GTK_BOX (box), TRUE);
+ gtk_grid_attach (GTK_GRID (fontchooser->palette_grid), box, 0, -1, 4, 1);
+
+ toggle = gtk_check_button_new_with_label (_("Default"));
+ g_object_set_data (G_OBJECT (toggle), "palette", (gpointer) "default");
+ g_signal_connect (toggle, "toggled", G_CALLBACK (palette_changed), fontchooser);
+ if (fontchooser->palette == NULL ||
+ g_strcmp0 (fontchooser->palette, "default") == 0)
+ gtk_check_button_set_active (GTK_CHECK_BUTTON (toggle), TRUE);
+ gtk_box_append (GTK_BOX (box), toggle);
+ first_palette = toggle;
+
+ toggle = gtk_check_button_new_with_label (_("Light"));
+ g_object_set_data (G_OBJECT (toggle), "palette", (gpointer) "light");
+ g_signal_connect (toggle, "toggled", G_CALLBACK (palette_changed), fontchooser);
+ if (g_strcmp0 (fontchooser->palette, "light") == 0)
+ gtk_check_button_set_active (GTK_CHECK_BUTTON (toggle), TRUE);
+ gtk_check_button_set_group (GTK_CHECK_BUTTON (toggle), GTK_CHECK_BUTTON (first_palette));
+ gtk_box_append (GTK_BOX (box), toggle);
+
+ toggle = gtk_check_button_new_with_label (_("Dark"));
+ g_object_set_data (G_OBJECT (toggle), "palette", (gpointer) "dark");
+ g_signal_connect (toggle, "toggled", G_CALLBACK (palette_changed), fontchooser);
+ if (g_strcmp0 (fontchooser->palette, "dark") == 0)
+ gtk_check_button_set_active (GTK_CHECK_BUTTON (toggle), TRUE);
+ gtk_check_button_set_group (GTK_CHECK_BUTTON (toggle), GTK_CHECK_BUTTON (first_palette));
+ gtk_box_append (GTK_BOX (box), toggle);
+
+ for (unsigned int i = 0; i < hb_ot_color_palette_get_count (hb_face); i++)
+ {
+ char *palette;
+ char *label;
+ hb_ot_name_id_t name_id;
+ unsigned int n_colors;
+ hb_color_t *colors;
+ GtkWidget *colors_grid;
+
+ palette = g_strdup (pango2_hb_face_get_palette_name (PANGO2_HB_FACE (face), i));
+
+ /* Look for a display name in the font, unlikely as it is */
+ name_id = hb_ot_color_palette_get_name_id (hb_face, i);
+ if (name_id != HB_OT_NAME_ID_INVALID)
+ {
+ char buf[80];
+ unsigned int len;
+
+ len = sizeof (buf);
+ hb_ot_name_get_utf8 (hb_face, name_id, HB_LANGUAGE_INVALID, &len, buf);
+ label = g_strdup (buf);
+ }
+ else if (palette)
+ label = g_strdup_printf (_("Palette %s"), palette);
+ else
+ label = g_strdup_printf (_("Palette %u"), i);
+
+ if (!palette)
+ palette = g_strdup_printf ("palette%u", i);
+
+ toggle = gtk_check_button_new_with_label (label);
+ g_object_set_data_full (G_OBJECT (toggle), "palette", palette, g_free);
+ if (g_strcmp0 (fontchooser->palette, palette) == 0)
+ gtk_check_button_set_active (GTK_CHECK_BUTTON (toggle), TRUE);
+
+ g_signal_connect (toggle, "toggled", G_CALLBACK (palette_changed), fontchooser);
+
+ gtk_check_button_set_group (GTK_CHECK_BUTTON (toggle), GTK_CHECK_BUTTON (first_palette));
+
+ g_free (label);
+
+ int row = i / 3;
+ int col = i % 3;
+ gtk_grid_attach (GTK_GRID (fontchooser->palette_grid), toggle, 2 * col, row, 1, 1);
+
+ n_colors = hb_ot_color_palette_get_colors (hb_face, i, 0, NULL, NULL);
+ colors = g_new (hb_color_t, n_colors);
+ n_colors = hb_ot_color_palette_get_colors (hb_face, i, 0, &n_colors, colors);
+
+ colors_grid = gtk_grid_new ();
+ gtk_grid_attach (GTK_GRID (fontchooser->palette_grid), colors_grid, 2 * col + 1, row, 1, 1);
+ gtk_widget_set_valign (colors_grid, GTK_ALIGN_CENTER);
+
+ /* HACK - defeat first-child/last-child theming */
+ gtk_grid_attach (GTK_GRID (colors_grid), gtk_picture_new (), -1, 0, 1, 1);
+
+ for (int k = 0; k < n_colors; k++)
+ {
+ GtkWidget *color;
+
+ color = gtk_color_swatch_new ();
+ gtk_color_swatch_set_rgba (GTK_COLOR_SWATCH (color),
+ &(GdkRGBA){ hb_color_get_red (colors[k])/255.,
+ hb_color_get_green (colors[k])/255.,
+ hb_color_get_blue (colors[k])/255.,
+ hb_color_get_alpha (colors[k])/255.});
+ gtk_widget_set_size_request (color, 16, 16);
+ gtk_grid_attach (GTK_GRID (colors_grid), color, k % 5, k / 5, 1, 1);
+ }
+
+ /* HACK - defeat first-child/last-child theming */
+ gtk_grid_attach (GTK_GRID (colors_grid), gtk_picture_new (), 6, 0, 1, 1);
+ }
+ }
+
+ return TRUE;
+}
+
static void
gtk_font_chooser_widget_merge_font_desc (GtkFontChooserWidget *fontchooser,
const Pango2FontDescription *font_desc)
@@ -2424,6 +2591,8 @@ gtk_font_chooser_widget_merge_font_desc (GtkFontChooserWidget *fontchooser
has_tweak = TRUE;
if (gtk_font_chooser_widget_update_font_variations (fontchooser))
has_tweak = TRUE;
+ if (gtk_font_chooser_widget_update_palettes (fontchooser))
+ has_tweak = TRUE;
g_simple_action_set_enabled (G_SIMPLE_ACTION (fontchooser->tweak_action), has_tweak);
}
diff --git a/gtk/ui/gtkfontchooserwidget.ui b/gtk/ui/gtkfontchooserwidget.ui
index c7079a1201..1efa9cbb91 100644
--- a/gtk/ui/gtkfontchooserwidget.ui
+++ b/gtk/ui/gtkfontchooserwidget.ui
@@ -387,6 +387,12 @@
<property name="spacing">12</property>
</object>
</child>
+ <child>
+ <object class="GtkGrid" id="palette_grid">
+ <property name="row-spacing">12</property>
+ <property name="column-spacing">12</property>
+ </object>
+ </child>
</object>
</child>
</object>
diff --git a/tests/testfontchooserdialog.c b/tests/testfontchooserdialog.c
index 81e45985b1..b039d041a8 100644
--- a/tests/testfontchooserdialog.c
+++ b/tests/testfontchooserdialog.c
@@ -173,6 +173,10 @@ main (int argc, char *argv[])
g_object_set_data (G_OBJECT (toggle), "flag", GUINT_TO_POINTER (GTK_FONT_CHOOSER_LEVEL_FEATURES));
g_signal_connect (toggle, "notify::active", G_CALLBACK (level_changed), font_button);
gtk_box_append (GTK_BOX (box), toggle);
+ toggle = gtk_check_button_new_with_label ("Palette");
+ g_object_set_data (G_OBJECT (toggle), "flag", GUINT_TO_POINTER (GTK_FONT_CHOOSER_LEVEL_PALETTE));
+ g_signal_connect (toggle, "notify::active", G_CALLBACK (level_changed), font_button);
+ gtk_box_append (GTK_BOX (box), toggle);
gtk_widget_show (window);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]