summaryrefslogtreecommitdiff
path: root/pango
diff options
context:
space:
mode:
authorOwen Taylor <otaylor@redhat.com>2000-04-05 00:31:59 +0000
committerOwen Taylor <otaylor@src.gnome.org>2000-04-05 00:31:59 +0000
commit613302136667231bcefd772b419369516eb3bf45 (patch)
tree919ed907f3ca69f79210d0778c65df8bec97d4d0 /pango
parent52f2e805bf993f711d09ba6fe4972c7f7ee33eae (diff)
downloadpango-613302136667231bcefd772b419369516eb3bf45.tar.gz
Add user data to PangoContext
Tue Apr 4 20:13:06 2000 Owen Taylor <otaylor@redhat.com> * pango/pango-context.h: Add user data to PangoContext * pango/pangox.[ch] examples/viewer.c: Rework system for create GC's so that the necessary information is stored on the PangoContext instead of being passed to layout_render() * pango/utils.[ch] pango/pango-context.c: fribidi-0.1.9 wants UCS-4 not UCS2; switch accordingly. * pango/fonts.c pango/pango-font.h pango/pangox.c: Add functions to get overall font metrics, possibly per-language. (Right now, just font ascent, descent.) The implementation of this for X is horribly complex.
Diffstat (limited to 'pango')
-rw-r--r--pango/fonts.c36
-rw-r--r--pango/pango-context.c51
-rw-r--r--pango/pango-context.h7
-rw-r--r--pango/pango-font.h38
-rw-r--r--pango/pango-layout.c18
-rw-r--r--pango/pango-layout.h2
-rw-r--r--pango/pangox.c377
-rw-r--r--pango/pangox.h20
-rw-r--r--pango/utils.c53
9 files changed, 487 insertions, 115 deletions
diff --git a/pango/fonts.c b/pango/fonts.c
index 5b74a0f7..ad6de117 100644
--- a/pango/fonts.c
+++ b/pango/fonts.c
@@ -431,11 +431,13 @@ pango_font_unref (PangoFont *font)
* font.
*/
void
-pango_font_set_data (PangoFont *font,
- gchar *key,
+pango_font_set_data (PangoFont *font,
+ const gchar *key,
gpointer data,
GDestroyNotify destroy_func)
{
+ g_return_if_fail (font != NULL);
+
g_datalist_set_data_full (&font->data, key, data, destroy_func);
}
@@ -449,9 +451,11 @@ pango_font_set_data (PangoFont *font,
* Returns the data, or NULL if that key does not exist.
*/
gpointer
-pango_font_get_data (PangoFont *font,
- gchar *key)
+pango_font_get_data (PangoFont *font,
+ const gchar *key)
{
+ g_return_val_if_fail (font != NULL, NULL);
+
return g_datalist_get_data (&font->data, key);
}
@@ -521,7 +525,31 @@ pango_font_get_glyph_extents (PangoFont *font,
font->klass->get_glyph_extents (font, glyph, ink_rect, logical_rect);
}
+
+/**
+ * pango_font_get_metrics:
+ * @font: a #PangoFont
+ * @lang: language tag used to determine which script to get the metrics
+ * for, or %NULL to indicate to get the metrics for the entire
+ * font.
+ * @metrics: Structure to fill in with the metrics of the font
+ *
+ * Get overall metric information for a font. Since the metrics may be
+ * substantially different for different scripts, a language tag can
+ * be provided to indicate that the metrics should be retrieved that
+ * correspond to the script(s) used by that language.
+ **/
+void
+pango_font_get_metrics (PangoFont *font,
+ const gchar *lang,
+ PangoFontMetrics *metrics)
+{
+ g_return_if_fail (font != NULL);
+
+ font->klass->get_metrics (font, lang, metrics);
+}
+
/**
* pango_font_map_init:
* @fontmap: a #PangoFontMap
diff --git a/pango/pango-context.c b/pango/pango-context.c
index 95c5bab2..c768c7d5 100644
--- a/pango/pango-context.c
+++ b/pango/pango-context.c
@@ -35,6 +35,7 @@ struct _PangoContext
PangoFontDescription *font_desc;
GSList *font_maps;
+ GData *data;
};
static void add_engines (PangoContext *context,
@@ -63,6 +64,7 @@ pango_context_new (void)
result->base_dir = PANGO_DIRECTION_LTR;
result->lang = NULL;
result->font_maps = NULL;
+ result->data = NULL;
desc.family_name = "serif";
desc.style = PANGO_STYLE_NORMAL;
@@ -454,6 +456,44 @@ pango_context_get_base_dir (PangoContext *context)
}
/**
+ * pango_context_set_data:
+ * @context: a #PangoContext
+ * @key: the string key that identifies the data
+ * @data: the data to store
+ * @destroy_func: the function to free @data when it is no longer needed (may be %NULL)
+ *
+ * Adds user data to a #PangoContext.
+ **/
+void
+pango_context_set_data (PangoContext *context,
+ const char *key,
+ gpointer data,
+ GDestroyNotify destroy_func)
+{
+ g_return_if_fail (context != NULL);
+
+ g_datalist_set_data_full (&context->data, key, data, destroy_func);
+}
+
+/**
+ * pango_context_get_data:
+ * @context: a #PangoContext
+ * @key: the string key that identifies the data
+ *
+ * Retrieves user data from a #PangoContext
+ *
+ * Return value: the data, if @key was found, or %NULL.
+ **/
+gpointer
+pango_context_get_data (PangoContext *context,
+ const char *key)
+{
+ g_return_val_if_fail (context != NULL, NULL);
+
+ return g_datalist_get_data (&context->data, key);
+}
+
+/**
* pango_itemize:
* @context: a structure holding information that affects
the itemization process.
@@ -474,10 +514,9 @@ pango_itemize (PangoContext *context,
PangoAttrList *attrs)
{
GUChar4 *text_ucs4;
- gint n_chars;
+ int n_chars, i;
guint8 *embedding_levels;
FriBidiCharType base_dir;
- gint i;
PangoItem *item;
const char *p;
const char *next;
@@ -502,7 +541,7 @@ pango_itemize (PangoContext *context,
if (length == 0)
return NULL;
-
+
/* First, apply the bidirectional algorithm to break
* the text into directional runs.
*/
@@ -513,6 +552,9 @@ pango_itemize (PangoContext *context,
n_chars = unicode_strlen (text, length);
embedding_levels = g_new (guint8, n_chars);
+ fribidi_log2vis_get_embedding_levels (text_ucs4, n_chars, &base_dir,
+ embedding_levels);
+
/* Storing these as ranges would be a lot more efficient,
* but also more complicated... we take the simple
* approach for now.
@@ -522,9 +564,6 @@ pango_itemize (PangoContext *context,
fonts = g_new0 (PangoFont *, n_chars);
extra_attr_lists = g_new0 (GSList *, n_chars);
- fribidi_log2vis_get_embedding_levels (text_ucs4, n_chars, &base_dir,
- embedding_levels);
-
/* Now, fill in the appropriate shapers, language engines and fonts for
* each character.
*/
diff --git a/pango/pango-context.h b/pango/pango-context.h
index 9a5885c5..26228b1c 100644
--- a/pango/pango-context.h
+++ b/pango/pango-context.h
@@ -59,6 +59,13 @@ void pango_context_set_base_dir (PangoContext
PangoDirection direction);
PangoDirection pango_context_get_base_dir (PangoContext *context);
+void pango_context_set_data (PangoContext *context,
+ const char *key,
+ gpointer data,
+ GDestroyNotify destroy_func);
+gpointer pango_context_get_data (PangoContext *context,
+ const char *key);
+
/* Break a string of Unicode characters into segments with
* consistent shaping/language engine and bidrectional level.
* Returns a GList of PangoItem's
diff --git a/pango/pango-font.h b/pango/pango-font.h
index f6fd7ea4..063b0cea 100644
--- a/pango/pango-font.h
+++ b/pango/pango-font.h
@@ -33,6 +33,7 @@ typedef struct _PangoFontDescription PangoFontDescription;
typedef struct _PangoFontClass PangoFontClass;
typedef struct _PangoFontMap PangoFontMap;
typedef struct _PangoFontMapClass PangoFontMapClass;
+typedef struct _PangoFontMetrics PangoFontMetrics;
typedef enum {
PANGO_STYLE_NORMAL,
@@ -74,6 +75,12 @@ struct _PangoFontDescription
int size;
};
+struct _PangoFontMetrics
+{
+ int ascent;
+ int descent;
+};
+
PangoFontDescription *pango_font_description_copy (const PangoFontDescription *desc);
gboolean pango_font_description_compare (const PangoFontDescription *desc1,
const PangoFontDescription *desc2);
@@ -109,28 +116,35 @@ struct _PangoFontClass
PangoGlyph glyph,
PangoRectangle *ink_rect,
PangoRectangle *logical_rect);
+ void (*get_metrics) (PangoFont *font,
+ const gchar *lang,
+ PangoFontMetrics *metrics);
};
void pango_font_init (PangoFont *font);
void pango_font_ref (PangoFont *font);
void pango_font_unref (PangoFont *font);
gpointer pango_font_get_data (PangoFont *font,
- gchar *key);
+ const gchar *key);
void pango_font_set_data (PangoFont *font,
- gchar *key,
+ const gchar *key,
gpointer data,
GDestroyNotify destroy_func);
-PangoFontDescription *pango_font_describe (PangoFont *font);
-PangoCoverage * pango_font_get_coverage (PangoFont *font,
- const char *lang);
-PangoEngineShape * pango_font_find_shaper (PangoFont *font,
- const char *lang,
- guint32 ch);
-void pango_font_get_glyph_extents (PangoFont *font,
- PangoGlyph glyph,
- PangoRectangle *ink_rect,
- PangoRectangle *logical_rect);
+
+PangoFontDescription *pango_font_describe (PangoFont *font);
+PangoCoverage * pango_font_get_coverage (PangoFont *font,
+ const char *lang);
+PangoEngineShape * pango_font_find_shaper (PangoFont *font,
+ const char *lang,
+ guint32 ch);
+void pango_font_get_metrics (PangoFont *font,
+ const gchar *lang,
+ PangoFontMetrics *metrics);
+void pango_font_get_glyph_extents (PangoFont *font,
+ PangoGlyph glyph,
+ PangoRectangle *ink_rect,
+ PangoRectangle *logical_rect);
/*
* Font Map
diff --git a/pango/pango-layout.c b/pango/pango-layout.c
index ae499232..12076d33 100644
--- a/pango/pango-layout.c
+++ b/pango/pango-layout.c
@@ -144,6 +144,24 @@ pango_layout_unref (PangoLayout *layout)
}
/**
+ * pango_layout_get_context:
+ * @layout: a #PangoLayout
+ *
+ * Retrieves the #PangoContext used for this layout.
+ *
+ * Return value: The #PangoContext for the layout. This does not
+ * have an additional refcount added, so if you want to keep
+ * a copy of this around, you must reference it yourself.
+ **/
+PangoContext *
+pango_layout_get_context (PangoLayout *layout)
+{
+ g_return_if_fail (layout != NULL);
+
+ return layout->context;
+}
+
+/**
* pango_layout_set_width:
* @layout: a #PangoLayout.
* @width: the desired width, or -1 to indicate that no wrapping should be
diff --git a/pango/pango-layout.h b/pango/pango-layout.h
index c9a2f432..b1a9bf1e 100644
--- a/pango/pango-layout.h
+++ b/pango/pango-layout.h
@@ -58,6 +58,8 @@ void pango_layout_ref (PangoLayout *layout);
void pango_layout_unref (PangoLayout *layout);
+PangoContext *pango_layout_get_context (PangoLayout *layout);
+
void pango_layout_set_attributes (PangoLayout *layout,
PangoAttrList *attrs);
void pango_layout_set_text (PangoLayout *layout,
diff --git a/pango/pangox.c b/pango/pangox.c
index 64721c4c..1cfcd004 100644
--- a/pango/pangox.c
+++ b/pango/pangox.c
@@ -20,8 +20,11 @@
*/
#include <X11/Xlib.h>
+#include <fribidi/fribidi.h>
+#include <unicode.h>
#include "modules.h"
#include "pangox.h"
+#include "utils.h"
#include <ctype.h>
#include <math.h>
#include <stdio.h>
@@ -36,9 +39,12 @@ typedef struct _PangoXFontMap PangoXFontMap;
typedef struct _PangoXSubfontInfo PangoXSubfontInfo;
typedef struct _PangoXSizeInfo PangoXSizeInfo;
+typedef struct _PangoXMetricsInfo PangoXMetricsInfo;
typedef struct _PangoXFamilyEntry PangoXFamilyEntry;
typedef struct _PangoXFontEntry PangoXFontEntry;
+typedef struct _PangoXContextInfo PangoXContextInfo;
+
struct _PangoXSizeInfo
{
char *identifier;
@@ -66,6 +72,12 @@ struct _PangoXSubfontInfo
XFontStruct *font_struct;
};
+struct _PangoXMetricsInfo
+{
+ const char *lang;
+ PangoFontMetrics metrics;
+};
+
struct _PangoXFont
{
PangoFont font;
@@ -85,6 +97,8 @@ struct _PangoXFont
int n_subfonts;
int max_subfonts;
+ GSList *metrics_by_lang;
+
PangoXFontEntry *entry; /* Used to remove cached fonts */
};
@@ -102,6 +116,12 @@ struct _PangoXFontMap
double resolution; /* (points / pixel) * PANGO_SCALE */
};
+struct _PangoXContextInfo
+{
+ PangoGetGCFunc get_gc_func;
+ PangoFreeGCFunc free_gc_func;
+};
+
/* This is the largest field length we will accept. If a fontname has a field
larger than this we will skip it. */
#define XLFD_MAX_FIELD_LEN 64
@@ -174,17 +194,20 @@ static void pango_x_font_map_list_families (PangoFontMap *
int *n_families);
static void pango_x_font_map_read_aliases (PangoXFontMap *xfontmap);
-static void pango_x_font_destroy (PangoFont *font);
-static PangoFontDescription *pango_x_font_describe (PangoFont *font);
-static PangoCoverage * pango_x_font_get_coverage (PangoFont *font,
- const char *lang);
-static PangoEngineShape * pango_x_font_find_shaper (PangoFont *font,
- const char *lang,
- guint32 ch);
-static void pango_x_font_get_glyph_extents (PangoFont *font,
- PangoGlyph glyph,
- PangoRectangle *ink_rect,
- PangoRectangle *logical_rect);
+static void pango_x_font_destroy (PangoFont *font);
+static PangoFontDescription *pango_x_font_describe (PangoFont *font);
+static PangoCoverage * pango_x_font_get_coverage (PangoFont *font,
+ const char *lang);
+static PangoEngineShape * pango_x_font_find_shaper (PangoFont *font,
+ const char *lang,
+ guint32 ch);
+static void pango_x_font_get_glyph_extents (PangoFont *font,
+ PangoGlyph glyph,
+ PangoRectangle *ink_rect,
+ PangoRectangle *logical_rect);
+static void pango_x_font_get_metrics (PangoFont *font,
+ const gchar *lang,
+ PangoFontMetrics *metrics);
static PangoXSubfontInfo * pango_x_find_subfont (PangoFont *font,
PangoXSubfont subfont_index);
@@ -225,7 +248,8 @@ PangoFontClass pango_x_font_class = {
pango_x_font_describe,
pango_x_font_get_coverage,
pango_x_font_find_shaper,
- pango_x_font_get_glyph_extents
+ pango_x_font_get_glyph_extents,
+ pango_x_font_get_metrics
};
PangoFontMapClass pango_x_font_map_class = {
@@ -1206,23 +1230,64 @@ pango_x_insert_font (PangoXFontMap *xfontmap,
}
+/**
+ * pango_x_get_context:
+ * @display: an X display (As returned by XOpenDisplay().)
+ *
+ * Retrieves a #PangoContext appropriate for rendering with X fonts on the given display.
+ *
+ * Return value: the new #PangoContext
+ **/
PangoContext *
pango_x_get_context (Display *display)
{
PangoContext *result;
+ PangoXContextInfo *info;
+
+ g_return_val_if_fail (display != NULL, NULL);
result = pango_context_new ();
+
+ info = g_new (PangoXContextInfo, 1);
+ info->get_gc_func = NULL;
+ info->free_gc_func = NULL;
+ pango_context_set_data (result, "pango-x-info", info, (GDestroyNotify)g_free);
+
pango_context_add_font_map (result, pango_x_font_map_for_display (display));
return result;
}
/**
+ * pango_x_context_set_funcs:
+ * @context: a #PangoContext.
+ * @get_gc_func: function called to create a new GC for a given color.
+ * @free_gc_func: function called to free a GC created with @get_gc_func.
+ *
+ * Sets the functions that will be used to get GC's in various colors when
+ * rendering layouts with this context.
+ **/
+void
+pango_x_context_set_funcs (PangoContext *context,
+ PangoGetGCFunc get_gc_func,
+ PangoFreeGCFunc free_gc_func)
+{
+ PangoXContextInfo *info;
+
+ g_return_if_fail (context != NULL);
+
+ info = pango_context_get_data (context, "pango-x-info");
+
+ info->get_gc_func = get_gc_func;
+ info->free_gc_func = free_gc_func;
+}
+
+/**
* pango_x_load_font:
* @display: the X display
* @spec: a comma-separated list of XLFD's
*
- * Load up a logical font based on a "fontset" style
+ * Loads up a logical font based on a "fontset" style
* text specification.
*
* Returns a new #PangoFont
@@ -1254,6 +1319,8 @@ pango_x_load_font (Display *display,
result->n_subfonts = 0;
result->max_subfonts = 1;
+ result->metrics_by_lang = NULL;
+
result->size = -1;
result->entry = NULL;
@@ -1299,6 +1366,8 @@ pango_x_load_font_with_size (Display *display,
result->n_subfonts = 0;
result->max_subfonts = 1;
+ result->metrics_by_lang = NULL;
+
result->size = size;
result->entry = NULL;
@@ -1417,6 +1486,236 @@ pango_x_font_get_glyph_extents (PangoFont *font,
}
}
+/* Get composite font metrics for all subfonts in list
+ */
+static void
+get_font_metrics_from_subfonts (PangoFont *font,
+ GSList *subfonts,
+ PangoFontMetrics *metrics)
+{
+ GSList *tmp_list = subfonts;
+ gboolean first = TRUE;
+
+ metrics->ascent = 0;
+ metrics->descent = 0;
+
+ while (tmp_list)
+ {
+ PangoXSubfontInfo *subfont = pango_x_find_subfont (font, GPOINTER_TO_UINT (tmp_list->data));
+
+ if (subfont)
+ {
+ XFontStruct *fs = pango_x_get_font_struct (font, subfont);
+ if (fs)
+ {
+ if (first)
+ {
+ metrics->ascent = fs->ascent * PANGO_SCALE;
+ metrics->descent = fs->descent * PANGO_SCALE;
+ first = FALSE;
+ }
+ else
+ {
+ metrics->ascent = MAX (fs->ascent * PANGO_SCALE, metrics->ascent);
+ metrics->descent = MAX (fs->descent * PANGO_SCALE, metrics->descent);
+ }
+ }
+ }
+ else
+ g_warning ("Invalid subfont %d in get_font_metrics_from_subfonts", GPOINTER_TO_UINT (tmp_list->data));
+
+ tmp_list = tmp_list->next;
+ }
+}
+
+/* Get composite font metrics for all subfonts resulting from shaping
+ * string str with the given font
+ *
+ * This duplicates quite a bit of code from pango_itemize. This function
+ * should die and we should simply add the ability to specify particular
+ * fonts when itemizing.
+ */
+static void
+get_font_metrics_from_string (PangoFont *font,
+ const char *lang,
+ const char *str,
+ PangoFontMetrics *metrics)
+{
+ const char *start, *p;
+ PangoGlyphString *glyph_str = pango_glyph_string_new ();
+ PangoEngineShape *shaper, *last_shaper;
+ int last_level;
+ GUChar4 *text_ucs4;
+ int n_chars, i;
+ guint8 *embedding_levels;
+ FriBidiCharType base_dir = PANGO_DIRECTION_LTR;
+ GSList *subfonts = NULL;
+
+ n_chars = unicode_strlen (str, -1);
+
+ text_ucs4 = _pango_utf8_to_ucs4 (str, strlen (str));
+ if (!text_ucs4)
+ return;
+
+ embedding_levels = g_new (guint8, n_chars);
+ fribidi_log2vis_get_embedding_levels (text_ucs4, n_chars, &base_dir,
+ embedding_levels);
+ g_free (text_ucs4);
+
+ last_shaper = NULL;
+ last_level = 0;
+
+ i = 0;
+ p = start = str;
+ while (*p)
+ {
+ unicode_char_t wc;
+ p = unicode_get_utf8 (p, &wc);
+
+ shaper = pango_font_find_shaper (font, lang, wc);
+ if (p > start &&
+ (shaper != last_shaper || last_level != embedding_levels[i]))
+ {
+ PangoAnalysis analysis;
+ int j;
+
+ analysis.shape_engine = shaper;
+ analysis.lang_engine = NULL;
+ analysis.font = font;
+ analysis.level = last_level;
+
+ pango_shape (start, p - start, &analysis, glyph_str);
+
+ for (j = 0; j < glyph_str->num_glyphs; j++)
+ {
+ PangoXSubfont subfont = PANGO_X_GLYPH_SUBFONT (glyph_str->glyphs[j].glyph);
+ if (!g_slist_find (subfonts, GUINT_TO_POINTER ((guint)subfont)))
+ subfonts = g_slist_prepend (subfonts, GUINT_TO_POINTER ((guint)subfont));
+ }
+
+ start = p;
+ }
+
+ last_shaper = shaper;
+ last_level = embedding_levels[i];
+ i++;
+ }
+
+ get_font_metrics_from_subfonts (font, subfonts, metrics);
+ g_slist_free (subfonts);
+
+ pango_glyph_string_free (glyph_str);
+ g_free (embedding_levels);
+}
+
+typedef struct {
+ const char *lang;
+ const char *str;
+} LangInfo;
+
+int
+lang_info_compare (const void *key, const void *val)
+{
+ const LangInfo *lang_info = val;
+
+ return strncmp (key, lang_info->lang, 2);
+}
+
+/* The following array is supposed to contain enough text to tickle all necessary fonts for each
+ * of the languages in the following. Yes, it's pretty lame. Not all of the languages
+ * in the following have sufficient text to excercise all the accents for the language, and
+ * there are obviously many more languages to include as well.
+ */
+LangInfo lang_texts[] = {
+ { "ar", "Arabic السلام عليكم" },
+ { "cs", "Czech (česky) Dobrý den" },
+ { "da", "Danish (Dansk) Hej, Goddag" },
+ { "el", "Greek (Ελληνικά) Γειά σας" },
+ { "en", "English Hello" },
+ { "eo", "Esperanto Saluton" },
+ { "es", "Spanish (Español) ¡Hola!" },
+ { "et", "Estonian Tere, Tervist" },
+ { "fi", "Finnish (Suomi) Hei" },
+ { "fr", "French (Français)" },
+ { "de", "German Grüß Gott" },
+ { "iw", "Hebrew שלום" },
+ { "il", "Italiano Ciao, Buon giorno" },
+ { "ja", "Japanese (日本語) こんにちは, コンニチハ" },
+ { "ko", "Korean (한글) 안녕하세요, 안녕하십니까" },
+ { "mt", "Maltese Ċaw, Saħħa" },
+ { "nl", "Nederlands, Vlaams Hallo, Dag" },
+ { "no", "Norwegian (Norsk) Hei, God dag" },
+ { "pl", "Polish Dzień dobry, Hej" },
+ { "ru", "Russian (Русский)" },
+ { "sk", "Slovak Dobrý deň" },
+ { "sv", "Swedish (Svenska) Hej, Goddag" },
+ { "tr", "Turkish (Türkçe) Merhaba" },
+ { "zh", "Chinese (中文,普通话,汉语)" }
+};
+
+static void
+pango_x_font_get_metrics (PangoFont *font,
+ const gchar *lang,
+ PangoFontMetrics *metrics)
+{
+ PangoXMetricsInfo *info;
+ PangoXFont *xfont = (PangoXFont *)font;
+ GSList *tmp_list;
+
+ const char *lookup_lang;
+ const char *str;
+
+ if (lang)
+ {
+ LangInfo *lang_info = bsearch (lang, lang_texts,
+ G_N_ELEMENTS (lang_texts), sizeof (LangInfo),
+ lang_info_compare);
+
+ if (lang_info)
+ {
+ lookup_lang = lang_info->lang;
+ str = lang_info->str;
+ }
+ else
+ {
+ lookup_lang = "UNKNOWN";
+ str = "French (Français)"; /* Assume iso-8859-1 */
+ }
+ }
+ else
+ {
+ lookup_lang = "NONE";
+
+ /* Complete junk
+ */
+ str = "السلام عليكم česky Ελληνικά Français 日本語 한글 Русский 中文,普通话,汉语 Türkçe";
+ }
+
+ tmp_list = xfont->metrics_by_lang;
+ while (tmp_list)
+ {
+ info = tmp_list->data;
+
+ if (info->lang == lookup_lang) /* We _don't_ need strcmp */
+ break;
+
+ tmp_list = tmp_list->next;
+ }
+
+ if (!tmp_list)
+ {
+ info = g_new (PangoXMetricsInfo, 1);
+ info->lang = lookup_lang;
+
+ xfont->metrics_by_lang = g_slist_prepend (xfont->metrics_by_lang, info);
+
+ get_font_metrics_from_string (font, lang, str, &info->metrics);
+ }
+
+ *metrics = info->metrics;
+ return;
+}
+
/* Compare the tail of a to b */
static gboolean
match_end (char *a, char *b)
@@ -1753,6 +2052,9 @@ pango_x_font_destroy (PangoFont *font)
g_hash_table_foreach (xfont->subfonts_by_charset, subfonts_foreach, NULL);
g_hash_table_destroy (xfont->subfonts_by_charset);
+ g_slist_foreach (xfont->metrics_by_lang, (GFunc)g_free, NULL);
+ g_slist_free (xfont->metrics_by_lang);
+
if (xfont->entry)
xfont->entry->cached_fonts = g_slist_remove (xfont->entry->cached_fonts, xfont);
@@ -2013,32 +2315,31 @@ pango_x_get_unknown_glyph (PangoFont *font)
* pango_x_render_layout_line:
* @display: the X display
* @drawable: the drawable on which to draw string
+ * @gc: GC to use for uncolored drawing
* @line: a #PangoLayoutLine
* @x: the x position of start of string (in pixels)
* @y: the y position of baseline (in pixels)
- * @get_gc: function to call to retrieve a GC for a particular color
- * @free_gc: function to call to free a GC retrieved from get_gc
- * @user_data: extra data to pass to get_gc and free_gc
*
* Render a #PangoLayoutLine onto an X drawable
*/
void
pango_x_render_layout_line (Display *display,
Drawable drawable,
+ GC gc,
PangoLayoutLine *line,
int x,
- int y,
- PangoGetGCFunc get_gc,
- PangoFreeGCFunc free_gc,
- gpointer user_data)
+ int y)
{
GSList *tmp_list = line->runs;
+ PangoRectangle overall_rect;
PangoRectangle logical_rect;
PangoRectangle ink_rect;
+ PangoContext *context = pango_layout_get_context (line->layout);
+ PangoXContextInfo *info = pango_context_get_data (context, "pango-x-info");
int x_off = 0;
- pango_layout_line_get_extents (line,NULL, &logical_rect);
+ pango_layout_line_get_extents (line,NULL, &overall_rect);
while (tmp_list)
{
@@ -2052,10 +2353,10 @@ pango_x_render_layout_line (Display *display,
pango_x_get_item_properties (run->item, &uline, &fg_color, &fg_set, &bg_color, &bg_set);
- if (fg_set)
- fg_gc = (*get_gc) (&fg_color, user_data);
+ if (fg_set && info->get_gc_func)
+ fg_gc = info->get_gc_func (context, &fg_color, gc);
else
- fg_gc = (*get_gc) (NULL, user_data);
+ fg_gc = gc;
if (uline == PANGO_UNDERLINE_NONE)
pango_glyph_string_extents (run->glyphs, run->item->analysis.font,
@@ -2064,17 +2365,18 @@ pango_x_render_layout_line (Display *display,
pango_glyph_string_extents (run->glyphs, run->item->analysis.font,
&ink_rect, &logical_rect);
- if (bg_set)
+ if (bg_set && info->get_gc_func)
{
- GC bg_gc = (*get_gc) (&bg_color, user_data);
+ GC bg_gc = info->get_gc_func (context, &bg_color, gc);
XFillRectangle (display, drawable, bg_gc,
x + (x_off + logical_rect.x) / PANGO_SCALE,
- y + logical_rect.y / PANGO_SCALE,
+ y + overall_rect.y / PANGO_SCALE,
logical_rect.width / PANGO_SCALE,
- logical_rect.height / PANGO_SCALE);
+ overall_rect.height / PANGO_SCALE);
- (*free_gc) (bg_gc, user_data);
+ if (info->free_gc_func)
+ info->free_gc_func (context, bg_gc);
}
pango_x_render (display, drawable, fg_gc, run->item->analysis.font, run->glyphs,
@@ -2101,7 +2403,8 @@ pango_x_render_layout_line (Display *display,
break;
}
- (*free_gc) (fg_gc, user_data);
+ if (fg_set && info->get_gc_func && info->free_gc_func)
+ info->free_gc_func (context, fg_gc);
x_off += logical_rect.width;
}
@@ -2111,11 +2414,10 @@ pango_x_render_layout_line (Display *display,
* pango_x_render_layout:
* @display: the X display
* @drawable: the drawable on which to draw string
+ * @gc: GC to use for uncolored drawing
* @layout: a #PangoLayout
* @x: the X position of the left of the layout (in pixels)
* @y: the Y position of the top of the layout (in pixels)
- * @get_gc: function to call to retrieve a GC for a particular color
- * @free_gc: function to call to free a GC retrieved from get_gc
* @user_data: extra data to pass to get_gc and free_gc
*
* Render a #PangoLayoutLine onto an X drawable
@@ -2123,12 +2425,10 @@ pango_x_render_layout_line (Display *display,
void
pango_x_render_layout (Display *display,
Drawable drawable,
+ GC gc,
PangoLayout *layout,
int x,
- int y,
- PangoGetGCFunc get_gc,
- PangoFreeGCFunc free_gc,
- gpointer user_data)
+ int y)
{
PangoRectangle logical_rect;
GSList *tmp_list;
@@ -2190,9 +2490,8 @@ pango_x_render_layout (Display *display,
}
}
- pango_x_render_layout_line (display, drawable,
- line, x + x_offset / PANGO_SCALE, y + (y_offset - logical_rect.y) / PANGO_SCALE,
- get_gc, free_gc, user_data);
+ pango_x_render_layout_line (display, drawable, gc,
+ line, x + x_offset / PANGO_SCALE, y + (y_offset - logical_rect.y) / PANGO_SCALE);
y_offset += logical_rect.height;
tmp_list = tmp_list->next;
diff --git a/pango/pangox.h b/pango/pangox.h
index 3460263d..abdf148f 100644
--- a/pango/pangox.h
+++ b/pango/pangox.h
@@ -33,12 +33,16 @@ extern "C" {
#define PANGO_RENDER_TYPE_X "PangoRenderX"
-typedef GC (*PangoGetGCFunc) (PangoAttrColor *color, void *user_data);
-typedef void (*PangoFreeGCFunc) (GC gc, void *user_data);
+typedef GC (*PangoGetGCFunc) (PangoContext *context, PangoAttrColor *color, GC base_gc);
+typedef void (*PangoFreeGCFunc) (PangoContext *context, GC gc);
/* Calls for applications
*/
PangoContext * pango_x_get_context (Display *display);
+void pango_x_context_set_funcs (PangoContext *context,
+ PangoGetGCFunc get_gc_func,
+ PangoFreeGCFunc free_gc_func);
+
PangoFont * pango_x_load_font (Display *display,
gchar *spec);
void pango_x_render (Display *display,
@@ -50,20 +54,16 @@ void pango_x_render (Display *display,
gint y);
void pango_x_render_layout_line (Display *display,
Drawable drawable,
+ GC gc,
PangoLayoutLine *line,
int x,
- int y,
- PangoGetGCFunc get_gc,
- PangoFreeGCFunc free_gc,
- gpointer user_data);
+ int y);
void pango_x_render_layout (Display *display,
Drawable drawable,
+ GC gc,
PangoLayout *layout,
int x,
- int y,
- PangoGetGCFunc get_gc,
- PangoFreeGCFunc free_gc,
- gpointer user_data);
+ int y);
/* API for rendering modules
*/
diff --git a/pango/utils.c b/pango/utils.c
index 5a04ccc7..6f7ff8ca 100644
--- a/pango/utils.c
+++ b/pango/utils.c
@@ -153,56 +153,21 @@ _pango_utf8_to_ucs2 (const char *str, int len)
}
-#ifdef __GLIBC__
-# define UCS4_CHARSET "UNICODELITTLE"
-#else
-# if G_BYTE_ORDER == G_LITTLE_ENDIAN
-# define UCS4_CHARSET "UCS-4-LE"
-# else
-# define UCS4_CHARSET "UCS-4-BE"
-# endif
-#endif
-
GUChar4 *
_pango_utf8_to_ucs4 (const char *str, int len)
{
- iconv_t cd;
- char *outbuf, *result;
- const char *inbuf;
- size_t inbytesleft;
- size_t outbytesleft;
- gint outlen;
-
- gint count;
-
- cd = iconv_open (UCS4_CHARSET, "UTF-8");
+ GUChar4 *result;
+ int n_chars, i;
+ const char *p;
- if (cd == (iconv_t)-1)
- g_error ("No converter from UTF-8 to " UCS4_CHARSET);
-
- if (len < 0)
- len = strlen (str);
-
- outlen = unicode_strlen (str, len) * sizeof(GUChar4);
- result = g_malloc (outlen);
-
- inbuf = str;
- inbytesleft = len;
- outbuf = result;
- outbytesleft = outlen;
-
- count = iconv (cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
-
- if (count < 0 && (errno != E2BIG))
- {
- g_free (result);
- result = NULL;
- }
-
- iconv_close (cd);
+ n_chars = unicode_strlen (str, len);
+ result = g_new (GUChar4, n_chars);
- return (GUChar4 *)result;
+ p = str;
+ for (i=0; i < n_chars; i++)
+ p = unicode_get_utf8 (p, &result[i]);
+ return result;
}
/**