mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-01-22 13:30:25 +01:00
freetype: Fix for test case ft-text-vertial-layout.
Fix scaled font metrics and glyph metrics calculation for vertical layout. Test case ft-text-vertial-layout passes now.
This commit is contained in:
parent
6b5be506ed
commit
5ae2a78a29
1 changed files with 94 additions and 30 deletions
|
|
@ -1461,19 +1461,28 @@ _cairo_ft_scaled_font_create (cairo_ft_unscaled_font_t *unscaled,
|
|||
fs_metrics.ascent = DOUBLE_FROM_26_6(metrics->ascender) * y_factor;
|
||||
fs_metrics.descent = DOUBLE_FROM_26_6(- metrics->descender) * y_factor;
|
||||
fs_metrics.height = DOUBLE_FROM_26_6(metrics->height) * y_factor;
|
||||
fs_metrics.max_x_advance = DOUBLE_FROM_26_6(metrics->max_advance) * x_factor;
|
||||
if (!(scaled_font->ft_options.load_flags & FT_LOAD_VERTICAL_LAYOUT)) {
|
||||
fs_metrics.max_x_advance = DOUBLE_FROM_26_6(metrics->max_advance) * x_factor;
|
||||
fs_metrics.max_y_advance = 0;
|
||||
} else {
|
||||
fs_metrics.max_x_advance = 0;
|
||||
fs_metrics.max_y_advance = DOUBLE_FROM_26_6(metrics->max_advance) * y_factor;
|
||||
}
|
||||
} else {
|
||||
double scale = face->units_per_EM;
|
||||
|
||||
fs_metrics.ascent = face->ascender / scale;
|
||||
fs_metrics.descent = - face->descender / scale;
|
||||
fs_metrics.height = face->height / scale;
|
||||
fs_metrics.max_x_advance = face->max_advance_width / scale;
|
||||
if (!(scaled_font->ft_options.load_flags & FT_LOAD_VERTICAL_LAYOUT)) {
|
||||
fs_metrics.max_x_advance = face->max_advance_width / scale;
|
||||
fs_metrics.max_y_advance = 0;
|
||||
} else {
|
||||
fs_metrics.max_x_advance = 0;
|
||||
fs_metrics.max_y_advance = face->max_advance_height / scale;
|
||||
}
|
||||
}
|
||||
|
||||
/* FIXME: this doesn't do vertical layout atm. */
|
||||
fs_metrics.max_y_advance = 0.0;
|
||||
|
||||
_cairo_scaled_font_set_metrics (&scaled_font->base, &fs_metrics);
|
||||
|
||||
return &scaled_font->base;
|
||||
|
|
@ -1716,6 +1725,23 @@ _decompose_glyph_outline (FT_Face face,
|
|||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Translate glyph to match its metrics.
|
||||
*/
|
||||
static void
|
||||
_cairo_ft_scaled_glyph_vertical_layout_bearing_fix (FT_GlyphSlot glyph)
|
||||
{
|
||||
FT_Pos x = glyph->metrics.vertBearingX - glyph->metrics.horiBearingX;
|
||||
FT_Pos y = -glyph->metrics.vertBearingY - glyph->metrics.horiBearingY;
|
||||
|
||||
if (glyph->format == FT_GLYPH_FORMAT_OUTLINE)
|
||||
FT_Outline_Translate(&glyph->outline, x, y);
|
||||
else if (glyph->format == FT_GLYPH_FORMAT_BITMAP) {
|
||||
glyph->bitmap_left += x / 64;
|
||||
glyph->bitmap_top += y / 64;
|
||||
}
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_ft_scaled_glyph_init (void *abstract_font,
|
||||
cairo_scaled_glyph_t *scaled_glyph,
|
||||
|
|
@ -1730,6 +1756,7 @@ _cairo_ft_scaled_glyph_init (void *abstract_font,
|
|||
int load_flags = scaled_font->ft_options.load_flags;
|
||||
FT_Glyph_Metrics *metrics;
|
||||
double x_factor, y_factor;
|
||||
cairo_bool_t vertical_layout = FALSE;
|
||||
|
||||
face = cairo_ft_scaled_font_lock_face (abstract_font);
|
||||
if (!face)
|
||||
|
|
@ -1739,6 +1766,15 @@ _cairo_ft_scaled_glyph_init (void *abstract_font,
|
|||
(info & CAIRO_SCALED_GLYPH_INFO_SURFACE) == 0)
|
||||
load_flags |= FT_LOAD_NO_BITMAP;
|
||||
|
||||
/*
|
||||
* Don't pass FT_LOAD_VERTICAL_LAYOUT to FT_Load_Glyph here as
|
||||
* suggested by freetype people.
|
||||
*/
|
||||
if (load_flags & FT_LOAD_VERTICAL_LAYOUT) {
|
||||
load_flags &= ~FT_LOAD_VERTICAL_LAYOUT;
|
||||
vertical_layout = TRUE;
|
||||
}
|
||||
|
||||
error = FT_Load_Glyph (scaled_font->unscaled->face,
|
||||
_cairo_scaled_glyph_index(scaled_glyph),
|
||||
load_flags);
|
||||
|
|
@ -1758,6 +1794,9 @@ _cairo_ft_scaled_glyph_init (void *abstract_font,
|
|||
FT_GlyphSlot_Embolden (glyph);
|
||||
#endif
|
||||
|
||||
if (vertical_layout)
|
||||
_cairo_ft_scaled_glyph_vertical_layout_bearing_fix (glyph);
|
||||
|
||||
if (info & CAIRO_SCALED_GLYPH_INFO_METRICS) {
|
||||
/*
|
||||
* Compute font-space metrics
|
||||
|
|
@ -1791,35 +1830,57 @@ _cairo_ft_scaled_glyph_init (void *abstract_font,
|
|||
FT_Pos x1, x2;
|
||||
FT_Pos y1, y2;
|
||||
FT_Pos advance;
|
||||
|
||||
if (!vertical_layout) {
|
||||
x1 = (metrics->horiBearingX) & -64;
|
||||
x2 = (metrics->horiBearingX + metrics->width + 63) & -64;
|
||||
y1 = (-metrics->horiBearingY) & -64;
|
||||
y2 = (-metrics->horiBearingY + metrics->height + 63) & -64;
|
||||
|
||||
advance = ((metrics->horiAdvance + 32) & -64);
|
||||
|
||||
fs_metrics.x_bearing = DOUBLE_FROM_26_6 (x1) * x_factor;
|
||||
fs_metrics.y_bearing = DOUBLE_FROM_26_6 (y1) * y_factor;
|
||||
|
||||
fs_metrics.width = DOUBLE_FROM_26_6 (x2 - x1) * x_factor;
|
||||
fs_metrics.height = DOUBLE_FROM_26_6 (y2 - y1) * y_factor;
|
||||
|
||||
x1 = (metrics->horiBearingX) & -64;
|
||||
x2 = (metrics->horiBearingX + metrics->width + 63) & -64;
|
||||
y1 = (-metrics->horiBearingY) & -64;
|
||||
y2 = (-metrics->horiBearingY + metrics->height + 63) & -64;
|
||||
fs_metrics.x_advance = DOUBLE_FROM_26_6 (advance) * x_factor;
|
||||
fs_metrics.y_advance = 0;
|
||||
} else {
|
||||
x1 = (metrics->vertBearingX) & -64;
|
||||
x2 = (metrics->vertBearingX + metrics->width + 63) & -64;
|
||||
y1 = (metrics->vertBearingY) & -64;
|
||||
y2 = (metrics->vertBearingY + metrics->height + 63) & -64;
|
||||
|
||||
advance = ((metrics->vertAdvance + 32) & -64);
|
||||
|
||||
fs_metrics.x_bearing = DOUBLE_FROM_26_6 (x1) * x_factor;
|
||||
fs_metrics.y_bearing = DOUBLE_FROM_26_6 (y1) * y_factor;
|
||||
|
||||
fs_metrics.width = DOUBLE_FROM_26_6 (x2 - x1) * x_factor;
|
||||
fs_metrics.height = DOUBLE_FROM_26_6 (y2 - y1) * y_factor;
|
||||
|
||||
advance = ((metrics->horiAdvance + 32) & -64);
|
||||
|
||||
fs_metrics.x_bearing = DOUBLE_FROM_26_6 (x1) * x_factor;
|
||||
fs_metrics.y_bearing = DOUBLE_FROM_26_6 (y1) * y_factor;
|
||||
|
||||
fs_metrics.width = DOUBLE_FROM_26_6 (x2 - x1) * x_factor;
|
||||
fs_metrics.height = DOUBLE_FROM_26_6 (y2 - y1) * y_factor;
|
||||
|
||||
/*
|
||||
* use untransformed advance values
|
||||
* XXX uses horizontal advance only at present; should provide FT_LOAD_VERTICAL_LAYOUT
|
||||
*/
|
||||
fs_metrics.x_advance = DOUBLE_FROM_26_6 (advance) * x_factor;
|
||||
fs_metrics.y_advance = 0;
|
||||
fs_metrics.x_advance = 0;
|
||||
fs_metrics.y_advance = DOUBLE_FROM_26_6 (advance) * y_factor;
|
||||
}
|
||||
} else {
|
||||
fs_metrics.x_bearing = DOUBLE_FROM_26_6 (metrics->horiBearingX) * x_factor;
|
||||
fs_metrics.y_bearing = DOUBLE_FROM_26_6 (-metrics->horiBearingY) * y_factor;
|
||||
fs_metrics.width = DOUBLE_FROM_26_6 (metrics->width) * x_factor;
|
||||
fs_metrics.height = DOUBLE_FROM_26_6 (metrics->height) * y_factor;
|
||||
|
||||
fs_metrics.width = DOUBLE_FROM_26_6 (metrics->width) * x_factor;
|
||||
fs_metrics.height = DOUBLE_FROM_26_6 (metrics->height) * y_factor;
|
||||
|
||||
fs_metrics.x_advance = DOUBLE_FROM_26_6 (metrics->horiAdvance) * x_factor;
|
||||
fs_metrics.y_advance = 0 * y_factor;
|
||||
if (!vertical_layout) {
|
||||
fs_metrics.x_bearing = DOUBLE_FROM_26_6 (metrics->horiBearingX) * x_factor;
|
||||
fs_metrics.y_bearing = DOUBLE_FROM_26_6 (-metrics->horiBearingY) * y_factor;
|
||||
|
||||
fs_metrics.x_advance = DOUBLE_FROM_26_6 (metrics->horiAdvance) * x_factor;
|
||||
fs_metrics.y_advance = 0 * y_factor;
|
||||
} else {
|
||||
fs_metrics.x_bearing = DOUBLE_FROM_26_6 (metrics->vertBearingX) * x_factor;
|
||||
fs_metrics.y_bearing = DOUBLE_FROM_26_6 (metrics->vertBearingY) * y_factor;
|
||||
|
||||
fs_metrics.x_advance = 0 * x_factor;
|
||||
fs_metrics.y_advance = DOUBLE_FROM_26_6 (metrics->vertAdvance) * y_factor;
|
||||
}
|
||||
}
|
||||
|
||||
_cairo_scaled_glyph_set_metrics (scaled_glyph,
|
||||
|
|
@ -1862,6 +1923,9 @@ _cairo_ft_scaled_glyph_init (void *abstract_font,
|
|||
cairo_ft_scaled_font_unlock_face (abstract_font);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
if (vertical_layout)
|
||||
_cairo_ft_scaled_glyph_vertical_layout_bearing_fix (glyph);
|
||||
|
||||
}
|
||||
if (glyph->format == FT_GLYPH_FORMAT_OUTLINE)
|
||||
status = _decompose_glyph_outline (face, &scaled_font->base.options,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue