/* File: gbscript.c */ static char version[] = "GBscript version 1.11 (07/05/1993) by Yan Zhou ~{V\\lM~}"; /* GBscript: Convert GB file to Postscript Version : 1.11 (07/05/1993) Author : Yan Zhou ~{V\lM~} Email : yan@nimbus.anu.edu.au $Modified: Tue May 11 12:56:59 1993 by yan $ All Rights Reserved. Absolutely No Warranty. Free For Non-commercial Purpose Only. History o 1.11: May 1993 DOS support and bug fixes o 1.10: April 1993 faster output PS file, better defaults/settings and new features: multiple columns page orientation 16x16 font file o 1.00: March 1993 first release */ #include #include #ifdef __BORLANDC__ #include #include #include #include #include "getopt.h" # ifdef __STDC__ int stricmp(const char *, const char *); # endif #else # ifdef SYSV # include # else # include # endif #endif #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__) #include #define stricmp strcasecmp #endif #ifndef SEEK_SET # define SEEK_SET 0 #endif #ifndef PROLOGUE_PATH #define PROLOGUE_PATH "." #endif #define FALSE 0 #define TRUE (!FALSE) #define GBBEGIN 0x00A1 #define GBEND 0x00FE #define GBRANGE (GBEND - GBBEGIN + 1) #define GBTOTAL (GBRANGE * GBRANGE) #define MAXFONTBYTE 72 #define FONTNUM 1 #define FONTSONG 0 #define FONTDEFAULT FONTSONG #define PRINTPNO 0x01 #define USECSIZE 0x02 #define LANDSCAPE 0x10 #ifdef __MSDOS__ # define DIRSEP '\\' #else # define DIRSEP '/' #endif /* Macros */ #define isGB(c) ((c) >= GBBEGIN && (c) <= GBEND) #define isASCII(c) (!((c) & 0xFF00)) #define GBcode(h,l) ((((h) & 0x7F) << 8) | ((l) & 0x7F)) /* Types */ struct CCharInfo { int psfont; /* which font */ unsigned char code; /* code for this char */ }; struct CFontInfo { char fontname[64]; /* fontname */ FILE *fp; /* file pointer */ int fontbyte; int size; int gapbegin; /* missing zones */ int gapend; }; struct TextContext { unsigned char cfont; /* current chinese font */ int psfont; /* current PS font */ unsigned char code; /* current code */ int pspage; /* page number */ int pscol; /* column number */ float xposition; /* current X position */ float yposition; /* current Y position */ }; struct PageContext { unsigned int flag; /* reset margins */ float pw; /* A4 paper size */ float ph; int ncol; /* column number */ int colw; /* column width */ int colgap; /* column gap */ int cpl; /* characters per line */ float lm; /* left margin */ float rm; /* right */ float bm; /* bottom */ float tm; /* top */ int tabwidth; /* = n CC space */ float dbscale; /* CC character size */ float sbratio; /* ASCII/CC */ float linespace; /* line spacing */ float sbwidth; /* ASCII char size */ }; struct StringSection { int psfont; /* using which psfont? */ int start; /* start position */ int length; }; struct FreqInfo { int index; /* GB char index */ char freq; /* frequency */ }; /* Global Variables */ struct CFontInfo cfont[FONTNUM] = { { "cclib.24", NULL, 72, 24, 1, 0} }; struct FreqInfo ccfrq[GBTOTAL]; struct CCharInfo cchar[GBTOTAL]; struct TextContext tcont = { FONTDEFAULT, 0, 255, 0, 0, 0}; struct PageContext pcont = { PRINTPNO, 8.5 * 72, 11.0 *72, 1, 504.0, 0.0, 41, 54.0, 558.0, 54.0, 738.0, 2, 12.0, 0.5, 0.0, 0.0}; char homedir[256] = PROLOGUE_PATH; char pfilename[64]= "gbscript.pro"; char tfilename[64]; char ifilename[256] = ""; char ofilename[256] = ""; char *progname; /* Function Prototypes */ #if defined(__STDC__) void Init(int, char **); void ScanCommandLine(int, char **); void Usage(void); void ScanInput(FILE *, FILE *); int GetNextChar(FILE *); void AddFontEntry(int, FILE *); void GetFontBitMap(int, char *); void StartPS(FILE *); void WriteOutput(FILE *, FILE *); void WriteLine(FILE *, unsigned char *, struct StringSection *, int, int); int FreqCompare(const void *, const void *); void GenFontDict(FILE *); void CharStat(int, int); void Exit(int); int isASCBRK(int); int isGBSYM(int); #else void Init(); void ScanCommandLine(); void Usage(); void ScanInput(); int GetNextChar(); void AddFontEntry(); void GetFontBitMap(); void StartPS(); void WriteOutput(); void WriteLine(); int FreqCompare(); void GenFontDict(); void CharStat(); void Exit(); int isASCBRK(); int isGBSYM(); #endif /* * Use functions instead of macros, * as some compilers may have length restriction */ int isASCBRK(c) int c; { switch (c) { case '.': case ',': case ' ': case '!': case ':': case ';': case '?': return(TRUE); } return(FALSE); } int isGBSYM(c) int c; { switch (c) { case 0x2122: case 0x2123: case 0x2129: case 0x2321: case 0x232c: case 0x232e: case 0x233a: case 0x233b: case 0x233f: case 0x212f: case 0x2131: case 0x2133: case 0x2135: case 0x2137: case 0x2139: case 0x213b: case 0x213d: case 0x213f: case 0x2163: case 0x2164: case 0x2165: case 0x2166: case 0x233e: case 0x235d: case 0x237d: case 0x2329: case 0x2325: return(TRUE); } return(FALSE); } /* Exit */ void Exit(code) int code; { unlink(tfilename); exit(code); } /* Main entry */ main(argc, argv) int argc; char **argv; { FILE *fin = stdin; FILE *fout= stdout; FILE *tempf; /* Init */ Init(argc, argv); /* input file */ if (ifilename[0]) { fin = fopen(ifilename, "r"); if (fin == NULL) { fprintf(stderr, "Cannot open input file %s. Abort.\n", ifilename); Exit(1); } } /* output file */ if (ofilename[0]) { fout = fopen(ofilename, "w"); if (fout == NULL) { fprintf(stderr, "Cannot open output file %s. Abort.\n", ofilename); Exit(1); } } /* Create PS header */ StartPS(fout); /* prepare a temporary file */ tmpnam(tfilename); if ((tempf = fopen(tfilename, "w")) == NULL) { fprintf(stderr, "Cannot create temporary file %s. Abort\n", tfilename); Exit(1); } /* Check input */ ScanInput(fin, tempf); fclose(fin); fclose(tempf); /* Generate PS Font Dictionaries */ GenFontDict(fout); if ((fin = fopen(tfilename, "r")) == NULL) { fprintf(stderr, "Temporary file %s lost. Abort.\n", tfilename); Exit(1); } WriteOutput(fin, fout); fclose(fin); fclose(fout); unlink(tfilename); /* End gracefully */ return(0); } /* void Init() Function : Initializations, commmand line parsing Return : void Parameters: 2 1 : argc 2 : argv */ void Init(argc, argv) int argc; char **argv; { int i; int ac; float f; char *av[100]; char en[256]; /* Init */ progname = argv[0]; for (i=0; i 0) { pcont.ncol = d; } else Usage(); break; case 'r': sscanf(optarg, "%f", &f); if (f > 0) { pcont.sbratio = f; } else Usage(); break; case 's': if (stricmp(optarg, "default") !=0) sscanf(optarg, "%f", &f); else f = pcont.dbscale; if (f > 0) { pcont.dbscale = f; pcont.flag |= USECSIZE; } else Usage(); break; case 't': sscanf(optarg, "%d", &d); if (d >= 0) pcont.tabwidth = d; else Usage(); break; case 'm': if (stricmp(optarg, "default")!=0) { /* -m */ if (argc < optind+3) Usage(); sscanf(argv[optind-1], "%f", &(pcont.lm)); sscanf(argv[optind], "%f", &(pcont.bm)); sscanf(argv[optind+1], "%f", &(pcont.rm)); sscanf(argv[optind+2], "%f", &(pcont.tm)); optind += 3; if (pcont.lm >= pcont.rm || pcont.bm >= pcont.tm) Usage(); } pcont.flag &= ~USECSIZE; break; case 'o': if (stricmp(optarg, "landscape") == 0) { pcont.flag |= LANDSCAPE; } else if (stricmp(optarg, "portrait") == 0) { pcont.flag &= ~LANDSCAPE; } else Usage(); break; case 'w': sscanf(optarg, "%d", &d); if (d > 0) { pcont.cpl = d; } else Usage(); break; case 'g': if (argc < optind+1) Usage(); sscanf(argv[optind-1], "%d", &(cfont[FONTDEFAULT].gapbegin)); sscanf(argv[optind], "%d", &(cfont[FONTDEFAULT].gapend)); optind++; break; } } i = optind; if (i < argc) { strcpy(ifilename, argv[i]); i++; } if (i < argc) { strcpy(ofilename, argv[i]); i++; } } /* void Usage() Function : print help messages about program usage Return : exit abnormally. Parameters: void */ void Usage() { fprintf(stderr, "%s\n", version); fprintf(stderr, "Usage: [setenv GBSCRIPT options;] %s [options] [ []]\n\n", progname, progname); fprintf(stderr, "Options: (72 points = 1 inch) (DEFAULT VALUE)\n"); fprintf(stderr, " -h This message\n"); fprintf(stderr, " -b 16 | 24 Bitmap font size (24x24)\n"); fprintf(stderr, " -c Set Chinese font name (%s)\n", cfont[FONTDEFAULT].fontname); fprintf(stderr, " -d Set home directory (%s)\n", homedir); fprintf(stderr, " -m Set margins (%4.1f %4.1f %4.1f %4.1f)\n", pcont.lm, pcont.bm, pcont.rm, pcont.tm); fprintf(stderr, " -m default Use default margins\n"); fprintf(stderr, " -n Set multiple columns per one page (%d)\n", pcont.ncol); fprintf(stderr, " -o landscape|portrait Print orientation (%s)\n", pcont.flag & LANDSCAPE ? "Landscape" : "Portrait"); fprintf(stderr, " -p yes|no Print page number (%s)\n", pcont.flag & PRINTPNO ? "Yes" : "No"); fprintf(stderr, " -r Ascii : Chinese Character (%3.1f)\n", pcont.sbratio); fprintf(stderr, " -s Set character size (%3.1f)\n", pcont.dbscale); fprintf(stderr, " -s default Use default character size\n"); fprintf(stderr, " -t Set tab width = n Chinese Character (%d)\n", pcont.tabwidth); fprintf(stderr, " -w Chinese characters per column (%d)\n", pcont.cpl); Exit(-1); } /* void StartPS(FILE *) Function : Start PS header Return : void Parameters: 1 1 : Output stream */ void StartPS(fout) FILE *fout; { char fullname[256]; FILE *pf; int c; long time_val; /* Full name for prologue file */ if ( #ifdef __MSDOS__ pfilename[1] != ':' && #endif pfilename[0] != '.' && pfilename[0] != DIRSEP) strcpy(fullname, homedir); else fullname[0] = 0; strcat(fullname, pfilename); /* Open prologue file */ if ((pf = fopen(fullname, "r")) == NULL) { fprintf(stderr, "Cannot open prologue file %s, Quit\n", fullname); Exit(1); } /* PS header, comments */ fprintf(fout, "%%!PS-Adobe-2.1\n"); fprintf(fout, "%%%%Title:\n"); fprintf(fout, "%%%%Creator: %s\n", version); time(&time_val); fprintf(fout, "%%%%CreationDate: %s", ctime(&time_val)); fprintf(fout, "%%%%BoundingBox: %5.2f %5.2f %5.2f %5.2f\n", pcont.lm, pcont.bm, pcont.rm, pcont.tm); fprintf(fout, "%%%%Pages: (atend)\n"); fprintf(fout, "%%%%EndComments\n"); /* Copy GBscript prologue file */ while ((c = fgetc(pf)) != EOF) fputc(c, fout); fclose(pf); } /* void ScanInput(FILE *, FILE *) Function : Check used Chinese Characters in the input Return : void Parameters: 2 1 : Input stream 2 : Temporary file (copy of Input) */ void ScanInput(fin, tempf) FILE *fin; FILE *tempf; { int chi; int i; int hi, lo; fprintf(stderr, "Scanning Input ..."); /* Parse the input GB file */ while ((chi = GetNextChar(fin)) != EOF) { hi = (chi & 0x7F00) >> 8; lo = (chi & 0x007F); if (hi) { /* chi is a GB character (2 bytes) */ CharStat(hi, lo); hi |= 0x80; lo |= 0x80; fputc(hi, tempf); } switch (lo) { case '\r': /* Ignore '\r' */ break; case '\t': /* Substitude TAB with spaces */ for (i=0; i index */ i = (hi + 0x80 - GBBEGIN) * GBRANGE + (lo + 0x80 - GBBEGIN); if (ccfrq[i].freq < 127) ccfrq[i].freq ++; } /* int FreqCompare(const void *, const void *) Function : compare function for qsort Return : -, 0 or + 1, 2 : two elements for comparison */ int FreqCompare(a, b) const void *a; const void *b; { return(((struct FreqInfo *)b)->freq - ((struct FreqInfo *)a)->freq); } /* void GenFontDict(fout) Function : Create PS fonts in the sequence of frequency of usages. Return : void. Parameters : 1 1 : output */ void GenFontDict(fout) FILE *fout; { int i; int j; fprintf(stderr, "Generating Font Dictionaries "); /* Skip unused Chinese characters */ for (j=0; j < GBTOTAL && ccfrq[j].freq > 0; j++); for (i=0; i < GBTOTAL; i++) { if (ccfrq[i].freq > 0) { if (j < i) { ccfrq[j] = ccfrq[i]; ccfrq[i].freq = 0; for (j++; j < GBTOTAL && ccfrq[j].freq > 0; j++); } } } /* Sorting to frequency descending order */ qsort(ccfrq, j, sizeof(struct FreqInfo), FreqCompare); for (i=0; i 0) { fputs(" end\n", fout); fputs("end\n", fout); /* of NewFontDict */ fprintf(fout, "/CCF-%d exch definefont pop\n", tcont.psfont); fputs("%%EndFont\n", fout); } /* Some constants */ fprintf(fout, "/LM %5.2f def\n", pcont.lm); fprintf(fout, "/RM %5.2f def\n", pcont.rm); fprintf(fout, "/BM %5.2f def\n", pcont.bm); fprintf(fout, "/TM %5.2f def\n", pcont.tm); fprintf(fout, "/PW %5.2f def\n", (pcont.rm - pcont.lm)); fprintf(fout, "/PH %5.2f def\n", (pcont.tm - pcont.bm)); fprintf(fout, "/PT %5.2f def\n", pcont.dbscale); fprintf(fout, "/AW %5.2f def\n", pcont.sbwidth); fprintf(fout, "/LS %5.2f def\n", pcont.linespace); /* Set some usefile findfont and setfont aliases */ fputs("%!\n% Useful aliases for fonts\n", fout); fputs("/Fa PT /Courier f def /fa {Fa setfont} bd\n",fout); fputs("/Fa Fa [AW Fa setfont (X) stringwidth pop div 0 0 1 0 PT .1 mul] makefont def\n", fout); fputs("/Fb PT /Courier-Bold f def\n", fout); for (i=1; i<=tcont.psfont; i++) fprintf(fout, "/F%d PT /CCF-%d f def /f%d {F%d setfont} bd\n", i, i, i, i); fputs("%!\n", fout); fputs(" Done.\n", stderr); } /* void AddFontEntry(int, FILE *) Function : Add a char to PS font. Return : void. Parameters : 2 1 : index of the character, 0 for 0x2121. 2 : output */ void AddFontEntry(index, fout) int index; FILE *fout; { unsigned char fbm[MAXFONTBYTE]; int i; if (cchar[index].psfont > 0) /* Already registered */ return; /* Wrong index */ if (index < 0 || index >= GBTOTAL) return; /* Read bitmap font file */ GetFontBitMap(index, (char *)fbm); if (tcont.code < 255) tcont.code ++; else { /* start a new PS font */ if (tcont.psfont > 0) { /* end */ fputs(" end\n", fout); fputs("end\n", fout); /* of NewFontDict */ fprintf(fout, "/CCF-%d exch definefont pop\n", tcont.psfont); fputs("%%EndFont\n", fout); } /* New font */ fprintf(stderr, "."); tcont.psfont ++; tcont.code = 0; fprintf(fout, "%%%%BeginFont: /CCF-%d\n", tcont.psfont); fputs("8 dict dup begin\n", fout); fputs(" /FontType 3 def\n", fout); fprintf(fout, " /FontMatrix Matrix%d def\n", cfont[tcont.cfont].size); fprintf(fout, " /FontBBox BBox%d def\n", cfont[tcont.cfont].size); fprintf(fout, " /BuildChar /BuildChar%d ld\n", cfont[tcont.cfont].size); fprintf(fout, " /Encoding GBencoding def\n"); fprintf(fout, " /UniqueID %d def\n", cfont[tcont.cfont].size*100+tcont.psfont); fputs(" /CharData 256 dict def\n", fout); fputs(" CharData begin\n", fout); } cchar[index].psfont = tcont.psfont; cchar[index].code = tcont.code; /* Character bitmap in hex-string */ fprintf(fout, "\t/C%02x <", tcont.code); for (i=0; i d\n", fout); } /* void GetFontBitMap(int, char *) Function : return the bitmap of a specified char. Return : void. Parameters : 2 1 : character index, (0 for 0x2121) 2 : memory for bitmap, size must >= FONTBYTE */ void GetFontBitMap(index, fbm) int index; char *fbm; { struct CFontInfo *cfip; char fullname[256]; int MISSING = FALSE; int zone; #ifdef __BORLANDC__ int save_fmode = _fmode; _fmode = O_BINARY; #endif /* Ensure the existance of default font file */ cfip = &cfont[FONTDEFAULT]; if (cfip->fp == NULL) { /* Full path name */ if ( #ifdef __MSDOS__ cfip->fontname[1] != ':' && #endif cfip->fontname[0] != '.' && cfip->fontname[0] != DIRSEP) strcpy(fullname, homedir); else fullname[0] = 0; strcat(fullname, cfip->fontname); /* Open default font file */ cfip->fp = fopen(fullname, "r"); } /* Open current font file */ cfip = &cfont[tcont.cfont]; if (cfip->fp == NULL) { /* Full path name */ if ( #ifdef __MSDOS__ cfip->fontname[1] != ':' && #endif cfip->fontname[0] != '.' && cfip->fontname[0] != DIRSEP) strcpy(fullname, homedir); else fullname[0] = 0; strcat(fullname, cfip->fontname); cfip->fp = fopen(fullname, "r"); } if (cfip->fp == NULL) { /* Specified font file not exist, substitude with default font file */ cfip->fp = cfont[FONTDEFAULT].fp; } /* No font file available, abort */ if (cfip->fp == NULL) { fprintf(stderr, "Cannot open font file %s, Quit.\n", fullname); Exit(1); } zone = index % GBRANGE; if ((zone >= cfip->gapbegin) && (zone <= cfip->gapend)) MISSING = TRUE; else { /* skip zone gap */ if ((cfip->gapend >= cfip->gapbegin) && (zone > cfip->gapend)) index -= ((cfip->gapend - cfip->gapbegin + 1) * GBRANGE); /* Seek ... */ fseek(cfip->fp, (long)index*cfip->fontbyte*sizeof(char), SEEK_SET); /* And read ... */ MISSING = (fread(fbm, 1, sizeof(char) * cfip->fontbyte, cfip->fp) != sizeof(char)*cfip->fontbyte); } if (MISSING) { int i; fprintf(stderr, "GB 0x%02x%02x bitmap missing. Ignore.\n", GBBEGIN + (index/GBRANGE), GBBEGIN + (index % GBRANGE)); /* use a black square to indicate missing char */ /* do not bother to use memset or bset, SYSV BSD? */ for (i=0; ifontbyte; i++) fbm[i] = 0xff; } #ifdef __BORLANDC__ _fmode = save_fmode; #endif } /* int GetNextChar(FILE *) Function : read an ASCII or a GB (2 bytes) character from input Return : int, character code, NULL:EOF. Parameters: 2 1 : input */ int GetNextChar(fin) FILE *fin; { int ca; int cb; ca = fgetc(fin); if (ca == EOF) return(EOF); if (isGB(ca)) { cb = fgetc(fin); if (!isGB(cb)) { fprintf(stderr, "Invalid GB code 0x%2x%2x ignored.\n", ca, cb); ca = 0x21; cb = 0x21; } return(GBcode(ca, cb)); } return(ca); } /* void WriteOutput(FILE *, FILE *) Function : write real file contents. Return : void. Parameters: 2 1 : input 2 : output */ void WriteOutput(fin, fout) FILE *fin; FILE *fout; { struct StringSection *section; unsigned char *line; float linewidth = 0.0; float charwidth; int nsec = -1; int noff = -1; int dbch; /* Double Byte Character */ int index; int hi; int lo; int psfont; int code; int si; /* Init state */ tcont.pspage = 0; tcont.pscol = pcont.ncol; tcont.xposition = pcont.lm; tcont.yposition = pcont.bm; /* Allocate memory */ si = (int)(pcont.colw/pcont.dbscale+20); section = (struct StringSection *)malloc(sizeof(struct StringSection) * si); line = (unsigned char *)malloc(sizeof(char) * si); fprintf(stderr, "Generating Postscript Pages:"); /* main loop, until end of input stream */ while ((dbch = GetNextChar(fin)) != EOF) { /* find corresponding psfont, index into that psfont, and char width*/ hi = (dbch & 0x7F00) >> 8; lo = (dbch & 0x007F); if (!isASCII(dbch)) { /* a GB code */ index = (hi + 0x80 - GBBEGIN) * GBRANGE + (lo + 0x80 - GBBEGIN); psfont = cchar[index].psfont; code = cchar[index].code; charwidth = pcont.dbscale; } else { psfont = 0; /* ASCII font */ code = lo; charwidth = pcont.sbwidth; } /* A new line encountered, do not adjust this line. */ if ((psfont == 0) && (code == '\n')) { /* newline */ WriteLine(fout, line, section, nsec, FALSE); linewidth = 0.0; noff = -1; nsec = -1; continue; } /* Line full? Break the line here */ if ((charwidth + linewidth) > (pcont.colw - pcont.dbscale)) { /* But there are forbidden rules ... */ si = section[nsec].start+section[nsec].length - 1; if ((!hi && (section[nsec].psfont > 0 || (section[nsec].psfont == 0 && isASCBRK(line[si])))) || (hi && !isGBSYM(dbch))) { WriteLine(fout, line, section, nsec, TRUE); linewidth = 0.0; noff = -1; nsec = -1; } } /* Append the char to this line */ noff++; line[noff] = code; linewidth += charwidth; /* Can current charater be added into current section? */ if (nsec < 0 || psfont != section[nsec].psfont) { /* start a new section */ nsec ++; section[nsec].psfont = psfont; section[nsec].start = noff; section[nsec].length = 1; } else { section[nsec].length ++; } } /* Last line, Flush it */ if (noff >= 0) { WriteLine(fout, line, section, nsec, FALSE); } /* Last page, Flush it */ if (tcont.pspage) fputs("e\n", fout); /* Trailor */ fputs("%%Trailor\n", fout); fprintf(fout, "%%%%Pages: %d 1\n", tcont.pspage); fprintf(stderr, "\n=> Total %d Pages.\n", tcont.pspage); } /* void WriteLine(FILE *, unsigned char *, struct StringSection *, int, int) Function : void. Parameters: 5 1 : output file 2 : line contents 3 : line secionts 4 : number of sections 5 : adjust ? */ void WriteLine(fout, line, section, nsec, adjust) FILE *fout; unsigned char *line; struct StringSection *section; int nsec; int adjust; { float newy; float width = 0; int sbc = 0; int dbc = 0; float dbsp; float sbsp; int i, j, k; char buff[256]; static linecounter = 0; /* Move to next line */ newy = tcont.yposition - pcont.linespace; /* New page ? */ if (newy < pcont.bm) { tcont.pscol ++; tcont.yposition = pcont.tm; if (pcont.flag & PRINTPNO) { tcont.yposition -= pcont.linespace * 2; } if (tcont.pscol >= pcont.ncol) { tcont.pscol = 0; /* End last page */ if (tcont.pspage > 0) { fprintf(fout, "e\n"); } /* Start a new page */ tcont.pspage ++; tcont.xposition = pcont.lm; fprintf(fout, "%%%%Page: Page%d %d\n", tcont.pspage, tcont.pspage); fprintf(fout, "b\n"); if (pcont.flag & LANDSCAPE) { fprintf(fout, "90 rotate 0 -%4.1f translate\n", pcont.ph); } /* Page number */ if (pcont.flag & PRINTPNO) { fprintf(fout, "(%d) pnum\n", tcont.pspage); } fprintf(stderr, " %d", tcont.pspage); } else { tcont.xposition += pcont.colw + pcont.colgap; fprintf(fout, "restore save\n"); if (pcont.flag & LANDSCAPE) { fprintf(fout, "90 rotate 0 -%4.1f translate\n", pcont.ph); } } fprintf(fout, "/CM %4.1f def\n", tcont.xposition); newy = tcont.yposition - pcont.linespace; tcont.psfont = -1; linecounter = 0; } if (linecounter > 60 && linecounter % 60 == 1) { fprintf(fout, "restore save\n"); if (pcont.flag & LANDSCAPE) { fprintf(fout, "90 rotate 0 -%4.1f translate\n", pcont.ph); } fprintf(fout, "/CM %4.1f def\n", tcont.xposition); tcont.psfont = -1; } linecounter ++; if (nsec >= 0) fprintf(fout, "%5.2f n\n", newy); tcont.yposition = newy; /* Get rid of trailing null sections */ while (nsec >= 0 && section[nsec].length <= 0) nsec --; /* Get rid of trailing spaces at the end of line */ i = section[nsec].start + section[nsec].length - 1; while (nsec >= 0 && ((section[nsec].psfont == 0) && (line[i] == ' '))){ j = section[nsec].length; while (j > 0 && ((section[nsec].psfont == 0) && (line[i] == ' '))) { i--; j--; } section[nsec].length = j; if (j <= 0) nsec --; i = section[nsec].start + section[nsec].length - 1; } /* Need line adjustment */ for (i=0; i<=nsec; i++) { if (section[i].psfont == 0) { width += pcont.sbwidth * section[i].length; sbc += section[i].length; } else { width += pcont.dbscale * section[i].length; dbc += section[i].length; } } /* Just a blank line */ if ((sbc + dbc) <= 0) return; /* Line adjustments */ width = (pcont.colw - width) / (pcont.sbwidth * sbc + pcont.dbscale * dbc); dbsp = width * pcont.dbscale; sbsp = width * pcont.sbwidth; /* Ensure proper adjustment */ if (dbsp < -0.005) adjust = TRUE; else if (dbsp < 0.005) adjust = FALSE; /* Write out */ for (i=0; i<=nsec; i++) { /* Skip null sections */ if (section[i].length <= 0) continue; /* Select corresponding font */ if (section[i].psfont != tcont.psfont) { if (section[i].psfont == 0) { fprintf(fout, "fa "); } else { fprintf(fout, "f%d ", section[i].psfont); } tcont.psfont = section[i].psfont; } if (adjust) { if (tcont.psfont == 0) fprintf(fout, "%4.2f", sbsp); else fprintf(fout, "%4.2f", dbsp); } /* String in hex format */ k = section[i].start + section[i].length; for (j=section[i].start; ja\n"); else fprintf(fout, ">s\n"); } } /* End */