pangocairo show_glyph_string vs. glyph_string_path



Hello all,

in one application I try to use pango_cairo_glyph_string_path() so
that I can specify subsequent fill and stroke.

However, I do not understand how to deal with line leading properly
when I iterate over the 'runs'.

I would expect cases #1 and #2 in my attached source code, to give
identical visual layout (except for fill/stroke)
as case #0.

However, case #1 does not seem to apply line leading. Case #2 somehow
resets position.

What did I miss?

Thanks,
-- 
Leon
/**
 * @file
 * 
 * http://www.cl.cam.ac.uk/~mgk25/ucs/utf-8-history.txt
 * http://www.cl.cam.ac.uk/~mgk25/unicode.html
 * Indian languages:
 * http://acharya.iitm.ac.in/demos/unicode_testview.php
 * 
 * Drawing custom glyphs in text:
 * http://svn.gnome.org/svn/pango/trunk/examples/cairoshape.c
 */

/* c99 `pkg-config --cflags --libs pangocairo` captions.c -o captions */


/**
 * I would like the visual layout of case #0 to reproduce in case 1 and 2
 * What did I miss?
 * 
 * 0 - use pangocairo to show layout 
 * 1 - iterate over runs, pangocairo shows run
 * 2 - iterate over runs, pangocairo creates cairo path, cairo renders
 */
#define CASE (2) 

#include <stdio.h>
#include <string.h>
#include <unistd.h>

#include <pango/pangocairo.h>

#define FONT "Sans Regular 27"
static PangoLayout *get_pango_layout(cairo_t *cr, const char *text,
		double *width, double *height)
{
	PangoLayout *layout = NULL;
	PangoRectangle logical;
  PangoFontDescription *desc = NULL;

	layout = pango_cairo_create_layout(cr);
  desc = pango_font_description_from_string(FONT);
  pango_layout_set_font_description (layout, desc);
  pango_font_description_free(desc);
  desc = NULL;
	
	pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
	pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER);
	pango_layout_set_width(layout, 300 * PANGO_SCALE);
	pango_layout_set_text(layout, text, -1);
	pango_layout_get_pixel_extents(layout, NULL, &logical);

	if (width)
		*width = logical.width;
	if (height)
		*height = logical.height;

	return layout;
}

#define WIDTH 800
#define HEIGHT 600

int main(int argc, char *argv[])
{
  cairo_t *cr = NULL;
  double width, height;
  cairo_status_t status;

  cairo_surface_t *surface = NULL;
  surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, WIDTH, HEIGHT);
  cr = cairo_create(surface);

  PangoLayout *layout = NULL;
  layout = get_pango_layout(cr, "Some guy wants to pay an extra-ordinary amount of money, say £30", &width, &height);
  
  int line_number = 0;  
  PangoLayoutLine *line = NULL;
  line = pango_layout_get_line_readonly(layout, line_number);
  while (line)
  {
    line = pango_layout_get_line_readonly(layout, ++line_number);
  }
  printf("%d lines\n", line_number);
  
  PangoLayoutIter *iter = NULL;
  iter = pango_layout_get_iter(layout);
  
  cairo_move_to(cr, width, height/2);
    
  
#if (CASE == 0) /* let pangocairo render the text */
  pango_cairo_show_layout(cr, layout);
#else /* we iterate over the runs ourselves */
  PangoLayoutRun *run = NULL;
  run = pango_layout_iter_get_run_readonly(iter);
  int run_number = 0;
  while (run)
  {
    printf("run = %p\n", (void *)run);
    printf("Handling run #%d\n", run_number++);
    /* single run within a PangoLayoutLine, alternate name is PangoGlyphItem */
    PangoGlyphString *glyphs = run->glyphs;
    if (glyphs)
    {
      PangoFont *font = run->item->analysis.font;
      if (font)
      {
#if (CASE == 1) /* let pangocairo render the glyphs */
        pango_cairo_show_glyph_string(cr, font, glyphs);
#else /* let pangocairo put the glyphs on cairo's path, render using cairo */        
        pango_cairo_glyph_string_path(cr, font, glyphs);
        /* blue halo */
        cairo_set_source_rgba(cr, 0., 0., 0., .5);
        cairo_set_line_width(cr, 3.);
        cairo_stroke_preserve(cr);

        /* green letters */
        cairo_set_source_rgb(cr, 1., 1., 1.);
        cairo_fill(cr);
#endif        
      }
    }
    gboolean progress = pango_layout_iter_next_run(iter);
    if (progress == FALSE) printf("Reached end of layout.\n");
    run = pango_layout_iter_get_run_readonly(iter);
    /* end-of-line? and not on the last line? */
    if ((run == NULL) && (pango_layout_iter_at_last_line(iter) == FALSE))
    {
      /* proceed to next line */
      pango_layout_iter_next_line(iter);
      run = pango_layout_iter_get_run_readonly(iter);
      printf("next line\n");
    }
  }
  pango_layout_iter_free(iter);
  iter = NULL;
#endif  
  g_object_unref(layout);
  layout = NULL;

  status = cairo_status(cr);
  cairo_destroy(cr);
  cr = NULL;

  if (status)
  {
    fprintf(stderr, "An error occured whilst during drawing text: %s\n",
        cairo_status_to_string(status));
    return 1;
  }

  status = cairo_surface_write_to_png(surface, "captions.png");
  if (status)
  {
    fprintf(stderr, "An error occured whilst writing the png: %s\n",
        cairo_status_to_string(status));
    return 1;
  }

  cairo_surface_destroy(surface);

  return 0;
}


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