summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOwen Taylor <otaylor@redhat.com>2004-11-21 15:58:43 +0000
committerOwen Taylor <otaylor@src.gnome.org>2004-11-21 15:58:43 +0000
commit666a3fe46a6f2dc2dffb79b9ad433cffa2540994 (patch)
treebd5d6fb66d4db37a20bc28382d98987d2fbd6fad
parent301a8f9b0f88011c1eba2ee6a1221aa9a03129f7 (diff)
downloadpango-666a3fe46a6f2dc2dffb79b9ad433cffa2540994.tar.gz
Don't just call pango_fontset_get_metrics() to implement
Sun Nov 21 10:52:03 2004 Owen Taylor <otaylor@redhat.com> * pango/pango-context.c: Don't just call pango_fontset_get_metrics() to implement pango_context_get_metrics(), since that skips our normal font selection algorithm. Rather itemize the sample string and get the metrics from that. (#149438, Felipe Heidrich)
-rw-r--r--ChangeLog7
-rw-r--r--ChangeLog.pre-1-107
-rw-r--r--ChangeLog.pre-1-87
-rw-r--r--pango/pango-context.c149
4 files changed, 161 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog
index a6c33956..067efe27 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+Sun Nov 21 10:52:03 2004 Owen Taylor <otaylor@redhat.com>
+
+ * pango/pango-context.c: Don't just call pango_fontset_get_metrics()
+ to implement pango_context_get_metrics(), since that skips our
+ normal font selection algorithm. Rather itemize the sample string
+ and get the metrics from that. (#149438, Felipe Heidrich)
+
2004-10-24 Tor Lillqvist <tml@iki.fi>
[Merge from HEAD]
diff --git a/ChangeLog.pre-1-10 b/ChangeLog.pre-1-10
index a6c33956..067efe27 100644
--- a/ChangeLog.pre-1-10
+++ b/ChangeLog.pre-1-10
@@ -1,3 +1,10 @@
+Sun Nov 21 10:52:03 2004 Owen Taylor <otaylor@redhat.com>
+
+ * pango/pango-context.c: Don't just call pango_fontset_get_metrics()
+ to implement pango_context_get_metrics(), since that skips our
+ normal font selection algorithm. Rather itemize the sample string
+ and get the metrics from that. (#149438, Felipe Heidrich)
+
2004-10-24 Tor Lillqvist <tml@iki.fi>
[Merge from HEAD]
diff --git a/ChangeLog.pre-1-8 b/ChangeLog.pre-1-8
index a6c33956..067efe27 100644
--- a/ChangeLog.pre-1-8
+++ b/ChangeLog.pre-1-8
@@ -1,3 +1,10 @@
+Sun Nov 21 10:52:03 2004 Owen Taylor <otaylor@redhat.com>
+
+ * pango/pango-context.c: Don't just call pango_fontset_get_metrics()
+ to implement pango_context_get_metrics(), since that skips our
+ normal font selection algorithm. Rather itemize the sample string
+ and get the metrics from that. (#149438, Felipe Heidrich)
+
2004-10-24 Tor Lillqvist <tml@iki.fi>
[Merge from HEAD]
diff --git a/pango/pango-context.c b/pango/pango-context.c
index 79b70187..f1d2c407 100644
--- a/pango/pango-context.c
+++ b/pango/pango-context.c
@@ -641,7 +641,8 @@ itemize_state_init (ItemizeState *state,
int start_index,
int length,
PangoAttrList *attrs,
- PangoAttrIterator *cached_iter)
+ PangoAttrIterator *cached_iter,
+ const PangoFontDescription *desc)
{
gunichar *text_ucs4;
long n_chars;
@@ -675,17 +676,35 @@ itemize_state_init (ItemizeState *state,
state->attr_iter = cached_iter;
state->free_attr_iter = FALSE;
}
- else
+ else if (attrs)
{
state->attr_iter = pango_attr_list_get_iterator (attrs);
state->free_attr_iter = TRUE;
}
+ else
+ {
+ state->attr_iter = NULL;
+ state->free_attr_iter = FALSE;
+ }
- state->font_desc = NULL;
- state->lang = NULL;
+ if (state->attr_iter)
+ {
+ state->font_desc = NULL;
+ state->lang = NULL;
- advance_attr_iterator_to (state->attr_iter, start_index);
- update_attr_iterator (state);
+ advance_attr_iterator_to (state->attr_iter, start_index);
+ update_attr_iterator (state);
+ }
+ else
+ {
+ state->font_desc = pango_font_description_copy_static (desc ? desc : state->context->font_desc);
+ state->lang = state->context->language;
+ state->extra_attrs = NULL;
+ state->copy_extra_attrs = FALSE;
+
+ state->attr_end = state->end;
+ state->enable_fallback = TRUE;
+ }
/* Initialize the script iterator
*/
@@ -1162,7 +1181,31 @@ pango_itemize_with_base_dir (PangoContext *context,
return NULL;
itemize_state_init (&state, context, text, base_dir, start_index, length,
- attrs, cached_iter);
+ attrs, cached_iter, NULL);
+
+ do
+ itemize_state_process_run (&state);
+ while (itemize_state_next (&state));
+
+ itemize_state_finish (&state);
+
+ return g_list_reverse (state.result);
+}
+
+static GList *
+itemize_with_font (PangoContext *context,
+ const char *text,
+ int start_index,
+ int length,
+ const PangoFontDescription *desc)
+{
+ ItemizeState state;
+
+ if (length == 0)
+ return NULL;
+
+ itemize_state_init (&state, context, text, context->base_dir, start_index, length,
+ NULL, NULL, desc);
do
itemize_state_process_run (&state);
@@ -1215,6 +1258,85 @@ pango_itemize (PangoContext *context,
text, start_index, length, attrs, cached_iter);
}
+static gboolean
+get_first_metrics_foreach (PangoFontset *fontset,
+ PangoFont *font,
+ gpointer data)
+{
+ PangoFontMetrics *fontset_metrics = data;
+ PangoLanguage *language = PANGO_FONTSET_GET_CLASS (fontset)->get_language (fontset);
+ PangoFontMetrics *font_metrics = pango_font_get_metrics (font, language);
+ guint save_ref_count;
+
+ /* Initialize the fontset metrics to metrics of the first font in the
+ * fontset; saving the refcount and restoring it is a bit of hack but avoids
+ * having to update this code for each metrics addition.
+ */
+ save_ref_count = fontset_metrics->ref_count;
+ *fontset_metrics = *font_metrics;
+ fontset_metrics->ref_count = save_ref_count;
+
+ pango_font_metrics_unref (font_metrics);
+
+ return TRUE; /* Stops iteration */
+}
+
+static PangoFontMetrics *
+get_base_metrics (PangoFontset *fontset)
+{
+ PangoFontMetrics *metrics = pango_font_metrics_new ();
+
+ /* Initialize the metrics from the first font in the fontset */
+ pango_fontset_foreach (fontset, get_first_metrics_foreach, metrics);
+
+ return metrics;
+}
+
+static void
+update_metrics_from_items (PangoFontMetrics *metrics,
+ PangoLanguage *language,
+ GList *items)
+
+{
+ GHashTable *fonts_seen = g_hash_table_new (NULL, NULL);
+ int count = 0;
+ GList *l;
+
+ for (l = items; l; l = l->next)
+ {
+ PangoItem *item = l->data;
+ PangoFont *font = item->analysis.font;
+
+ if (g_hash_table_lookup (fonts_seen, font) == NULL)
+ {
+ PangoFontMetrics *raw_metrics = pango_font_get_metrics (font, language);
+ g_hash_table_insert (fonts_seen, font, font);
+
+ /* metrics will already be initialized from the first font in the fontset */
+ metrics->ascent = MAX (metrics->ascent, raw_metrics->ascent);
+ metrics->descent = MAX (metrics->descent, raw_metrics->descent);
+
+ if (count == 0)
+ {
+ metrics->approximate_char_width = raw_metrics->approximate_char_width;
+ metrics->approximate_digit_width = raw_metrics->approximate_digit_width;
+ }
+ else
+ {
+ metrics->approximate_char_width += raw_metrics->approximate_char_width;
+ metrics->approximate_digit_width += raw_metrics->approximate_digit_width;
+ }
+ count++;
+ pango_font_metrics_unref (raw_metrics);
+ }
+ }
+
+ g_hash_table_destroy (fonts_seen);
+
+ metrics->approximate_char_width /= count;
+ metrics->approximate_digit_width /= count;
+}
+
/**
* pango_context_get_metrics:
* @context: a #PangoContext
@@ -1246,13 +1368,22 @@ pango_context_get_metrics (PangoContext *context,
{
PangoFontset *current_fonts = NULL;
PangoFontMetrics *metrics;
-
+ const char *sample_str;
+ GList *items;
+
g_return_val_if_fail (PANGO_IS_CONTEXT (context), NULL);
g_return_val_if_fail (desc != NULL, NULL);
current_fonts = pango_font_map_load_fontset (context->font_map, context, desc, language);
+ metrics = get_base_metrics (current_fonts);
+
+ sample_str = pango_language_get_sample_string (language);
+ items = itemize_with_font (context, sample_str, 0, strlen (sample_str), desc);
+
+ update_metrics_from_items (metrics, language, items);
- metrics = pango_fontset_get_metrics (current_fonts);
+ g_list_foreach (items, (GFunc)pango_item_free, NULL);
+ g_list_free (items);
g_object_unref (current_fonts);