00001
00002
00003
00004
00005
00006
00007
00008
00009 #include <aconf.h>
00010
00011 #ifdef USE_GCC_PRAGMAS
00012 #pragma implementation
00013 #endif
00014
00015 #include <stdio.h>
00016 #include <stdlib.h>
00017 #include <stddef.h>
00018 #include <string.h>
00019 #include "gmem.h"
00020 #include "GString.h"
00021 #include "Object.h"
00022 #include "Stream.h"
00023 #include "GfxState.h"
00024 #include "GfxFont.h"
00025 #include "Error.h"
00026 #include "PBMOutputDev.h"
00027
00028
00029
00030 PBMOutputDev *PBMOutputDev::makePBMOutputDev(char *displayName,
00031 char *fileRootA) {
00032 Display *displayA;
00033 Pixmap pixmapA;
00034 Window dummyWinA;
00035 int screenA;
00036 int invertA;
00037 unsigned long black, white;
00038 PBMOutputDev *out;
00039
00040 if (!(displayA = XOpenDisplay(displayName))) {
00041 fprintf(stderr, "Couldn't open display '%s'\n", displayName);
00042 exit(1);
00043 }
00044 screenA = DefaultScreen(displayA);
00045
00046 black = BlackPixel(displayA, screenA);
00047 white = WhitePixel(displayA, screenA);
00048 if ((black & 1) == (white & 1)) {
00049 fprintf(stderr, "Weird black/white pixel colors\n");
00050 XCloseDisplay(displayA);
00051 return NULL;
00052 }
00053 invertA = (white & 1) == 1 ? 0xff : 0x00;
00054
00055 dummyWinA = XCreateSimpleWindow(displayA, RootWindow(displayA, screenA),
00056 0, 0, 1, 1, 0,
00057 black, white);
00058 pixmapA = XCreatePixmap(displayA, dummyWinA, 1, 1, 1);
00059 out = new PBMOutputDev(displayA, screenA, pixmapA, dummyWinA,
00060 invertA, fileRootA);
00061 return out;
00062 }
00063
00064 void PBMOutputDev::killPBMOutputDev(PBMOutputDev *out) {
00065 Display *displayA;
00066 Pixmap pixmapA;
00067 Window dummyWinA;
00068
00069 displayA = out->display;
00070 pixmapA = out->pixmap;
00071 dummyWinA = out->dummyWin;
00072
00073 delete out;
00074
00075
00076
00077
00078 XFreePixmap(displayA, pixmapA);
00079 XDestroyWindow(displayA, dummyWinA);
00080 XCloseDisplay(displayA);
00081 }
00082
00083 PBMOutputDev::PBMOutputDev(Display *displayA, int screenA,
00084 Pixmap pixmapA, Window dummyWinA,
00085 int invertA, char *fileRootA):
00086 XOutputDev(displayA, screenA,
00087 DefaultVisual(displayA, screenA),
00088 DefaultColormap(displayA, screenA),
00089 gFalse,
00090 WhitePixel(displayA, DefaultScreen(displayA)),
00091 gFalse, 1, 1)
00092 {
00093 display = displayA;
00094 screen = screenA;
00095 pixmap = pixmapA;
00096 dummyWin = dummyWinA;
00097 invert = invertA;
00098 fileRoot = fileRootA;
00099 fileName = (char *)gmalloc(strlen(fileRoot) + 20);
00100 }
00101
00102 PBMOutputDev::~PBMOutputDev() {
00103 gfree(fileName);
00104 }
00105
00106 void PBMOutputDev::startPage(int pageNum, GfxState *state) {
00107 curPage = pageNum;
00108 width = (int)(state->getPageWidth() + 0.5);
00109 height = (int)(state->getPageHeight() + 0.5);
00110 XFreePixmap(display, pixmap);
00111 pixmap = XCreatePixmap(display, dummyWin, width, height, 1);
00112 setPixmap(pixmap, width, height);
00113 XOutputDev::startPage(pageNum, state);
00114 }
00115
00116 void PBMOutputDev::endPage() {
00117 XImage *image;
00118 FILE *f;
00119 int p;
00120 int x, y, i;
00121
00122 image = XCreateImage(display, DefaultVisual(display, screen),
00123 1, ZPixmap, 0, NULL, width, height, 8, 0);
00124 image->data = (char *)gmalloc(height * image->bytes_per_line);
00125 XGetSubImage(display, pixmap, 0, 0, width, height, 1, ZPixmap,
00126 image, 0, 0);
00127
00128 sprintf(fileName, "%s-%06d.pbm", fileRoot, curPage);
00129 if (!(f = fopen(fileName, "wb"))) {
00130 fprintf(stderr, "Couldn't open output file '%s'\n", fileName);
00131 goto err;
00132 }
00133 fprintf(f, "P4\n");
00134 fprintf(f, "%d %d\n", width, height);
00135
00136 for (y = 0; y < height; ++y) {
00137 for (x = 0; x+8 <= width; x += 8) {
00138 p = 0;
00139 for (i = 0; i < 8; ++i)
00140 p = (p << 1) + (XGetPixel(image, x+i, y) & 1);
00141 p ^= invert;
00142 fputc((char)p, f);
00143 }
00144 if (width & 7) {
00145 p = 0;
00146 for (i = 0; i < (width & 7); ++i)
00147 p = (p << 1) + (XGetPixel(image, x+i, y) & 1);
00148 p <<= 8 - (width & 7);
00149 p ^= invert;
00150 fputc((char)p, f);
00151 }
00152 }
00153
00154 fclose(f);
00155
00156 err:
00157 gfree(image->data);
00158 image->data = NULL;
00159 XDestroyImage(image);
00160
00161 XOutputDev::endPage();
00162 }