Subject: Modification of ChiRK for HZ/zW support

From: Bo Yang <[email-masked]>
Date: Fri, 3 Jul 1992 14:37:54 -0700

Since the creation of alt.chinese.text( though I still havn't get it on our
machine :-)), I've got several requests for modification of ChiRK so that
HZ/zW coding could be recognized. Here is the modified the version of chirk.c
and text.c ( Let's call them 1.1a ). The defaul is the same as before, to
use with HZ:

	chirk -h ***.hz

with zW:

	chirk -z ***.zw

The original -h flag( HighFont) was changed to -H. Also in chirk.c, the
psignal() call was deleted since it won't compile on some machines.

Goodluck.  ( How do you get alt.chinese.text, anyway? I didn't see it on RFD or
CFV)

Bo Yang ( ~{Qn  2*~}, here you go :-))

---------------- text.c,  CUT HERE ------------------------
/* ChiRK 1.1a  (c) 1992 Bo Yang                                           */

#include "chirk.h"

#include <fcntl.h>
#include <string.h>

extern BOOL     big5;
extern BOOL     autowrap;
extern BOOL     eightypl;
extern BOOL     bitmapfont;
extern BOOL     highfont;
extern BOOL     interactive;

extern char    *clearstr;
extern void     (*outchar) ();
extern FILE    *fp;
extern unsigned int fx, fy;
extern int      pagenum;
extern int	HZon, zWon;

unsigned int    Yp = Lheight;
unsigned int    Xp = 0;
int             lcwidth, cwidth = 80;
int             cheight;
int             lfheight;

void
dummy(len, code)		/* do nothing, use with page counting   */
      int             len, code;
{
}

/* clear screen and display page number and the help at the bottom  */

void
newpage(page)
      int             page;
{
      int             org_80;

      if (page == 0) {
	    outchar = dummy;	/* page==0: Do not write on screen;  */
	    return;		/* Count the Pages only;    */
      }
      if (bitmapfont)
	    outchar = outcharB;
      else
	    outchar = outcharV;
      fputs(clearstr, fp);
      fx = (fy = 0);
      outvct();
      fputc(C_Move, fp);
      fy = highfont ? HiLbtline : Lbtline;
      fx = Lwidth - 2;
      outvct();
      fx = 0;
      outvct();
      fputc(C_Move, fp);
      Yp = highfont ? HiLbtline : Lbtline;
      Xp = 0;
      org_80 = eightypl;
      eightypl = TRUE;
      outtext("ChiRK 1.1");
      eightypl = org_80;
}

/*
 * display a screenful of text( return number of chars written, or utill end
 * of the string( return 0)
 */

int
outtext(Pbuf)
      unsigned char  *Pbuf;
{
      int             i = 0, j = 0, k = 0, l, cp = 1, wr = 0, ret = 0;
      unsigned int    quwei;
      unsigned char   chr, cb1;
      static unsigned char hzhighbit=0;

      lcwidth = eightypl ? 25 : 34;
      cwidth = eightypl ? 80 : 60;
      while (i < cheight && (chr = Pbuf[k]) != '\0') {
	    switch (chr) {
	    case 13:
		  ret = 1;
	    case 10:
		  if (ret == 2) {
			ret = 0;
			break;
		  }
		  if (autowrap || !wr) {
			Yp -= lfheight;
			Xp = 0;
			i++;
		  }
		  if( zWon) hzhighbit=0;
		  cp = 1;
		  j = 0;
		  wr = 0;
		  break;
	    case 9:
		  Xp += 8 * lcwidth;
		  j += 8;
		  ret = 0;
		  break;
	    default:
		  ret = 0;
		  if( HZon && chr == '~' && Pbuf[k+1]=='{'){
			hzhighbit= 0x80;
			k++;}
		  else if( HZon && chr== '~' && Pbuf[k+1]=='}') {
			hzhighbit=0; k++;}
		  else if( zWon && j==0 && !wr && chr== 'z' && Pbuf[k+1]=='W'){
			hzhighbit= 0x80;
			k++;}
		  else{/*
		   * if (chr>127 && chr <161) chr -= 128;
		   */ chr |= hzhighbit;
		      if (((chr > 160) && (cp > 0)) ||
			  ((chr >= 0x40) && (cp < 0))) {
			cp = -cp;
			if (cp < 0)
			      cb1 = chr;
			else {
			      if (autowrap || !wr) {
				    if (j + 2 > cwidth) {
					  Yp -= lfheight;
					  Xp = 0;
					  if (++i == cheight)
						return (k - 1);
					  wr = 1;
					  j = 0;
				    }
			      }
			      if (autowrap || !wr) {
				    quwei = big5 ? big5order(cb1, chr)
					  : gborder(cb1, chr);
				    (*outchar) (2, quwei);
				    Xp += lcwidth << 1;
				    j += 2;
			      }
			}
		    } else {
			if (autowrap || !wr) {
			      if (j + 1 > cwidth) {
				    Yp -= lfheight;
				    Xp = 0;
				    if (++i == cheight)
					  return (k);
				    wr = 1;
				    j = 0;
			      }
			}
			if (autowrap || !wr) {
			      (*outchar) (1, chr);
			      Xp += lcwidth;
			      j += 1;
			}
		  }
	     }
	    }
	    ret++;
	    k++;
      }
      return (chr == '\0' ? 0 : k);
}

int
showpage(page, Pbuf)
      int             page;
      char           *Pbuf;
{
      char            title[80];
      int             textln, org_80;

      newpage(page);
      Yp = Lheight - 2;
      Xp = 0;
      textln = outtext(Pbuf);
      org_80 = eightypl;
      eightypl = TRUE;
      Yp = highfont ? HiLbtline : Lbtline;
      Xp = 0;
      if (interactive) {
	    sprintf(title, "          | Page %d/%d |\0", page, pagenum);
	    outtext(title);
	    if (page < pagenum)
		  outtext(" page forward: nSPACE ");
	    else
		  outtext("                      ");
	    if (page < pagenum || page > 1)
		  outtext("|");
	    if (page > 1)
		  outtext(" page back: nB ");
	    else
		  outtext("               ");
	    outtext("| exit: Q");
      }
      eightypl = org_80;
      return (textln);
}

/*
 * big5order - big5 font order
 */
static unsigned int
big5order(h, l)
      unsigned char   h, l;
{
      register unsigned int charno;

      if (h < 0xA4) {
	    if (l < 0x7F)
		  charno = (h - 0xA1) * 157 + (l - 56);
	    else
		  charno = (h - 0xA1) * 157 + (l - 90);
      } else {
	    if (l < 0x7F)
		  charno = (h - 0xA4) * 157 + (l + 709);
	    else
		  charno = (h - 0xA4) * 157 + (l + 675);
      }
      return (charno);
}

/*
 * gborder - gb font order
 */
unsigned int
gborder(h, l)
      unsigned char   h, l;
{
      register unsigned int charno;

      if (l < 0xa1)		/* GB low is >= 0xa1, make it space */
	    return (0);

      if (h > 175)
	    h -= (bitmapfont ? 8 : 6);
      charno = (h - 161) * 94 + (l - 161);

      return (charno);
}
------------------------ CUT HERE, end of text.c ----------------------
------------------------- Did you foget copying this first :-)---------

------------------------ chirk.c, CUT HERE ----------------------------
/* ChiRK 1.1a  (c) 1992 Bo Yang                                           */

#include <fcntl.h>
#include <signal.h>
#include <string.h>
#include <setjmp.h>

#include "chirk.h"
#include "control.h"

char           *getenv();

extern int      cwidth;		/* number of chars per line  */
extern int      cheight, lfheight;

char           *initstr = Tekinitstr;	/* Tektronics graphics initialization */
char           *teststr = Tekteststr;	/* Tektronics graphics test, not used
					 * yet */
