[cairo-commit] src/cairo-ft-font.c
ç½æ¶å Jinghua Luo
jinghua at kemper.freedesktop.org
Wed Jun 7 12:46:07 PDT 2006
src/cairo-ft-font.c | 126 +++++++++++++++++++++++++++++++++++++++-------------
1 files changed, 95 insertions(+), 31 deletions(-)
New commits:
diff-tree 5ae2a78a297730cd9d2f45be9f23fbf6e2bffe7d (from 6b5be506ed160675232bea31b17f458040f6b2d8)
Author: Jinghua Luo <sunmoon1997 at gmail.com>
Date: Thu Jun 8 03:45:38 2006 +0800
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.
diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c
index 002466b..61a2c23 100644
--- a/src/cairo-ft-font.c
+++ b/src/cairo-ft-font.c
@@ -1461,19 +1461,28 @@ _cairo_ft_scaled_font_create (cairo_ft_u
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 fac
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 *abs
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 *abs
(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 *abs
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 *abs
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;
-
- 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;
- } 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.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;
- 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 = 0;
+ fs_metrics.y_advance = DOUBLE_FROM_26_6 (advance) * y_factor;
+ }
+ } else {
+ 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 *abs
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,
More information about the cairo-commit
mailing list