Writing a PangoLayoutLine on a line in cairo



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 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;
}



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