summaryrefslogtreecommitdiff
path: root/pango/pangoxft-font.c
diff options
context:
space:
mode:
authorOwen Taylor <otaylor@redhat.com>2004-07-10 20:50:53 +0000
committerOwen Taylor <otaylor@src.gnome.org>2004-07-10 20:50:53 +0000
commit5bf0c1d04b6ed75ad2c88fbed1e1eaecf0dcbfa2 (patch)
tree82f722e254dbc6b5cb1446b87103e27c8b0aecf8 /pango/pangoxft-font.c
parent19dea7b162bb2d12911d38770d8cc87accc40fe7 (diff)
downloadpango-5bf0c1d04b6ed75ad2c88fbed1e1eaecf0dcbfa2.tar.gz
Add hinted/transform flags to the font structure to allow efficient
Sat Jul 10 16:39:44 2004 Owen Taylor <otaylor@redhat.com> * pango/pangofc-font.[ch]: Add hinted/transform flags to the font structure to allow efficient conditionalization of behavior rather than repeatedly extracting the information from the FcPattern. * pango/pangofc-font.c pango/pangofc-private.h pango/pangoft2.c: Move the glyph metrics computation into a _pango_fc_font_get_raw_extents() function that can be shared with the Xft backend. * pango/pangoxft.c: When a transform is in effect, don't get glyph extents from Xft ... they are device space and not useful, use _pango_fc_font_get_raw_extents() instead.
Diffstat (limited to 'pango/pangoxft-font.c')
-rw-r--r--pango/pangoxft-font.c157
1 files changed, 115 insertions, 42 deletions
diff --git a/pango/pangoxft-font.c b/pango/pangoxft-font.c
index 1d0adfa5..8b7412ee 100644
--- a/pango/pangoxft-font.c
+++ b/pango/pangoxft-font.c
@@ -25,6 +25,7 @@
#include "pangofc-fontmap.h"
#include "pangoxft-private.h"
+#include "pangofc-private.h"
#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))
@@ -434,71 +435,143 @@ pango_xft_font_finalize (GObject *object)
XftFontClose (display, xfont->xft_font);
}
+ if (xfont->glyph_info)
+ g_hash_table_destroy (xfont->glyph_info);
+
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
+get_glyph_extents_missing (PangoXftFont *xfont,
+ PangoGlyph glyph,
+ PangoRectangle *ink_rect,
+ PangoRectangle *logical_rect)
+
+{
+ PangoFont *font = PANGO_FONT (xfont);
+ XftFont *xft_font = xft_font_get_font (font);
+
+ gint cols = (glyph & ~PANGO_XFT_UNKNOWN_FLAG) > 0xffff ? 3 : 2;
+
+ get_mini_font (font);
+
+ if (ink_rect)
+ {
+ ink_rect->x = 0;
+ ink_rect->y = - PANGO_SCALE * xft_font->ascent + (PANGO_SCALE * (xft_font->ascent) + xft_font->descent - xfont->mini_height * 2 - xfont->mini_pad * 5) / 2;
+ ink_rect->width = xfont->mini_width * cols + xfont->mini_pad * (2 * cols + 1);
+ ink_rect->height = xfont->mini_height * 2 + xfont->mini_pad * 5;
+ }
+
+ if (logical_rect)
+ {
+ logical_rect->x = 0;
+ logical_rect->y = - PANGO_SCALE * xft_font->ascent;
+ logical_rect->width = xfont->mini_width * cols + xfont->mini_pad * (2 * cols + 2);
+ logical_rect->height = (xft_font->ascent + xft_font->descent) * PANGO_SCALE;
+ }
+}
+
+static void
+get_glyph_extents_xft (PangoFcFont *fcfont,
+ PangoGlyph glyph,
+ PangoRectangle *ink_rect,
+ PangoRectangle *logical_rect)
+{
+ XftFont *xft_font = xft_font_get_font ((PangoFont *)fcfont);
+ XGlyphInfo extents;
+ Display *display;
+
+ _pango_xft_font_map_get_info (fcfont->fontmap, &display, NULL);
+
+ FT_UInt ft_glyph = glyph;
+ XftGlyphExtents (display, xft_font, &ft_glyph, 1, &extents);
+
+ if (ink_rect)
+ {
+ ink_rect->x = - extents.x * PANGO_SCALE; /* Xft crack-rock sign choice */
+ 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 = - xft_font->ascent * PANGO_SCALE;
+ logical_rect->width = extents.xOff * PANGO_SCALE;
+ logical_rect->height = (xft_font->ascent + xft_font->descent) * PANGO_SCALE;
+ }
+}
+
+typedef struct
+{
+ PangoRectangle ink_rect;
+ PangoRectangle logical_rect;
+} Extents;
+
+static void
+get_glyph_extents_raw (PangoXftFont *xfont,
+ PangoGlyph glyph,
+ PangoRectangle *ink_rect,
+ PangoRectangle *logical_rect)
+{
+ Extents *extents;
+
+ if (!xfont->glyph_info)
+ xfont->glyph_info = g_hash_table_new_full (NULL, NULL,
+ NULL, (GDestroyNotify)g_free);
+
+ extents = g_hash_table_lookup (xfont->glyph_info,
+ GUINT_TO_POINTER (glyph));
+
+ if (!extents)
+ {
+ extents = g_new (Extents, 1);
+
+ _pango_fc_font_get_raw_extents (PANGO_FC_FONT (xfont),
+ FT_LOAD_NO_BITMAP | FT_LOAD_NO_HINTING,
+ glyph,
+ &extents->ink_rect,
+ &extents->logical_rect);
+
+ g_hash_table_insert (xfont->glyph_info,
+ GUINT_TO_POINTER (glyph),
+ extents);
+ }
+
+ if (ink_rect)
+ *ink_rect = extents->ink_rect;
+
+ if (logical_rect)
+ *logical_rect = extents->logical_rect;
+}
+
+static void
pango_xft_font_get_glyph_extents (PangoFont *font,
PangoGlyph glyph,
PangoRectangle *ink_rect,
PangoRectangle *logical_rect)
{
PangoXftFont *xfont = (PangoXftFont *)font;
- XftFont *xft_font = xft_font_get_font (font);
PangoFcFont *fcfont = PANGO_FC_FONT (font);
- XGlyphInfo extents;
- Display *display;
if (!fcfont->fontmap) /* Display closed */
goto fallback;
- _pango_xft_font_map_get_info (fcfont->fontmap, &display, NULL);
-
if (glyph == (PangoGlyph)-1)
glyph = 0;
if (glyph & PANGO_XFT_UNKNOWN_FLAG)
{
- gint cols = (glyph & ~PANGO_XFT_UNKNOWN_FLAG) > 0xffff ? 3 : 2;
-
- get_mini_font (font);
-
- if (ink_rect)
- {
- ink_rect->x = 0;
- ink_rect->y = PANGO_SCALE * (- xft_font->ascent + (xft_font->ascent + xft_font->descent - xfont->mini_height * 2 - xfont->mini_pad * 5) / 2);
- ink_rect->width = PANGO_SCALE * (xfont->mini_width * cols + xfont->mini_pad * (2 * cols + 1));
- 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 * xft_font->ascent;
- logical_rect->width = PANGO_SCALE * (xfont->mini_width * cols + xfont->mini_pad * (2 * cols + 2));
- logical_rect->height = (xft_font->ascent + xft_font->descent) * PANGO_SCALE;
- }
+ get_glyph_extents_missing (xfont, glyph, ink_rect, logical_rect);
}
else if (glyph)
{
- FT_UInt ft_glyph = glyph;
- XftGlyphExtents (display, xft_font, &ft_glyph, 1, &extents);
-
- if (ink_rect)
- {
- ink_rect->x = - extents.x * PANGO_SCALE; /* Xft crack-rock sign choice */
- 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 = - xft_font->ascent * PANGO_SCALE;
- logical_rect->width = extents.xOff * PANGO_SCALE;
- logical_rect->height = (xft_font->ascent + xft_font->descent) * PANGO_SCALE;
- }
+ if (!fcfont->transform)
+ get_glyph_extents_xft (fcfont, glyph, ink_rect, logical_rect);
+ else
+ get_glyph_extents_raw (xfont, glyph, ink_rect, logical_rect);
}
else
{