首页 > 解决方案 > c 用 cairo 和 cups 打印更多页面

问题描述

我需要在linux环境下的C中,以图像为背景打印文档。我找到了一个使用 Cairo 矢量图形库编写 PostScript 的示例,然后将其发送到 CUPS 进行打印。我修改了初始源代码以将其与背景图像 (background-img.png) 集成。

要打印的文本不止一页,我想知道如何在多个页面上打印,保持相同的图像作为背景并只更改前景文本?如何调整背景图像的大小以匹配 A4 页面的大小?

这是用作起点的代码:

// 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 word\n", 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;
}

更新:我添加了“第二页”中的文字。我可以创建另一个页面,但我无法调整背景图像的大小。如何调整图像大小以适合 A4 尺寸?

更新 我使用 cairo_surface_set_device_scale 来调整图像大小,使用单声道字体使用固定宽度字体

更新 现在的问题是代码可以与 cairo-1.15.12-4 一起使用,而如果我尝试使用 cairo-1.8.8-3.1 进行编译,我会得到对 cairo_surface_set_device_scale' 的未定义引用。我能解决什么问题?目前我无法使用 rpm 更新库,因为我必须更新整个操作系统。我可以以某种方式替换cairo_surface_set_device_scale执行相同任务的函数吗?

更新: 在开罗邮件列表中,我找到了以下功能:

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 result;
}

但与 cairo_surface_set_device_scale 相比,质量非常低。

标签: clinuxgraphicscairocups

解决方案


推荐阅读