RE: Finding width of a piece of text



> -----Original Message-----
> From: Ian Puleston
> Sent: Sunday, April 26, 2009 8:31 PM
> 
> > -----Original Message-----
> > From: > Behdad Esfahbod
> > Sent: Sunday, April 26, 2009 6:13 PM
> >
> > On 04/26/2009 07:27 PM, Ian Puleston wrote:
> > >
> > > with Pango I have a need to find the width that a piece of 
> > > text will be displayed.
> > >
> > > I can't use pango_cairo_create_layout() at this point because I
> > > don't yet know what print device it will be printed on.
> >
> > Then at least 1) make sure your context is set to 72 dpi, and 2) set
> > font options to disable metrics hinting.
> >
> > behdad
> 
> I added a call to pango_cairo_context_set_resolution(ctx, 72) and that
> fixed it.

Well it nearly fixed it. I'm using this to truncate text to fit into fixed
width columns when it is printed, and although its generally working well
I've noticed that some text is getting truncated when it doesn't quite need
to be. So I added some debug printing of the text width and it is not being
reported quite the same as the width that the text is printed.

The function that I wrote to get the text width is below. For the text "Ian
Puleston" with Arial font and point size 10 it returns width 60416 Pango
units which translates to 0.82" (60416 / 1024 / 72), but when that is
printed the name takes just about exactly 0.75" width.

So anyone got any idea what may be wrong with the following code to cause
that?


/*==========================================================================
==*/
/*
 * This calculates the width that some given text will be when printed.
 */
int
getPrintWidth(const char *pText, PangoAttrList *textAttrs)
{
    GtkWidget               *lbl;
    PangoAttrList           *attrList;
    PangoLayout             *layout;
    PangoContext            *ctx;
    cairo_font_options_t    *fontOpts;
    int                     width, height;

    /* We can find the size by putting the text into a label widget, setting
     * the resolution of that widget to 72dpi (dot == point) and querying
the
     * width of the resulting layout */
    lbl = gtk_label_new(pText);
    attrList = pango_attr_list_copy(textAttrs);
    g_assert(attrList);
    gtk_label_set_attributes(GTK_LABEL(lbl), attrList);
    layout = gtk_label_get_layout(GTK_LABEL(lbl));
    g_assert(layout);

    /* To get the correct text width we need to make sure the label we put
     * it in has a resolution of 72dpi (a dot is equivalent to a text point)
*/
    ctx = pango_layout_get_context(layout);
    g_assert(ctx);
    pango_cairo_context_set_resolution(ctx, 72);

    /* This next probably isn't needed but to make sure font size is
consistent
     * we turn off font metrics hinting (to do with constant font size on
zoom) */
    fontOpts = cairo_font_options_create();
    cairo_font_options_set_hint_metrics(fontOpts, CAIRO_HINT_METRICS_OFF);
    pango_cairo_context_set_font_options(ctx, fontOpts);

    pango_layout_get_size(layout, &width, &height);

    gtk_widget_destroy(lbl);
    pango_attr_list_unref(attrList);
    cairo_font_options_destroy(fontOpts);

    g_print("'%s' width %d\n", pText, width);

    return (width);
}






[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]