Re: Re: Printing with gtk+, cairo and pango - need to iterate glyphsand problems with pango attributes



I tried the code below on debian GNU/Linux unstable as well on win32. The output
was a bit different but didn't work on both operating systems.


#include <gtk/gtk.h>

void
begin_print(GtkPrintOperation *operation, GtkPrintContext *context)
{
  gtk_print_operation_set_n_pages(operation, 1);
  gtk_print_operation_set_use_full_page(operation, FALSE);
} 

void
draw_page(GtkPrintOperation *operation, GtkPrintContext *context, gint page_nr)
{
  PangoLayout *layout, *test_attribute, *test_iterateing;
  PangoFontDescription *desc;
  PangoAttrList *attr_list;
  PangoAttribute *attribute;
  PangoLayoutRun *run;
  cairo_t *cr;
  GSList *list0, *list1;
  PangoRectangle logical_rect;
  double x_off, y_off;
  int width, height;
  guint i;

  cr = gtk_print_context_get_cairo_context(context);
  layout = gtk_print_context_create_pango_layout(context);

  desc = pango_font_description_from_string("Sans 12\0");

  /* test attribute */
  test_attribute = pango_layout_copy(layout);
  pango_layout_set_text(test_attribute, "Title\nsecondary text\0", -1);
  pango_layout_set_font_description(test_attribute, desc);

  attr_list = pango_attr_list_new();

  attribute = pango_attr_size_new(14);
  attribute->start_index = 0;
  attribute->end_index = 6;
  pango_attr_list_insert(attr_list, attribute);

  attribute = pango_attr_size_new(7);
  attribute->start_index = 6;
  attribute->end_index = 15;
  pango_attr_list_insert(attr_list, attribute);

  pango_layout_set_attributes(test_attribute, attr_list);

  cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
  cairo_move_to(cr, 0.0, 0.0);
  pango_cairo_show_layout(cr, test_attribute);


  /* test iterateing */
  test_iterateing = pango_layout_copy(layout);
  pango_layout_set_text(test_attribute, "0123456789\0", -1);
  pango_layout_set_font_description(test_iterateing, desc);

  list0 = pango_layout_get_lines(layout);

  pango_layout_get_size(test_attribute, &width, &height);
  height *= PANGO_SCALE;
  y_off = (double) height;
    
  while(list0 != NULL){
    list1 = ((PangoLayoutLine *) (list0->data))->runs;
    x_off = 0.0;

    while(list1 != NULL){
      run = (PangoLayoutRun *) list1->data;
      
      pango_glyph_string_extents(run->glyphs, run->item->analysis.font,
				 NULL, &logical_rect);

      cairo_move_to(cr, x_off, y_off);
      pango_cairo_show_glyph_string(cr, run->item->analysis.font, run->glyphs);
      
      x_off += (double)(logical_rect.width * PANGO_SCALE);
      list1 = list1->next;
    }

    y_off += height;
    list0 = list0->next;
  }

  g_object_unref(layout);
  g_object_unref(test_attribute);
  g_object_unref(test_iterateing);

  pango_font_description_free(desc);
} 

void
end_print(GtkPrintOperation *operation, GtkPrintContext *context)
{
}

gboolean
delete_event(GtkWindow *window, gpointer data)
{
  gtk_main_quit();

  return(FALSE);
}

void
button_clicked(GtkButton *button, gpointer data)
{
  GtkWindow *window;
  GtkPrintOperation *operation;
  GError *error;

  window = (GtkWindow *) gtk_widget_get_toplevel((GtkWidget *) button);
  
  operation = gtk_print_operation_new();
  error = NULL;
 
  g_signal_connect((GObject *) operation, "begin-print\0",
		   G_CALLBACK (begin_print), window);
  g_signal_connect((GObject *) operation, "draw-page\0",
		   G_CALLBACK (draw_page), window);
  g_signal_connect((GObject *) operation, "end-print\0",
		   G_CALLBACK (end_print), window);

  gtk_print_operation_run(operation,
			  GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG,
			  window,
			  &error);

  if(error != NULL){
    GtkWidget *dialog;
   
    dialog = gtk_message_dialog_new ((GtkWindow *) window, 0,
				     GTK_MESSAGE_ERROR,
				     GTK_BUTTONS_OK,
				     "An error occured while trying to print:\0");
    gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),
error->message);
   
    gtk_dialog_run(GTK_DIALOG (dialog));
    gtk_widget_destroy(dialog);
   
    g_error_free(error);
  }

  g_object_unref(operation);
}


int
main(int argc, char **argv)
{
  GtkWindow *window;
  GtkButton *button;
  
  gtk_init(&argc, &argv);

  window = (GtkWindow *) gtk_window_new(GTK_WINDOW_TOPLEVEL);
  g_signal_connect((GObject *) window, "delete-event\0",
		   G_CALLBACK(delete_event), NULL);

  button = (GtkButton *) gtk_button_new_with_label("print\0");
  gtk_container_add((GtkContainer *) window, (GtkWidget *) button);
  g_signal_connect((GObject *) button, "clicked\0",
		   G_CALLBACK(button_clicked), NULL);

  gtk_widget_show_all((GtkWidget *) window);

  gtk_main();

  return(0);
}





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