forked from AuroraMiddleware/gtk
fontchooserwidget: Refactor code so we actually optimize
Previously, we would pango_font_describe() every time the code ran and we wouldn't ever hit the optimized quick exit. The code now is a lot more complex because the compute-actual-value-when-required-the-first-time approach is not supported out of the box in GtkTreeModel (or GValue).
This commit is contained in:
parent
3fc5d09890
commit
31191d5566
@ -145,9 +145,9 @@ static void gtk_font_chooser_widget_set_font (GtkFontChooserWidget *
|
|||||||
const gchar *fontname);
|
const gchar *fontname);
|
||||||
|
|
||||||
static PangoFontDescription *gtk_font_chooser_widget_get_font_desc (GtkFontChooserWidget *fontchooser);
|
static PangoFontDescription *gtk_font_chooser_widget_get_font_desc (GtkFontChooserWidget *fontchooser);
|
||||||
static void gtk_font_chooser_widget_merge_font_desc(GtkFontChooserWidget *fontchooser,
|
static void gtk_font_chooser_widget_merge_font_desc(GtkFontChooserWidget *fontchooser,
|
||||||
PangoFontDescription *font_desc,
|
const PangoFontDescription *font_desc,
|
||||||
GtkTreeIter *iter);
|
GtkTreeIter *iter);
|
||||||
static void gtk_font_chooser_widget_take_font_desc (GtkFontChooserWidget *fontchooser,
|
static void gtk_font_chooser_widget_take_font_desc (GtkFontChooserWidget *fontchooser,
|
||||||
PangoFontDescription *font_desc);
|
PangoFontDescription *font_desc);
|
||||||
|
|
||||||
@ -179,6 +179,63 @@ G_DEFINE_TYPE_WITH_CODE (GtkFontChooserWidget, gtk_font_chooser_widget, GTK_TYPE
|
|||||||
G_IMPLEMENT_INTERFACE (GTK_TYPE_FONT_CHOOSER,
|
G_IMPLEMENT_INTERFACE (GTK_TYPE_FONT_CHOOSER,
|
||||||
gtk_font_chooser_widget_iface_init))
|
gtk_font_chooser_widget_iface_init))
|
||||||
|
|
||||||
|
typedef struct _GtkDelayedFontDescription GtkDelayedFontDescription;
|
||||||
|
struct _GtkDelayedFontDescription {
|
||||||
|
PangoFontFace *face;
|
||||||
|
PangoFontDescription *desc;
|
||||||
|
guint ref_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
static GtkDelayedFontDescription *
|
||||||
|
gtk_delayed_font_description_new (PangoFontFace *face)
|
||||||
|
{
|
||||||
|
GtkDelayedFontDescription *result;
|
||||||
|
|
||||||
|
result = g_slice_new0 (GtkDelayedFontDescription);
|
||||||
|
|
||||||
|
result->face = g_object_ref (face);
|
||||||
|
result->desc = NULL;
|
||||||
|
result->ref_count = 1;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GtkDelayedFontDescription *
|
||||||
|
gtk_delayed_font_description_ref (GtkDelayedFontDescription *desc)
|
||||||
|
{
|
||||||
|
desc->ref_count++;
|
||||||
|
|
||||||
|
return desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gtk_delayed_font_description_unref (GtkDelayedFontDescription *desc)
|
||||||
|
{
|
||||||
|
desc->ref_count--;
|
||||||
|
|
||||||
|
if (desc->ref_count > 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
g_object_unref (desc->face);
|
||||||
|
if (desc->desc)
|
||||||
|
pango_font_description_free (desc->desc);
|
||||||
|
|
||||||
|
g_slice_free (GtkDelayedFontDescription, desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const PangoFontDescription *
|
||||||
|
gtk_delayed_font_description_get (GtkDelayedFontDescription *desc)
|
||||||
|
{
|
||||||
|
if (desc->desc == NULL)
|
||||||
|
desc->desc = pango_font_face_describe (desc->face);
|
||||||
|
|
||||||
|
return desc->desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define GTK_TYPE_DELAYED_FONT_DESCRIPTION (gtk_delayed_font_description_get_type ())
|
||||||
|
G_DEFINE_BOXED_TYPE (GtkDelayedFontDescription, gtk_delayed_font_description,
|
||||||
|
gtk_delayed_font_description_ref,
|
||||||
|
gtk_delayed_font_description_unref)
|
||||||
static void
|
static void
|
||||||
gtk_font_chooser_widget_set_property (GObject *object,
|
gtk_font_chooser_widget_set_property (GObject *object,
|
||||||
guint prop_id,
|
guint prop_id,
|
||||||
@ -379,39 +436,13 @@ row_activated_cb (GtkTreeView *view,
|
|||||||
g_free (fontname);
|
g_free (fontname);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PangoFontDescription *
|
|
||||||
tree_model_get_font_description (GtkTreeModel *model,
|
|
||||||
GtkTreeIter *iter)
|
|
||||||
{
|
|
||||||
PangoFontDescription *desc, *face_desc;
|
|
||||||
PangoFontFace *face;
|
|
||||||
|
|
||||||
gtk_tree_model_get (model, iter,
|
|
||||||
FONT_DESC_COLUMN, &desc,
|
|
||||||
-1);
|
|
||||||
if (pango_font_description_get_set_fields (desc) != 0)
|
|
||||||
return desc;
|
|
||||||
|
|
||||||
gtk_tree_model_get (model, iter,
|
|
||||||
FACE_COLUMN, &face,
|
|
||||||
-1);
|
|
||||||
face_desc = pango_font_face_describe (face);
|
|
||||||
g_object_unref (face);
|
|
||||||
|
|
||||||
pango_font_description_merge (desc, face_desc, TRUE);
|
|
||||||
|
|
||||||
pango_font_description_free (face_desc);
|
|
||||||
|
|
||||||
return desc;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cursor_changed_cb (GtkTreeView *treeview,
|
cursor_changed_cb (GtkTreeView *treeview,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
GtkFontChooserWidget *fontchooser = user_data;
|
GtkFontChooserWidget *fontchooser = user_data;
|
||||||
GtkFontChooserWidgetPrivate *priv = fontchooser->priv;
|
GtkFontChooserWidgetPrivate *priv = fontchooser->priv;
|
||||||
PangoFontDescription *desc;
|
GtkDelayedFontDescription *desc;
|
||||||
GtkTreeIter filter_iter, iter;
|
GtkTreeIter filter_iter, iter;
|
||||||
GtkTreePath *path = NULL;
|
GtkTreePath *path = NULL;
|
||||||
|
|
||||||
@ -431,9 +462,15 @@ cursor_changed_cb (GtkTreeView *treeview,
|
|||||||
gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (priv->filter_model),
|
gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (priv->filter_model),
|
||||||
&iter,
|
&iter,
|
||||||
&filter_iter);
|
&filter_iter);
|
||||||
desc = tree_model_get_font_description (priv->model, &iter);
|
gtk_tree_model_get (priv->filter_model, &iter,
|
||||||
|
FONT_DESC_COLUMN, &desc,
|
||||||
|
-1);
|
||||||
|
|
||||||
gtk_font_chooser_widget_merge_font_desc (fontchooser, desc, &iter);
|
gtk_font_chooser_widget_merge_font_desc (fontchooser,
|
||||||
|
gtk_delayed_font_description_get (desc),
|
||||||
|
&iter);
|
||||||
|
|
||||||
|
gtk_delayed_font_description_unref (desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -515,6 +552,8 @@ gtk_font_chooser_widget_class_init (GtkFontChooserWidgetClass *klass)
|
|||||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||||
|
|
||||||
|
g_type_ensure (GTK_TYPE_DELAYED_FONT_DESCRIPTION);
|
||||||
|
|
||||||
widget_class->screen_changed = gtk_font_chooser_widget_screen_changed;
|
widget_class->screen_changed = gtk_font_chooser_widget_screen_changed;
|
||||||
widget_class->style_updated = gtk_font_chooser_widget_style_updated;
|
widget_class->style_updated = gtk_font_chooser_widget_style_updated;
|
||||||
|
|
||||||
@ -676,23 +715,23 @@ gtk_font_chooser_widget_load_fonts (GtkFontChooserWidget *fontchooser,
|
|||||||
|
|
||||||
for (j = 0; j < n_faces; j++)
|
for (j = 0; j < n_faces; j++)
|
||||||
{
|
{
|
||||||
PangoFontDescription *empty_font_desc;
|
GtkDelayedFontDescription *desc;
|
||||||
const gchar *face_name;
|
const gchar *face_name;
|
||||||
|
|
||||||
face_name = pango_font_face_get_face_name (faces[j]);
|
face_name = pango_font_face_get_face_name (faces[j]);
|
||||||
|
|
||||||
family_and_face = g_strconcat (fam_name, " ", face_name, NULL);
|
family_and_face = g_strconcat (fam_name, " ", face_name, NULL);
|
||||||
empty_font_desc = pango_font_description_new ();
|
desc = gtk_delayed_font_description_new (faces[j]);
|
||||||
|
|
||||||
gtk_list_store_insert_with_values (list_store, &iter, -1,
|
gtk_list_store_insert_with_values (list_store, &iter, -1,
|
||||||
FAMILY_COLUMN, families[i],
|
FAMILY_COLUMN, families[i],
|
||||||
FACE_COLUMN, faces[j],
|
FACE_COLUMN, faces[j],
|
||||||
FONT_DESC_COLUMN, empty_font_desc,
|
FONT_DESC_COLUMN, desc,
|
||||||
PREVIEW_TITLE_COLUMN, family_and_face,
|
PREVIEW_TITLE_COLUMN, family_and_face,
|
||||||
-1);
|
-1);
|
||||||
|
|
||||||
g_free (family_and_face);
|
g_free (family_and_face);
|
||||||
pango_font_description_free (empty_font_desc);
|
gtk_delayed_font_description_unref (desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_free (faces);
|
g_free (faces);
|
||||||
@ -830,22 +869,21 @@ gtk_font_chooser_widget_cell_data_func (GtkTreeViewColumn *column,
|
|||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
GtkFontChooserWidget *fontchooser = user_data;
|
GtkFontChooserWidget *fontchooser = user_data;
|
||||||
PangoFontDescription *font_desc;
|
GtkDelayedFontDescription *desc;
|
||||||
PangoAttrList *attrs;
|
PangoAttrList *attrs;
|
||||||
char *preview_title, *text;
|
char *preview_title, *text;
|
||||||
gsize first_line_len;
|
gsize first_line_len;
|
||||||
|
|
||||||
font_desc = tree_model_get_font_description (tree_model, iter);
|
|
||||||
|
|
||||||
gtk_tree_model_get (tree_model, iter,
|
gtk_tree_model_get (tree_model, iter,
|
||||||
PREVIEW_TITLE_COLUMN, &preview_title,
|
PREVIEW_TITLE_COLUMN, &preview_title,
|
||||||
|
FONT_DESC_COLUMN, &desc,
|
||||||
-1);
|
-1);
|
||||||
|
|
||||||
text = g_strconcat (preview_title, "\n", fontchooser->priv->preview_text, NULL);
|
text = g_strconcat (preview_title, "\n", fontchooser->priv->preview_text, NULL);
|
||||||
first_line_len = strlen (preview_title) + 1;
|
first_line_len = strlen (preview_title) + 1;
|
||||||
|
|
||||||
attrs = gtk_font_chooser_widget_get_preview_attributes (fontchooser,
|
attrs = gtk_font_chooser_widget_get_preview_attributes (fontchooser,
|
||||||
font_desc,
|
gtk_delayed_font_description_get (desc),
|
||||||
first_line_len);
|
first_line_len);
|
||||||
|
|
||||||
g_object_set (cell,
|
g_object_set (cell,
|
||||||
@ -853,7 +891,7 @@ gtk_font_chooser_widget_cell_data_func (GtkTreeViewColumn *column,
|
|||||||
"text", text,
|
"text", text,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
pango_font_description_free (font_desc);
|
gtk_delayed_font_description_unref (desc);
|
||||||
pango_attr_list_unref (attrs);
|
pango_attr_list_unref (attrs);
|
||||||
g_free (text);
|
g_free (text);
|
||||||
g_free (preview_title);
|
g_free (preview_title);
|
||||||
@ -928,26 +966,37 @@ gtk_font_chooser_widget_find_font (GtkFontChooserWidget *fontchooser,
|
|||||||
valid;
|
valid;
|
||||||
valid = gtk_tree_model_iter_next (priv->model, iter))
|
valid = gtk_tree_model_iter_next (priv->model, iter))
|
||||||
{
|
{
|
||||||
PangoFontDescription *desc;
|
GtkDelayedFontDescription *desc;
|
||||||
|
PangoFontDescription *merged;
|
||||||
PangoFontFamily *family;
|
PangoFontFamily *family;
|
||||||
|
|
||||||
gtk_tree_model_get (priv->model, iter,
|
gtk_tree_model_get (priv->model, iter,
|
||||||
FAMILY_COLUMN, &family,
|
FAMILY_COLUMN, &family,
|
||||||
|
FONT_DESC_COLUMN, &desc,
|
||||||
-1);
|
-1);
|
||||||
|
|
||||||
if (!my_pango_font_family_equal (pango_font_description_get_family (font_desc),
|
if (!my_pango_font_family_equal (pango_font_description_get_family (font_desc),
|
||||||
pango_font_family_get_name (family)))
|
pango_font_family_get_name (family)))
|
||||||
continue;
|
{
|
||||||
|
gtk_delayed_font_description_unref (desc);
|
||||||
|
g_object_unref (family);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
desc = tree_model_get_font_description (priv->model, iter);
|
merged = pango_font_description_copy_static (gtk_delayed_font_description_get (desc));
|
||||||
|
|
||||||
pango_font_description_merge_static (desc, font_desc, FALSE);
|
pango_font_description_merge_static (merged, font_desc, FALSE);
|
||||||
if (pango_font_description_equal (desc, font_desc)) {
|
if (pango_font_description_equal (merged, font_desc))
|
||||||
pango_font_description_free (desc);
|
{
|
||||||
break;
|
gtk_delayed_font_description_unref (desc);
|
||||||
}
|
pango_font_description_free (merged);
|
||||||
|
g_object_unref (family);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
pango_font_description_free (desc);
|
gtk_delayed_font_description_unref (desc);
|
||||||
|
pango_font_description_free (merged);
|
||||||
|
g_object_unref (family);
|
||||||
}
|
}
|
||||||
|
|
||||||
return valid;
|
return valid;
|
||||||
@ -1092,9 +1141,9 @@ gtk_font_chooser_widget_ensure_selection (GtkFontChooserWidget *fontchooser)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gtk_font_chooser_widget_merge_font_desc (GtkFontChooserWidget *fontchooser,
|
gtk_font_chooser_widget_merge_font_desc (GtkFontChooserWidget *fontchooser,
|
||||||
PangoFontDescription *font_desc,
|
const PangoFontDescription *font_desc,
|
||||||
GtkTreeIter *iter)
|
GtkTreeIter *iter)
|
||||||
{
|
{
|
||||||
GtkFontChooserWidgetPrivate *priv = fontchooser->priv;
|
GtkFontChooserWidgetPrivate *priv = fontchooser->priv;
|
||||||
PangoFontMask mask;
|
PangoFontMask mask;
|
||||||
@ -1107,10 +1156,7 @@ gtk_font_chooser_widget_merge_font_desc (GtkFontChooserWidget *fontchooser,
|
|||||||
/* sucky test, because we can't restrict the comparison to
|
/* sucky test, because we can't restrict the comparison to
|
||||||
* only the parts that actually do get merged */
|
* only the parts that actually do get merged */
|
||||||
if (pango_font_description_equal (font_desc, priv->font_desc))
|
if (pango_font_description_equal (font_desc, priv->font_desc))
|
||||||
{
|
return;
|
||||||
pango_font_description_free (font_desc);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
pango_font_description_merge (priv->font_desc, font_desc, TRUE);
|
pango_font_description_merge (priv->font_desc, font_desc, TRUE);
|
||||||
|
|
||||||
@ -1140,8 +1186,6 @@ gtk_font_chooser_widget_merge_font_desc (GtkFontChooserWidget *fontchooser,
|
|||||||
|
|
||||||
gtk_font_chooser_widget_update_preview_attributes (fontchooser);
|
gtk_font_chooser_widget_update_preview_attributes (fontchooser);
|
||||||
|
|
||||||
pango_font_description_free (font_desc); /* adopted */
|
|
||||||
|
|
||||||
g_object_notify (G_OBJECT (fontchooser), "font");
|
g_object_notify (G_OBJECT (fontchooser), "font");
|
||||||
g_object_notify (G_OBJECT (fontchooser), "font-desc");
|
g_object_notify (G_OBJECT (fontchooser), "font-desc");
|
||||||
}
|
}
|
||||||
@ -1171,6 +1215,8 @@ gtk_font_chooser_widget_take_font_desc (GtkFontChooserWidget *fontchooser,
|
|||||||
{
|
{
|
||||||
gtk_font_chooser_widget_merge_font_desc (fontchooser, font_desc, &priv->font_iter);
|
gtk_font_chooser_widget_merge_font_desc (fontchooser, font_desc, &priv->font_iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pango_font_description_free (font_desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const gchar*
|
static const gchar*
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
<!-- column-name face -->
|
<!-- column-name face -->
|
||||||
<column type="PangoFontFace"/>
|
<column type="PangoFontFace"/>
|
||||||
<!-- column-name description -->
|
<!-- column-name description -->
|
||||||
<column type="PangoFontDescription"/>
|
<column type="GtkDelayedFontDescription"/>
|
||||||
<!-- column-name preview-title -->
|
<!-- column-name preview-title -->
|
||||||
<column type="gchararray"/>
|
<column type="gchararray"/>
|
||||||
</columns>
|
</columns>
|
||||||
|
Loading…
Reference in New Issue
Block a user