diff options
author | Owen Taylor <otaylor@redhat.com> | 2004-07-10 20:50:53 +0000 |
---|---|---|
committer | Owen Taylor <otaylor@src.gnome.org> | 2004-07-10 20:50:53 +0000 |
commit | 5bf0c1d04b6ed75ad2c88fbed1e1eaecf0dcbfa2 (patch) | |
tree | 82f722e254dbc6b5cb1446b87103e27c8b0aecf8 /pango/pangofc-font.c | |
parent | 19dea7b162bb2d12911d38770d8cc87accc40fe7 (diff) | |
download | pango-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/pangofc-font.c')
-rw-r--r-- | pango/pangofc-font.c | 151 |
1 files changed, 144 insertions, 7 deletions
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); +} + |