Перейти к содержимому

gtk+ Печать (часть 2)

29.07.2010

В  предыдущей части я рассказывал как средствами gtk+ и gtk+ printing api распечатать изображение. В данной статье мы продолжим работу с печатью, но здесь в отличие от 1 статьи у нас будет немножко другое задание. Допустим нам нужно распечатать наше изображение в высоком разрешении и с хорошим качеством. Так же допустим что изображение не помещается полностью на A4. В этом посте я расскажу как грамотно разрезать изображение и вывести постранично на печать.

Здесь у нас присутствует та же функция что и в первой части – print_pixbuf:

void   print_pixbuf(GtkWidget* widget, MainWin* mw)
{
    GtkPrintOperation *op;
    GtkPrintOperationResult res;
    GtkPrintSettings *settings;

    op = gtk_print_operation_new ();

    gtk_print_operation_set_n_pages (op, 1);
    gtk_print_operation_set_unit (op, GTK_UNIT_MM);
    g_signal_connect (op, "draw_page", G_CALLBACK (draw_page), mw);
    res = gtk_print_operation_run (op, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG, mw, NULL);
}

Данная функция отвечает за установку свойств печати и вызова диалогового окна печати:

Далее у нас будут еще две функции:

begin-print: в данном случае используется для установки количества страниц. Мы проверяем если изображение меньше чем А4, то мы распечатываем его так как оно есть, если больше, то мы посчитаем, на сколько страниц нужно его разбить

#include <math.h>

static gboolean is_on = FALSE;

static void begin_print (GtkPrintOperation *oper, GtkPrintContext *context, gpointer user_data)
{
   GdkPixbuf* pixbuf =   gdk_pixbuf_new_from_file(file_path, NULL);
   cairo_t *cr = gtk_print_context_get_cairo_context (context);

   int image_width = gdk_pixbuf_get_width(pixbuf);
   int image_height = gdk_pixbuf_get_height(pixbuf);

   gint page_width =  (gint)gtk_print_context_get_width(context);
   gint page_height = (gint)gtk_print_context_get_height(context);

   int n_xpages = ceil((double)image_width / page_width);
   int n_ypages = ceil((double)image_height / page_height);
   int n_all_pages = n_xpages * n_ypages;
  
  is_on = FALSE;

 if (image_width < page_width && image_height < page_height)
  {
     gtk_print_operation_set_n_pages(oper, 1);
     gdk_cairo_set_source_pixbuf(cr, pixbuf, 0, 0);

     is_on = FALSE;
 }
else
{
     is_on = TRUE;
     gtk_print_operation_set_n_pages(oper, n_all_pages);
}

 g_object_unref(pixbuf);
}

И вторая функция draw_page, отвечающая непосредственно за вывод на печать и отрисовку страниц:

static void draw_page (GtkPrintOperation * oper, GtkPrintContext * context,
            			  gint nr, gpointer user_data)
{
  cairo_t *cr = gtk_print_context_get_cairo_context (context);

  if (is_on == FALSE)
  {
     cairo_paint(cr);
  }
  else
  {
    int i = 0;
    int j = 0;
    int k = 0;

    GdkPixbuf* pixbuf = gdk_pixbuf_new_from_file(file_path, NULL);

    gint page_width =  (gint)gtk_print_context_get_width(context);
    gint page_height = (gint)gtk_print_context_get_height(context);
    int image_width = gdk_pixbuf_get_width(pixbuf);

    int count_w = 0;

    while (image_width > page_width)
    {
       image_width = image_width - page_width;
       count_w++;
    }

    if (image_width != 0)
	count_w++;

    for (i; i < nr + 1; i++)
    {
        gdk_cairo_set_source_pixbuf(cr, pixbuf, j, k);
	j -= page_width + 40;

	if (i == count_w - 1)
	{
	  j = 0;
          k -= page_height;
        }
    }
  }
}

Вот в принципе и все, можно печатать в высоком качестве. Если у вас появились какие-либо вопросы или пожелания оставляйте в комментариях.

From → coding, gtk+

Добавить комментарий

Добавить комментарий

Fill in your details below or click an icon to log in:

Gravatar
Логотип WordPress.com

You are commenting using your WordPress.com account. Log Out / Изменить )

Фотография Twitter

You are commenting using your Twitter account. Log Out / Изменить )

Фотография Facebook

You are commenting using your Facebook account. Log Out / Изменить )

Connecting to %s

Follow

Get every new post delivered to your Inbox.