summaryrefslogtreecommitdiff
path: root/pango/pangoxft-font.c
diff options
context:
space:
mode:
authorOwen Taylor <otaylor@redhat.com>2000-12-15 01:10:13 +0000
committerOwen Taylor <otaylor@src.gnome.org>2000-12-15 01:10:13 +0000
commitf2bb9b92d5cebe5594e73e2eeea8a1a606da9005 (patch)
tree0eb5ddbd7f3c77b799603fcc21e444f6d9941d6c /pango/pangoxft-font.c
parent016c4d7047fd3ac2f76667f4ffe3b3a22ad0b902 (diff)
downloadpango-f2bb9b92d5cebe5594e73e2eeea8a1a606da9005.tar.gz
Fix macro breakage.
Thu Dec 14 19:00:46 2000 Owen Taylor <otaylor@redhat.com> * modules/indic/pango-indic-script.h: Fix macro breakage. * modules/basic/tables-big.i: Remove extra copy of basic_ranges. * modules/thai/thai.c: Fix various warnings. * configure.in Makefile.am pangoxft.pc.in pango-config.in modules/basic/Makefile.am modules/basic/basic-xft.c pango/Makefile.am pango/pangoxft-font.[ch] pango/pangoxft-fontmap.c pango/pangoxft.h pango/pangoxft-private.h: Initial support for rendering via Xft and the Xrender extension.
Diffstat (limited to 'pango/pangoxft-font.c')
-rw-r--r--pango/pangoxft-font.c474
1 files changed, 474 insertions, 0 deletions
diff --git a/pango/pangoxft-font.c b/pango/pangoxft-font.c
new file mode 100644
index 00000000..66a3d356
--- /dev/null
+++ b/pango/pangoxft-font.c
@@ -0,0 +1,474 @@
+/* Pango
+ * pangoxft-font.c: Routines for handling X fonts
+ *
+ * Copyright (C) 2000 Red Hat Software
+ *
+ * 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 "pangoxft-private.h"
+#include "X11/Xft/XftFreetype.h"
+#include "modules.h"
+
+#define PANGO_TYPE_XFT_FONT (pango_xft_font_get_type ())
+#define PANGO_XFT_FONT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_XFT_FONT, PangoXftFont))
+#define PANGO_XFT_FONT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PANGO_TYPE_XFT_FONT, PangoXftFontClass))
+#define PANGO_XFT_IS_FONT(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_TYPE_XFT_FONT))
+#define PANGO_XFT_IS_FONT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PANGO_TYPE_XFT_FONT))
+#define PANGO_XFT_FONT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PANGO_TYPE_XFT_FONT, PangoXftFontClass))
+
+#define PANGO_XFT_UNKNOWN_FLAG 0x10000000
+
+typedef struct _PangoXftFontClass PangoXftFontClass;
+
+struct _PangoXftFontClass
+{
+ PangoFontClass parent_class;
+};
+
+static PangoFontClass *parent_class; /* Parent class structure for PangoXftFont */
+
+static void pango_xft_font_class_init (PangoXftFontClass *class);
+static void pango_xft_font_init (PangoXftFont *xfont);
+static void pango_xft_font_shutdown (GObject *object);
+static void pango_xft_font_finalize (GObject *object);
+
+static PangoFontDescription *pango_xft_font_describe (PangoFont *font);
+static PangoCoverage * pango_xft_font_get_coverage (PangoFont *font,
+ const char *lang);
+static PangoEngineShape * pango_xft_font_find_shaper (PangoFont *font,
+ const char *lang,
+ guint32 ch);
+static void pango_xft_font_get_glyph_extents (PangoFont *font,
+ PangoGlyph glyph,
+ PangoRectangle *ink_rect,
+ PangoRectangle *logical_rect);
+static void pango_xft_font_get_metrics (PangoFont *font,
+ const gchar *lang,
+ PangoFontMetrics *metrics);
+
+
+static GType
+pango_xft_font_get_type (void)
+{
+ static GType object_type = 0;
+
+ if (!object_type)
+ {
+ static const GTypeInfo object_info =
+ {
+ sizeof (PangoXftFontClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) pango_xft_font_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (PangoXftFont),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) pango_xft_font_init,
+ };
+
+ object_type = g_type_register_static (PANGO_TYPE_FONT,
+ "PangoXftFont",
+ &object_info, 0);
+ }
+
+ return object_type;
+}
+
+static void
+pango_xft_font_init (PangoXftFont *xfont)
+{
+ xfont->in_cache = FALSE;
+}
+
+static void
+pango_xft_font_class_init (PangoXftFontClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+ PangoFontClass *font_class = PANGO_FONT_CLASS (class);
+
+ parent_class = g_type_class_peek_parent (class);
+
+ object_class->finalize = pango_xft_font_finalize;
+ object_class->shutdown = pango_xft_font_shutdown;
+
+ font_class->describe = pango_xft_font_describe;
+ font_class->get_coverage = pango_xft_font_get_coverage;
+ font_class->find_shaper = pango_xft_font_find_shaper;
+ font_class->get_glyph_extents = pango_xft_font_get_glyph_extents;
+ font_class->get_metrics = pango_xft_font_get_metrics;
+}
+
+PangoXftFont *
+_pango_xft_font_new (PangoFontMap *fontmap,
+ const PangoFontDescription *description,
+ XftFont *xft_font)
+{
+ PangoXftFont *xfont;
+
+ g_return_val_if_fail (fontmap != NULL, NULL);
+ g_return_val_if_fail (description != NULL, NULL);
+ g_return_val_if_fail (xft_font != NULL, NULL);
+
+ xfont = (PangoXftFont *)g_object_new (PANGO_TYPE_XFT_FONT, NULL);
+
+ xfont->fontmap = fontmap;
+
+ g_object_ref (G_OBJECT (fontmap));
+ xfont->description = pango_font_description_copy (description);
+ xfont->xft_font = xft_font;
+
+ _pango_xft_font_map_add (xfont->fontmap, xfont);
+
+ return xfont;
+}
+
+static PangoFont *
+get_mini_font (PangoFont *font)
+{
+ PangoXftFont *xfont = (PangoXftFont *)font;
+
+ if (!xfont->mini_font)
+ {
+ Display *display;
+ PangoFontDescription desc;
+ int i;
+ int width = 0, height = 0;
+ XGlyphInfo extents;
+ XftFont *mini_xft;
+
+ _pango_xft_font_map_get_info (xfont->fontmap, &display, NULL);
+
+ desc.family_name = "monospace";
+ desc.style = PANGO_STYLE_NORMAL;
+ desc.variant = PANGO_VARIANT_NORMAL;
+ desc.weight = PANGO_WEIGHT_NORMAL;
+
+ desc.size = 0.5 * xfont->description->size;
+
+ xfont->mini_font = pango_font_map_load_font (xfont->fontmap, &desc);
+ mini_xft = ((PangoXftFont *)xfont->mini_font)->xft_font;
+
+ for (i = 0 ; i < 16 ; i++)
+ {
+ char c = i < 10 ? '0' + i : 'A' + i - 10;
+
+ XftTextExtents8 (display, mini_xft, &c, 1, &extents);
+
+ width = MAX (width, extents.width);
+ height = MAX (height, extents.height);
+ }
+
+ xfont->mini_width = width;
+ xfont->mini_height = height;
+ xfont->mini_pad = MAX (height / 10, 1);
+ }
+
+ return xfont->mini_font;
+}
+
+static void
+draw_box (XftDraw *draw,
+ XftColor *color,
+ PangoXftFont *xfont,
+ gint x,
+ gint y,
+ gint width,
+ gint height)
+{
+ XftDrawRect (draw, color,
+ x, y, width, xfont->mini_pad);
+ XftDrawRect (draw, color,
+ x, y + xfont->mini_pad, xfont->mini_pad, height - xfont->mini_pad * 2);
+ XftDrawRect (draw, color,
+ x + width - xfont->mini_pad, y + xfont->mini_pad, xfont->mini_pad, height - xfont->mini_pad * 2);
+ XftDrawRect (draw, color,
+ x, y + height - xfont->mini_pad, width, xfont->mini_pad);
+}
+
+void
+pango_xft_render (XftDraw *draw,
+ XftColor *color,
+ PangoFont *font,
+ PangoGlyphString *glyphs,
+ gint x,
+ gint y)
+{
+ PangoXftFont *xfont = PANGO_XFT_FONT (font);
+ Display *display;
+ int i;
+ int x_off = 0;
+
+ g_return_if_fail (draw != NULL);
+ g_return_if_fail (color != NULL);
+ g_return_if_fail (font != NULL);
+ g_return_if_fail (glyphs != NULL);
+
+ /* Slow initial implementation. For speed, it should really
+ * collect the characters into runs, and draw multiple
+ * characters with each XftDrawString32 call.
+ */
+
+ _pango_xft_font_map_get_info (xfont->fontmap, &display, NULL);
+
+ for (i=0; i<glyphs->num_glyphs; i++)
+ {
+ PangoGlyph glyph = glyphs->glyphs[i].glyph;
+
+ if (glyph)
+ {
+ if (glyph & PANGO_XFT_UNKNOWN_FLAG)
+ {
+ char buf[5];
+ int ys[3];
+ int xs[3];
+ int j, k;
+
+ PangoFont *mini_font = get_mini_font (font);
+ XftFont *mini_xft = ((PangoXftFont *)mini_font)->xft_font;
+
+ glyph &= ~PANGO_XFT_UNKNOWN_FLAG;
+
+ ys[0] = y + PANGO_PIXELS (glyphs->glyphs[i].geometry.y_offset) - xfont->xft_font->ascent + (xfont->xft_font->ascent + xfont->xft_font->descent - xfont->mini_height * 2 - xfont->mini_pad * 5) / 2;
+ ys[1] = ys[0] + 2 * xfont->mini_pad + xfont->mini_height;
+ ys[2] = ys[1] + xfont->mini_height + xfont->mini_pad;
+
+ xs[0] = x + PANGO_PIXELS (x_off + glyphs->glyphs[i].geometry.x_offset);
+ xs[1] = xs[0] + 2 * xfont->mini_pad;
+ xs[2] = xs[1] + xfont->mini_width + xfont->mini_pad;
+
+ draw_box (draw, color, xfont,
+ xs[0], ys[0],
+ xfont->mini_width * 2 + xfont->mini_pad * 5,
+ xfont->mini_height * 2 + xfont->mini_pad * 5);
+
+ g_snprintf (buf, sizeof(buf), "%04X", glyph);
+
+ for (j = 0; j < 2; j++)
+ for (k = 0; k < 2; k++)
+ XftDrawString8 (draw, color, mini_xft,
+ xs[k+1], ys[j+1],
+ &buf[2*j + k], 1);
+ }
+ else
+ XftDrawString32 (draw, color, xfont->xft_font,
+ x + PANGO_PIXELS (x_off + glyphs->glyphs[i].geometry.x_offset),
+ y + PANGO_PIXELS (glyphs->glyphs[i].geometry.y_offset),
+ &glyph, 1);
+ }
+
+ x_off += glyphs->glyphs[i].geometry.width;
+ }
+}
+
+static void
+pango_xft_font_get_metrics (PangoFont *font,
+ const gchar *lang,
+ PangoFontMetrics *metrics)
+{
+ PangoXftFont *xfont = (PangoXftFont *)font;
+
+ metrics->ascent = PANGO_SCALE * xfont->xft_font->ascent;
+ metrics->descent = PANGO_SCALE * xfont->xft_font->descent;
+
+ return;
+}
+
+static void
+pango_xft_font_shutdown (GObject *object)
+{
+ PangoXftFont *xfont = PANGO_XFT_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_xft_font_map_cache_add (xfont->fontmap, xfont);
+
+ G_OBJECT_CLASS (parent_class)->shutdown (object);
+}
+
+static void
+pango_xft_font_finalize (GObject *object)
+{
+ PangoXftFont *xfont = (PangoXftFont *)object;
+
+ _pango_xft_font_map_remove (xfont->fontmap, xfont);
+
+ if (xfont->mini_font)
+ g_object_unref (xfont->mini_font);
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static PangoFontDescription *
+pango_xft_font_describe (PangoFont *font)
+{
+ PangoXftFont *xfont = (PangoXftFont *)font;
+
+ return pango_font_description_copy (xfont->description);
+}
+
+static PangoCoverage *
+pango_xft_font_get_coverage (PangoFont *font,
+ const char *lang)
+{
+ PangoXftFont *xfont = (PangoXftFont *)font;
+ PangoCoverage *coverage;
+ Display *display;
+ int i;
+
+ _pango_xft_font_map_get_info (xfont->fontmap, &display, NULL);
+
+ coverage = _pango_xft_font_map_get_coverage (xfont->fontmap,
+ xfont->description->family_name);
+
+ if (coverage)
+ return pango_coverage_ref (coverage);
+
+ /* Ugh, this is going to be SLOW */
+
+ coverage = pango_coverage_new ();
+ for (i = 0; i < G_MAXUSHORT; i++)
+ {
+ if (XftGlyphExists (display, xfont->xft_font, i))
+ pango_coverage_set (coverage, i, PANGO_COVERAGE_EXACT);
+ }
+
+ _pango_xft_font_map_set_coverage (xfont->fontmap, xfont->description->family_name, coverage);
+
+ return coverage;
+}
+
+static void
+pango_xft_font_get_glyph_extents (PangoFont *font,
+ PangoGlyph glyph,
+ PangoRectangle *ink_rect,
+ PangoRectangle *logical_rect)
+{
+ PangoXftFont *xfont = (PangoXftFont *)font;
+ XGlyphInfo extents;
+ Display *display;
+
+ _pango_xft_font_map_get_info (xfont->fontmap, &display, NULL);
+
+ if (glyph == (PangoGlyph)-1)
+ glyph = 0;
+
+ if (glyph & PANGO_XFT_UNKNOWN_FLAG)
+ {
+ get_mini_font (font);
+
+ if (ink_rect)
+ {
+ ink_rect->x = 0;
+ ink_rect->y = PANGO_SCALE * (- xfont->xft_font->ascent + (xfont->xft_font->ascent + xfont->xft_font->descent - xfont->mini_height * 2 - xfont->mini_pad * 5) / 2);
+ ink_rect->width = PANGO_SCALE * (xfont->mini_width * 2 + xfont->mini_pad * 5);
+ ink_rect->height = PANGO_SCALE * (xfont->mini_height * 2 + xfont->mini_pad * 5);
+ }
+
+ if (logical_rect)
+ {
+ logical_rect->x = 0;
+ logical_rect->y = - PANGO_SCALE * xfont->xft_font->ascent;
+ logical_rect->width = PANGO_SCALE * (xfont->mini_width * 2 + xfont->mini_pad * 6);
+ logical_rect->height = (xfont->xft_font->ascent + xfont->xft_font->descent) * PANGO_SCALE;
+ }
+ }
+ else
+ {
+ XftTextExtents32 (display, xfont->xft_font, &glyph, 1, &extents);
+
+ if (ink_rect)
+ {
+ ink_rect->x = extents.x * PANGO_SCALE;
+ ink_rect->y = extents.y * PANGO_SCALE;
+ ink_rect->width = extents.width * PANGO_SCALE;
+ ink_rect->height = extents.height * PANGO_SCALE;
+ }
+
+ if (logical_rect)
+ {
+ logical_rect->x = 0;
+ logical_rect->y = - xfont->xft_font->ascent * PANGO_SCALE;
+ logical_rect->width = extents.xOff * PANGO_SCALE;
+ logical_rect->height = (xfont->xft_font->ascent + xfont->xft_font->descent) * PANGO_SCALE;
+ }
+ }
+}
+
+static PangoMap *
+pango_xft_get_shaper_map (const char *lang)
+{
+ 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_XFT);
+ }
+
+ return pango_find_map (lang, engine_type_id, render_type_id);
+}
+
+static PangoEngineShape *
+pango_xft_font_find_shaper (PangoFont *font,
+ const gchar *lang,
+ guint32 ch)
+{
+ PangoMap *shape_map = NULL;
+
+ shape_map = pango_xft_get_shaper_map (lang);
+ return (PangoEngineShape *)pango_map_get_engine (shape_map, ch);
+}
+
+XftFont *
+pango_xft_font_get_font (PangoFont *font)
+{
+ PangoXftFont *xfont;
+
+ g_return_val_if_fail (PANGO_XFT_IS_FONT (font), NULL);
+
+ xfont = PANGO_XFT_FONT (font);
+
+ return xfont->xft_font;
+}
+
+Display *
+pango_xft_font_get_display (PangoFont *font)
+{
+ PangoXftFont *xfont;
+ Display *display;
+
+ g_return_val_if_fail (PANGO_XFT_IS_FONT (font), NULL);
+
+ xfont = PANGO_XFT_FONT (font);
+ _pango_xft_font_map_get_info (xfont->fontmap, &display, NULL);
+
+ return display;
+}
+
+PangoGlyph
+pango_xft_font_get_unknown_glyph (PangoFont *font,
+ gunichar wc)
+{
+ g_return_val_if_fail (PANGO_XFT_IS_FONT (font), -1);
+
+ return wc | PANGO_XFT_UNKNOWN_FLAG;
+}