summaryrefslogtreecommitdiff
path: root/pango/pangox.c
diff options
context:
space:
mode:
authorBehdad Esfahbod <behdad@behdad.org>2012-08-16 21:48:50 -0400
committerBehdad Esfahbod <behdad@behdad.org>2012-08-16 22:02:41 -0400
commit194b6ee552318ec6c494f34ed9f0979d0460fe4f (patch)
treeaf5b939f4750a4208b58c06b71fe09cdefa144f0 /pango/pangox.c
parent8168660e5f1906aed2a45d30529058f51473bcef (diff)
downloadpango-194b6ee552318ec6c494f34ed9f0979d0460fe4f.tar.gz
Remove PangoX
Been overdue...
Diffstat (limited to 'pango/pangox.c')
-rw-r--r--pango/pangox.c1790
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);
-}