[cairo] Re: Rotated text bug on drawable target
graydon hoare
graydon at redhat.com
Thu Nov 4 22:53:16 PST 2004
Carl Worth wrote:
> But with the code as in CVS the glyphs are positioned quite badly. Looks
> like rotations within the 1st quadrant are roughly correct. But
> rotations within the 3rd quadrant align the glyphs by their tops rather
> than along the baseline. Within the 2nd and 4th quadrants the positions
> transitions between the two extremes.
yeah, it was sort of a combination of a couple signage errors and the
use of bearings rather than bounding box offsets in the render glyph
loader. the attached patch seems to fix it, on my end (included a minor
fix to the clip code too).
ok to commit?
-graydon
2004-11-05 Graydon Hoare <graydon at redhat.com>
* src/cairo_ft_font.c: Change the signs of a variety of
metrics, which were backwards.
* src/cairo_gstate.c (_cairo_gstate_clip): Return early if we
found a rectangular clip at all, not just in error case.
* src/cairo_xlib_surface.c
(_xlib_glyphset_cache_create_entry): Give render glyphset entry
the negative bbox offsets it wants, not the bearings.
-------------- next part --------------
--- src/cairo_ft_font.c 22 Oct 2004 01:40:50 -0000 1.25
+++ src/cairo_ft_font.c 5 Nov 2004 06:42:31 -0000
@@ -527,7 +527,7 @@
continue;
x += val->extents.x_advance;
- y -= val->extents.y_advance;
+ y += val->extents.y_advance;
}
_cairo_unlock_global_image_glyph_cache ();
@@ -614,7 +614,7 @@
cairo_ft_font_create_for_ft_face accept an
FcPattern. */
glyph_min.x = glyphs[i].x + img->extents.x_bearing;
- glyph_min.y = glyphs[i].y - img->extents.y_bearing;
+ glyph_min.y = glyphs[i].y + img->extents.y_bearing;
glyph_max.x = glyph_min.x + img->extents.width;
glyph_max.y = glyph_min.y + img->extents.height;
@@ -640,7 +640,7 @@
extents->width = total_max.x - total_min.x;
extents->height = total_max.y - total_min.y;
extents->x_advance = glyphs[i-1].x + (img == NULL ? 0 : img->extents.x_advance) - origin.x;
- extents->y_advance = glyphs[i-1].y + 0 - origin.y;
+ extents->y_advance = glyphs[i-1].y + (img == NULL ? 0 : img->extents.y_advance) - origin.y;
return CAIRO_STATUS_SUCCESS;
}
@@ -688,7 +688,7 @@
continue;
x1 = _cairo_fixed_from_double (glyphs[i].x + img->size.x);
- y1 = _cairo_fixed_from_double (glyphs[i].y - img->size.y);
+ y1 = _cairo_fixed_from_double (glyphs[i].y + img->size.y);
x2 = x1 + _cairo_fixed_from_double (img->size.width);
y2 = y1 + _cairo_fixed_from_double (img->size.height);
@@ -763,10 +763,10 @@
&(img->image->base),
surface,
source_x + x + img->size.x,
- source_y + y - img->size.y,
+ source_y + y + img->size.y,
0, 0,
x + img->size.x,
- y - img->size.y,
+ y + img->size.y,
(double) img->size.width,
(double) img->size.height);
@@ -928,12 +928,19 @@
if (FT_Load_Glyph (font->val->face, val->key.index, FT_LOAD_DEFAULT) != 0)
return CAIRO_STATUS_NO_MEMORY;
+ /*
+ * Note: the font's coordinate system is upside down from ours, so the
+ * Y coordinates of the bearing and advance need to be negated.
+ */
+
val->extents.x_bearing = DOUBLE_FROM_26_6 (metrics->horiBearingX);
- val->extents.y_bearing = DOUBLE_FROM_26_6 (metrics->horiBearingY);
+ val->extents.y_bearing = -DOUBLE_FROM_26_6 (metrics->horiBearingY);
+
val->extents.width = DOUBLE_FROM_26_6 (metrics->width);
val->extents.height = DOUBLE_FROM_26_6 (metrics->height);
+
val->extents.x_advance = DOUBLE_FROM_26_6 (font->val->face->glyph->advance.x);
- val->extents.y_advance = DOUBLE_FROM_26_6 (font->val->face->glyph->advance.y);
+ val->extents.y_advance = -DOUBLE_FROM_26_6 (font->val->face->glyph->advance.y);
outline = &glyphslot->outline;
@@ -983,10 +990,15 @@
_cairo_image_surface_assume_ownership_of_data (val->image);
}
+ /*
+ * Note: the font's coordinate system is upside down from ours, so the
+ * Y coordinate of the control box needs to be negated.
+ */
+
val->size.width = (unsigned short) width;
val->size.height = (unsigned short) height;
val->size.x = (short) (cbox.xMin >> 6);
- val->size.y = (short) (cbox.yMax >> 6);
+ val->size.y = - (short) (cbox.yMax >> 6);
return CAIRO_STATUS_SUCCESS;
}
--- src/cairo_gstate.c 3 Nov 2004 23:05:24 -0000 1.63
+++ src/cairo_gstate.c 5 Nov 2004 06:42:31 -0000
@@ -1760,8 +1760,8 @@
if (status != CAIRO_INT_STATUS_UNSUPPORTED) {
_cairo_traps_fini (&traps);
- return status;
}
+ return status;
}
/* Otherwise represent the clip as a mask surface. */
--- src/cairo_xlib_surface.c 22 Oct 2004 01:40:50 -0000 1.27
+++ src/cairo_xlib_surface.c 5 Nov 2004 06:42:31 -0000
@@ -839,8 +839,45 @@
v->info.width = im->image ? im->image->stride : im->size.width;
v->info.height = im->size.height;
- v->info.x = - im->extents.x_bearing;
- v->info.y = im->extents.y_bearing;
+
+ /*
+ * Most of the font rendering system thinks of glyph tiles as having
+ * an origin at (0,0) and an x and y bounding box "offset" which
+ * extends possibly off into negative coordinates, like so:
+ *
+ *
+ * (x,y) <-- probably negative numbers
+ * +----------------+
+ * | . |
+ * | . |
+ * |......(0,0) |
+ * | |
+ * | |
+ * +----------------+
+ * (width+x,height+y)
+ *
+ * This is a postscript-y model, where each glyph has its own
+ * coordinate space, so it's what we expose in terms of metrics. It's
+ * apparantly what everyone's expecting. Everyone except the Render
+ * extension. Render wants to see a glyph tile starting at (0,0), with
+ * an origin offset inside, like this:
+ *
+ * (0,0)
+ * +---------------+
+ * | . |
+ * | . |
+ * |......(x,y) |
+ * | |
+ * | |
+ * +---------------+
+ * (width,height)
+ *
+ * Luckily, this is just the negation of the numbers we already have
+ * sitting around for x and y.
+ */
+
+ v->info.x = -im->size.x;
+ v->info.y = -im->size.y;
v->info.xOff = 0;
v->info.yOff = 0;
More information about the cairo
mailing list