]> mj.ucw.cz Git - paperjam.git/blob - gs.cc
Measure bboxes by Ghostscripting
[paperjam.git] / gs.cc
1 #include <cassert>
2 #include <cstdlib>
3 #include <cstdio>
4 #include <unistd.h>
5 #include <sys/wait.h>
6
7 #include "jam.h"
8
9 vector<BBox> gs_bboxes(const char *in)
10 {
11   int pipes[2];
12   if (pipe(pipes) < 0)
13     die("Cannot create pipe: %m");
14
15   pid_t pid = fork();
16   if (pid < 0)
17     die("Cannot fork: %m");
18
19   if (!pid)
20     {
21       close(pipes[0]);
22       dup2(pipes[1], 1);
23       dup2(pipes[1], 2);
24       close(pipes[1]);
25       execlp("gs", "gs", "-sDEVICE=bbox", "-dSAFER", "-dBATCH", "-dNOPAUSE", "-q", in, NULL);
26       die("Cannot execute gs: %m");
27     }
28
29   close(pipes[1]);
30   FILE *f = fdopen(pipes[0], "r");
31   if (!f)
32     die("fdopen failed: %m");
33
34   char line[1024];
35   vector<BBox> bboxes;
36   while (fgets(line, sizeof(line), f))
37     {
38       char *eol = strchr(line, '\n');
39       if (!eol)
40         die("Ghostscript produced too long lines");
41       *eol = 0;
42
43       if (!strncmp(line, "%%HiResBoundingBox: ", 20))
44         {
45           double x1, y1, x2, y2;
46           if (sscanf(line+20, "%lf%lf%lf%lf", &x1, &y1, &x2, &y2) != 4)
47             die("Cannot parse Ghostscript output: %s", line);
48           bboxes.push_back(BBox(x1, y1, x2, y2));
49         }
50       else if (line[0] != '%')
51         fprintf(stderr, "%s\n", line);
52     }
53   fclose(f);
54
55   int stat;
56   if (waitpid(pid, &stat, 0) < 0)
57     die("wait failed: %m");
58   if (!WIFEXITED(stat) || WEXITSTATUS(stat))
59     die("Ghostscript failed");
60
61   return bboxes;
62 }