]> www.fi.muni.cz Git - evince.git/blob - pdf/xpdf/PBMOutputDev.cc
Merge with Xpdf 2.02 and make it build
[evince.git] / pdf / xpdf / PBMOutputDev.cc
1 //========================================================================
2 //
3 // PBMOutputDev.cc
4 //
5 // Copyright 1998-2003 Glyph & Cog, LLC
6 //
7 //========================================================================
8
9 #include <aconf.h>
10
11 #ifdef USE_GCC_PRAGMAS
12 #pragma implementation
13 #endif
14
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <stddef.h>
18 #include <string.h>
19 #include "gmem.h"
20 #include "GString.h"
21 #include "Object.h"
22 #include "Stream.h"
23 #include "GfxState.h"
24 #include "GfxFont.h"
25 #include "Error.h"
26 #include "PBMOutputDev.h"
27
28 //------------------------------------------------------------------------
29
30 PBMOutputDev *PBMOutputDev::makePBMOutputDev(char *displayName,
31                                              char *fileRootA) {
32   Display *displayA;
33   Pixmap pixmapA;
34   Window dummyWinA;
35   int screenA;
36   int invertA;
37   unsigned long black, white;
38   PBMOutputDev *out;
39
40   if (!(displayA = XOpenDisplay(displayName))) {
41     fprintf(stderr, "Couldn't open display '%s'\n", displayName);
42     exit(1);
43   }
44   screenA = DefaultScreen(displayA);
45
46   black = BlackPixel(displayA, screenA);
47   white = WhitePixel(displayA, screenA);
48   if ((black & 1) == (white & 1)) {
49     fprintf(stderr, "Weird black/white pixel colors\n");
50     XCloseDisplay(displayA);
51     return NULL;
52   } 
53   invertA = (white & 1) == 1 ? 0xff : 0x00;
54
55   dummyWinA = XCreateSimpleWindow(displayA, RootWindow(displayA, screenA),
56                                   0, 0, 1, 1, 0,
57                                   black, white);
58   pixmapA = XCreatePixmap(displayA, dummyWinA, 1, 1, 1);
59   out = new PBMOutputDev(displayA, screenA, pixmapA, dummyWinA,
60                          invertA, fileRootA);
61   return out;
62 }
63
64 void PBMOutputDev::killPBMOutputDev(PBMOutputDev *out) {
65   Display *displayA;
66   Pixmap pixmapA;
67   Window dummyWinA;
68
69   displayA = out->display;
70   pixmapA = out->pixmap;
71   dummyWinA = out->dummyWin;
72
73   delete out;
74
75   // these have to be done *after* the XOutputDev (parent of the
76   // PBMOutputDev) is deleted, since XOutputDev::~XOutputDev() needs
77   // them
78   XFreePixmap(displayA, pixmapA);
79   XDestroyWindow(displayA, dummyWinA);
80   XCloseDisplay(displayA);
81 }
82
83 PBMOutputDev::PBMOutputDev(Display *displayA, int screenA,
84                            Pixmap pixmapA, Window dummyWinA,
85                            int invertA, char *fileRootA):
86   XOutputDev(displayA, screenA,
87              DefaultVisual(displayA, screenA),
88              DefaultColormap(displayA, screenA),
89              gFalse,
90              WhitePixel(displayA, DefaultScreen(displayA)),
91              gFalse, 1, 1)
92 {
93   display = displayA;
94   screen = screenA;
95   pixmap = pixmapA;
96   dummyWin = dummyWinA;
97   invert = invertA;
98   fileRoot = fileRootA;
99   fileName = (char *)gmalloc(strlen(fileRoot) + 20);
100 }
101
102 PBMOutputDev::~PBMOutputDev() {
103   gfree(fileName);
104 }
105
106 void PBMOutputDev::startPage(int pageNum, GfxState *state) {
107   curPage = pageNum;
108   width = (int)(state->getPageWidth() + 0.5);
109   height = (int)(state->getPageHeight() + 0.5);
110   XFreePixmap(display, pixmap);
111   pixmap = XCreatePixmap(display, dummyWin, width, height, 1);
112   setPixmap(pixmap, width, height);
113   XOutputDev::startPage(pageNum, state);
114 }
115
116 void PBMOutputDev::endPage() {
117   XImage *image;
118   FILE *f;
119   int p;
120   int x, y, i;
121
122   image = XCreateImage(display, DefaultVisual(display, screen),
123                        1, ZPixmap, 0, NULL, width, height, 8, 0);
124   image->data = (char *)gmalloc(height * image->bytes_per_line);
125   XGetSubImage(display, pixmap, 0, 0, width, height, 1, ZPixmap,
126                image, 0, 0);
127
128   sprintf(fileName, "%s-%06d.pbm", fileRoot, curPage);
129   if (!(f = fopen(fileName, "wb"))) {
130     fprintf(stderr, "Couldn't open output file '%s'\n", fileName);
131     goto err;
132   }
133   fprintf(f, "P4\n");
134   fprintf(f, "%d %d\n", width, height);
135
136   for (y = 0; y < height; ++y) {
137     for (x = 0; x+8 <= width; x += 8) {
138       p = 0;
139       for (i = 0; i < 8; ++i)
140         p = (p << 1) + (XGetPixel(image, x+i, y) & 1);
141       p ^= invert;
142       fputc((char)p, f);
143     }
144     if (width & 7) {
145       p = 0;
146       for (i = 0; i < (width & 7); ++i)
147         p = (p << 1) + (XGetPixel(image, x+i, y) & 1);
148       p <<= 8 - (width & 7);
149       p ^= invert;
150       fputc((char)p, f);
151     }
152   }
153
154   fclose(f);
155
156  err:
157   gfree(image->data);
158   image->data = NULL;
159   XDestroyImage(image);
160
161   XOutputDev::endPage();
162 }