[cairo] Writing a PangoLayoutLine on a line in cairo
Dov Grobgeld
dov.grobgeld at gmail.com
Sat Feb 3 11:48:29 PST 2007
I'm trying to understand how to get the baseline information from a
single line PangoLayout or equivalently a PangoLayoutLine.
More concretely I would like to translate the following postscript
program into Pango/Cairo:
%!
1.0 0 0 setrgbcolor
100 100 moveto
150 0 rlineto stroke
100 100 moveto
/Helvetica findfont 36 scalefont setfont
0 setgray
(yd) show
showpage
This programs draws a red line at position 100 100 from the lower
corner left of the page and then writes "yd" on it. Note that the
descender of the y descends below the y=100 line.
In pango_cairo_show_layout() on the other hand, the layout logical
upper left corner is aligned at the current cairo point when drawing,
and I could not find any PangoLayout call that gets the distance from
the top of the logical rectangle to the baseline position. Is this a
bug, or did I miss something?
Here is some pangocairo code that shows this alignment. So the
question is how can I get the distance from the top of the PangoLayout
to the baseline?
Regards,
Dov
//======================================================================
// Example that shows the relation between cairo coordinates and
// Pango coordinates.
//
// Dov Grobgeld <dov.grobgeld at gmail.com>
// Sat 2007-02-03 21:43
//
// This program is in the public domain
//
// Compile with:
//
// gcc `pkg-config --cflags --libs pangocairo` -o pango-bbox pango-bbox.c
//----------------------------------------------------------------------
#include <math.h>
#include <pango/pangocairo.h>
#define WIDTH 800
#define HEIGHT 300
static void
draw_text (cairo_t *cr,
const char *text)
{
PangoLayout *layout;
PangoFontDescription *desc;
PangoRectangle ink_rect, logical_rect;
int width, height;
double x, y;
// Center coordinates on the middle of the region we are drawing
cairo_translate (cr, WIDTH/2, HEIGHT/2);
// Create a PangoLayout, set the font and text
layout = pango_cairo_create_layout (cr);
pango_layout_set_markup (layout, text, -1);
desc = pango_font_description_from_string ("Serif 70");
pango_layout_set_font_description (layout, desc);
pango_font_description_free (desc);
pango_layout_get_extents(layout,
&ink_rect,
&logical_rect);
x = -((double)logical_rect.width / PANGO_SCALE) / 2;
y = -((double)logical_rect.height / PANGO_SCALE) / 2;
// Draw a green point at the current x,y position
cairo_set_source_rgba (cr, 0.0, 1.0, 0.0, 0.5); // green
cairo_arc(cr,
x, y,
5, 0, 2*M_PI);
cairo_fill(cr);
// Draw the logical rectangle
cairo_set_source_rgba (cr, 0.0, 0.0, 1.0, 0.5); // blue
cairo_rectangle(cr,
x+logical_rect.x/PANGO_SCALE,
y+logical_rect.y/PANGO_SCALE,
logical_rect.width/PANGO_SCALE,
logical_rect.height/PANGO_SCALE);
cairo_stroke(cr);
// Draw the text
cairo_move_to (cr, x, y);
cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); // black
pango_cairo_show_layout (cr, layout);
// Question: How can I draw a line at the baseline position?
// free the layout object
g_object_unref (layout);
}
int main (int argc, char **argv)
{
cairo_t *cr;
const char *filename = "pango-bbox.png";
cairo_surface_t *surface;
surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, WIDTH, HEIGHT);
cr = cairo_create (surface);
cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
cairo_paint (cr);
draw_text (cr,
"yd"
);
cairo_show_page (cr);
cairo_destroy (cr);
cairo_surface_write_to_png(surface, filename);
cairo_surface_destroy (surface);
return 0;
}
More information about the cairo
mailing list