char           *overstr = Tekoverstr;	/* Tektronics graphics exit */
char           *clearstr = Tekclearstr;

#define  BufSize 248
#define  MaxFileLn  128000	/* Maxmum text length, chang if have problem */
#define  Cclibln   481000	/* Length of cclib.v	 */

BOOL            big5 = BIG5;	/* view big5 encoded Chinese? */
BOOL            autowrap = TRUE;
BOOL            eightypl = TRUE;/* 80 chars per line?   */
BOOL            bitmapfont = FALSE;	/* default vector font  */
BOOL            doubleline = FALSE;	/* use with Hi-Res monitors  */
BOOL            highfont = FALSE;	/* higher font for VT2xx terminals */
BOOL            interactive = TRUE;	/* otherwise use as a filter */
BOOL		HZon = FALSE;
BOOL		zWon = FALSE;

void            (*outchar) ();
jmp_buf         env;
FILE           *fp = stdout;
unsigned char  *ccfont;
int             pagenum = 0;

/* interactive  interface   */

void
tekccview(Hfile, Hcclib)
      int             Hfile, Hcclib;
{
      int             i, j, k, cb1, quwei, quitflag = 0, pageln = 1;
      static unsigned char Fbuf[MaxFileLn], ccbuf[Cclibln], kchr;
      long int        chpst = 0, fileln = 0;
      int             page = 1, num0 = 0, num = 1;

      while (!quitflag) {
	    if (read(Hfile, &Fbuf[fileln], BufSize) > 0) {
		  while (Fbuf[++fileln] > 0);
		  if (quitflag = (fileln + BufSize > MaxFileLn))
			fputs("File too long, trancated\n", stderr);
	    } else
		  quitflag = 1;
      }

      fileln = 0;
      quitflag = 0;
      while (!quitflag) {
	    if (read(Hcclib, &ccbuf[fileln], 480061) > 0)
		  while (Fbuf[++fileln] > 0);
	    else
		  quitflag = 1;
      }
      ccfont = ccbuf;

      while (pageln) {		/* figure out the total pages:   */
	    pageln = showpage(0, &Fbuf[chpst += pageln]);
	    pagenum++;
      }

      chpst = 0;
      setjmp(env);		/* return here after being stopped	 */
      pageln = showpage(1, &Fbuf[chpst]);
      quitflag = 0;
      while (!quitflag) {
	    fflush(fp);
	    kchr = interactive ? getchr() : (page == pagenum ? 'q' : 'f');
	    switch (kchr) {
	    case ' ':
	    case 13:
	    case 'f':
	    case 'F':
		  if (page == pagenum)
			break;
		  if (page + num > pagenum)
			num = pagenum - page;
		  for (i = 0; i < num - 1; i++) {
			chpst += pageln;
			pageln = showpage(0, &Fbuf[chpst]);
			page++;
		  }
		  chpst += pageln;
		  setjmp(env);	/* return here also		 */
		  pageln = showpage(++page, &Fbuf[chpst]);
		  num0 = 0;
		  break;
	    case 'b':
	    case 'B':
		  if (page == 1)
			break;
		  chpst = 0;
		  page = page - num > 1 ? page - num : 1;
		  for (i = 1; i < page; i++) {
			pageln = showpage(0, &Fbuf[chpst]);
			chpst += pageln;
		  }
		  setjmp(env);	/* here too	 */
		  pageln = showpage(page, &Fbuf[chpst]);
		  num0 = 0;
		  break;
	    case '0':
	    case '1':
	    case '2':
	    case '3':
	    case '4':
	    case '5':
	    case '6':
	    case '7':
	    case '8':
	    case '9':
		  num0 = num0 > 1000 ? (num0 % 1000) * 10 + kchr - '0' :
			num0 * 10 + kchr - '0';
		  break;
	    case 'q':
	    case 'Q':
		  quitflag = 1;
		  break;
	    default:
		  num0 = 0;
	    }
	    num = num0 ? num0 : 1;
      }
}

