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