Re: pango_layout_set_width() versus measured widths
- From: Behdad Esfahbod <behdad behdad org>
- To: blp cs stanford edu
- Cc: gtk-list gnome org
- Subject: Re: pango_layout_set_width() versus measured widths
- Date: Fri, 25 Dec 2009 19:25:23 +0100
I've now pushed a fix to pango master. I'll put in the next stable release
also if/when that happens.
http://git.gnome.org/browse/pango/commit/?id=2cd9c4b416cbe55dd68106003f360e861a6722be
Thanks,
behdad
On 12/22/2009 11:13 PM, Ben Pfaff wrote:
In working with Pango I found an oddity that I do not understand.
It may be a bug, or it might just be my misunderstanding.
As part of a table layout procedure for printing, my code wishes
to find out the width of the longest word in a Pango layout, so
it sets the width of the layout to 1, turns on word wrapping, and
measures the width of the layout, something like this:
pango_layout_set_width (layout, 1);
pango_layout_set_wrap (layout, PANGO_WRAP_WORD);
pango_layout_get_size (layout,&width, NULL);
Later on, the width of the table column might have been adjusted
upward or downward for other reasons, so it renders it with
PANGO_WRAP_WORD_CHAR to prevent overflowing the column
boundary. I was surprised to discover that, when the layout
width is set to the same value returned by
pango_layout_get_size(), this caused some words to wrap anyhow.
I'm enclosing a simple example program. You can invoke it to
measure the size of rendering "A string of text" with a width of
1 and word-wrapping, as above, e.g. showing input, output, and
an ASCII rendering of the produced foo.pdf:
# ./a.out "A string of text" 1 word
size: width=47032
extents: ink width=45416, logical width=47032
pixel extents: ink width=45, logical width=46
+------+
|A |
|string|
|of |
|text |
+------+
Then giving the exact width reported by this run, plus word-char,
yields:
# ./a.out "A string of text" 47032 word-char
size: width=36632
extents: ink width=35112, logical width=36632
pixel extents: ink width=35, logical width=36
+-----+
|A |
|strin|
|g of |
|text |
+-----+
To get word-char to produce the results that I expect, I have to
add 5208, which is the reported width of " ":
# ./a.out "A string of text" 52240 word-char
size: width=47032
extents: ink width=45416, logical width=47032
pixel extents: ink width=45, logical width=46
+------+
|A |
|string|
|of |
|text |
+------+
Any guidance would be appreciated. I can always add the width of
a space myself, but I don't understand why it is necessary.
Here is my test program:
#include<pango/pangocairo.h>
#include<cairo/cairo-pdf.h>
#include<cairo/cairo.h>
#include<stdlib.h>
#include<string.h>
int
main (int argc, char **argv)
{
cairo_t *cr;
char *filename;
cairo_status_t status;
cairo_surface_t *surface;
PangoLayout *layout;
PangoFontDescription *desc;
PangoRectangle ink, logical;
int width;
if (argc != 4)
{
g_printerr ("Usage: pangocairo STRING WIDTH WRAP_MODE\n");
return 1;
}
/* Create surface and clear to all-white. */
surface = cairo_pdf_surface_create ("foo.pdf", 200, 200);
cr = cairo_create (surface);
cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
cairo_paint (cr);
/* Create Pango layout. */
layout = pango_cairo_create_layout (cr);
desc = pango_font_description_from_string ("Sans 12");
pango_layout_set_font_description (layout, desc);
pango_font_description_free (desc);
pango_layout_set_text (layout, argv[1], -1);
/* Set Pango options according to command line. */
pango_layout_set_width (layout, atoi (argv[2]));
if (!strcmp (argv[3], "word"))
pango_layout_set_wrap (layout, PANGO_WRAP_WORD);
else if (!strcmp (argv[3], "char"))
pango_layout_set_wrap (layout, PANGO_WRAP_CHAR);
else if (!strcmp (argv[3], "word-char"))
pango_layout_set_wrap (layout, PANGO_WRAP_WORD_CHAR);
else
{
g_printerr ("WRAP_MODE must be 'word' or 'char' or 'word-char'");
return 1;
}
/* Draw layout. */
cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
cairo_move_to (cr, 0, 0);
pango_cairo_show_layout (cr, layout);
/* Print various sizes. */
pango_layout_get_size (layout,&width, NULL);
printf ("size: width=%d\n", width);
pango_layout_get_extents (layout,&ink,&logical);
printf ("extents: ink width=%d, logical width=%d\n",
ink.width, logical.width);
pango_layout_get_pixel_extents (layout,&ink,&logical);
printf ("pixel extents: ink width=%d, logical width=%d\n",
ink.width, logical.width);
/* Clean up. */
g_object_unref (layout);
cairo_destroy (cr);
cairo_surface_finish (surface);
status = cairo_surface_status (surface);
cairo_surface_destroy (surface);
if (status != CAIRO_STATUS_SUCCESS)
{
g_printerr ("Could not save pdf to '%s'\n", filename);
return 1;
}
return 0;
}
--
Ben Pfaff
http://benpfaff.org
_______________________________________________
gtk-list mailing list
gtk-list gnome org
http://mail.gnome.org/mailman/listinfo/gtk-list
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]