This example graphically shows the meaning of the logical bounding box of a pango line, as well as the difference in alignment between a PangoLayout and the corresponding PangoLayoutLine. It also illustrates how to go back and forth between pango and cairo coordinates.

   1 //======================================================================
   2 // Example that shows the relation between cairo coordinates and
   3 // Pango coordinates.
   4 //
   5 // Dov Grobgeld <dov.grobgeld@gmail.com>
   6 // Sat 2007-02-03 21:43
   7 //
   8 // This program is in the public domain
   9 //
  10 // Compile with:
  11 //
  12 //    gcc `pkg-config --cflags --libs pangocairo` -o pango-bbox  pango-bbox.c
  13 //----------------------------------------------------------------------
  14 #include <math.h>
  15 #include <pango/pangocairo.h>
  16 
  17 #define WIDTH 800
  18 #define HEIGHT 300
  19 
  20 // Returns the "depth" of a layout, that is the distance from the
  21 // top of the layout to the baseline of the first line in the
  22 // layout.
  23 int get_layout_depth(PangoLayout *layout)
  24 {
  25   PangoLayoutLine *layout_line = pango_layout_get_line(layout,0);
  26   PangoRectangle rect;
  27 
  28   pango_layout_line_get_extents(layout_line,
  29                                 NULL,
  30                                 &rect);
  31 
  32   return PANGO_ASCENT(rect);
  33 }
  34                         
  35 static void
  36 draw_text (cairo_t *cr,
  37            const char *text)
  38 {
  39   PangoLayout *layout;
  40   PangoLayoutLine *layout_line;
  41   PangoFontDescription *desc;
  42   PangoRectangle ink_rect, logical_rect;
  43   int width, height;
  44   double x, y;
  45   double depth;
  46 
  47   // Center coordinates on the middle of the region we are drawing
  48   cairo_translate (cr, WIDTH/2, HEIGHT/2);
  49 
  50   // Create a PangoLayout, set the font and text 
  51   layout = pango_cairo_create_layout (cr);
  52   
  53   pango_layout_set_markup (layout, text, -1);
  54   desc = pango_font_description_from_string ("Serif 70");
  55   pango_layout_set_font_description (layout, desc);
  56   pango_font_description_free (desc);
  57 
  58   pango_layout_get_extents(layout,
  59                            &ink_rect,
  60                            &logical_rect);
  61   x = -((double)logical_rect.width / PANGO_SCALE) / 2;
  62   y = -((double)logical_rect.height / PANGO_SCALE) / 2;
  63 
  64   // Draw a green point at the current x,y position
  65   cairo_set_source_rgba (cr, 0.0, 1.0, 0.0, 0.5); // green
  66   cairo_arc(cr,
  67             x, y,
  68             5, 0, 2*M_PI);
  69   cairo_fill(cr);
  70     
  71   // Draw the logical rectancgle
  72   cairo_set_source_rgba (cr, 0.0, 0.0, 1.0, 0.5); // blue
  73   cairo_rectangle(cr,
  74                   x+logical_rect.x/PANGO_SCALE,
  75                   y+logical_rect.y/PANGO_SCALE,
  76                   logical_rect.width/PANGO_SCALE,
  77                   logical_rect.height/PANGO_SCALE);
  78   cairo_stroke(cr);
  79 
  80   // Draw the depth line
  81   depth = (double)get_layout_depth(layout);
  82   cairo_set_source_rgba (cr, 0.5, 0.0, 0.5, 0.5);
  83   cairo_move_to(cr, x, y+depth/PANGO_SCALE);
  84   cairo_rel_line_to(cr, logical_rect.width/PANGO_SCALE, 0);
  85   cairo_stroke(cr);
  86 
  87   // Draw the text
  88   cairo_move_to (cr, x, y+depth/PANGO_SCALE);
  89   cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); // black
  90   pango_cairo_show_layout_line (cr, pango_layout_get_line(layout,0));
  91 
  92   // Draw same text but with pango_cairo_show_layout
  93   cairo_move_to (cr, x+1.2*logical_rect.width/PANGO_SCALE, y);
  94   cairo_set_source_rgb (cr, 0.6, 0.6, 0.6); // grey
  95   pango_cairo_show_layout (cr, layout);
  96   
  97   /* free the layout object */
  98   g_object_unref (layout);
  99 }
 100 
 101 int main (int argc, char **argv)
 102 {
 103   cairo_t *cr;
 104   const char *filename = "pango-bbox.png";
 105   cairo_surface_t *surface;
 106 
 107   surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, WIDTH, HEIGHT);
 108 
 109   cr = cairo_create (surface);
 110 
 111   cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
 112   cairo_paint (cr);
 113   draw_text (cr,
 114              "yd"
 115              );
 116   cairo_show_page (cr);
 117   cairo_destroy (cr);
 118   
 119   cairo_surface_write_to_png(surface, filename);
 120 
 121   cairo_surface_destroy (surface);
 122 
 123   return 0;
 124 }

The resulting output: pangolayoutline-output.png

Projects/Pango/LayoutLineBbox (last edited 2013-12-02 17:28:30 by WilliamJonMcCann)