diff options
Diffstat (limited to 'pango/pangox.c')
-rw-r--r-- | pango/pangox.c | 392 |
1 files changed, 192 insertions, 200 deletions
diff --git a/pango/pangox.c b/pango/pangox.c index aa34a361..0bd1de72 100644 --- a/pango/pangox.c +++ b/pango/pangox.c @@ -26,40 +26,40 @@ #include <string.h> typedef struct _PangoXFont PangoXFont; -typedef struct _PangoXCFont PangoXCFont; -typedef struct _PangoXCharsetInfo PangoXCharsetInfo; +typedef struct _PangoXSubfontInfo PangoXSubfontInfo; -struct _PangoXCFont { +struct _PangoXSubfontInfo { gchar *xlfd; XFontStruct *font_struct; }; -struct _PangoXCharsetInfo { - PangoXCharset charset; - gchar *name; - GSList *cfonts; -}; - struct _PangoXFont { PangoFont font; Display *display; char **fonts; + int n_fonts; + + /* hash table mapping from charset-name to array of PangoXSubfont ids, + * of length n_fonts + */ + GHashTable *subfonts_by_charset; - GHashTable *charsets_by_name; - PangoXCharsetInfo **charsets; + PangoXSubfontInfo **subfonts; - gint n_charsets; - gint max_charsets; + gint n_subfonts; + gint max_subfonts; }; -static XCharStruct *pango_x_get_per_char (PangoXCFont *cfont, - guint16 glyph_index); -static PangoXCFont *pango_x_find_cfont (PangoXFont *font, - PangoXCharset charset, - guint16 index, - XCharStruct **per_char_return); -static void pango_x_font_destroy (PangoFont *font); +static PangoXSubfontInfo *pango_x_find_subfont (PangoFont *font, + PangoXSubfont subfont_index); +static XCharStruct * pango_x_get_per_char (PangoXSubfontInfo *subfont, + guint16 char_index); +static void pango_x_font_destroy (PangoFont *font); +static gboolean pango_x_find_glyph (PangoFont *font, + PangoGlyph glyph, + PangoXSubfontInfo **subfont_return, + XCharStruct **charstruct_return); PangoFontClass pango_x_font_class = { pango_x_font_destroy @@ -93,11 +93,14 @@ pango_x_load_font (Display *display, result->fonts = g_strsplit(spec, ",", -1); - result->charsets_by_name = g_hash_table_new (g_str_hash, g_str_equal); - result->charsets = g_new (PangoXCharsetInfo *, 1); + for (result->n_fonts = 0; result->fonts[result->n_fonts]; result->n_fonts++) + /* Nothing */ - result->n_charsets = 0; - result->max_charsets = 1; + result->subfonts_by_charset = g_hash_table_new (g_str_hash, g_str_equal); + result->subfonts = g_new (PangoXSubfontInfo *, 1); + + result->n_subfonts = 0; + result->max_subfonts = 1; return (PangoFont *)result; } @@ -126,7 +129,6 @@ pango_x_render (Display *display, * collect the characters into runs, and draw multiple * characters with each XDrawString16 call. */ - PangoXFont *xfont = (PangoXFont *)font; Font old_fid = None; XFontStruct *fs; int i; @@ -137,25 +139,18 @@ pango_x_render (Display *display, for (i=0; i<glyphs->num_glyphs; i++) { guint16 index = PANGO_X_GLYPH_INDEX (glyphs->glyphs[i].glyph); - guint16 charset = PANGO_X_GLYPH_CHARSET (glyphs->glyphs[i].glyph); - PangoXCFont *cfont; + guint16 subfont_index = PANGO_X_GLYPH_SUBFONT (glyphs->glyphs[i].glyph); + PangoXSubfontInfo *subfont; XChar2b c; - if (charset < 1 || charset > xfont->n_charsets) - { - g_warning ("Glyph string contains invalid charset %d", charset); - continue; - } - - cfont = pango_x_find_cfont (xfont, charset, index, NULL); - - if (cfont) + subfont = pango_x_find_subfont (font, subfont_index); + if (subfont) { c.byte1 = index / 256; c.byte2 = index % 256; - fs = cfont->font_struct; + fs = subfont->font_struct; if (fs->fid != old_fid) { @@ -167,9 +162,9 @@ pango_x_render (Display *display, x + glyphs->glyphs[i].geometry.x_offset / 72, y + glyphs->glyphs[i].geometry.y_offset / 72, &c, 1); - - x += glyphs->glyphs[i].geometry.width / 72; } + + x += glyphs->glyphs[i].geometry.width / 72; } } @@ -190,7 +185,7 @@ pango_x_render (Display *display, */ void pango_x_glyph_extents (PangoFont *font, - PangoGlyph glyph, + PangoGlyph glyph, gint *lbearing, gint *rbearing, gint *width, @@ -199,23 +194,10 @@ pango_x_glyph_extents (PangoFont *font, gint *logical_ascent, gint *logical_descent) { - PangoXFont *xfont = (PangoXFont *)font; - PangoXCFont *cfont; - XCharStruct *cs; + PangoXSubfontInfo *subfont; - guint16 index = PANGO_X_GLYPH_INDEX (glyph); - guint16 charset = PANGO_X_GLYPH_CHARSET (glyph); - - if (charset < 1 || charset > xfont->n_charsets) - { - g_warning ("Glyph string contains invalid charset %d\n", charset); - return; - } - - cfont = pango_x_find_cfont (xfont, charset, index, &cs); - - if (cfont) + if (pango_x_find_glyph (font, glyph, &subfont, &cs)) { if (lbearing) *lbearing = cs->lbearing; @@ -228,9 +210,9 @@ pango_x_glyph_extents (PangoFont *font, if (descent) *descent = cs->descent; if (logical_ascent) - *logical_ascent = cfont->font_struct->ascent; + *logical_ascent = subfont->font_struct->ascent; if (logical_descent) - *logical_descent = cfont->font_struct->descent; + *logical_descent = subfont->font_struct->descent; } else { @@ -279,7 +261,8 @@ pango_x_extents (PangoFont *font, gint *logical_ascent, gint *logical_descent) { - PangoXFont *xfont = (PangoXFont *)font; + PangoXSubfontInfo *subfont; + XCharStruct *cs; int i; @@ -296,15 +279,9 @@ pango_x_extents (PangoFont *font, for (i=0; i<glyphs->num_glyphs; i++) { - XCharStruct *cs; - - guint16 index = PANGO_X_GLYPH_INDEX (glyphs->glyphs[i].glyph); - guint16 charset = PANGO_X_GLYPH_CHARSET (glyphs->glyphs[i].glyph); - PangoGlyphGeometry *geometry = &glyphs->glyphs[i].geometry; - PangoXCFont *cfont = pango_x_find_cfont (xfont, charset, index, &cs); - - if (cfont) + + if (pango_x_find_glyph (font, glyphs->glyphs[i].glyph, &subfont, &cs)) { if (i == 0) { @@ -312,9 +289,9 @@ pango_x_extents (PangoFont *font, t_rbearing = cs->rbearing + geometry->x_offset / 72; t_ascent = cs->ascent + geometry->y_offset / 72; t_descent = cs->descent - geometry->y_offset / 72; - - t_logical_ascent = cfont->font_struct->ascent + geometry->y_offset / 72; - t_logical_descent = cfont->font_struct->descent - geometry->y_offset / 72; + + t_logical_ascent = subfont->font_struct->ascent + geometry->y_offset / 72; + t_logical_descent = subfont->font_struct->descent - geometry->y_offset / 72; } else { @@ -324,8 +301,8 @@ pango_x_extents (PangoFont *font, t_width + cs->rbearing + geometry->x_offset / 72); t_ascent = MAX (t_ascent, cs->ascent + geometry->y_offset / 72); t_descent = MAX (t_descent, cs->descent - geometry->y_offset / 72); - t_logical_ascent = MAX (t_logical_ascent, cfont->font_struct->ascent + geometry->y_offset / 72); - t_logical_descent = MAX (t_logical_descent, cfont->font_struct->descent - geometry->y_offset / 72); + t_logical_ascent = MAX (t_logical_ascent, subfont->font_struct->ascent + geometry->y_offset / 72); + t_logical_descent = MAX (t_logical_descent, subfont->font_struct->descent - geometry->y_offset / 72); } } @@ -416,107 +393,119 @@ name_for_charset (char *xlfd, char *charset) } /** - * pango_x_find_charset: - * @font: a #PangoFont - * @charset: string name of charset - * - * Look up the character set ID for a character set in the given font. - * If a character set ID has not yet been assigned, a new ID will be assigned. + * pango_x_list_subfonts: + * @font: a PangoFont + * @charsets: the charsets to list subfonts for. + * @n_charsets: the number of charsets in @charsets + * @subfont_ids: location to store a pointer to an array of subfont IDs for each found subfont + * the result must be freed using g_free() + * @subfont_charsets: location to store a pointer to an array of subfont IDs for each found subfont + * the result must be freed using g_free() * - * Return value: Character ID for character set, if there is a match in this - * font, otherwise 0. + * Returns number of charsets found **/ -PangoXCharset -pango_x_find_charset (PangoFont *font, - gchar *charset) +int +pango_x_list_subfonts (PangoFont *font, + char **charsets, + int n_charsets, + PangoXSubfont **subfont_ids, + int **subfont_charsets) { PangoXFont *xfont = (PangoXFont *)font; - PangoXCharsetInfo *info; - int i; + PangoXSubfont **subfont_lists; + int i, j; + int n_subfonts = 0; g_return_val_if_fail (font != NULL, 0); - g_return_val_if_fail (charset != NULL, 0); + g_return_val_if_fail (n_charsets == 0 || charsets != NULL, 0); - info = g_hash_table_lookup (xfont->charsets_by_name, charset); + subfont_lists = g_new (PangoXSubfont *, n_charsets); - if (!info) + for (j=0; j<n_charsets; j++) { - info = g_new (PangoXCharsetInfo, 1); - - info->cfonts = NULL; - - for (i = 0; xfont->fonts[i]; i++) + subfont_lists[j] = g_hash_table_lookup (xfont->subfonts_by_charset, charsets[j]); + if (!subfont_lists[j]) { - char *xlfd = name_for_charset (xfont->fonts[i], charset); - - if (xlfd) + subfont_lists[j] = g_new (PangoXSubfont, xfont->n_fonts); + + for (i = 0; i < xfont->n_fonts; i++) { - int count; - char **names = XListFonts (xfont->display, xlfd, 1, &count); - if (count > 0) + PangoXSubfontInfo *info = NULL; + char *xlfd = name_for_charset (xfont->fonts[i], charsets[j]); + + if (xlfd) { - PangoXCFont *cfont = g_new (PangoXCFont, 1); - - cfont->xlfd = g_strdup (names[0]); - cfont->font_struct = NULL; - - info->cfonts = g_slist_append (info->cfonts, cfont); + int count; + char **names = XListFonts (xfont->display, xlfd, 1, &count); + if (count > 0) + { + info = g_new (PangoXSubfontInfo, 1); + + info->xlfd = g_strdup (names[0]); + info->font_struct = NULL; + } + + g_free (xlfd); } - - XFreeFontNames (names); - g_free (xlfd); + + if (info) + { + xfont->n_subfonts++; + + if (xfont->n_subfonts > xfont->max_subfonts) + { + xfont->max_subfonts *= 2; + xfont->subfonts = g_renew (PangoXSubfontInfo *, xfont->subfonts, xfont->max_subfonts); + } + + xfont->subfonts[xfont->n_subfonts - 1] = info; + subfont_lists[j][i] = xfont->n_subfonts; + } + else + subfont_lists[j][i] = 0; } + + g_hash_table_insert (xfont->subfonts_by_charset, g_strdup (charsets[j]), subfont_lists[j]); } - if (info->cfonts) - { - info->name = g_strdup (charset); - g_hash_table_insert (xfont->charsets_by_name, info->name, info); + for (i = 0; i < xfont->n_fonts; i++) + if (subfont_lists[j][i]) + n_subfonts++; + } - xfont->n_charsets++; + *subfont_ids = g_new (PangoXSubfont, n_subfonts); + *subfont_charsets = g_new (int, n_subfonts); - if (xfont->n_charsets > xfont->max_charsets) - { - xfont->max_charsets *= 2; - xfont->charsets = g_renew (PangoXCharsetInfo *, xfont->charsets, xfont->max_charsets); - } - - info->charset = xfont->n_charsets; - xfont->charsets[xfont->n_charsets - 1] = info; - } - else + n_subfonts = 0; + + for (i=0; i<xfont->n_fonts; i++) + for (j=0; j<n_charsets; j++) + if (subfont_lists[j][i]) { - g_free (info); - info = NULL; + (*subfont_ids)[n_subfonts] = subfont_lists[j][i]; + (*subfont_charsets)[n_subfonts] = j; + n_subfonts++; } - } - if (info) - return info->charset; - else - return 0; + g_free (subfont_lists); + + return n_subfonts; } gboolean pango_x_has_glyph (PangoFont *font, PangoGlyph glyph) { - PangoXFont *xfont = (PangoXFont *)font; - - guint16 index, charset; - g_return_val_if_fail (font != NULL, FALSE); - - index = PANGO_X_GLYPH_INDEX (glyph); - charset = PANGO_X_GLYPH_CHARSET (glyph); - if (charset < 1 || charset > xfont->n_charsets) - { - g_warning ("Glyph string contains invalid charset %d", charset); - return FALSE; - } - - return (pango_x_find_cfont (xfont, charset, index, NULL) != NULL); + return pango_x_find_glyph (font, glyph, NULL, NULL); +} + +static void +subfonts_foreach (gpointer key, gpointer value, gpointer data) +{ + g_free (key); + g_free (value); } static void @@ -525,32 +514,22 @@ pango_x_font_destroy (PangoFont *font) PangoXFont *xfont = (PangoXFont *)font; int i; - g_hash_table_destroy (xfont->charsets_by_name); + g_hash_table_destroy (xfont->subfonts_by_charset); - for (i=0; i<xfont->n_charsets; i++) + for (i=0; i<xfont->n_subfonts; i++) { - GSList *cfonts = xfont->charsets[i]->cfonts; - - while (cfonts) - { - PangoXCFont *cfont = cfonts->data; - - g_free (cfont->xlfd); - if (cfont->font_struct) - XFreeFont (xfont->display, cfont->font_struct); - - g_free (cfont); - - cfonts = cfonts->next; - } + PangoXSubfontInfo *info = xfont->subfonts[i]; - g_slist_free (xfont->charsets[i]->cfonts); + g_free (info->xlfd); + if (info->font_struct) + XFreeFont (xfont->display, info->font_struct); - g_free (xfont->charsets[i]->name); - g_free (xfont->charsets[i]); + g_free (info); } - g_free (xfont->charsets); + g_free (xfont->subfonts); + + g_hash_table_foreach (xfont->subfonts_by_charset, subfonts_foreach, NULL); g_strfreev (xfont->fonts); g_free (font); @@ -558,17 +537,35 @@ pango_x_font_destroy (PangoFont *font) /* Utility functions */ +static PangoXSubfontInfo * +pango_x_find_subfont (PangoFont *font, + PangoXSubfont subfont_index) +{ + PangoXFont *xfont = (PangoXFont *)font; + + if (subfont_index < 1 || subfont_index > xfont->n_subfonts) + { + g_warning ("Invalid subfont %d", subfont_index); + return NULL; + } + + return xfont->subfonts[subfont_index-1]; +} + static XCharStruct * -pango_x_get_per_char (PangoXCFont *cfont, guint16 glyph_index) +pango_x_get_per_char (PangoXSubfontInfo *subfont, + guint16 char_index) { + XFontStruct *fs; + + int index; guint8 byte1; guint8 byte2; - - XFontStruct *fs = cfont->font_struct; - int index; - byte1 = glyph_index / 256; - byte2 = glyph_index % 256; + byte1 = char_index / 256; + byte2 = char_index % 256; + + fs = subfont->font_struct; if ((fs->min_byte1 == 0) && (fs->min_byte1 == 0)) { @@ -581,7 +578,7 @@ pango_x_get_per_char (PangoXCFont *cfont, guint16 glyph_index) { if (byte1 < fs->min_byte1 || byte1 > fs->max_byte1 || byte2 < fs->min_char_or_byte2 || byte2 > fs->max_char_or_byte2) - return NULL; + return FALSE; index = ((byte1 - fs->min_byte1) * (fs->max_char_or_byte2 - fs->min_char_or_byte2 + 1)) + @@ -594,39 +591,34 @@ pango_x_get_per_char (PangoXCFont *cfont, guint16 glyph_index) return &fs->min_bounds; } -static PangoXCFont * -pango_x_find_cfont (PangoXFont *font, PangoXCharset charset, guint16 index, XCharStruct **per_char_return) +static gboolean +pango_x_find_glyph (PangoFont *font, + PangoGlyph glyph, + PangoXSubfontInfo **subfont_return, + XCharStruct **charstruct_return) { - GSList *cfonts = font->charsets[charset - 1]->cfonts; + PangoXSubfontInfo *subfont; + XCharStruct *cs; + + guint16 char_index = PANGO_X_GLYPH_INDEX (glyph); + guint16 subfont_index = PANGO_X_GLYPH_SUBFONT (glyph); + + subfont = pango_x_find_subfont (font, subfont_index); + if (!subfont) + return FALSE; - while (cfonts) - { - XCharStruct *per_char; - PangoXCFont *cfont = cfonts->data; - - if (!cfont->font_struct) - { - cfont->font_struct = XLoadQueryFont (font->display, cfont->xlfd); - if (!cfont->font_struct) - g_error ("Error loading font '%s'\n", cfont->xlfd); - } + cs = pango_x_get_per_char (subfont, char_index); - per_char = pango_x_get_per_char (cfont, index); + if (cs->width != 0) + { + if (subfont_return) + *subfont_return = subfont; - if (per_char && per_char->width != 0) - { - if (per_char_return) - *per_char_return = per_char; - - return cfont; - } - - cfonts = cfonts->next; + if (charstruct_return) + *charstruct_return = cs; + + return TRUE; } - - if (per_char_return) - *per_char_return = NULL; - - return NULL; + else + return FALSE; } - |