diff options
author | Behdad Esfahbod <behdad@behdad.org> | 2012-08-16 21:48:50 -0400 |
---|---|---|
committer | Behdad Esfahbod <behdad@behdad.org> | 2012-08-16 22:02:41 -0400 |
commit | 194b6ee552318ec6c494f34ed9f0979d0460fe4f (patch) | |
tree | af5b939f4750a4208b58c06b71fe09cdefa144f0 /pango/pangox.c | |
parent | 8168660e5f1906aed2a45d30529058f51473bcef (diff) | |
download | pango-194b6ee552318ec6c494f34ed9f0979d0460fe4f.tar.gz |
Remove PangoX
Been overdue...
Diffstat (limited to 'pango/pangox.c')
-rw-r--r-- | pango/pangox.c | 1790 |
1 files changed, 0 insertions, 1790 deletions
diff --git a/pango/pangox.c b/pango/pangox.c deleted file mode 100644 index 24bca5ea..00000000 --- a/pango/pangox.c +++ /dev/null @@ -1,1790 +0,0 @@ -/* pangox.c: Routines for handling X fonts - * - * Copyright (C) 1999 Red Hat Software - * Copyright (C) 2000 SuSE Linux Ltd - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include "config.h" -#include <string.h> -#include <stdlib.h> -#include <math.h> - -#include <X11/Xlib.h> -#include "pango-impl-utils.h" - -#undef PANGO_DISABLE_DEPRECATED - -#include "pangox.h" -#include "pangox-private.h" - -#define PANGO_TYPE_X_FONT (pango_x_font_get_type ()) -#define PANGO_X_FONT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_X_FONT, PangoXFont)) -#define PANGO_X_FONT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PANGO_TYPE_X_FONT, PangoXFontClass)) -#define PANGO_X_IS_FONT(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_TYPE_X_FONT)) -#define PANGO_X_IS_FONT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PANGO_TYPE_X_FONT)) -#define PANGO_X_FONT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PANGO_TYPE_X_FONT, PangoXFontClass)) - -typedef struct _PangoXFontClass PangoXFontClass; -typedef struct _PangoXMetricsInfo PangoXMetricsInfo; -typedef struct _PangoXContextInfo PangoXContextInfo; - -struct _PangoXSubfontInfo -{ - char *xlfd; - XFontStruct *font_struct; - gboolean is_1byte; - int range_byte1; - int range_byte2; -}; - -struct _PangoXMetricsInfo -{ - const char *sample_str; - PangoFontMetrics *metrics; -}; - -struct _PangoXContextInfo -{ - PangoGetGCFunc get_gc_func; - PangoFreeGCFunc free_gc_func; -}; - -struct _PangoXFontClass -{ - PangoFontClass parent_class; -}; - -static void pango_x_font_dispose (GObject *object); -static void pango_x_font_finalize (GObject *object); - -static PangoFontDescription *pango_x_font_describe (PangoFont *font); -static PangoCoverage * pango_x_font_get_coverage (PangoFont *font, - PangoLanguage *language); -static PangoEngineShape * pango_x_font_find_shaper (PangoFont *font, - PangoLanguage *language, - guint32 ch); -static void pango_x_font_get_glyph_extents (PangoFont *font, - PangoGlyph glyph, - PangoRectangle *ink_rect, - PangoRectangle *logical_rect); -static PangoFontMetrics * pango_x_font_get_metrics (PangoFont *font, - PangoLanguage *language); -static PangoFontMap * pango_x_font_get_font_map (PangoFont *font); - -static PangoXSubfontInfo * pango_x_find_subfont (PangoFont *font, - PangoXSubfont subfont_index); -static XCharStruct * pango_x_get_per_char (PangoFont *font, - PangoXSubfontInfo *subfont, - guint16 char_index); -static gboolean pango_x_find_glyph (PangoFont *font, - PangoGlyph glyph, - PangoXSubfontInfo **subfont_return, - XCharStruct **charstruct_return); -static XFontStruct * pango_x_get_font_struct (PangoFont *font, - PangoXSubfontInfo *info); - -static void pango_x_get_item_properties (PangoItem *item, - PangoUnderline *uline, - PangoAttrColor *fg_color, - gboolean *fg_set, - PangoAttrColor *bg_color, - gboolean *bg_set); - -static inline PangoXSubfontInfo * -pango_x_find_subfont (PangoFont *font, - PangoXSubfont subfont_index) -{ - PangoXFont *xfont = (PangoXFont *)font; - - if (subfont_index < 1 || subfont_index > xfont->n_subfonts) - return NULL; - - return xfont->subfonts[subfont_index-1]; -} - -static void -pango_x_make_font_struct (PangoFont *font, PangoXSubfontInfo *info) -{ - PangoXFont *xfont = (PangoXFont *)font; - PangoXFontCache *cache; - - cache = pango_x_font_map_get_font_cache (xfont->fontmap); - - info->font_struct = pango_x_font_cache_load (cache, info->xlfd); - if (!info->font_struct) - { - g_warning ("Cannot load font for XLFD '%s\n", info->xlfd); - - /* Prevent a segfault, but probably not much more */ - info->font_struct = pango_x_font_cache_load (cache, "fixed"); - } - - info->is_1byte = (info->font_struct->min_byte1 == 0 && info->font_struct->max_byte1 == 0); - info->range_byte1 = info->font_struct->max_byte1 - info->font_struct->min_byte1 + 1; - info->range_byte2 = info->font_struct->max_char_or_byte2 - info->font_struct->min_char_or_byte2 + 1; -} - -static inline XFontStruct * -pango_x_get_font_struct (PangoFont *font, PangoXSubfontInfo *info) -{ - if (!info->font_struct) - pango_x_make_font_struct (font, info); - - return info->font_struct; -} - -static void -free_context_info (PangoXContextInfo *info) -{ - g_slice_free (PangoXContextInfo, info); -} - -static PangoXContextInfo * -get_context_info (PangoContext *context) -{ - PangoXContextInfo *info; - static GQuark quark = 0; - - if (G_UNLIKELY (!quark)) - quark = g_quark_from_static_string ("pango-x-info"); - - info = g_object_get_qdata (G_OBJECT (context), quark); - - if (G_UNLIKELY (!info)) - { - info = g_slice_new (PangoXContextInfo); - info->get_gc_func = NULL; - info->free_gc_func = NULL; - g_object_set_qdata_full (G_OBJECT (context), - quark, - info, (GDestroyNotify)free_context_info); - } - - return info; -} - -/** - * 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. - * - * Deprecated: 1.22: Use pango_x_font_map_for_display() followed by - * pango_font_map_create_context() instead. - **/ -PangoContext * -pango_x_get_context (Display *display) -{ - return pango_font_map_create_context (pango_x_font_map_for_display (display)); -} - -/** - * 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 = get_context_info (context); - - info->get_gc_func = get_gc_func; - info->free_gc_func = free_gc_func; -} - -G_DEFINE_TYPE (PangoXFont, pango_x_font, PANGO_TYPE_FONT); - -static void -pango_x_font_init (PangoXFont *xfont) -{ - xfont->subfonts_by_charset = g_hash_table_new (g_str_hash, g_str_equal); - - xfont->n_subfonts = 0; - xfont->max_subfonts = 1; - - xfont->subfonts = g_new (PangoXSubfontInfo *, xfont->max_subfonts); - - xfont->metrics_by_lang = NULL; - - xfont->size = -1; - xfont->xface = NULL; -} - -static void -pango_x_font_class_init (PangoXFontClass *class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (class); - PangoFontClass *font_class = PANGO_FONT_CLASS (class); - - object_class->finalize = pango_x_font_finalize; - object_class->dispose = pango_x_font_dispose; - - font_class->describe = pango_x_font_describe; - font_class->get_coverage = pango_x_font_get_coverage; - font_class->find_shaper = pango_x_font_find_shaper; - font_class->get_glyph_extents = pango_x_font_get_glyph_extents; - font_class->get_metrics = pango_x_font_get_metrics; - font_class->get_font_map = pango_x_font_get_font_map; -} - -PangoXFont * -pango_x_font_new (PangoFontMap *fontmap, const char *spec, int size) -{ - PangoXFont *result; - - g_return_val_if_fail (fontmap != NULL, NULL); - g_return_val_if_fail (spec != NULL, NULL); - - result = g_object_new (PANGO_TYPE_X_FONT, NULL); - - g_assert (result->fontmap == NULL); - result->fontmap = fontmap; - g_object_add_weak_pointer (G_OBJECT (result->fontmap), (gpointer *) (gpointer) &result->fontmap); - - result->display = pango_x_fontmap_get_display (fontmap); - - result->fonts = g_strsplit(spec, ",", -1); - for (result->n_fonts = 0; result->fonts[result->n_fonts]; result->n_fonts++) - ; /* Nothing */ - - result->size = size; - - return result; -} - -/** - * pango_x_load_font: - * @display: the X display. - * @spec: a comma-separated list of XLFD's. - * - * Loads up a logical font based on a "fontset" style text - * specification. This is not remotely useful (Pango API's generally - * work in terms of #PangoFontDescription) and the result may not - * work correctly in all circumstances. Use of this function should - * be avoided. - * - * Returns: a new #PangoFont. - */ -PangoFont * -pango_x_load_font (Display *display, - const char *spec) -{ - PangoXFont *result; - - g_return_val_if_fail (display != NULL, NULL); - g_return_val_if_fail (spec != NULL, NULL); - - result = pango_x_font_new (pango_x_font_map_for_display (display), spec, -1); - - return (PangoFont *)result; -} - - -#define FLUSH \ - G_STMT_START { \ - if (charcount) \ - { \ - XDrawString16 (display, d, gc, \ - glyph_x0, glyph_y0, \ - xcharbuffer, charcount); \ - charcount = 0; \ - } \ - } G_STMT_END - - -/** - * pango_x_render: - * @display: the X display. - * @d: the drawable on which to draw string. - * @gc: the graphics context. - * @font: the font in which to draw the string. - * @glyphs: the glyph string to draw. - * @x: the x position of start of string (in pixels). - * @y: the y position of baseline (in pixels). - * - * Renders a #PangoGlyphString onto an X drawable. - */ -void -pango_x_render (Display *display, - Drawable d, - GC gc, - PangoFont *font, - PangoGlyphString *glyphs, - int x, - int y) -{ - Font old_fid = None; - XFontStruct *fs; - int i; - int x_off = 0; - - /* - * We collect the characters in this buffer as long as the font does not - * change. At that time, or when the buffer runs full, or at the end, - * then we empty the buffer. - */ - XChar2b xcharbuffer[1000]; - int glyph_x0 = 0, expected_x = 0; /* x/y initializations are to quiet GCC */ - int glyph_y0 = 0; - int charcount = 0; - - g_return_if_fail (display != NULL); - g_return_if_fail (glyphs != NULL); - - for (i=0; i<glyphs->num_glyphs; i++) - { - PangoGlyph glyph = glyphs->glyphs[i].glyph; - int glyph_x = x + PANGO_PIXELS (x_off + glyphs->glyphs[i].geometry.x_offset); - int glyph_y = y + PANGO_PIXELS (glyphs->glyphs[i].geometry.y_offset); - - /* Clip glyphs into the X coordinate range; we really - * want to clip glyphs with an ink rect outside the - * [0,32767] x [0,32767] rectangle but looking up - * the ink rect here would be a noticeable speed hit. - * This is close enough. - */ - if (!(glyph != PANGO_GLYPH_EMPTY && - glyph_x >= -16384 && glyph_x <= 32767 && - glyph_y >= -16384 && glyph_y <= 32767)) - goto next_glyph; - - if (G_LIKELY ((glyph & PANGO_GLYPH_UNKNOWN_FLAG) == 0)) - { - guint16 index = PANGO_X_GLYPH_INDEX (glyph); - guint16 subfont_index = PANGO_X_GLYPH_SUBFONT (glyph); - PangoXSubfontInfo *subfont; - - subfont = pango_x_find_subfont (font, subfont_index); - if (subfont) - { - fs = pango_x_get_font_struct (font, subfont); - if (!fs) - continue; - - if (fs->fid != old_fid) - { - FLUSH; - XSetFont (display, gc, fs->fid); - old_fid = fs->fid; - } - - if (charcount == G_N_ELEMENTS (xcharbuffer) || - (charcount > 0 && (glyph_y != glyph_y0 || - glyph_x != expected_x))) - FLUSH; - - if (charcount == 0) - { - glyph_x0 = glyph_x; - glyph_y0 = glyph_y; - } - xcharbuffer[charcount].byte1 = index / 256; - xcharbuffer[charcount].byte2 = index % 256; - - expected_x = glyph_x + XTextWidth16 (fs, &xcharbuffer[charcount], 1); - - charcount++; - } else - goto unknown_glyph; - } else { - PangoFontMetrics *metrics; - int x1, y1, x2, y2; /* rectangle the character should go inside. */ - int baseline; - int stroke_thick; - gunichar wc; - gboolean invalid_input; - - unknown_glyph: - FLUSH; - - if (font) - metrics = pango_font_get_metrics (font, NULL); - else - metrics = NULL; - - if (metrics) - { - y1 = glyph_y - PANGO_PIXELS (metrics->ascent); - y2 = y1 + PANGO_PIXELS (metrics->ascent + metrics->descent); - } - else - { - y2 = glyph_y; - y1 = y2 - PANGO_UNKNOWN_GLYPH_HEIGHT; - } - - x1 = glyph_x; - x2 = x1 + PANGO_PIXELS (glyphs->glyphs[i].geometry.width); - - baseline = glyph_y; - stroke_thick = MAX ((int) (0.5 + 0.025 * (y2 - y1)), 1); - - if (glyph & PANGO_GLYPH_UNKNOWN_FLAG) - wc = glyph & ~PANGO_GLYPH_UNKNOWN_FLAG; - else - wc = 0; - invalid_input = glyph == PANGO_GLYPH_INVALID_INPUT || wc > 0x10FFFF; - - switch (wc) - { - case '\n': - case '\r': - case 0x2028: /* Line separator */ - case 0x2029: /* Paragraph separator */ - { - /* Draw a carriage-return thingy */ - PangoRectangle up_stroke; - PangoRectangle across_stroke; - - int hborder = (x2 - x1) * 0.1; - int arrow_height = 0.25 * (y2 - y1); - int top_border = (y2 - y1) * 0.25; - - int arrow_x, arrow_width, tmp_height; - - /* Draw the arrow-head */ - - tmp_height = (stroke_thick % 2 == 0) ? 2 : 1; /* Starting height */ - arrow_height = 2 * ((1 + arrow_height - tmp_height) / 2) + tmp_height; /* Force symmetry */ - arrow_width = 2 + arrow_height - tmp_height; - - for (arrow_x = x1 + hborder; arrow_x < x1 + hborder + arrow_width; arrow_x++) - { - XDrawLine (display, d, gc, - arrow_x, - baseline - stroke_thick + (stroke_thick - tmp_height) / 2, - arrow_x, - baseline - stroke_thick + (stroke_thick - tmp_height) / 2 + tmp_height - 1); - - if ((arrow_x - x1 - hborder) % 2 == 1) - tmp_height += 2; - } - - across_stroke.x = arrow_x; - across_stroke.width = x2 - hborder - arrow_x - stroke_thick; - across_stroke.y = baseline - stroke_thick; - across_stroke.height = stroke_thick; - - XFillRectangle (display, d, gc, - across_stroke.x, across_stroke.y, - across_stroke.width, across_stroke.height); - - up_stroke.x = across_stroke.x + across_stroke.width; - up_stroke.width = stroke_thick; - up_stroke.y = y1 + top_border; - up_stroke.height = baseline - up_stroke.y; - - XFillRectangle (display, d, gc, - up_stroke.x, up_stroke.y, - up_stroke.width, up_stroke.height); - } - break; - - default: - { - /* Perhaps we should draw the box-with-numbers as in the - * other backends, though we have no guarantee of having - * an appropriate size of font. Right now, we just - * draw an empty box. (To draw the box-with-numbers. - * the backends would have to be changed to use - * pango_x_font_get_unknown_glyph() rather than - * pango_x_get_unknown_glyph(). - */ - - int xspace = MAX ((int) (0.5 + 0.1 * (x2 - x1)), 1); - int yspace = MAX ((int) (0.5 + 0.1 * (y2 - y1)), 1); - - x1 += xspace; - x2 -= xspace; - y1 += yspace; - y2 -= yspace; - - XFillRectangle (display, d, gc, - x1, y1, - x2 - x1, stroke_thick); - XFillRectangle (display, d, gc, - x1, y1 + stroke_thick, - stroke_thick, y2 - y1 - 2 * stroke_thick); - XFillRectangle (display, d, gc, - x2 - stroke_thick, y1 + stroke_thick, - stroke_thick, y2 - y1 - 2 * stroke_thick); - XFillRectangle (display, d, gc, - x1, y2 - stroke_thick, - x2 - x1, stroke_thick); - if (invalid_input) - { - XDrawLine (display, d, gc, - x1, y1, - x2-1, y2-1); - XDrawLine (display, d, gc, - x2-1, y1, - x1, y2-1); - } - - break; - } - } - - pango_font_metrics_unref (metrics); - } - - next_glyph: - x_off += glyphs->glyphs[i].geometry.width; - } - FLUSH; -} - -#undef FLUSH - -static void -pango_x_font_get_glyph_extents (PangoFont *font, - PangoGlyph glyph, - PangoRectangle *ink_rect, - PangoRectangle *logical_rect) -{ - XCharStruct *cs; - PangoXSubfontInfo *subfont; - - if (glyph == PANGO_GLYPH_EMPTY) - { - if (ink_rect) - ink_rect->x = ink_rect->width = ink_rect->y = ink_rect->height = 0; - if (logical_rect) - logical_rect->x = logical_rect->width = logical_rect->y = logical_rect->height = 0; - return; - } - if ((glyph & PANGO_GLYPH_UNKNOWN_FLAG) == 0 && pango_x_find_glyph (font, glyph, &subfont, &cs)) - { - if (ink_rect) - { - ink_rect->x = PANGO_SCALE * cs->lbearing; - ink_rect->width = PANGO_SCALE * (cs->rbearing - cs->lbearing); - ink_rect->y = PANGO_SCALE * -cs->ascent; - ink_rect->height = PANGO_SCALE * (cs->ascent + cs->descent); - } - if (logical_rect) - { - logical_rect->x = 0; - logical_rect->width = PANGO_SCALE * cs->width; - logical_rect->y = - PANGO_SCALE * subfont->font_struct->ascent; - logical_rect->height = PANGO_SCALE * (subfont->font_struct->ascent + subfont->font_struct->descent); - } - } - else - { - PangoFontMetrics *metrics; - gunichar wc; - gdouble width_factor; - int w; - - if (glyph & PANGO_GLYPH_UNKNOWN_FLAG) - wc = glyph & (~PANGO_GLYPH_UNKNOWN_FLAG); - else - wc = 0; - - switch (wc) - { - case '\n': - case '\r': - case 0x2028: /* Line separator */ - case 0x2029: /* Paragraph separator */ - { -#define MAGIC_FACTOR 1.2 - - /* carriage-return thingy */ - width_factor = MAGIC_FACTOR; - break; - } - default: - { - /* Unknown glyph square */ - width_factor = 1.0; - } - } - - metrics = pango_font_get_metrics (font, NULL); - - if (metrics) - { - w = metrics->approximate_char_width * width_factor; - w = PANGO_SCALE * PANGO_PIXELS (w); - - if (ink_rect) - { - ink_rect->x = PANGO_SCALE; - ink_rect->width = w - 2 * PANGO_SCALE; - ink_rect->y = - (metrics->ascent - PANGO_SCALE); - ink_rect->height = metrics->ascent + metrics->descent - 2 * PANGO_SCALE; - } - if (logical_rect) - { - logical_rect->x = 0; - logical_rect->width = w; - logical_rect->y = - metrics->ascent; - logical_rect->height = metrics->ascent + metrics->descent; - } - - pango_font_metrics_unref (metrics); - } - else - { - if (ink_rect) - ink_rect->x = ink_rect->y = ink_rect->height = ink_rect->width = 0; - if (logical_rect) - logical_rect->x = logical_rect->y = logical_rect->height = logical_rect->width = 0; - } - } -} - -static gboolean -get_int_prop (Atom atom, - XFontStruct *fs, - int *val) -{ - int i; - - *val = 0; - - i = 0; - while (i < fs->n_properties) - { - if (fs->properties[i].name == atom) - { - *val = fs->properties[i].card32; - return TRUE; - } - - ++i; - } - - return FALSE; -} - -/* Call @func with each glyph resulting from shaping @string with each - * glyph. 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 -itemize_string_foreach (PangoFont *font, - PangoLanguage *language, - const char *str, - void (*func) (PangoFont *font, - PangoGlyphInfo *glyph_info, - gpointer data), - gpointer data) -{ - const char *start, *p; - PangoGlyphString *glyph_str = pango_glyph_string_new (); - PangoEngineShape *shaper, *last_shaper; - int last_level; - int i; - guint8 *embedding_levels; - PangoDirection base_dir = PANGO_DIRECTION_LTR; - gboolean finished = FALSE; - - embedding_levels = pango_log2vis_get_embedding_levels (str, -1, &base_dir); - - last_shaper = NULL; - last_level = 0; - - i = 0; - p = start = str; - while (*p || !finished) - { - gunichar wc; - - if (*p) - { - wc = g_utf8_get_char (p); - shaper = pango_font_find_shaper (font, language, wc); - } - else - { - finished = TRUE; - shaper = NULL; - } - - if (p > start && - (finished || - (shaper != last_shaper || last_level != embedding_levels[i]))) - { - PangoAnalysis analysis = { NULL }; - int j; - - analysis.shape_engine = last_shaper; - analysis.font = font; - analysis.language = language; - analysis.level = last_level; - - pango_shape (start, p - start, &analysis, glyph_str); - - for (j = 0; j < glyph_str->num_glyphs; j++) - (*func) (font, &glyph_str->glyphs[j], data); - - start = p; - } - - if (!finished) - { - p = g_utf8_next_char (p); - - last_shaper = shaper; - last_level = embedding_levels[i]; - i++; - } - } - - pango_glyph_string_free (glyph_str); - g_free (embedding_levels); -} - -/* Get composite font metrics for all subfonts in list - */ -static void -get_font_metrics_from_subfonts (PangoFont *font, - GSList *subfonts, - PangoFontMetrics *metrics) -{ - PangoXFont *xfont = (PangoXFont *)font; - GSList *tmp_list = subfonts; - gboolean first = TRUE; - int total_avg_widths = 0; - int n_avg_widths = 0; - Atom avg_width_atom; - - avg_width_atom = pango_x_fontmap_atom_from_name (xfont->fontmap, - "AVERAGE_WIDTH"); - - 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); - gint avg_width = 0; - - 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); - } - - if (get_int_prop (avg_width_atom, fs, &avg_width)) - { - /* convert decipoints --> Pango units. - * Resolution is in (points * PANGO_SCALE) / pixel, - * avg_width in decipoints. - * We want pixels * PANGO_SCALE - */ - - /* Convert to points * PANGO_SCALE */ - avg_width *= PANGO_SCALE / (double) 10.0; - /* Convert to pixels * PANGO_SCALE */ - avg_width *= (PANGO_SCALE / PANGO_X_FONT_MAP (PANGO_X_FONT (font)->fontmap)->resolution); - } - else - { - avg_width = PANGO_SCALE * ((fs->min_bounds.width + fs->max_bounds.width) / 2); - } - } - - if (avg_width) - { - total_avg_widths += avg_width; - n_avg_widths += 1; - } - } - else - g_warning ("Invalid subfont %d in get_font_metrics_from_subfonts", GPOINTER_TO_UINT (tmp_list->data)); - - tmp_list = tmp_list->next; - } - - /* This is pretty darn bogus. */ - if (n_avg_widths) - metrics->approximate_char_width = total_avg_widths / n_avg_widths; - else - metrics->approximate_char_width = PANGO_UNKNOWN_GLYPH_WIDTH * PANGO_SCALE; - if (metrics->ascent + metrics->descent == 0) - { - metrics->ascent = PANGO_UNKNOWN_GLYPH_HEIGHT * PANGO_SCALE; - metrics->descent = 0; - } -} - -static void -get_subfonts_foreach (PangoFont *font, - PangoGlyphInfo *glyph_info, - gpointer data) -{ - GSList **subfonts = data; - PangoGlyph glyph = glyph_info->glyph; - PangoXSubfont subfont; - - if (glyph == PANGO_GLYPH_EMPTY) - return; - - /* Use an arbitrary subfont for unknown glyphs...*/ - if (glyph & PANGO_GLYPH_UNKNOWN_FLAG) - { - if (((PangoXFont *)font)->n_subfonts > 0) - glyph = PANGO_X_MAKE_GLYPH (1, 0); - else - return; - } - - subfont = PANGO_X_GLYPH_SUBFONT (glyph); - if (!g_slist_find (*subfonts, GUINT_TO_POINTER ((guint)subfont))) - *subfonts = g_slist_prepend (*subfonts, GUINT_TO_POINTER ((guint)subfont)); -} - -/* Get composite font metrics for all subfonts resulting from shaping - * string str with the given font - */ -static void -get_font_metrics_from_string (PangoFont *font, - PangoLanguage *language, - const char *str, - PangoFontMetrics *metrics) -{ - GSList *subfonts = NULL; - - itemize_string_foreach (font, language, str, get_subfonts_foreach, &subfonts); - get_font_metrics_from_subfonts (font, subfonts, metrics); - g_slist_free (subfonts); -} - -static void -average_width_foreach (PangoFont *font G_GNUC_UNUSED, - PangoGlyphInfo *glyph_info, - gpointer data) -{ - int *width = data; - - *width += glyph_info->geometry.width; -} - -/* Get composite font metrics for all subfonts resulting from shaping - * string str with the given font - */ -static gdouble -get_total_width_for_string (PangoFont *font, - PangoLanguage *language, - const char *str) -{ - int width = 0; - - itemize_string_foreach (font, language, str, average_width_foreach, &width); - - return width; -} - -static PangoFontMetrics * -pango_x_font_get_metrics (PangoFont *font, - PangoLanguage *language) -{ - PangoXMetricsInfo *info = NULL; /* Quiet gcc */ - PangoXFont *xfont = (PangoXFont *)font; - GSList *tmp_list; - - const char *sample_str = pango_language_get_sample_string (language); - - tmp_list = xfont->metrics_by_lang; - while (tmp_list) - { - info = tmp_list->data; - - if (info->sample_str == sample_str) /* We _don't_ need strcmp */ - break; - - tmp_list = tmp_list->next; - } - - if (!tmp_list) - { - PangoFontMetrics *metrics; - - info = g_slice_new0 (PangoXMetricsInfo); - - xfont->metrics_by_lang = g_slist_prepend (xfont->metrics_by_lang, info); - - info->sample_str = sample_str; - metrics = pango_font_metrics_new (); - - get_font_metrics_from_string (font, language, sample_str, metrics); - - metrics->approximate_digit_width = get_total_width_for_string (font, language, "0123456789") / 10; - - info->metrics = metrics; - } - - return pango_font_metrics_ref (info->metrics); -} - -static PangoFontMap * -pango_x_font_get_font_map (PangoFont *font) -{ - PangoXFont *xfont = (PangoXFont *)font; - - return xfont->fontmap; -} - -/* Compare the tail of a to b */ -static gboolean -match_end (const char *a, const char *b) -{ - size_t len_a = strlen (a); - size_t len_b = strlen (b); - - if (len_b > len_a) - return FALSE; - else - return (strcmp (a + len_a - len_b, b) == 0); -} - -/* Substitute in a charset into an XLFD. Return the - * (g_malloc'd) new name, or %NULL if the XLFD cannot - * match the charset - */ -static char * -name_for_charset (char *xlfd, char *charset) -{ - char *p; - char *dash_charset = g_strconcat ("-", charset, NULL); - char *result = NULL; - int ndashes = 0; - - for (p = xlfd; *p; p++) - if (*p == '-') - ndashes++; - - if (ndashes == 14) /* Complete XLFD */ - { - if (match_end (xlfd, "-*-*")) - { - result = g_malloc (strlen (xlfd) - 4 + strlen (dash_charset) + 1); - strncpy (result, xlfd, strlen (xlfd) - 4); - strcpy (result + strlen (xlfd) - 4, dash_charset); - } - if (match_end (xlfd, dash_charset)) - result = g_strdup (xlfd); - } - else if (ndashes == 13) - { - if (match_end (xlfd, "-*")) - { - result = g_malloc (strlen (xlfd) - 2 + strlen (dash_charset) + 1); - strncpy (result, xlfd, strlen (xlfd) - 2); - strcpy (result + strlen (xlfd) - 2, dash_charset); - } - if (match_end (xlfd, dash_charset)) - result = g_strdup (xlfd); - } - else - { - if (match_end (xlfd, "*")) - { - result = g_malloc (strlen (xlfd) + strlen (dash_charset) + 1); - strcpy (result, xlfd); - strcpy (result + strlen (xlfd), dash_charset); - } - if (match_end (xlfd, dash_charset)) - result = g_strdup (xlfd); - } - - g_free (dash_charset); - return result; -} - -static PangoXSubfont -pango_x_insert_subfont (PangoFont *font, const char *xlfd) -{ - PangoXFont *xfont = (PangoXFont *)font; - PangoXSubfontInfo *info; - - info = g_slice_new (PangoXSubfontInfo); - - info->xlfd = g_strdup (xlfd); - info->font_struct = NULL; - - 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; - - return xfont->n_subfonts; -} - -/** - * 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(). - * - * Lists the subfonts of a given font. The result is ordered first by charset, - * and then within each charset, by the order of fonts in the font specification. - * - * Return value: length of the arrays stored in @subfont_ids and - * @subfont_charsets. - **/ -int -pango_x_list_subfonts (PangoFont *font, - char **charsets, - int n_charsets, - PangoXSubfont **subfont_ids, - int **subfont_charsets) -{ - PangoXFont *xfont = (PangoXFont *)font; - PangoXSubfont **subfont_lists; - PangoFontMap *fontmap; - int i, j; - int n_subfonts = 0; - - g_return_val_if_fail (font != NULL, 0); - g_return_val_if_fail (n_charsets == 0 || charsets != NULL, 0); - - fontmap = pango_x_font_map_for_display (xfont->display); - - subfont_lists = g_new (PangoXSubfont *, n_charsets); - - for (j=0; j<n_charsets; j++) - { - subfont_lists[j] = g_hash_table_lookup (xfont->subfonts_by_charset, charsets[j]); - if (!subfont_lists[j]) - { - subfont_lists[j] = g_new (PangoXSubfont, xfont->n_fonts); - - for (i = 0; i < xfont->n_fonts; i++) - { - PangoXSubfont subfont = 0; - char *xlfd; - - if (xfont->size == -1) - { - xlfd = name_for_charset (xfont->fonts[i], charsets[j]); - - if (xlfd) - { - int count; - char **names = XListFonts (xfont->display, xlfd, 1, &count); - if (count > 0) - subfont = pango_x_insert_subfont (font, names[0]); - - XFreeFontNames (names); - g_free (xlfd); - } - } - else - { - xlfd = pango_x_make_matching_xlfd (fontmap, xfont->fonts[i], charsets[j], xfont->size); - if (xlfd) - { - subfont = pango_x_insert_subfont (font, xlfd); - g_free (xlfd); - } - } - - subfont_lists[j][i] = subfont; - } - - g_hash_table_insert (xfont->subfonts_by_charset, g_strdup (charsets[j]), subfont_lists[j]); - } - - for (i = 0; i < xfont->n_fonts; i++) - if (subfont_lists[j][i]) - n_subfonts++; - } - - *subfont_ids = g_new (PangoXSubfont, n_subfonts); - *subfont_charsets = g_new (int, n_subfonts); - - n_subfonts = 0; - - for (j=0; j<n_charsets; j++) - for (i=0; i<xfont->n_fonts; i++) - if (subfont_lists[j][i]) - { - (*subfont_ids)[n_subfonts] = subfont_lists[j][i]; - (*subfont_charsets)[n_subfonts] = j; - n_subfonts++; - } - - g_free (subfont_lists); - - return n_subfonts; -} - -/** - * pango_x_has_glyph: - * @font: a #PangoFont which must be from the X backend. - * @glyph: the index of a glyph in the font. (Formed - * using the #PANGO_X_MAKE_GLYPH macro) - * - * Checks if the given glyph is present in a X font. - * - * Return value: %TRUE if the glyph is present. - **/ -gboolean -pango_x_has_glyph (PangoFont *font, - PangoGlyph glyph) -{ - 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; - - cs = pango_x_get_per_char (font, subfont, char_index); - - if (cs && (cs->lbearing != cs->rbearing || cs->width != 0)) - return TRUE; - else - return FALSE; -} - -/** - * pango_x_font_subfont_xlfd: - * @font: a #PangoFont which must be from the X backend. - * @subfont_id: the id of a subfont within the font. - * - * Determines the X Logical Font Description for the specified - * subfont. - * - * Return value: A newly-allocated string containing the XLFD for the - * subfont. This string must be freed with g_free(). - **/ -char * -pango_x_font_subfont_xlfd (PangoFont *font, - PangoXSubfont subfont_id) -{ - PangoXSubfontInfo *subfont; - - g_return_val_if_fail (font != NULL, NULL); - g_return_val_if_fail (PANGO_X_IS_FONT (font), NULL); - - subfont = pango_x_find_subfont (font, subfont_id); - if (!subfont) - { - g_warning ("pango_x_font_subfont_xlfd: Invalid subfont_id specified"); - return NULL; - } - - return g_strdup (subfont->xlfd); -} - -static void -pango_x_font_dispose (GObject *object) -{ - PangoXFont *xfont = PANGO_X_FONT (object); - - /* If the font is not already in the freed-fonts cache, add it, - * if it is already there, do nothing and the font will be - * freed. - */ - if (!xfont->in_cache && xfont->fontmap) - pango_x_fontmap_cache_add (xfont->fontmap, xfont); - - G_OBJECT_CLASS (pango_x_font_parent_class)->dispose (object); -} - - -static void -subfonts_foreach (gpointer key, gpointer value, gpointer data G_GNUC_UNUSED) -{ - g_free (key); - g_free (value); -} - -static void -free_metrics_info (PangoXMetricsInfo *info) -{ - pango_font_metrics_unref (info->metrics); - g_slice_free (PangoXMetricsInfo, info); -} - -static void -pango_x_font_finalize (GObject *object) -{ - PangoXFont *xfont = (PangoXFont *)object; - PangoXFontCache *cache = pango_x_font_map_get_font_cache (xfont->fontmap); - - int i; - - for (i=0; i<xfont->n_subfonts; i++) - { - PangoXSubfontInfo *info = xfont->subfonts[i]; - - g_free (info->xlfd); - - if (info->font_struct) - pango_x_font_cache_unload (cache, info->font_struct); - - g_slice_free (PangoXSubfontInfo, info); - } - - g_free (xfont->subfonts); - - 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)free_metrics_info, NULL); - g_slist_free (xfont->metrics_by_lang); - - if (xfont->xface) - pango_x_face_remove (xfont->xface, (PangoFont *)xfont); - - g_assert (xfont->fontmap != NULL); - g_object_remove_weak_pointer (G_OBJECT (xfont->fontmap), (gpointer *) (gpointer) &xfont->fontmap); - xfont->fontmap = NULL; - - g_strfreev (xfont->fonts); - - G_OBJECT_CLASS (pango_x_font_parent_class)->finalize (object); -} - -static PangoFontDescription * -pango_x_font_describe (PangoFont *font) -{ - /* FIXME: this doesn't work for fonts from pango_x_font_load() - */ - PangoXFont *xfont = (PangoXFont *)font; - - if (xfont->xface) - { - PangoFontDescription *desc = pango_font_face_describe (PANGO_FONT_FACE (xfont->xface)); - pango_font_description_set_size (desc, xfont->size); - - return desc; - } - else - return NULL; -} - -PangoMap * -pango_x_get_shaper_map (PangoLanguage *language) -{ - static guint engine_type_id = 0; - static guint render_type_id = 0; - - if (engine_type_id == 0) - { - engine_type_id = g_quark_from_static_string (PANGO_ENGINE_TYPE_SHAPE); - render_type_id = g_quark_from_static_string (PANGO_RENDER_TYPE_X); - } - - return pango_find_map (language, engine_type_id, render_type_id); -} - -static PangoCoverage * -pango_x_font_get_coverage (PangoFont *font, - PangoLanguage *language) -{ - PangoXFont *xfont = (PangoXFont *)font; - - return pango_x_face_get_coverage (xfont->xface, font, language); -} - -static PangoEngineShape * -pango_x_font_find_shaper (PangoFont *font G_GNUC_UNUSED, - PangoLanguage *language, - guint32 ch) -{ - PangoMap *shape_map = NULL; - PangoScript script; - - shape_map = pango_x_get_shaper_map (language); - script = pango_script_for_unichar (ch); - return (PangoEngineShape *)pango_map_get_engine (shape_map, script); -} - -/* Utility functions */ - -static XCharStruct * -pango_x_get_per_char (PangoFont *font, - PangoXSubfontInfo *subfont, - guint16 char_index) -{ - XFontStruct *fs; - - int index; - int byte1; - int byte2; - - fs = pango_x_get_font_struct (font, subfont); - if (!fs) - return NULL; - - if (subfont->is_1byte) - { - index = (int)char_index - fs->min_char_or_byte2; - if (index < 0 || index >= subfont->range_byte2) - return NULL; - } - else - { - byte1 = (int)(char_index / 256) - fs->min_byte1; - if (byte1 < 0 || byte1 >= subfont->range_byte1) - return NULL; - - byte2 = (int)(char_index % 256) - fs->min_char_or_byte2; - if (byte2 < 0 || byte2 >= subfont->range_byte2) - return NULL; - - index = byte1 * subfont->range_byte2 + byte2; - } - - if (fs->per_char) - return &fs->per_char[index]; - else - return &fs->min_bounds; -} - -static gboolean -pango_x_find_glyph (PangoFont *font, - PangoGlyph glyph, - PangoXSubfontInfo **subfont_return, - XCharStruct **charstruct_return) -{ - 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; - - cs = pango_x_get_per_char (font, subfont, char_index); - - if (cs && (cs->lbearing != cs->rbearing || cs->width != 0)) - { - if (subfont_return) - *subfont_return = subfont; - - if (charstruct_return) - *charstruct_return = cs; - - return TRUE; - } - else - return FALSE; -} - -/** - * pango_x_get_unknown_glyph: - * @font: a #PangoFont. - * - * Returns the index of a glyph suitable for drawing unknown characters; - * you should generally use PANGO_GET_UNKNOWN_GLYPH() instead, - * since that may return a glyph that provides a better representation - * of a particular char. (E.g., by showing hex digits, or a glyph - * representative of a certain Unicode range.) - * - * Return value: a glyph index into @font. - **/ -PangoGlyph -pango_x_get_unknown_glyph (PangoFont *font G_GNUC_UNUSED) -{ - return PANGO_GET_UNKNOWN_GLYPH (0); -} - -/** - * pango_x_render_layout_line: - * @display: the X display. - * @drawable: the drawable on which to draw. - * @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). - * - * Renders a #PangoLayoutLine onto an X drawable. - */ -void -pango_x_render_layout_line (Display *display, - Drawable drawable, - GC gc, - PangoLayoutLine *line, - int x, - 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 = get_context_info (context); - - int x_off = 0; - - pango_layout_line_get_extents (line,NULL, &overall_rect); - - while (tmp_list) - { - PangoUnderline uline = PANGO_UNDERLINE_NONE; - PangoLayoutRun *run = tmp_list->data; - PangoAttrColor fg_color, bg_color; - gboolean fg_set, bg_set; - GC fg_gc; - - tmp_list = tmp_list->next; - - pango_x_get_item_properties (run->item, &uline, &fg_color, &fg_set, &bg_color, &bg_set); - - if (fg_set && info->get_gc_func) - fg_gc = info->get_gc_func (context, &fg_color.color, gc); - else - fg_gc = gc; - - if (uline == PANGO_UNDERLINE_NONE) - pango_glyph_string_extents (run->glyphs, run->item->analysis.font, - NULL, &logical_rect); - else - pango_glyph_string_extents (run->glyphs, run->item->analysis.font, - &ink_rect, &logical_rect); - - if (bg_set && info->get_gc_func) - { - GC bg_gc = info->get_gc_func (context, &bg_color.color, gc); - - XFillRectangle (display, drawable, bg_gc, - x + (x_off + logical_rect.x) / PANGO_SCALE, - y + overall_rect.y / PANGO_SCALE, - logical_rect.width / PANGO_SCALE, - overall_rect.height / PANGO_SCALE); - - 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, - x + x_off / PANGO_SCALE, y); - - switch (uline) - { - case PANGO_UNDERLINE_NONE: - break; - case PANGO_UNDERLINE_DOUBLE: - XDrawLine (display, drawable, fg_gc, - x + (x_off + ink_rect.x) / PANGO_SCALE - 1, y + 4, - x + (x_off + ink_rect.x + ink_rect.width) / PANGO_SCALE, y + 4); - /* Fall through */ - case PANGO_UNDERLINE_SINGLE: - XDrawLine (display, drawable, fg_gc, - x + (x_off + ink_rect.x) / PANGO_SCALE - 1, y + 2, - x + (x_off + ink_rect.x + ink_rect.width) / PANGO_SCALE, y + 2); - break; - case PANGO_UNDERLINE_ERROR: - { - int point_x; - int counter = 0; - int end_x = x + (x_off + ink_rect.x + ink_rect.width) / PANGO_SCALE; - - for (point_x = x + PANGO_PIXELS (x_off + ink_rect.x) - 1; - point_x <= end_x; - point_x += 2) - { - if (counter) - XDrawLine (display, drawable, gc, - point_x, y + 2, MIN (point_x + 1, end_x), y + 2); - else - XDrawLine (display, drawable, gc, - point_x, y + 3, MIN (point_x + 1, end_x), y + 3); - - counter = (counter + 1) % 2; - } - } - break; - case PANGO_UNDERLINE_LOW: - XDrawLine (display, drawable, fg_gc, - x + (x_off + ink_rect.x) / PANGO_SCALE - 1, y + (ink_rect.y + ink_rect.height) / PANGO_SCALE + 2, - x + (x_off + ink_rect.x + ink_rect.width) / PANGO_SCALE, y + (ink_rect.y + ink_rect.height) / PANGO_SCALE + 2); - break; - } - - if (fg_set && info->get_gc_func && info->free_gc_func) - info->free_gc_func (context, fg_gc); - - x_off += logical_rect.width; - } -} - -/** - * pango_x_render_layout: - * @display: the X display. - * @drawable: the drawable on which to draw. - * @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). - * - * Renders a #PangoLayout onto an X drawable. - */ -void -pango_x_render_layout (Display *display, - Drawable drawable, - GC gc, - PangoLayout *layout, - int x, - int y) -{ - PangoLayoutIter *iter; - - g_return_if_fail (display != NULL); - g_return_if_fail (PANGO_IS_LAYOUT (layout)); - - iter = pango_layout_get_iter (layout); - - do - { - PangoRectangle logical_rect; - PangoLayoutLine *line; - int baseline; - - line = pango_layout_iter_get_line_readonly (iter); - - pango_layout_iter_get_line_extents (iter, NULL, &logical_rect); - baseline = pango_layout_iter_get_baseline (iter); - - pango_x_render_layout_line (display, drawable, gc, - line, - x + PANGO_PIXELS (logical_rect.x), - y + PANGO_PIXELS (baseline)); - } - while (pango_layout_iter_next_line (iter)); - - pango_layout_iter_free (iter); -} - -/* This utility function is duplicated here and in pango-layout.c; should it be - * public? Trouble is - what is the appropriate set of properties? - */ -static void -pango_x_get_item_properties (PangoItem *item, - PangoUnderline *uline, - PangoAttrColor *fg_color, - gboolean *fg_set, - PangoAttrColor *bg_color, - gboolean *bg_set) -{ - GSList *tmp_list = item->analysis.extra_attrs; - - if (fg_set) - *fg_set = FALSE; - - if (bg_set) - *bg_set = FALSE; - - while (tmp_list) - { - PangoAttribute *attr = tmp_list->data; - - switch ((int) attr->klass->type) - { - case PANGO_ATTR_UNDERLINE: - if (uline) - *uline = ((PangoAttrInt *)attr)->value; - break; - - case PANGO_ATTR_FOREGROUND: - if (fg_color) - *fg_color = *((PangoAttrColor *)attr); - if (fg_set) - *fg_set = TRUE; - - break; - - case PANGO_ATTR_BACKGROUND: - if (bg_color) - *bg_color = *((PangoAttrColor *)attr); - if (bg_set) - *bg_set = TRUE; - - break; - - default: - break; - } - tmp_list = tmp_list->next; - } -} - -/** - * pango_x_apply_ligatures: - * @font: unused - * @subfont: unused - * @glyphs: unused - * @n_glyphs: unused - * @clusters: unused - * - * Previously did subfont-specific ligation. Now a no-op. - * - * Return value: %FALSE, always. - */ -gboolean -pango_x_apply_ligatures (PangoFont *font G_GNUC_UNUSED, - PangoXSubfont subfont_id G_GNUC_UNUSED, - gunichar **glyphs G_GNUC_UNUSED, - int *n_glyphs G_GNUC_UNUSED, - int **clusters G_GNUC_UNUSED) -{ - return FALSE; -} - -/** - * pango_x_find_first_subfont: - * @font: A #PangoFont. - * @rfont: A pointer to a #PangoXSubfont. - * @charsets: An array of charsets. - * @n_charsets: The number of charsets in @charsets. - * - * Looks for subfonts with the @charset charset, - * in @font, and puts the first one in *@rfont. - * - * Return value: %TRUE if *@rfont now contains a font. - */ -gboolean -pango_x_find_first_subfont (PangoFont *font, - char **charsets, - int n_charsets, - PangoXSubfont *rfont) -{ - int n_subfonts; - gboolean result = FALSE; - PangoXSubfont *subfonts; - int *subfont_charsets; - - g_return_val_if_fail (font, 0); - g_return_val_if_fail (charsets, 0); - g_return_val_if_fail (rfont, 0); - - n_subfonts = pango_x_list_subfonts (font, charsets, n_charsets, - &subfonts, &subfont_charsets); - - if (n_subfonts > 0) - { - *rfont = subfonts[0]; - result = TRUE; - } - - g_free (subfonts); - g_free (subfont_charsets); - return result; -} - -/** - * pango_x_fallback_shape: - * @font: A #PangoFont. - * @glyphs: A pointer to a #PangoGlyphString. - * @text: UTF-8 string. - * @n_chars: Number of UTF-8 seqs in @text. - * - * This is a simple fallback shaper, that can be used - * if no subfont that supports a given script is found. - * For every character in @text, it puts the unknown glyph. - */ -void -pango_x_fallback_shape (PangoFont *font, - PangoGlyphString *glyphs, - const char *text, - int n_chars) -{ - PangoGlyph unknown_glyph = pango_x_get_unknown_glyph (font); - PangoRectangle logical_rect; - const char *p; - int i; - - g_return_if_fail (font); - g_return_if_fail (glyphs); - g_return_if_fail (text); - g_return_if_fail (n_chars >= 0); - - pango_font_get_glyph_extents (font, unknown_glyph, NULL, &logical_rect); - pango_glyph_string_set_size (glyphs, n_chars); - p = text; - for (i = 0; i < n_chars; i++) - { - glyphs->glyphs[i].glyph = unknown_glyph; - - glyphs->glyphs[i].geometry.x_offset = 0; - glyphs->glyphs[i].geometry.y_offset = 0; - glyphs->glyphs[i].geometry.width = logical_rect.width; - - glyphs->log_clusters[i] = p - text; - - p = g_utf8_next_char (p); - } -} - -/** - * pango_x_font_get_unknown_glyph: - * @font: a #PangoFont. - * @wc: the Unicode character for which a glyph is needed. - * - * Returns the index of a glyph suitable for drawing @wc as an - * unknown character. - * - * Use PANGO_GET_UNKNOWN_GLYPH() instead. - * - * Return value: a glyph index into @font. - */ -PangoGlyph -pango_x_font_get_unknown_glyph (PangoFont *font G_GNUC_UNUSED, - gunichar wc) -{ - return PANGO_GET_UNKNOWN_GLYPH (wc); -} |