1 /*
2  * pdfdrawbb.c
3  *
4  * draw the bounding box of each page
5  */
6 
7 #include <stdlib.h>
8 #include <stdio.h>
9 #include <unistd.h>
10 #include <string.h>
11 
12 #include <poppler.h>
13 #include <cairo.h>
14 #include <cairo-pdf.h>
15 
16 /*
17  * add suffix to a pdf filename
18  */
pdfaddsuffix(char * infile,char * suffix)19 char *pdfaddsuffix(char *infile, char *suffix)
20 {
21     char *basename;
22     char *outfile;
23     char *pos;
24 
25     basename = g_path_get_basename(infile);
26 
27     outfile = malloc(strlen(infile) + strlen(suffix) + 10);
28     strcpy(outfile, basename);
29     g_free(basename);
30 
31     pos = strrchr(outfile, '.');
32     if (pos != NULL && (!strcmp(pos, ".pdf") || !strcmp(pos, ".PDF")))
33         *pos = '\0';
34 
35     strcat(outfile, "-");
36     strcat(outfile, suffix);
37     strcat(outfile, ".pdf");
38     return outfile;
39 }
40 
41 /*
42  * main
43  */
main(int argc,char * argv[])44 int main(int argc, char *argv[])
45 {
46     int opt;
47     gboolean usage = FALSE;
48     char *infilename, *outfilename;
49 
50     GError *err = NULL;
51     GFile *infile;
52     PopplerDocument *doc;
53     PopplerPage *page;
54     int npages, n;
55     PopplerRectangle bb;
56     gboolean hg;
57 
58     gdouble width, height;
59     cairo_surface_t *surface;
60     cairo_t *cr;
61 
62     /* arguments */
63 
64     while ((opt = getopt(argc, argv, "h")) != -1)
65         switch (opt) {
66         case 'h':
67             usage = TRUE;
68             break;
69         }
70 
71     if (!usage && argc - 1 < optind) {
72         g_print("input file name missing\n");
73         usage = TRUE;
74     }
75     if (usage) {
76         g_print("usage:\n");
77         g_print("\tpdfdrawbb");
78         g_print("[-h] file.pdf\n");
79         g_print("\t\t-h\t\tthis help\n");
80         exit(EXIT_FAILURE);
81     }
82     infilename = argv[optind];
83     if (!infilename)
84         exit(EXIT_FAILURE);
85     outfilename = pdfaddsuffix(argv[optind], "bb");
86 
87     /* open file */
88 
89     infile = g_file_new_for_path(infilename);
90     if (infile == NULL)
91         exit(EXIT_FAILURE);
92 
93     doc = poppler_document_new_from_gfile(infile, NULL, NULL, &err);
94     if (doc == NULL) {
95         g_printerr("error opening pdf file: %s\n", err->message);
96         g_error_free(err);
97         exit(EXIT_FAILURE);
98     }
99 
100     /* pages */
101 
102     npages = poppler_document_get_n_pages(doc);
103     if (npages < 1) {
104         g_print("no page in document\n");
105         exit(EXIT_FAILURE);
106     }
107 
108     /* copy to destination */
109 
110     surface = cairo_pdf_surface_create(outfilename, 1.0, 1.0);
111 
112     g_print("infile: %s\n", infilename);
113     g_print("outfile: %s\n", outfilename);
114 
115     for (n = 0; n < npages; n++) {
116         g_print("page %d:\n", n);
117         page = poppler_document_get_page(doc, n);
118         poppler_page_get_size(page, &width, &height);
119         cairo_pdf_surface_set_size(surface, width, height);
120 
121         hg = poppler_page_get_bounding_box(page, &bb);
122         if (hg)
123             g_print("bounding box %g,%g - %g,%g", bb.x1, bb.y1, bb.x2, bb.y2);
124         g_print("\n");
125 
126         cr = cairo_create(surface);
127         poppler_page_render_for_printing(page, cr);
128         if (hg) {
129             cairo_set_source_rgb(cr, 0.6, 0.6, 1.0);
130             cairo_rectangle(cr, bb.x1, bb.y1, bb.x2 - bb.x1, bb.y2 - bb.y1);
131             cairo_stroke(cr);
132         }
133         cairo_destroy(cr);
134         cairo_surface_show_page(surface);
135 
136         g_object_unref(page);
137     }
138 
139     cairo_surface_destroy(surface);
140 
141     return EXIT_SUCCESS;
142 }
143