[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