/*
 * interrupt and signal processing, make sure the terminal's OK when exiting
 * from the program
 */

#ifdef SIGTSTP
void
stopint()
{
      fflush(fp);
      tekover();
      (void) signal(SIGTSTP, SIG_DFL);
#if SIGSETMASK
      sigsetmask(0);
#endif
      kill(getpid(), SIGTSTP);	/* Leave here... Now returned */
      tekinit();
      longjmp(env, 1);
}
#endif

void
interrupt()
{
      (void) signal(SIGINT, SIG_DFL);
      tekover();
      exit(0);
}

/* put the terminal to graphics mode, keyboard to raw mode */

void
tekinit()
{
      (void) signal(SIGINT, interrupt);
#ifdef SIGTSTP
      (void) signal(SIGTSTP, stopint);
#endif
      fputs(initstr, fp);
      raw_mode(1);
}

/* switch back	 */

void
tekover()
{
      fputs(overstr, fp);
      fflush(fp);
      raw_mode(0);
}

main(argc, argv)
      int             argc;
      char           *argv[];
{
      int             i, j, Hfile = 0, Hcclib;
      char            filename[30], *termname, *cclibfile;

      for (i = 1; i < argc; i++) {
	    if (argv[i][0] == '-') {
		  for (j = 1; j < strlen(argv[i]); j++)
			switch (argv[i][j]) {
			case '5':
			      big5 = TRUE;

			case 'g':
			case 'G':
			      /* GouBiao encoded  */
			      big5 = FALSE;
			      break;
			case 'n':
			case 'N':
			      autowrap = FALSE;
			      break;
			case 'w':
			case 'W':
			      eightypl = FALSE;
			      break;
			case 'd':
			case 'D':
			      doubleline = TRUE;
			      break;
			case 'h':
			      HZon = TRUE;
			      break;
			case 'z': case 'Z':
			      zWon = TRUE;
			      break;
			case 'H':
			      highfont = TRUE;
			      break;
			case 'b':
			case 'B':
			      bitmapfont = TRUE;
			      break;
			case 'f':
			case 'F':
			      interactive = FALSE;
			      break;

			default:
			      fprintf(stderr, "Invalid flag = %c\n", argv[i][j]);
			}
	    } else if (!Hfile) {
		  strcpy(filename, argv[i]);
		  if ((Hfile = open(filename, O_RDONLY)) < 0) {
			fprintf(stderr, "Can't open file %s\n", filename);
			exit(-1);
		  }
	    } else
		  fprintf(stderr, "Extra argument = %s\n", argv[i]);
      }

      termname = getenv("TERM");/* use doubleline with Xterms  */
      if (strncmp(termname, "xterm", 5) == 0)
	    doubleline = TRUE;
      else if (strncmp(termname, "aixterm", 7) == 0)
	    doubleline = TRUE;

      /* no vector font available for big5 (?) */
      if (big5) {
	    bitmapfont = TRUE;
	    outchar = outcharB;
	    if (!(cclibfile = getenv("CHINESE16")))
		  cclibfile = CHINESE16;
      } else if (bitmapfont) {
	    outchar = outcharB;
	    if (!(cclibfile = getenv("CCLIB16")))
		  cclibfile = CCLIB16;
      } else {
	    outchar = outcharV;
	    if (!(cclibfile = getenv("CCLIBv")))
		  cclibfile = CCLIBv;
      }
      if ((Hcclib = open(cclibfile, O_RDONLY)) < 0) {
	    fprintf(stderr, "Can't open chinese font file %s\n", cclibfile);
	    exit(-1);
      }
      cheight = highfont ? HiCheight : Cheight;
      lfheight = highfont ? HiLFheight : LFheight;
      if (Hfile)
	    fputs("\nChiRK 1.1  by Bo Yang,  (c)1992\n\n", stderr);
      if (interactive)
	    tekinit();
      tekccview(Hfile, Hcclib);
      if (interactive)
	    tekover();
}