ft: set font size to em size when retrieving unhinted metrics

fixes text-unhinted-metrics test
This commit is contained in:
Adrian Johnson 2016-06-18 13:16:57 +09:30
parent d92015e4f9
commit bb4595130b

View file

@ -2208,6 +2208,55 @@ _cairo_ft_scaled_glyph_vertical_layout_bearing_fix (void *abstract_font,
}
}
static cairo_int_status_t
_cairo_ft_scaled_glyph_load_glyph (cairo_ft_scaled_font_t *scaled_font,
cairo_scaled_glyph_t *scaled_glyph,
FT_Face face,
int load_flags,
cairo_bool_t use_em_size,
cairo_bool_t vertical_layout)
{
FT_Error error;
cairo_status_t status;
if (use_em_size) {
cairo_matrix_t em_size;
cairo_matrix_init_scale (&em_size, face->units_per_EM, face->units_per_EM);
status = _cairo_ft_unscaled_font_set_scale (scaled_font->unscaled, &em_size);
} else {
status = _cairo_ft_unscaled_font_set_scale (scaled_font->unscaled,
&scaled_font->base.scale);
}
if (unlikely (status))
return status;
error = FT_Load_Glyph (face,
_cairo_scaled_glyph_index(scaled_glyph),
load_flags);
/* XXX ignoring all other errors for now. They are not fatal, typically
* just a glyph-not-found. */
if (error == FT_Err_Out_Of_Memory)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
/*
* synthesize glyphs if requested
*/
#if HAVE_FT_GLYPHSLOT_EMBOLDEN
if (scaled_font->ft_options.synth_flags & CAIRO_FT_SYNTHESIZE_BOLD)
FT_GlyphSlot_Embolden (face->glyph);
#endif
#if HAVE_FT_GLYPHSLOT_OBLIQUE
if (scaled_font->ft_options.synth_flags & CAIRO_FT_SYNTHESIZE_OBLIQUE)
FT_GlyphSlot_Oblique (face->glyph);
#endif
if (vertical_layout)
_cairo_ft_scaled_glyph_vertical_layout_bearing_fix (scaled_font, face->glyph);
return CAIRO_STATUS_SUCCESS;
}
static cairo_int_status_t
_cairo_ft_scaled_glyph_init (void *abstract_font,
cairo_scaled_glyph_t *scaled_glyph,
@ -2218,22 +2267,17 @@ _cairo_ft_scaled_glyph_init (void *abstract_font,
cairo_ft_unscaled_font_t *unscaled = scaled_font->unscaled;
FT_GlyphSlot glyph;
FT_Face face;
FT_Error error;
int load_flags = scaled_font->ft_options.load_flags;
FT_Glyph_Metrics *metrics;
double x_factor, y_factor;
cairo_bool_t vertical_layout = FALSE;
cairo_status_t status;
cairo_status_t status = CAIRO_STATUS_SUCCESS;
cairo_bool_t scaled_glyph_loaded = FALSE;
face = _cairo_ft_unscaled_font_lock_face (unscaled);
if (!face)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
status = _cairo_ft_unscaled_font_set_scale (scaled_font->unscaled,
&scaled_font->base.scale);
if (unlikely (status))
goto FAIL;
/* Ignore global advance unconditionally */
load_flags |= FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH;
@ -2264,37 +2308,23 @@ _cairo_ft_scaled_glyph_init (void *abstract_font,
/* load_flags |= FT_LOAD_COLOR; */
#endif
error = FT_Load_Glyph (face,
_cairo_scaled_glyph_index(scaled_glyph),
load_flags);
/* XXX ignoring all other errors for now. They are not fatal, typically
* just a glyph-not-found. */
if (error == FT_Err_Out_Of_Memory) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto FAIL;
}
glyph = face->glyph;
/*
* synthesize glyphs if requested
*/
#if HAVE_FT_GLYPHSLOT_EMBOLDEN
if (scaled_font->ft_options.synth_flags & CAIRO_FT_SYNTHESIZE_BOLD)
FT_GlyphSlot_Embolden (glyph);
#endif
#if HAVE_FT_GLYPHSLOT_OBLIQUE
if (scaled_font->ft_options.synth_flags & CAIRO_FT_SYNTHESIZE_OBLIQUE)
FT_GlyphSlot_Oblique (glyph);
#endif
if (vertical_layout)
_cairo_ft_scaled_glyph_vertical_layout_bearing_fix (scaled_font, glyph);
if (info & CAIRO_SCALED_GLYPH_INFO_METRICS) {
cairo_bool_t hint_metrics = scaled_font->base.options.hint_metrics != CAIRO_HINT_METRICS_OFF;
status = _cairo_ft_scaled_glyph_load_glyph (scaled_font,
scaled_glyph,
face,
load_flags,
!hint_metrics,
vertical_layout);
if (unlikely (status))
goto FAIL;
glyph = face->glyph;
scaled_glyph_loaded = hint_metrics;
/*
* Compute font-space metrics
*/
@ -2392,6 +2422,20 @@ _cairo_ft_scaled_glyph_init (void *abstract_font,
if ((info & CAIRO_SCALED_GLYPH_INFO_SURFACE) != 0) {
cairo_image_surface_t *surface;
if (!scaled_glyph_loaded) {
status = _cairo_ft_scaled_glyph_load_glyph (scaled_font,
scaled_glyph,
face,
load_flags,
FALSE,
vertical_layout);
if (unlikely (status))
goto FAIL;
glyph = face->glyph;
scaled_glyph_loaded = TRUE;
}
if (glyph->format == FT_GLYPH_FORMAT_OUTLINE) {
status = _render_glyph_outline (face, &scaled_font->ft_options.base,
&surface);
@ -2423,27 +2467,23 @@ _cairo_ft_scaled_glyph_init (void *abstract_font,
* so reload it. This will probably never occur though
*/
if ((info & CAIRO_SCALED_GLYPH_INFO_SURFACE) != 0) {
error = FT_Load_Glyph (face,
_cairo_scaled_glyph_index(scaled_glyph),
load_flags | FT_LOAD_NO_BITMAP);
/* XXX ignoring all other errors for now. They are not fatal, typically
* just a glyph-not-found. */
if (error == FT_Err_Out_Of_Memory) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto FAIL;
}
#if HAVE_FT_GLYPHSLOT_EMBOLDEN
if (scaled_font->ft_options.synth_flags & CAIRO_FT_SYNTHESIZE_BOLD)
FT_GlyphSlot_Embolden (glyph);
#endif
#if HAVE_FT_GLYPHSLOT_OBLIQUE
if (scaled_font->ft_options.synth_flags & CAIRO_FT_SYNTHESIZE_OBLIQUE)
FT_GlyphSlot_Oblique (glyph);
#endif
if (vertical_layout)
_cairo_ft_scaled_glyph_vertical_layout_bearing_fix (scaled_font, glyph);
scaled_glyph_loaded = FALSE;
load_flags |= FT_LOAD_NO_BITMAP;
}
if (!scaled_glyph_loaded) {
status = _cairo_ft_scaled_glyph_load_glyph (scaled_font,
scaled_glyph,
face,
load_flags,
FALSE,
vertical_layout);
if (unlikely (status))
goto FAIL;
glyph = face->glyph;
}
if (glyph->format == FT_GLYPH_FORMAT_OUTLINE)
status = _decompose_glyph_outline (face, &scaled_font->ft_options.base,
&path);