filters

PBMOutputDev.cc

00001 //========================================================================
00002 //
00003 // PBMOutputDev.cc
00004 //
00005 // Copyright 1998-2002 Glyph & Cog, LLC
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   // these have to be done *after* the XOutputDev (parent of the
00076   // PBMOutputDev) is deleted, since XOutputDev::~XOutputDev() needs
00077   // them
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 }
KDE Home | KDE Accessibility Home | Description of Access Keys