home *** CD-ROM | disk | FTP | other *** search
- /*
- * xvps.c - Postscript dialog box, file output functions
- *
- * callable functions:
- *
- * CreatePSD(geom) - creates the psW window. Doesn't map it.
- * PSDialog() - maps psW
- * PSCheckEvent(event) - called by event handler
- * PSSaveParams(str,int) - tells PSDialog what to do when 'Ok' clicked
- * PSResize() - called whenever ePic changes size
- */
-
- /*
- * Copyright 1989, 1990, 1991, 1992 by John Bradley and
- * The University of Pennsylvania
- *
- * Permission to use, copy, and distribute for non-commercial purposes,
- * is hereby granted without fee, providing that the above copyright
- * notice appear in all copies and that both the copyright notice and this
- * permission notice appear in supporting documentation.
- *
- * The software may be modified for your own purposes, but modified versions
- * may not be distributed.
- *
- * This software is provided "as is" without any expressed or implied warranty.
- *
- * The author may be contacted via:
- * US Mail: John Bradley
- * GRASP Lab, Room 301C
- * 3401 Walnut St.
- * Philadelphia, PA 19104
- *
- * Phone: (215) 898-8813
- * EMail: bradley@cis.upenn.edu
- */
-
-
- #include "xv.h"
-
- #define PSWIDE 431
- #define PSHIGH 350
- #define PMAX 200 /* size of square that a 'page' has to fit into */
-
- #define PS_NBUTTS 6
- #define PS_BOK 0
- #define PS_BCANC 1
- #define PS_BCENT 2
- #define PS_BMAX 3
- #define PS_BPOSX 4
- #define PS_BPOSY 5
-
- /* paperRB indicies */
- #define PSZ_NORM 0
- #define PSZ_A4 1
- #define PSZ_B5 2
- #define PSZ_LEGAL 3
- #define PSZ_BSIZE 4
- #define PSZ_4BY5 5
- #define PSZ_35MM 6
-
- /* orientRB indicies */
- #define ORNT_PORT 0
- #define ORNT_LAND 1
-
- #define BUTTH 24
-
- #define IN2CM 2.54
-
- #define PIX2INCH 72.0 /* # of pixels per inch, at 100% scaling */
-
- #ifdef __STDC__
- static void drawPSD(int, int, int, int);
- static void drawPosStr();
- static void drawSizeStr();
- static void drawResStr();
- static void drawPage();
- static void clickPSD(int, int);
- static void clickPage(int, int);
- static void doCmd(int);
- static void changedScale(void);
- static void setScale(void);
- static void changedPaper(void);
- static void setPaper(void);
- static void drawIRect(int);
- static void centerImage(void);
- static void maxImage(void);
- static void moveImage(double, double);
- static void writePS(void);
- static int rle_encode(byte *, byte *, int);
- static void psColorImage();
- static void psColorMap(FILE *fp, int, int, byte *, byte *, byte *);
- static void psRleCmapImage();
- static void epsPreview();
- static int writeBWStip(FILE *, byte *, char *, int, int);
- #else
- static void drawPSD(), drawPosStr(), drawSizeStr(), drawResStr();
- static void drawPage(), clickPSD(), clickPage(), doCmd(), changedScale();
- static void setScale(), changedPaper(), setPaper(), drawIRect();
- static void centerImage(), maxImage(), moveImage(), writePS();
- static void psColorImage(), psColorMap(), epsPreview();
- static void psRleCmapImage();
- static int rle_encode(), writeBWStip();
- #endif
-
-
- /* local variables */
- static Window pageF;
- static DIAL xsDial, ysDial;
- static RBUTT *orientRB, *paperRB;
- static CBUTT lockCB;
- static BUTT psbut[PS_NBUTTS];
- static double sz_inx, sz_iny; /* image size, in inches */
- static double pos_inx, pos_iny; /* top-left offset of image, in inches */
- static int dpix, dpiy; /* # of image pixels per inch */
- static int tracking=0; /* used in changedScale */
- static int posxType, posyType;
-
- /* sizes of pages in inches */
- static double paperSize[7][2] = { { 8.500, 11.000}, /* US NORMAL */
- { 8.267, 11.811}, /* A4 */
- { 7.283, 10.630}, /* B5 */
- { 8.500, 14.000}, /* US LEGAL */
- {11.000, 17.000}, /* B-size */
- { 3.875, 4.875}, /* 4 by 5 */
- { 0.945, 1.417}}; /* 35mm (24x36) */
-
- /* size of l+r margin and t+b margin. image is centered */
- static double margins[7][2] = { { 1.000, 1.000}, /* US NORMAL */
- { 1.000, 1.000}, /* A4 */
- { 1.000, 1.000}, /* B5 */
- { 1.000, 1.000}, /* US LEGAL */
- { 1.000, 1.000}, /* B-size */
- { 0.275, 0.275}, /* 4 by 5 */
- { 0.078, 0.078}}; /* 35mm (24x36) */
-
-
- static double psizex, psizey; /* current paper size, in inches */
- static double in2pix; /* inch to pixels in 'pageF' */
- static XRectangle pageRect; /* bounding rect of page, in screen coords */
-
- static char *filename; /* filename to save to */
- static int colorType; /* value of 'Colors' rbutt in dir box */
- static int firsttime=1; /* first time PSDialog being opened ? */
-
-
- /***************************************************/
- void CreatePSD(geom)
- char *geom;
- {
- psW = CreateWindow("xv postscript", geom, PSWIDE, PSHIGH, infofg, infobg);
- if (!psW) FatalError("can't create postscript window!");
- StoreDeleteWindowProp(psW);
-
- pageF = XCreateSimpleWindow(theDisp, psW, 20,30, PMAX+1,PMAX+1,
- 1,infofg,infobg);
- if (!pageF) FatalError("couldn't create frame windows");
-
- XSetWindowBackgroundPixmap(theDisp, pageF, grayTile);
-
- XSelectInput(theDisp, pageF, ExposureMask | ButtonPressMask);
- XSelectInput(theDisp, psW, ExposureMask | ButtonPressMask | KeyPressMask);
-
- CBCreate(&encapsCB, psW, 240, 7, "preview", infofg, infobg);
- CBCreate(&pscompCB, psW, 331, 7, "compress", infofg, infobg);
-
- DCreate(&xsDial, psW, 240, 30, 80, 100, 10, 800, 100, 5,
- infofg, infobg, "Width", "%");
- DCreate(&ysDial, psW, 331, 30, 80, 100, 10, 800, 100, 5,
- infofg, infobg, "Height", "%");
- xsDial.drawobj = changedScale;
- ysDial.drawobj = changedScale;
-
- CBCreate(&lockCB, psW, 319, 136, "", infofg, infobg);
- lockCB.val = 1;
-
- orientRB = RBCreate(NULL, psW, 36, 240+18, "Portrait", infofg, infobg);
- RBCreate(orientRB, psW, 36+80, 240+18, "Landscape", infofg, infobg);
-
- paperRB = RBCreate(NULL, psW,36, 240+18+36, "8.5\"x11\"", infofg, infobg);
- RBCreate(paperRB, psW, 36+80, 240+18+36, "A4", infofg, infobg);
- RBCreate(paperRB, psW, 36+154, 240+18+36, "B5", infofg, infobg);
- RBCreate(paperRB, psW, 36, 240+36+36, "8.5\"x14\"", infofg, infobg);
- RBCreate(paperRB, psW, 36+80, 240+36+36, "11\"x17\"", infofg, infobg);
- RBCreate(paperRB, psW, 36, 240+54+36, "4\"x5\"", infofg, infobg);
- RBCreate(paperRB, psW, 36+80, 240+54+36, "35mm slide", infofg, infobg);
-
- BTCreate(&psbut[PS_BOK], psW, PSWIDE-160, PSHIGH-10-BUTTH, 60, BUTTH,
- "Ok", infofg, infobg);
-
- BTCreate(&psbut[PS_BCANC], psW, PSWIDE-80, PSHIGH-10-BUTTH, 60, BUTTH,
- "Cancel", infofg, infobg);
-
- BTCreate(&psbut[PS_BCENT], psW, 240, 153, 88, BUTTH,
- "Center", infofg, infobg);
-
- BTCreate(&psbut[PS_BMAX], psW, 240+88+5, 153, 87, BUTTH,
- "Maxpect", infofg, infobg);
-
- BTCreate(&psbut[PS_BPOSX], psW, 256-14, 190+13-8, 8,8, "", infofg, infobg);
- BTCreate(&psbut[PS_BPOSY], psW, 256-14, 190+26-8, 8,8, "", infofg, infobg);
-
- posxType = posyType = 0;
- pos_inx = 1.0; pos_iny = 1.0; /* temporary bootstrapping... */
- setPaper();
- setScale();
-
- XMapSubwindows(theDisp, psW);
- }
-
-
- /***************************************************/
- void PSDialog(vis)
- int vis;
- {
- if (vis) {
- setScale();
- if (firsttime) centerImage();
- firsttime = 0;
- CenterMapWindow(psW, psbut[PS_BOK].x + psbut[PS_BOK].w/2,
- psbut[PS_BOK].y + psbut[PS_BOK].h/2, PSWIDE, PSHIGH);
- }
- else XUnmapWindow(theDisp, psW);
- psUp = vis;
- }
-
-
- /***************************************************/
- int PSCheckEvent(xev)
- XEvent *xev;
- {
- /* check event to see if it's for one of our subwindows. If it is,
- deal accordingly, and return '1'. Otherwise, return '0' */
-
- int rv;
- rv = 1;
-
- if (!psUp) return 0;
-
- if (xev->type == Expose) {
- int x,y,w,h;
- XExposeEvent *e = (XExposeEvent *) xev;
- x = e->x; y = e->y; w = e->width; h = e->height;
-
- /* throw away excess expose events for 'dumb' windows */
- if (e->count > 0 &&
- (e->window == xsDial.win || e->window == ysDial.win ||
- e->window == pageF)) {}
-
- else if (e->window == psW) drawPSD(x, y, w, h);
- else if (e->window == xsDial.win) DRedraw(&xsDial);
- else if (e->window == ysDial.win) DRedraw(&ysDial);
- else if (e->window == pageF) drawPage();
- else rv = 0;
- }
-
- else if (xev->type == ButtonPress) {
- XButtonEvent *e = (XButtonEvent *) xev;
- int x,y;
- x = e->x; y = e->y;
-
- if (e->button == Button1) {
- if (e->window == psW) clickPSD(x,y);
- else if (e->window == pageF) clickPage(x,y);
-
- else if (e->window == xsDial.win || e->window == ysDial.win) {
- if (e->window == xsDial.win) {
- tracking = 1;
- DTrack(&xsDial, x,y);
- tracking = 0;
- }
-
- else if (e->window == ysDial.win) {
- tracking = 2;
- DTrack(&ysDial, x,y);
- tracking = 0;
- }
- }
- else rv = 0;
- } /* button1 */
- else rv = 0;
- } /* button press */
-
-
- else if (xev->type == KeyPress) {
- XKeyEvent *e = (XKeyEvent *) xev;
- char buf[128]; KeySym ks;
- int stlen;
-
- stlen = XLookupString(e,buf,128,&ks,(XComposeStatus *) NULL);
- buf[stlen] = '\0';
-
- if (e->window == psW) {
- double dx, dy;
- int movekey;
-
- movekey = 0; dx = dy = 0.0;
-
- if (ks==XK_Left || ks==XK_KP_4) { dx = -0.001; movekey = 1; }
- else if (ks==XK_Right || ks==XK_KP_6) { dx = 0.001; movekey = 1; }
- else if (ks==XK_Up || ks==XK_KP_8) { dy = -0.001; movekey = 1; }
- else if (ks==XK_Down || ks==XK_KP_2) { dy = 0.001; movekey = 1; }
-
- else if (stlen) {
- if (buf[0] == '\r' || buf[0] == '\n') { /* enter */
- FakeButtonPress(&psbut[PS_BOK]);
- }
- else if (buf[0] == '\033') { /* ESC */
- FakeButtonPress(&psbut[PS_BCANC]);
- }
- }
-
- if (movekey) {
- if (e->state & ShiftMask) { dx *= 10.0; dy *= 10.0; }
- moveImage(pos_inx+dx, pos_iny+dy);
- }
- }
- else rv = 0;
- }
- else rv = 0;
-
- if (rv==0 && (xev->type == ButtonPress || xev->type == KeyPress)) {
- XBell(theDisp, 50);
- rv = 1; /* eat it */
- }
-
- return rv;
- }
-
-
- /***************************************************/
- void PSSaveParams(fname, col)
- char *fname;
- int col;
- {
- filename = fname;
- colorType = col;
- }
-
-
- /***************************************************/
- void PSResize()
- {
- if (!savenormCB.val) changedScale();
- }
-
-
-
-
-
-
- /***************************************************/
- static void drawPSD(x,y,w,h)
- int x,y,w,h;
- {
- char *title = "Save PostScript File...";
- int i,cx;
- XRectangle xr;
-
- xr.x = x; xr.y = y; xr.width = w; xr.height = h;
- XSetClipRectangles(theDisp, theGC, 0,0, &xr, 1, Unsorted);
-
- XSetForeground(theDisp, theGC, infofg);
- XSetBackground(theDisp, theGC, infobg);
-
- RBRedraw(orientRB,-1);
- RBRedraw(paperRB,-1);
-
- for (i=0; i<PS_NBUTTS; i++) BTRedraw(&psbut[i]);
-
- CBRedraw(&encapsCB);
- if (colorType != F_BWDITHER) CBRedraw(&pscompCB);
- CBRedraw(&lockCB);
-
- ULineString(psW, "Orientation", orientRB->x-16, orientRB->y-3-DESCENT);
- ULineString(psW, "Paper Size", paperRB->x-16, paperRB->y-3-DESCENT);
-
- /* draw 'lock' arrows */
- cx = 240 + 40; /* center of xsDial */
- XDrawLine(theDisp, psW, theGC, lockCB.x, lockCB.y+5, cx+2, lockCB.y+5);
- XDrawLine(theDisp, psW, theGC, cx+2, lockCB.y+5, cx+2, lockCB.y-2);
-
- XDrawLine(theDisp, psW, theGC, lockCB.x, lockCB.y+9, cx-2, lockCB.y+9);
- XDrawLine(theDisp, psW, theGC, cx-2, lockCB.y+9, cx-2, lockCB.y-2);
-
- XDrawLine(theDisp, psW, theGC, cx-2-3, lockCB.y-2+3, cx, lockCB.y-2-2);
- XDrawLine(theDisp, psW, theGC, cx+2+3, lockCB.y-2+3, cx, lockCB.y-2-2);
-
- cx = 330 + 40; /* center of ysDial */
- XDrawLine(theDisp, psW, theGC, lockCB.x+15, lockCB.y+5, cx-2, lockCB.y+5);
- XDrawLine(theDisp, psW, theGC, cx-2, lockCB.y+5, cx-2, lockCB.y-2);
-
- XDrawLine(theDisp, psW, theGC, lockCB.x+15, lockCB.y+9, cx+2, lockCB.y+9);
- XDrawLine(theDisp, psW, theGC, cx+2, lockCB.y+9, cx+2, lockCB.y-2);
-
- XDrawLine(theDisp, psW, theGC, cx-2-3, lockCB.y-2+3, cx, lockCB.y-2-2);
- XDrawLine(theDisp, psW, theGC, cx+2+3, lockCB.y-2+3, cx, lockCB.y-2-2);
-
- XDrawString(theDisp, psW, theGC, 10, 19, title, strlen(title));
-
- ULineString(psW, "Position:", 240, 190);
- drawPosStr();
- ULineString(psW, "Size:", 240, 190+45);
- drawSizeStr();
- ULineString(psW, "Resolution:", 240, 190+90);
- drawResStr();
-
-
- XSetClipMask(theDisp, theGC, None);
- }
-
-
- /***************************************************/
- static void drawPosStr()
- {
- int x,y;
- double cmx, cmy, inx, iny;
- char str[64], str1[64], *xst, *yst;
-
- x = 256; y = 190 + 13;
-
- switch (posxType) {
- case 0: xst = "Left: "; inx = pos_inx; break;
- case 1: xst = "Right:"; inx = psizex - (pos_inx + sz_inx); break;
- case 2: xst = "X Mid:"; inx = pos_inx + sz_inx/2; break;
- }
-
- switch (posyType) {
- case 0: yst = "Top: "; iny = pos_iny; break;
- case 1: yst = "Bot: "; iny = psizey - (pos_iny + sz_iny); break;
- case 2: yst = "Y Mid:"; iny = pos_iny + sz_iny/2; break;
- }
-
- cmx = inx * IN2CM;
- cmy = iny * IN2CM;
-
- sprintf(str, "%s %.3f\" (%.2fcm) ", xst, inx, cmx);
- sprintf(str1, "%s %.3f\" (%.2fcm) ", yst, iny, cmy);
-
- XSetForeground(theDisp, theGC, infofg);
- XSetBackground(theDisp, theGC, infobg);
-
- XSetFont(theDisp, theGC, monofont);
- XDrawImageString(theDisp, psW, theGC, x, y, str, strlen(str));
- XDrawImageString(theDisp, psW, theGC, x, y+13, str1, strlen(str1));
- XSetFont(theDisp, theGC, mfont);
- }
-
-
- /***************************************************/
- static void drawSizeStr()
- {
- int x,y;
- double cmx, cmy;
- char str[64], str1[64];
-
- x = 256; y = 190+13+45;
-
- cmx = sz_inx * IN2CM;
- cmy = sz_iny * IN2CM;
-
- sprintf(str, "%.3f\" x %.3f\" ", sz_inx, sz_iny);
- sprintf(str1, "%.2fcm x %.2fcm ", cmx, cmy);
-
- XSetForeground(theDisp, theGC, infofg);
- XSetBackground(theDisp, theGC, infobg);
- XSetFont(theDisp, theGC, monofont);
-
- XDrawImageString(theDisp, psW, theGC, x, y, str, strlen(str));
- XDrawImageString(theDisp, psW, theGC, x, y+13, str1, strlen(str1));
- XSetFont(theDisp, theGC, mfont);
- }
-
-
- /***************************************************/
- static void drawResStr()
- {
- int x,y;
- char str[64];
-
- x = 256; y = 190 + 13 + 90;
-
- sprintf(str, "%ddpi x %ddpi ", dpix, dpiy);
-
- XSetForeground(theDisp, theGC, infofg);
- XSetBackground(theDisp, theGC, infobg);
- XSetFont(theDisp, theGC, monofont);
- XDrawImageString(theDisp, psW, theGC, x, y, str, strlen(str));
- XSetFont(theDisp, theGC, mfont);
- }
-
-
-
-
- /***************************************************/
- static void drawPage()
- {
- /* draw page */
- XSetForeground(theDisp, theGC, infobg);
- XFillRectangle(theDisp, pageF, theGC, pageRect.x+1, pageRect.y+1,
- pageRect.width-1, pageRect.height-1);
-
- XSetForeground(theDisp, theGC, infofg);
- XDrawRectangle(theDisp, pageF, theGC, pageRect.x, pageRect.y,
- pageRect.width, pageRect.height);
-
- drawIRect(1);
- }
-
-
- /***************************************************/
- static void clickPSD(x,y)
- int x,y;
- {
- int i;
- BUTT *bp;
-
- /* check BUTTs */
-
- for (i=0; i<PS_NBUTTS; i++) {
- bp = &psbut[i];
- if (PTINRECT(x, y, bp->x, bp->y, bp->w, bp->h)) break;
- }
-
- if (i<PS_NBUTTS) { /* found one */
- if (BTTrack(bp)) doCmd(i);
- }
-
- /* check RBUTTs */
-
- else if ((i=RBClick(orientRB,x,y)) >= 0) {
- if (RBTrack(orientRB, i)) changedPaper();
- }
-
- else if ((i=RBClick(paperRB,x,y)) >= 0) {
- if (RBTrack(paperRB, i)) changedPaper();
- }
-
- /* check CBUTTs */
-
- else if (CBClick(&lockCB,x,y)) {
- if (CBTrack(&lockCB) && lockCB.val) { /* turned on lock */
- DSetVal(&ysDial, xsDial.val); /* copy xsDial.val to ysDial */
- changedScale();
- }
- }
-
- else if (CBClick(&encapsCB,x,y)) CBTrack(&encapsCB);
- else if (CBClick(&pscompCB,x,y)) CBTrack(&pscompCB);
- }
-
-
-
- /***************************************************/
- static void clickPage(mx,my)
- int mx,my;
- {
- Window rW,cW;
- int rx,ry,x,y;
- unsigned int mask;
- double offx, offy, newx, newy;
-
- /* compute offset (in inches) between 'drag point' and
- the top-left corner of the image */
-
- offx = ((mx - pageRect.x) / in2pix) - pos_inx;
- offy = ((my - pageRect.y) / in2pix) - pos_iny;
-
- /* if clicked outside of image rectangle, ignore */
- if (offx<0.0 || offy < 0.0 || offx>=sz_inx || offy >= sz_iny) return;
-
- while (1) {
- if (XQueryPointer(theDisp,pageF,&rW,&cW,&rx,&ry,&x,&y,&mask)) {
- if (!(mask & Button1Mask)) break; /* button released */
-
- /* compute new pos_inx, pos_iny based on x,y coords */
- newx = ((x-pageRect.x) / in2pix) - offx;
- newy = ((y-pageRect.y) / in2pix) - offy;
-
- moveImage(newx, newy);
- }
- }
- }
-
-
-
- /***************************************************/
- static void doCmd(cmd)
- int cmd;
- {
- switch (cmd) {
- case PS_BOK: writePS(); PSDialog(0); break;
-
- case PS_BCANC: PSDialog(0); break;
-
- case PS_BCENT: drawIRect(0);
- centerImage();
- drawIRect(1);
- drawPosStr();
- break;
-
- case PS_BMAX: drawIRect(0);
- maxImage();
- drawIRect(1);
- drawPosStr();
- drawSizeStr();
- drawResStr();
- break;
-
- case PS_BPOSX: posxType = (posxType + 1) % 3;
- drawPosStr();
- break;
-
- case PS_BPOSY: posyType = (posyType + 1) % 3;
- drawPosStr();
- break;
-
- default: break;
- }
- }
-
-
- /***************************************************/
- static void changedScale()
- {
- double oldx,oldy;
-
- drawIRect(0);
-
- if (lockCB.val) {
- if (tracking == 1) DSetVal(&ysDial, xsDial.val);
- else if (tracking == 2) DSetVal(&xsDial, ysDial.val);
- }
-
- oldx = pos_inx; oldy = pos_iny;
- setScale();
-
- drawIRect(1);
-
- if (pos_inx != oldx || pos_iny != oldy ||
- posxType != 0 || posyType != 0) drawPosStr();
- drawSizeStr();
- drawResStr();
- XFlush(theDisp);
- }
-
-
- /***************************************************/
- static void setScale()
- {
- double hsx, hsy;
-
- int w,h;
-
- if (savenormCB.val) { w = cWIDE; h = cHIGH; }
- else { w = eWIDE; h = eHIGH; }
-
- sz_inx = (double) w / PIX2INCH * (xsDial.val / 100.0);
- sz_iny = (double) h / PIX2INCH * (ysDial.val / 100.0);
-
- /* round to integer .001ths of an inch */
- sz_inx = floor(sz_inx * 1000.0 + 0.5) / 1000.0;
- sz_iny = floor(sz_iny * 1000.0 + 0.5) / 1000.0;
-
- dpix = (int) (PIX2INCH / (xsDial.val / 100.0));
- dpiy = (int) (PIX2INCH / (ysDial.val / 100.0));
-
- /* make sure 'center' of image is still on page */
- hsx = sz_inx/2; hsy = sz_iny/2;
- RANGE(pos_inx, -hsx, psizex-hsx);
- RANGE(pos_iny, -hsy, psizey-hsy);
-
- /* round to integer .001ths of an inch */
- pos_inx = floor(pos_inx * 1000.0 + 0.5) / 1000.0;
- pos_iny = floor(pos_iny * 1000.0 + 0.5) / 1000.0;
-
- }
-
-
- /***************************************************/
- static void changedPaper()
- {
- setPaper();
- XClearWindow(theDisp, pageF);
- centerImage();
- drawPosStr();
- drawPage();
- }
-
-
- /***************************************************/
- static void setPaper()
- {
- double tmp;
-
- psizex = paperSize[RBWhich(paperRB)][0];
- psizey = paperSize[RBWhich(paperRB)][1];
-
- in2pix = (double) PMAX / psizey;
-
- if (RBWhich(orientRB)==ORNT_LAND) {
- tmp = psizex; psizex = psizey; psizey = tmp;
- }
-
- pageRect.x = (int) ((PMAX/2) - ((psizex/2.0) * in2pix));
- pageRect.y = (int) ((PMAX/2) - ((psizey/2.0) * in2pix));
- pageRect.width = (int) (psizex * in2pix);
- pageRect.height = (int) (psizey * in2pix);
- }
-
-
- /***************************************************/
- static void drawIRect(draw)
- int draw;
- {
- int x,y,w,h;
- XRectangle xr;
-
- x = pageRect.x + (int) (pos_inx * in2pix);
- y = pageRect.y + (int) (pos_iny * in2pix);
- w = sz_inx * in2pix;
- h = sz_iny * in2pix;
-
- xr.x = pageRect.x + 1;
- xr.y = pageRect.y + 1;
- xr.width = pageRect.width - 1;
- xr.height = pageRect.height - 1;
-
- if (draw) XSetForeground(theDisp, theGC, infofg);
- else XSetForeground(theDisp, theGC, infobg);
-
- XSetClipRectangles(theDisp, theGC, 0,0, &xr, 1, Unsorted);
- XDrawRectangle(theDisp, pageF, theGC, x, y, w, h);
- XDrawLine(theDisp, pageF, theGC, x, y, x+w, y+h);
- XDrawLine(theDisp, pageF, theGC, x, y+h, x+w, y);
- XSetClipMask(theDisp, theGC, None);
- }
-
-
-
- /***************************************************/
- static void centerImage()
- {
- pos_inx = psizex/2 - sz_inx/2;
- pos_iny = psizey/2 - sz_iny/2;
-
- /* round to integer .001ths of an inch */
- pos_inx = floor(pos_inx * 1000.0 + 0.5) / 1000.0;
- pos_iny = floor(pos_iny * 1000.0 + 0.5) / 1000.0;
- }
-
-
- /***************************************************/
- static void maxImage()
- {
- double scx, scy;
- int w,h;
-
- if (savenormCB.val) { w = cWIDE; h = cHIGH; }
- else { w = eWIDE; h = eHIGH; }
-
- sz_inx = psizex - margins[RBWhich(paperRB)][0];
- sz_iny = psizey - margins[RBWhich(paperRB)][1];
-
- /* choose the smaller scaling factor */
- scx = sz_inx / w;
- scy = sz_iny / h;
-
- if (scx < scy) { sz_iny = w * scx; }
- else { sz_inx = h * scy; }
-
- DSetVal(&xsDial, (int) ((100 * (sz_inx * PIX2INCH) / w) + .5));
- DSetVal(&ysDial, xsDial.val);
-
- sz_inx = (double) w / PIX2INCH * (xsDial.val / 100.0);
- sz_iny = (double) h / PIX2INCH * (ysDial.val / 100.0);
-
- /* round to integer .001ths of an inch */
- sz_inx = floor(sz_inx * 1000.0 + 0.5) / 1000.0;
- sz_iny = floor(sz_iny * 1000.0 + 0.5) / 1000.0;
-
- dpix = (int) (PIX2INCH / (xsDial.val / 100.0));
- dpiy = (int) (PIX2INCH / (ysDial.val / 100.0));
-
- pos_inx = psizex/2 - sz_inx/2;
- pos_iny = psizey/2 - sz_iny/2;
-
- /* round to integer .001ths of an inch */
- pos_inx = floor(pos_inx * 1000.0 + 0.5) / 1000.0;
- pos_iny = floor(pos_iny * 1000.0 + 0.5) / 1000.0;
- }
-
-
- /***************************************************/
- static void moveImage(newx,newy)
- double newx, newy;
- {
- double hsx, hsy;
-
- hsx = sz_inx/2; hsy = sz_iny/2;
-
- /* round to integer .001ths of an inch */
- newx = floor(newx * 1000.0 + 0.5) / 1000.0;
- newy = floor(newy * 1000.0 + 0.5) / 1000.0;
-
- /* keep center of image within page limits */
- RANGE(newx, -hsx, psizex-hsx);
- RANGE(newy, -hsy, psizey-hsy);
-
- if (newx != pos_inx || newy != pos_iny) { /* moved */
- drawIRect(0);
- pos_inx = newx;
- pos_iny = newy;
- drawIRect(1);
- drawPosStr();
- }
- }
-
-
- /***************************************************/
- static void writePS()
- {
- FILE *fp;
- int i, j, q, err, rpix, gpix, bpix, nc;
- int iw, ih, ox, oy, slen, lwidth, bits, colorps, w, h;
- byte *inpix, *bwpic, *rmap, *gmap, *bmap;
-
- if (savenormCB.val) { inpix = cpic; w = cWIDE; h = cHIGH; }
- else { inpix = epic; w = eWIDE; h = eHIGH; }
-
- bwpic = NULL; rmap = r; gmap = g; bmap = b;
- nc = numcols;
-
- fp = OpenOutFile(filename);
- if (!fp) return;
-
- WaitCursor();
-
-
- bwpic = HandleBWandReduced(colorType, &nc, &rmap, &gmap, &bmap);
- if (bwpic) inpix = bwpic;
-
-
-
- /* printed image will have size iw,ih (in picas) */
- iw = (int) (sz_inx * 72.0 + 0.5);
- ih = (int) (sz_iny * 72.0 + 0.5);
-
- /* compute offset to bottom-left of image (in picas) */
- ox = (int) (pos_inx * 72.0 + 0.5);
- oy = (int) ((psizey - (pos_iny + sz_iny)) * 72.0 + 0.5);
-
-
- /*** write PostScript header ***/
-
-
- fprintf(fp,"%%!PS-Adobe-2.0 EPSF-2.0\n");
- fprintf(fp,"%%%%Title: %s\n",filename);
- fprintf(fp,"%%%%Creator: XV %s - by John Bradley\n",REVDATE);
-
- if (RBWhich(orientRB)==ORNT_LAND) /* Landscape mode */
- fprintf(fp,"%%%%BoundingBox: %d %d %d %d\n",
- (int) (pos_iny * 72.0 + 0.5),
- (int) (pos_inx * 72.0 + 0.5),
- (int) (pos_iny * 72.0 + 0.5) + iw,
- (int) (pos_inx * 72.0 + 0.5) + ih);
- else
- fprintf(fp,"%%%%BoundingBox: %d %d %d %d\n", ox, oy, ox+iw, oy+ih);
-
- fprintf(fp,"%%%%Pages: 1\n");
- fprintf(fp,"%%%%DocumentFonts:\n");
- fprintf(fp,"%%%%EndComments\n");
-
-
- switch (colorType) {
- case F_FULLCOLOR:
- case F_REDUCED: slen = w*3; bits = 8; colorps = 1; break;
- case F_GREYSCALE: slen = w; bits = 8; colorps = 0; break;
- case F_BWDITHER: slen = (w+7)/8; bits = 1; colorps = 0; break;
- default: FatalError("unknown colorType in writePS()"); break;
- }
-
- if (encapsCB.val) epsPreview(fp, inpix, colorType, w, h);
-
- fprintf(fp,"%%%%EndProlog\n\n");
-
- fprintf(fp,"%%%%Page: 1 1\n\n");
-
- fprintf(fp,"%% remember original state\n");
- fprintf(fp,"/origstate save def\n\n");
-
- fprintf(fp,"%% build a temporary dictionary\n");
- fprintf(fp,"20 dict begin\n\n");
-
- if (colorType == F_BWDITHER || !pscompCB.val) {
- fprintf(fp,"%% define string to hold a scanline's worth of data\n");
- fprintf(fp,"/pix %d string def\n\n", slen);
- }
-
- if (RBWhich(orientRB)==ORNT_LAND) { /* Landscape mode */
- fprintf(fp,"%% print in landscape mode\n");
- fprintf(fp,"90 rotate 0 %d translate\n\n",(int) (-psizey*72.0));
- }
-
- if (RBWhich(paperRB) == PSZ_4BY5 ||
- RBWhich(paperRB) == PSZ_35MM) {
- fprintf(fp,"%% we're going to a 4x5 or a 35mm film recorder.\n");
- fprintf(fp,"%% clear page to black to avoid registration problems\n");
- fprintf(fp,"newpath\n");
- fprintf(fp," 0 0 moveto\n");
- fprintf(fp," 0 %d rlineto\n", (int) (psizey * 72.0));
- fprintf(fp," %d 0 rlineto\n", (int) (psizex * 72.0));
- fprintf(fp," 0 %d rlineto\n", (int) (-psizey * 72.0));
- fprintf(fp," closepath\n");
- fprintf(fp," 0 setgray\n");
- fprintf(fp," fill\n\n");
- }
-
-
- fprintf(fp,"%% lower left corner\n");
- fprintf(fp,"%d %d translate\n\n",ox,oy);
-
- fprintf(fp,"%% size of image (on paper, in 1/72inch coords)\n");
- fprintf(fp,"%d %d scale\n\n",iw,ih);
-
- if (colorType == F_BWDITHER) { /* 1-bit dither code uses 'image' */
- fprintf(fp,"%% dimensions of data\n");
- fprintf(fp,"%d %d %d\n\n",w,h,bits);
-
- fprintf(fp,"%% mapping matrix\n");
- fprintf(fp,"[%d 0 0 %d 0 %d]\n\n", w, -h, h);
-
- fprintf(fp,"{currentfile pix readhexstring pop}\n");
- fprintf(fp,"image\n");
-
- /* write the actual image data */
-
- err = writeBWStip(fp, inpix, "", w, h);
- }
-
- else { /* all other formats */
- byte *rleline;
- unsigned long outbytes = 0;
-
- /* if we're using color, make sure 'colorimage' is defined */
- if (colorps) psColorImage(fp);
-
- if (pscompCB.val) { /* write colormap and rle-colormapped image funct */
- psColorMap(fp, colorps, nc, rmap, gmap, bmap);
- psRleCmapImage(fp);
- }
-
- fprintf(fp,"%d %d %d\t\t\t%% dimensions of data\n",w,h,bits);
- fprintf(fp,"[%d 0 0 %d 0 %d]\t\t%% mapping matrix\n", w, -h, h);
-
- if (pscompCB.val) fprintf(fp,"rlecmapimage\n");
- else {
- fprintf(fp,"{currentfile pix readhexstring pop}\n");
- if (colorps) fprintf(fp,"false 3 colorimage\n");
- else fprintf(fp,"image\n");
- }
-
- /* dump the image data to the file */
- err = 0;
-
- if (pscompCB.val) {
- rleline = (byte *) malloc(w * 2); /* much worse than possible */
- if (!rleline) FatalError("unable to malloc rleline in writePS()\n");
- }
-
- for (i=0; i<h && err != EOF; i++) {
- int rlen;
- lwidth = 0;
- putc('\n',fp);
-
- if ((i&0x1f) == 0) WaitCursor();
-
- if (pscompCB.val) { /* write rle-encoded colormapped image data */
- rlen = rle_encode(inpix, rleline, w);
- inpix += w;
- outbytes += rlen;
-
- for (j=0; j<rlen && err != EOF; j++) {
- err = fprintf(fp,"%02x", rleline[j]);
- lwidth += 2;
-
- if (lwidth>70) { putc('\n',fp); lwidth = 0; }
- }
- }
- else { /* write non-rle raw (gray/rgb) image data */
- for (j=0; j<w && err != EOF; j++) {
- rpix = rmap[*inpix];
- gpix = gmap[*inpix];
- bpix = bmap[*inpix];
-
- if (colorps) {
- err = fprintf(fp,"%02x%02x%02x",rpix,gpix,bpix);
- lwidth+=6;
- }
-
- else { /* greyscale */
- q = (rpix*21 + gpix*32 + bpix*11) / 64;
- err = fprintf(fp,"%02x", q);
- lwidth+=2;
- }
-
- if (lwidth>70) { putc('\n',fp); lwidth = 0; }
- inpix++;
- }
- }
- }
-
- if (pscompCB.val) {
- free(rleline);
- fprintf(fp,"\n\n");
- fprintf(fp,"%%\n");
- fprintf(fp,"%% Compression made this file %.2lf%% %s\n",
- 100.0 * ((double) outbytes) /
- ((double) eWIDE * eHIGH * ((colorps) ? 3 : 1)),
- "of the uncompressed size.");
- fprintf(fp,"%%\n");
- }
- }
-
-
- fprintf(fp,"\n\nshowpage\n\n");
-
- fprintf(fp,"%% stop using temporary dictionary\n");
- fprintf(fp,"end\n\n");
-
- fprintf(fp,"%% restore original state\n");
- fprintf(fp,"origstate restore\n\n");
- fprintf(fp,"%%%%Trailer\n");
-
- if (bwpic) free(bwpic);
-
- if (CloseOutFile(fp, filename, (err==EOF)) == 0) {
- DirBox(0);
- LoadCurrentDirectory(); /* wrote file: rescan directory */
- }
-
- SetCursors(-1);
- }
-
-
- /**********************************************/
- static int rle_encode(scanline, rleline, wide)
- byte *scanline, *rleline;
- int wide;
- {
- /* generates a rle-compressed version of the scan line.
- * rle is encoded as such:
- * <count> <value> # 'run' of count+1 equal pixels
- * <count | 0x80> <count+1 data bytes> # count+1 non-equal pixels
- *
- * count can range between 0 and 127
- *
- * returns length of the rleline vector
- */
-
- int i, j, blocklen, isrun, rlen;
- byte block[256], pix;
-
- blocklen = isrun = rlen = 0;
-
- for (i=0; i<wide; i++) {
- /* there are 5 possible states:
- * 0: block empty.
- * 1: block not empty, block is a run, current pix == previous pix
- * 2: block not empty, block is a run, current pix != previous pix
- * 3: block not empty, block not a run, current pix == previous pix
- * 4: block not empty, block not a run, current pix != previous pix
- */
-
- pix = scanline[i];
-
- if (!blocklen) { /* case 0: empty */
- block[blocklen++] = pix;
- isrun = 1;
- }
-
- else if (isrun) {
- if (pix == block[blocklen-1]) { /* case 1: isrun, prev==cur */
- block[blocklen++] = pix;
- }
- else { /* case 2: isrun, prev!=cur */
- if (blocklen>1) { /* we have a run block to flush */
- rleline[rlen++] = blocklen-1;
- rleline[rlen++] = block[0];
- block[0] = pix; /* start new run block with pix */
- blocklen = 1;
- }
- else {
- isrun = 0; /* blocklen<=1, turn into non-run */
- block[blocklen++] = pix;
- }
- }
- }
-
- else { /* not a run */
- if (pix == block[blocklen-1]) { /* case 3: non-run, prev==cur */
- if (blocklen>1) { /* have a non-run block to flush */
- rleline[rlen++] = (blocklen-1) | 0x80;
- for (j=0; j<blocklen; j++)
- rleline[rlen++] = block[j];
-
- block[0] = pix; /* start new run block with pix */
- blocklen = isrun = 1;
- }
- else {
- isrun = 1; /* blocklen<=1 turn into a run */
- block[blocklen++] = pix;
- }
- }
- else { /* case 4: non-run, prev!=cur */
- block[blocklen++] = pix;
- }
- }
-
- if (blocklen == 128) { /* max block length. flush */
- if (isrun) {
- rleline[rlen++] = blocklen-1;
- rleline[rlen++] = block[0];
- }
-
- else {
- rleline[rlen++] = (blocklen-1) | 0x80;
- for (j=0; j<blocklen; j++)
- rleline[rlen++] = block[j];
- }
-
- blocklen = 0;
- }
- }
-
- /* flush last block */
- if (isrun) {
- rleline[rlen++] = blocklen-1;
- rleline[rlen++] = block[0];
- }
-
- else {
- rleline[rlen++] = (blocklen-1) | 0x80;
- for (j=0; j<blocklen; j++)
- rleline[rlen++] = block[j];
- }
-
- return rlen;
- }
-
-
- /**********************************************/
- static void psColorImage(fp)
- FILE *fp;
- {
- /* spits out code that checks if the PostScript device in question
- knows about the 'colorimage' operator. If it doesn't, it defines
- 'colorimage' in terms of image (ie, generates a greyscale image from
- RGB data) */
-
-
- fprintf(fp,"%% define 'colorimage' if it isn't defined\n");
- fprintf(fp,"%% ('colortogray' and 'mergeprocs' come from xwd2ps\n");
- fprintf(fp,"%% via xgrab)\n");
- fprintf(fp,"/colorimage where %% do we know about 'colorimage'?\n");
- fprintf(fp," { pop } %% yes: pop off the 'dict' returned\n");
- fprintf(fp," { %% no: define one\n");
- fprintf(fp," /colortogray { %% define an RGB->I function\n");
- fprintf(fp," /rgbdata exch store %% call input 'rgbdata'\n");
- fprintf(fp," rgbdata length 3 idiv\n");
- fprintf(fp," /npixls exch store\n");
- fprintf(fp," /rgbindx 0 store\n");
- fprintf(fp," /grays npixls string store %% str to hold the result\n");
- fprintf(fp," 0 1 npixls 1 sub {\n");
- fprintf(fp," grays exch\n");
- fprintf(fp," rgbdata rgbindx get 20 mul %% Red\n");
- fprintf(fp," rgbdata rgbindx 1 add get 32 mul %% Green\n");
- fprintf(fp," rgbdata rgbindx 2 add get 12 mul %% Blue\n");
- fprintf(fp," add add 64 idiv %% I = .5G + .31R + .18B\n");
- fprintf(fp," put\n");
- fprintf(fp," /rgbindx rgbindx 3 add store\n");
- fprintf(fp," } for\n");
- fprintf(fp," grays\n");
- fprintf(fp," } bind def\n\n");
-
- fprintf(fp," %% Utility procedure for colorimage operator.\n");
- fprintf(fp," %% This procedure takes two procedures off the\n");
- fprintf(fp," %% stack and merges them into a single procedure.\n\n");
-
- fprintf(fp," /mergeprocs { %% def\n");
- fprintf(fp," dup length\n");
- fprintf(fp," 3 -1 roll\n");
- fprintf(fp," dup\n");
- fprintf(fp," length\n");
- fprintf(fp," dup\n");
- fprintf(fp," 5 1 roll\n");
- fprintf(fp," 3 -1 roll\n");
- fprintf(fp," add\n");
- fprintf(fp," array cvx\n");
- fprintf(fp," dup\n");
- fprintf(fp," 3 -1 roll\n");
- fprintf(fp," 0 exch\n");
- fprintf(fp," putinterval\n");
- fprintf(fp," dup\n");
- fprintf(fp," 4 2 roll\n");
- fprintf(fp," putinterval\n");
- fprintf(fp," } bind def\n\n");
-
- fprintf(fp," /colorimage { %% def\n");
- fprintf(fp," pop pop %% remove 'false 3' operands\n");
- fprintf(fp," {colortogray} mergeprocs\n");
- fprintf(fp," image\n");
- fprintf(fp," } bind def\n");
- fprintf(fp," } ifelse %% end of 'false' case\n");
- fprintf(fp,"\n\n\n");
- }
-
-
- /**********************************************/
- static void psColorMap(fp, color, nc, rmap, gmap, bmap)
- FILE *fp;
- int color, nc;
- byte *rmap, *gmap, *bmap;
- {
- /* spits out code for the colormap of the following image
- if !color, it spits out a mono-ized graymap */
-
- int i;
-
- fprintf(fp,"%% define the colormap\n");
- fprintf(fp,"/cmap %d string def\n\n\n", nc * ((color) ? 3 : 1));
-
- fprintf(fp,"%% load up the colormap\n");
- fprintf(fp,"currentfile cmap readhexstring\n");
-
- for (i=0; i<nc; i++) {
- if (color) fprintf(fp,"%02x%02x%02x ", rmap[i],gmap[i],bmap[i]);
- else fprintf(fp,"%02x ", MONO(rmap[i],gmap[i],bmap[i]));
-
- if ((i%10) == 9) fprintf(fp,"\n");
- }
- if (i%10) fprintf(fp,"\n");
- fprintf(fp,"pop pop %% lose return values from readhexstring\n\n\n");
-
- }
-
-
- /**********************************************/
- static void psRleCmapImage(fp, color)
- FILE *fp;
- {
- /* spits out code that defines the 'rlecmapimage' operator */
-
- fprintf(fp,"%% rlecmapimage expects to have 'w h bits matrix' on stack\n");
- fprintf(fp,"/rlecmapimage {\n");
- fprintf(fp," /buffer 1 string def\n");
- fprintf(fp," /rgbval 3 string def\n");
- fprintf(fp," /block 384 string def\n\n");
-
- fprintf(fp," %% proc to read a block from file, and return RGB data\n");
- fprintf(fp," { currentfile buffer readhexstring pop\n");
- fprintf(fp," /bcount exch 0 get store\n");
- fprintf(fp," bcount 128 ge\n");
- fprintf(fp," { %% it's a non-run block\n");
- fprintf(fp," 0 1 bcount 128 sub\n");
- fprintf(fp," { currentfile buffer readhexstring pop pop\n\n");
-
- if (color) {
- fprintf(fp," %% look up value in color map\n");
- fprintf(fp,"%s/rgbval cmap buffer 0 get 3 mul 3 getinterval store\n\n",
- " ");
- fprintf(fp," %% and put it in position i*3 in block\n");
- fprintf(fp," block exch 3 mul rgbval putinterval\n");
- fprintf(fp," } for\n");
- fprintf(fp," block 0 bcount 127 sub 3 mul getinterval\n");
- fprintf(fp," }\n\n");
- }
- else {
- fprintf(fp," %% look up value in gray map\n");
- fprintf(fp,"%s/rgbval cmap buffer 0 get 1 getinterval store\n\n",
- " ");
- fprintf(fp," %% and put it in position i in block\n");
- fprintf(fp," block exch rgbval putinterval\n");
- fprintf(fp," } for\n");
- fprintf(fp," block 0 bcount 127 sub getinterval\n");
- fprintf(fp," }\n\n");
- }
-
- fprintf(fp," { %% else it's a run block\n");
- fprintf(fp," currentfile buffer readhexstring pop pop\n\n");
-
- if (color) {
- fprintf(fp," %% look up value in colormap\n");
- fprintf(fp,"%s/rgbval cmap buffer 0 get 3 mul 3 getinterval store\n\n",
- " ");
- fprintf(fp,"%s0 1 bcount { block exch 3 mul rgbval putinterval } for\n\n",
- " ");
- fprintf(fp," block 0 bcount 1 add 3 mul getinterval\n");
- }
- else {
- fprintf(fp," %% look up value in graymap\n");
- fprintf(fp," /rgbval cmap buffer 0 get 1 getinterval store\n\n");
- fprintf(fp," 0 1 bcount { block exch rgbval putinterval } for\n\n");
- fprintf(fp," block 0 bcount 1 add getinterval\n");
- }
-
- fprintf(fp," } ifelse\n");
- fprintf(fp," } %% end of proc\n");
-
- if (color) fprintf(fp," false 3 colorimage\n");
- else fprintf(fp," image\n");
-
- fprintf(fp,"} bind def\n\n\n");
- }
-
-
-
- /**********************************************/
- static void epsPreview(fp, pic, colorType, w, h)
- FILE *fp;
- byte *pic;
- int colorType;
- int w, h;
- {
- byte *prev;
-
- /* put in an EPSI preview */
-
- if (colorType != F_BWDITHER) { /* have to generate a preview */
- prev = (byte *) malloc(w * h);
- if (!prev) {
- fprintf(stderr,"Unable to malloc in epsPreview\n");
- return;
- }
- FSDither(pic, w, h, prev);
- }
- else prev = pic;
-
- fprintf(fp,"%%%%BeginPreview: %d %d %d %d\n", w, h, 1,
- (w/(72*4) + 1) * h);
-
- writeBWStip(fp, prev, "% ", w, h);
-
- fprintf(fp,"%%%%EndPreview\n");
-
- if (colorType == F_BWDITHER) free(prev);
- }
-
-
- /***********************************/
- static int writeBWStip(fp, pic, prompt, w, h)
- FILE *fp;
- byte *pic;
- char *prompt;
- int w, h;
- {
- /* write the given 'pic' (B/W stippled, 1 byte per pixel, 0=blk,1=wht)
- out as hexadecimal, max of 72 hex chars per line.
-
- returns '0' if everythings fine, 'EOF' if writing failed */
-
- int err, i, j, lwidth;
- byte outbyte, bitnum, bit;
-
- err = 0;
-
- for (i=0; i<h && err != EOF; i++) {
- fprintf(fp, "%s", prompt);
-
- outbyte = bitnum = lwidth = 0;
-
- if ((i&0x3f) == 0) WaitCursor();
-
- for (j=0; j<w && err != EOF; j++) {
- bit = *pic;
- outbyte = (outbyte<<1) | ((bit)&0x01);
- bitnum++;
-
- if (bitnum==8) {
- err = fprintf(fp,"%02x",outbyte);
- lwidth+=2;
- outbyte = bitnum = 0;
- }
-
- if (lwidth>=72 && j+1<w) { fprintf(fp, "\n%s", prompt); lwidth = 0; }
- pic++;
- }
-
- if (bitnum) { /* few bits left over... */
- for ( ; bitnum<8; bitnum++) outbyte <<= 1;
- err = fprintf(fp,"%02x",outbyte);
- lwidth+=2;
- }
-
- fprintf(fp, "\n");
- }
-
- return err;
- }
-
-
-
-