[cairo] PATCH #4 - text extents
John Ellson
ellson at research.att.com
Tue Dec 9 20:34:35 PST 2003
I'm sorry for the churn on this.
This one works right - no more small errors in the right-bearing of the
bounding
rectangle.
John
-------------- next part --------------
? depcomp
? install-sh
? missing
? mkinstalldirs
Index: src/cairo.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo.c,v
retrieving revision 1.29
diff -r1.29 cairo.c
710d709
< /* XXX: NYI
734d732
< */
Index: src/cairo.h
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo.h,v
retrieving revision 1.32
diff -r1.32 cairo.h
399,401d398
<
< /* XXX: NYI
<
412a410,411
> /* XXX: NYI
>
Index: src/cairo_ft_font.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo_ft_font.c,v
retrieving revision 1.7
diff -r1.7 cairo_ft_font.c
43,48c43,46
< #define DOUBLE_TO_26_6(d) ((FT_F26Dot6)((d) * 63.0))
< #define DOUBLE_FROM_26_6(t) (((double)((t) >> 6)) \
< + ((double)((t) & 0x3F) / 63.0))
< #define DOUBLE_TO_16_16(d) ((FT_Fixed)((d) * 65535.0))
< #define DOUBLE_FROM_16_16(t) (((double)((t) >> 16)) \
< + ((double)((t) & 0xFFFF) / 65535.0))
---
> #define DOUBLE_TO_26_6(d) ((FT_F26Dot6)((d) * 64.0))
> #define DOUBLE_FROM_26_6(t) ((double)(t) / 64.0)
> #define DOUBLE_TO_16_16(d) ((FT_Fixed)((d) * 65536.0))
> #define DOUBLE_FROM_16_16(t) ((double)(t) / 65536.0)
324c322
< cairo_ft_font_t *ft;
---
> FT_Face face;
332c330
< ft = (cairo_ft_font_t *)font;
---
> face = ((cairo_ft_font_t *)font)->face;
346c344
< _install_font_matrix (&font->matrix, ft->face);
---
> _install_font_matrix (&font->matrix, face);
350c348
< (*glyphs)[i].index = FT_Get_Char_Index (ft->face, ucs4[i]);
---
> (*glyphs)[i].index = FT_Get_Char_Index (face, ucs4[i]);
354c352
< FT_Load_Glyph (ft->face, (*glyphs)[i].index, FT_LOAD_DEFAULT);
---
> FT_Load_Glyph (face, (*glyphs)[i].index, FT_LOAD_DEFAULT);
356,357c354,355
< x += DOUBLE_FROM_26_6 (ft->face->glyph->advance.x);
< y -= DOUBLE_FROM_26_6 (ft->face->glyph->advance.y);
---
> x += DOUBLE_FROM_26_6(face->glyph->advance.x);
> y -= DOUBLE_FROM_26_6(face->glyph->advance.y);
368,370c366
< double scale_x, scale_y;
< cairo_ft_font_t *ft = (cairo_ft_font_t *)font;
< cairo_status_t status = CAIRO_STATUS_SUCCESS;
---
> FT_Face face;
372c368
< _get_scale_factors(&font->matrix, &scale_x, &scale_y);
---
> face = ((cairo_ft_font_t *)font)->face;
374c370,374
< #define FONT_UNIT_TO_DEV(x) ((double)(x) / (double)(ft->face->units_per_EM))
---
> extents->ascent = DOUBLE_FROM_26_6(face->ascender);
> extents->descent = DOUBLE_FROM_26_6(face->descender);
> extents->height = DOUBLE_FROM_26_6(face->height);
> extents->max_x_advance = DOUBLE_FROM_26_6(face->max_advance_width);
> extents->max_y_advance = DOUBLE_FROM_26_6(face->max_advance_height);
376,381c376
< extents->ascent = FONT_UNIT_TO_DEV(ft->face->ascender) * scale_y;
< extents->descent = FONT_UNIT_TO_DEV(ft->face->descender) * scale_y;
< extents->height = FONT_UNIT_TO_DEV(ft->face->height) * scale_y;
< extents->max_x_advance = FONT_UNIT_TO_DEV(ft->face->max_advance_width) * scale_x;
< extents->max_y_advance = FONT_UNIT_TO_DEV(ft->face->max_advance_height) * scale_y;
< return status;
---
> return CAIRO_STATUS_SUCCESS;
390,391c385,391
< cairo_ft_font_t *ft;
< cairo_status_t status = CAIRO_STATUS_SUCCESS;
---
> FT_Face face;
> FT_GlyphSlot glyphslot;
> int i;
> FT_F26Dot6 X, Y;
> FT_F26Dot6 Left, Right, Top, Bottom;
> FT_F26Dot6 overall_Left, overall_Right;
> FT_F26Dot6 overall_Top, overall_Bottom;
393c393,394
< ft = (cairo_ft_font_t *)font;
---
> if (font == NULL || glyphs == NULL || extents == NULL)
> return CAIRO_STATUS_NO_MEMORY;
395c396,397
< /* FIXME: lift code from xft to do this */
---
> face = ((cairo_ft_font_t *)font)->face;
> glyphslot = face->glyph;
397c399,469
< return status;
---
> X = overall_Left = overall_Right = Y = overall_Top = overall_Bottom = 0;
>
> #define HORIZONTAL 1 /* FIXME - get cuurent vertical/horizontal mode from Fc???? */
> if (HORIZONTAL)
> {
> for (i = 0; i < num_glyphs; i++)
> {
> FT_Load_Glyph (face, glyphs[i].index, FT_LOAD_DEFAULT);
>
> Left = X + glyphslot->metrics.horiBearingX;
> Top = Y - glyphslot->metrics.horiBearingY;
> Right = Left + glyphslot->metrics.width;
> Bottom = Top + glyphslot->metrics.height;
>
> if (i==0)
> {
> /* The BB does not necessarily include 0,0 */
> overall_Left = Left;
> overall_Top = Top;
> overall_Right = Right;
> overall_Bottom = Bottom;
> }
> else
> {
> if (Left < overall_Left) overall_Left = Left;
> if (Top < overall_Top) overall_Top = Top;
> if (Right > overall_Right) overall_Right = Right;
> if (Bottom > overall_Bottom) overall_Bottom = Bottom;
> }
>
> X += glyphslot->metrics.horiAdvance;
> }
> }
> else
> {
> for (i = 0; i < num_glyphs; i++)
> {
> FT_Load_Glyph (face, glyphs[i].index, FT_LOAD_DEFAULT);
>
> Left = X + glyphslot->metrics.vertBearingX;
> Top = Y - glyphslot->metrics.vertBearingY;
> Right = Left + glyphslot->metrics.width;
> Bottom = Top + glyphslot->metrics.height;
>
> if (i==0)
> {
> /* The BB does not necessarily include 0,0 */
> overall_Left = Left;
> overall_Top = Top;
> overall_Right = Right;
> overall_Bottom = Bottom;
> }
> else
> {
> if (Left < overall_Left) overall_Left = Left;
> if (Top < overall_Top) overall_Top = Top;
> if (Right > overall_Right) overall_Right = Right;
> if (Bottom > overall_Bottom) overall_Bottom = Bottom;
> }
>
> Y += glyphslot->metrics.vertAdvance;
> }
> }
> extents->left_side_bearing = DOUBLE_FROM_26_6(overall_Left);
> extents->right_side_bearing = DOUBLE_FROM_26_6(overall_Right);
> extents->ascent = DOUBLE_FROM_26_6(overall_Top);
> extents->descent = DOUBLE_FROM_26_6(overall_Bottom);
> extents->x_advance = DOUBLE_FROM_26_6(X);
> extents->y_advance = DOUBLE_FROM_26_6(Y);
>
> return CAIRO_STATUS_SUCCESS;
399a472
>
558c631
< /* FIXME: lift code from xft to do this */
---
> /* XXX: lift code from xft to do this */
Index: src/cairo_gstate.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo_gstate.c,v
retrieving revision 1.33
diff -r1.33 cairo_gstate.c
1589a1590,1603
> static void
> _get_scale_factors(cairo_matrix_t *matrix, double *sx, double *sy)
> {
> double e0, e1;
> e1 = 1.; e0 = 0.;
>
> cairo_matrix_transform_distance (matrix, &e1, &e0);
> *sx = sqrt(e1*e1 + e0*e0);
>
> e1 = 1.; e0 = 0.;
> cairo_matrix_transform_distance (matrix, &e0, &e1);
> *sy = sqrt(e1*e1 + e0*e0);
> }
>
1595a1610
> double scale_x, scale_y;
1602a1618,1625
>
> _get_scale_factors(&gstate->ctm, &scale_x, &scale_y);
> extents->max_x_advance /= scale_x;
> extents->max_y_advance /= scale_y;
> extents->ascent /= scale_y;
> extents->descent /= scale_y;
> extents->height /= scale_y;
>
1624a1648
> double scale_x, scale_y;
1632a1657,1665
>
> _get_scale_factors(&gstate->ctm, &scale_x, &scale_y);
> extents->x_advance /= scale_x;
> extents->y_advance /= scale_y;
> extents->left_side_bearing /= scale_x;
> extents->right_side_bearing /= scale_x;
> extents->ascent /= scale_y;
> extents->descent /= scale_y;
>
1645a1679
> double scale_x, scale_y;
1667a1702,1709
> _get_scale_factors(&gstate->ctm, &scale_x, &scale_y);
> extents->x_advance /= scale_x;
> extents->y_advance /= scale_y;
> extents->left_side_bearing /= scale_x;
> extents->right_side_bearing /= scale_x;
> extents->ascent /= scale_y;
> extents->descent /= scale_y;
>
-------------- next part --------------
? autom4te.cache
? depcomp
Index: src/svg_cairo.c
===================================================================
RCS file: /cvs/xsvg/libsvg-cairo/src/svg_cairo.c,v
retrieving revision 1.22
diff -r1.22 svg_cairo.c
1122a1123,1125
> cairo_text_extents_t extents;
>
> _svg_cairo_select_font (svg_cairo);
1126a1130,1142
> if (svg_cairo->state->text_anchor != SVG_TEXT_ANCHOR_START) {
> cairo_text_extents (svg_cairo->cr, utf8, &extents);
>
> if (svg_cairo->state->text_anchor == SVG_TEXT_ANCHOR_END) {
> x -= extents.x_advance;
> y -= extents.y_advance;
> }
> else if (svg_cairo->state->text_anchor == SVG_TEXT_ANCHOR_MIDDLE) {
> x -= extents.x_advance / 2.0;
> y -= extents.y_advance / 2.0;
> }
> }
>
1137,1149d1152
< /* XXX: Temporarily disable since cairo_text_extents is currently not working
<
< if (svg_cairo->state->text_anchor != SVG_TEXT_ANCHOR_START) {
< double x, y, width, height, dx, dy;
< cairo_text_extents (svg_cairo->cr, utf8, &x, &y, &width, &height, &dx, &dy);
< if (svg_cairo->state->text_anchor == SVG_TEXT_ANCHOR_END)
< cairo_rel_move_to (svg_cairo->cr, -dx, -dy);
< else if (svg_cairo->state->text_anchor == SVG_TEXT_ANCHOR_MIDDLE)
< cairo_rel_move_to (svg_cairo->cr, -dx / 2, -dy / 2);
< }
< */
<
< _svg_cairo_select_font (svg_cairo);
-------------- next part --------------
A non-text attachment was scrubbed...
Name: text-bounds2.png
Type: image/png
Size: 14466 bytes
Desc: not available
Url : http://lists.freedesktop.org/archives/cairo/attachments/20031209/118124cd/text-bounds2.png
More information about the cairo
mailing list