c печать большего количества страниц с каиром и чашками

#c #linux #graphics #cairo #cups

Вопрос:

Мне нужно, на языке C в среде Linux, печатать документы с изображением в качестве фона. Я нашел пример, в котором используется библиотека векторной графики Cairo для создания постскриптума, а затем отправляет его в CUPS для печати. Я изменил исходный код, чтобы интегрировать его с фоновым изображением (background-img.png) .

Текст, подлежащий печати, состоит из более чем одной страницы, я хотел бы знать, как я могу печатать на нескольких страницах, сохраняя одно и то же изображение в качестве фона и изменяя только текст на переднем плане ? Как изменить размер фонового изображения, чтобы оно соответствовало размеру страницы формата А4 ?

Вот код, используемый в качестве отправной точки :

 // compile with:
//   gcc -Wall -o cairo_print_png cairo_print_png.c `pkg-config --cflags --libs cairo` `cups-config --cflags --libs`

#include <stdio.h>
#include <cairo.h>
#include <cairo-ps.h>
#include <cups/cups.h>

// A4 width, height in points, from GhostView manual:
// http://www.gnu.org/software/gv/manual/html_node/Paper-Keywords-and-paper-size-in-points.html
#define WIDTH  595  
#define HEIGHT 842  

int main(int argc, char** argv) {
int widthPng, heightPng;

if (argc!= 2){
   fprintf (stderr, "usage: %s wordn", argv[0]);
   return 1;
}

// setup
char* tmpfilename = tempnam(NULL,NULL);
cairo_surface_t* surface = cairo_ps_surface_create(tmpfilename, 
                                                 WIDTH, 
                                                 HEIGHT);
  
cairo_t *context = cairo_create(surface);

// draw some text
cairo_select_font_face(context, 
                     "mono", 
                     CAIRO_FONT_SLANT_NORMAL, 
                     CAIRO_FONT_WEIGHT_NORMAL);
cairo_set_font_size(context, 30);
cairo_move_to(context, WIDTH/2, HEIGHT/2);
cairo_show_text(context, argv[1]); // the text we got as a parameter

// draw a dotted box
const double pattern[] = {15.0, 10.0};
cairo_set_dash(context, pattern, 2, 0);
cairo_set_line_width(context, 5);
cairo_rectangle(context, WIDTH*0.33, HEIGHT*0.33, WIDTH*0.5, WIDTH*0.5);
cairo_stroke(context);  

cairo_surface_t* surface_png = cairo_image_surface_create_from_png("background-img.png");
if (surface_png == NULL || cairo_surface_status (surface_png)) {
   printf("***** load error *****n");
}  
widthPng = cairo_image_surface_get_width(surface_png);
heightPng = cairo_image_surface_get_height(surface_png);

cairo_surface_set_device_scale (surface_png,
                           widthPng/WIDTH*1.33,
                            heightPng/HEIGHT*1.29);
cairo_set_operator(context, CAIRO_OPERATOR_DEST_OVER);
cairo_set_source_surface(context, surface_png, 0, 0);
cairo_paint(context);

/*** second page ***/
{
   cairo_t *cr;
   cr = cairo_create (surface);

   /* Duplicate the last frame onto another page. (This is just a
    * way to sneak cairo_copy_page into the test).
    */   
   cairo_show_page (cr);
   
   //draw text on second page
   cairo_select_font_face(cr, 
                     "mono", 
                     CAIRO_FONT_SLANT_NORMAL, 
                     CAIRO_FONT_WEIGHT_NORMAL);
   cairo_set_font_size(cr, 30);
   cairo_move_to(cr, WIDTH/2, HEIGHT/2);
   cairo_show_text(cr, "text over second page");       

   cairo_set_operator(cr, CAIRO_OPERATOR_DEST_OVER);
   cairo_set_source_surface(cr, surface_png, 0, 0);
   cairo_paint(cr);

   cairo_destroy (cr);
 }  

// finish up    
cairo_show_page(context);
cairo_destroy(context);
cairo_surface_flush(surface);
cairo_surface_destroy(surface);

cairo_surface_flush(surface_png);
cairo_surface_destroy(surface_png);

// print    
cupsPrintFile("Cups-PDF", tmpfilename, "cairo PS", 0, NULL);  
unlink(tmpfilename);

return 0;
}
 

Обновить :
Я добавил текст, вложенный в «вторую страницу». Я могу создать другую страницу, но я не могу изменить размер фонового изображения.
Как я могу изменить размер изображения в соответствии с размером А4?

Обновление Я использовал cairo_surface_set_device_scale для изменения размера изображения, а шрифт mono для использования шрифта фиксированной ширины

Обновление Проблема теперь в том, что код работает с cairo-1.15.12-4, в то время как при попытке компиляции с cairo-1.8.8-3.1 я получаю неопределенную ссылку на cairo_surface_set_device_scale’. Как я могу решить эту проблему? На данный момент я не могу обновлять библиотеки с помощью rpm, так как мне пришлось бы обновлять всю операционную систему. Могу ли я каким-то образом заменить функции cairo_surface_set_device_scale with, которые выполняют ту же задачу?

Обновление: В списках рассылки в Каире я нашел следующую функцию, которая выполняет эту работу :

 cairo_surface_t *scale_to_half(cairo_surface_t *s, int orig_width, int
orig_height,  double x_scale, double y_scale)
{
   cairo_surface_t *result = cairo_surface_create_similar(s,
        cairo_surface_get_content(s), orig_width*x_scale, orig_height*y_scale);
   cairo_t *cr = cairo_create(result);
   cairo_scale(cr, x_scale, y_scale);
   cairo_set_source_surface(cr, s, 0, 0);
   cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
   cairo_paint(cr);
   cairo_destroy(cr);
   return resu<
}
 

но качество очень низкое по сравнению с cairo_surface_set_device_scale.

Комментарии:

1. Если вы нашли ответ, напишите его как ответ на свой собственный вопрос, а не как «добавление к вопросу»!

2. Я еще не нашел решения, качество изображения с измененным размером очень низкое по сравнению с качеством, полученным с помощью cairo_surface_set_device_scale

3. О, моя вина, прости. Не дочитал до конца последнюю статью