diff options
-rw-r--r-- | ChangeLog | 16 | ||||
-rw-r--r-- | ChangeLog.pre-1-10 | 16 | ||||
-rw-r--r-- | ChangeLog.pre-1-6 | 16 | ||||
-rw-r--r-- | ChangeLog.pre-1-8 | 16 | ||||
-rw-r--r-- | pango/pangofc-font.c | 151 | ||||
-rw-r--r-- | pango/pangofc-font.h | 3 | ||||
-rw-r--r-- | pango/pangofc-private.h | 6 | ||||
-rw-r--r-- | pango/pangoft2.c | 60 | ||||
-rw-r--r-- | pango/pangoxft-font.c | 157 | ||||
-rw-r--r-- | pango/pangoxft-private.h | 7 |
10 files changed, 345 insertions, 103 deletions
@@ -1,3 +1,19 @@ +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. + Fri Jul 9 15:23:39 2004 Manish Singh <yosh@gimp.org> * pango/pango-ot.h: Add declaration for pango_ot_buffer_set_rtl. diff --git a/ChangeLog.pre-1-10 b/ChangeLog.pre-1-10 index ba450d40..bf60861c 100644 --- a/ChangeLog.pre-1-10 +++ b/ChangeLog.pre-1-10 @@ -1,3 +1,19 @@ +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. + Fri Jul 9 15:23:39 2004 Manish Singh <yosh@gimp.org> * pango/pango-ot.h: Add declaration for pango_ot_buffer_set_rtl. diff --git a/ChangeLog.pre-1-6 b/ChangeLog.pre-1-6 index ba450d40..bf60861c 100644 --- a/ChangeLog.pre-1-6 +++ b/ChangeLog.pre-1-6 @@ -1,3 +1,19 @@ +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. + Fri Jul 9 15:23:39 2004 Manish Singh <yosh@gimp.org> * pango/pango-ot.h: Add declaration for pango_ot_buffer_set_rtl. diff --git a/ChangeLog.pre-1-8 b/ChangeLog.pre-1-8 index ba450d40..bf60861c 100644 --- a/ChangeLog.pre-1-8 +++ b/ChangeLog.pre-1-8 @@ -1,3 +1,19 @@ +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. + Fri Jul 9 15:23:39 2004 Manish Singh <yosh@gimp.org> * pango/pango-ot.h: Add declaration for pango_ot_buffer_set_rtl. diff --git a/pango/pangofc-font.c b/pango/pangofc-font.c index 0f9cdbc6..f1f72420 100644 --- a/pango/pangofc-font.c +++ b/pango/pangofc-font.c @@ -155,6 +155,40 @@ pango_fc_font_finalize (GObject *object) parent_class->finalize (object); } +static gboolean +pattern_is_hinted (FcPattern *pattern) +{ + FcBool hinting; + + if (FcPatternGetBool (pattern, + FC_HINTING, 0, &hinting) != FcResultMatch) + hinting = FcTrue; + + return hinting; +} + +static gboolean +pattern_is_transformed (FcPattern *pattern) +{ + FcMatrix *fc_matrix; + + if (FcPatternGetMatrix (pattern, FC_MATRIX, 0, &fc_matrix) == FcResultMatch) + { + FT_Matrix ft_matrix; + + ft_matrix.xx = 0x10000L * fc_matrix->xx; + ft_matrix.yy = 0x10000L * fc_matrix->yy; + ft_matrix.xy = 0x10000L * fc_matrix->xy; + ft_matrix.yx = 0x10000L * fc_matrix->yx; + + return ((ft_matrix.xy | ft_matrix.yx) != 0 || + ft_matrix.xx != 0x10000L || + ft_matrix.yy != 0x10000L); + } + else + return FALSE; +} + static void pango_fc_font_set_property (GObject *object, guint prop_id, @@ -174,6 +208,8 @@ pango_fc_font_set_property (GObject *object, FcPatternReference (pattern); fcfont->font_pattern = pattern; fcfont->description = pango_fc_font_description_from_pattern (pattern, TRUE); + fcfont->hinted = pattern_is_hinted (pattern); + fcfont->transform = pattern_is_transformed (pattern); } break; default: @@ -267,17 +303,12 @@ static void get_face_metrics (PangoFcFont *fcfont, PangoFontMetrics *metrics) { - FcBool hinting; FT_Face face = pango_fc_font_lock_face (fcfont); FcMatrix *fc_matrix; FT_Matrix ft_matrix; TT_OS2 *os2; gboolean have_transform = FALSE; - if (FcPatternGetBool (fcfont->font_pattern, - FC_HINTING, 0, &hinting) != FcResultMatch) - hinting = FcTrue; - if (FcPatternGetMatrix (fcfont->font_pattern, FC_MATRIX, 0, &fc_matrix) == FcResultMatch) { @@ -304,7 +335,7 @@ get_face_metrics (PangoFcFont *fcfont, FT_Vector_Transform (&vector, &ft_matrix); metrics->ascent = PANGO_UNITS_26_6 (vector.y); } - else if (hinting) + else if (fcfont->hinted) { metrics->descent = - PANGO_UNITS_26_6 (face->size->metrics.descender); metrics->ascent = PANGO_UNITS_26_6 (face->size->metrics.ascender); @@ -359,7 +390,7 @@ get_face_metrics (PangoFcFont *fcfont, /* If hinting is on for this font, quantize the underline and strikethrough position * to integer values. */ - if (hinting) + if (fcfont->hinted) { quantize_position (&metrics->underline_thickness, &metrics->underline_position); quantize_position (&metrics->strikethrough_thickness, &metrics->strikethrough_position); @@ -669,3 +700,109 @@ _pango_fc_font_set_decoder (PangoFcFont *font, if (priv->decoder) g_object_ref (priv->decoder); } + +static FT_Glyph_Metrics * +get_per_char (FT_Face face, + FT_Int32 load_flags, + PangoGlyph glyph) +{ + FT_Error error; + FT_Glyph_Metrics *result; + + error = FT_Load_Glyph (face, glyph, load_flags); + if (error == FT_Err_Ok) + result = &face->glyph->metrics; + else + result = NULL; + + return result; +} + +/** + * _pango_fc_font_get_raw_extents: + * @fcfont: a #PangoFcFont + * @load_flags: flags to pass to FT_Load_Glyph() + * @glyph: the glyph index to load + * @ink_rect: location to store ink extents of the glyph, or %NULL + * @logical_rect: location to store logical extents of the glyph or %NULL + * + * Gets the extents of a single glyph from a font. The extents are in + * user space; that is, they are not transformed by any matrix in effect + * for the font. + * + * Long term, this functionality probably belongs in the default + * implementation of the get_glyph_extents() virtual function. + * The other possibility would be to to make it public in something + * like it's current form, and also expose glyph information + * caching functionality similar to pango_ft2_font_set_glyph_info(). + **/ +void +_pango_fc_font_get_raw_extents (PangoFcFont *fcfont, + FT_Int32 load_flags, + PangoGlyph glyph, + PangoRectangle *ink_rect, + PangoRectangle *logical_rect) +{ + FT_Glyph_Metrics *gm; + FT_Face face; + + face = pango_fc_font_lock_face (fcfont); + + if (!glyph) + gm = NULL; + else + gm = get_per_char (face, load_flags, glyph); + + if (gm) + { + if (ink_rect) + { + ink_rect->x = PANGO_UNITS_26_6 (gm->horiBearingX); + ink_rect->width = PANGO_UNITS_26_6 (gm->width); + ink_rect->y = -PANGO_UNITS_26_6 (gm->horiBearingY); + ink_rect->height = PANGO_UNITS_26_6 (gm->height); + } + + if (logical_rect) + { + logical_rect->x = 0; + logical_rect->width = PANGO_UNITS_26_6 (gm->horiAdvance); + if (fcfont->hinted) + { + logical_rect->y = - PANGO_UNITS_26_6 (face->size->metrics.ascender); + logical_rect->height = PANGO_UNITS_26_6 (face->size->metrics.ascender - face->size->metrics.descender); + } + else + { + FT_Fixed ascender, descender; + + ascender = FT_MulFix (face->ascender, face->size->metrics.y_scale); + descender = FT_MulFix (face->descender, face->size->metrics.y_scale); + + logical_rect->y = - PANGO_UNITS_26_6 (ascender); + logical_rect->height = PANGO_UNITS_26_6 (ascender - descender); + } + } + } + else + { + if (ink_rect) + { + ink_rect->x = 0; + ink_rect->width = 0; + ink_rect->y = 0; + ink_rect->height = 0; + } + + if (logical_rect) + { + logical_rect->x = 0; + logical_rect->width = 0; + logical_rect->y = 0; + logical_rect->height = 0; + } + } + + pango_fc_font_unlock_face (fcfont); +} + diff --git a/pango/pangofc-font.h b/pango/pangofc-font.h index 927a4685..70e72432 100644 --- a/pango/pangofc-font.h +++ b/pango/pangofc-font.h @@ -74,6 +74,9 @@ struct _PangoFcFont PangoFontDescription *description; GSList *metrics_by_lang; + + guint hinted : 1; + guint transform : 1; }; /** diff --git a/pango/pangofc-private.h b/pango/pangofc-private.h index ea2c8744..a87b20a9 100644 --- a/pango/pangofc-private.h +++ b/pango/pangofc-private.h @@ -39,6 +39,12 @@ PangoFcDecoder *_pango_fc_font_get_decoder (PangoFcFont *font); void _pango_fc_font_set_decoder (PangoFcFont *font, PangoFcDecoder *decoder); +void _pango_fc_font_get_raw_extents (PangoFcFont *font, + FT_Int32 load_flags, + PangoGlyph glyph, + PangoRectangle *ink_rect, + PangoRectangle *logical_rect); + G_END_DECLS #endif /* __PANGOFC_PRIVATE_H__ */ diff --git a/pango/pangoft2.c b/pango/pangoft2.c index 3963299e..f787f00d 100644 --- a/pango/pangoft2.c +++ b/pango/pangoft2.c @@ -31,6 +31,7 @@ #include "pangoft2.h" #include "pangoft2-private.h" #include "pangofc-fontmap.h" +#include "pangofc-private.h" /* for compatibility with older freetype versions */ #ifndef FT_LOAD_TARGET_MONO @@ -558,72 +559,25 @@ pango_ft2_render (FT_Bitmap *bitmap, pango_ft2_render_transformed (bitmap, NULL, font, glyphs, x * PANGO_SCALE, y * PANGO_SCALE); } -static FT_Glyph_Metrics * -pango_ft2_get_per_char (PangoFont *font, - guint32 glyph_index) -{ - PangoFT2Font *ft2font = (PangoFT2Font *)font; - FT_Face face; - - face = pango_ft2_font_get_face (font); - - FT_Load_Glyph (face, glyph_index, ft2font->load_flags); - return &face->glyph->metrics; -} - static PangoFT2GlyphInfo * pango_ft2_font_get_glyph_info (PangoFont *font, PangoGlyph glyph, gboolean create) { PangoFT2Font *ft2font = (PangoFT2Font *)font; + PangoFcFont *fcfont = (PangoFcFont *)font; PangoFT2GlyphInfo *info; - FT_Glyph_Metrics *gm; info = g_hash_table_lookup (ft2font->glyph_info, GUINT_TO_POINTER (glyph)); if ((info == NULL) && create) { - FT_Face face = pango_ft2_font_get_face (font); - info = g_new0 (PangoFT2GlyphInfo, 1); - - if (glyph && (gm = pango_ft2_get_per_char (font, glyph))) - { - info->ink_rect.x = PANGO_UNITS_26_6 (gm->horiBearingX); - info->ink_rect.width = PANGO_UNITS_26_6 (gm->width); - info->ink_rect.y = -PANGO_UNITS_26_6 (gm->horiBearingY); - info->ink_rect.height = PANGO_UNITS_26_6 (gm->height); - - info->logical_rect.x = 0; - info->logical_rect.width = PANGO_UNITS_26_6 (gm->horiAdvance); - if (ft2font->load_flags & FT_LOAD_NO_HINTING) - { - FT_Fixed ascender, descender; - - ascender = FT_MulFix (face->ascender, face->size->metrics.y_scale); - descender = FT_MulFix (face->descender, face->size->metrics.y_scale); + info = g_new0 (PangoFT2GlyphInfo, 1); - info->logical_rect.y = - PANGO_UNITS_26_6 (ascender); - info->logical_rect.height = PANGO_UNITS_26_6 (ascender - descender); - } - else - { - info->logical_rect.y = - PANGO_UNITS_26_6 (face->size->metrics.ascender); - info->logical_rect.height = PANGO_UNITS_26_6 (face->size->metrics.ascender - face->size->metrics.descender); - } - } - else - { - info->ink_rect.x = 0; - info->ink_rect.width = 0; - info->ink_rect.y = 0; - info->ink_rect.height = 0; - - info->logical_rect.x = 0; - info->logical_rect.width = 0; - info->logical_rect.y = 0; - info->logical_rect.height = 0; - } + _pango_fc_font_get_raw_extents (fcfont, ft2font->load_flags, + glyph, + &info->ink_rect, + &info->logical_rect); g_hash_table_insert (ft2font->glyph_info, GUINT_TO_POINTER(glyph), info); } 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 { diff --git a/pango/pangoxft-private.h b/pango/pangoxft-private.h index 0ffdf6e5..cfd0b3fb 100644 --- a/pango/pangoxft-private.h +++ b/pango/pangoxft-private.h @@ -39,7 +39,12 @@ struct _PangoXftFont guint16 mini_width; /* metrics for missing glyph drawing */ guint16 mini_height; - guint16 mini_pad; + guint16 mini_pad; + + GHashTable *glyph_info; /* Used only when we can't get + * glyph extents out of Xft because + * we have a transformation in effect + */ }; PangoXftFont *_pango_xft_font_new (PangoXftFontMap *xftfontmap, |