From: [email-masked]
Date: Wed, 22 May 91 18:58:21 EST

[email-masked] wrote:

> Answer to a email-question as to the coding structure of the
> ET-fontfiles: Here the informations for the files with
> version 2.0:
>   ......

Many have found that ET coding has different layout from that of HKU-Ch16.
With the information provided by "[email-masked]",  it seems
easy to convert ET coding into BIG5 coding.  After take a look in the
character layout of HKU-Ch16.bdf,  I guess that the only different of the
2 coding may be the offset of Non-frequent BIG5 code in the coding scheme:
(the legal 2nd byte is from 0x40-0x7e, and 0xa1-0xfe)

  portion of codes in BIG5	coding in ET		coding in HKU-Ch16
  ------------------------	----------------	----------------
  Non-Chinese symbols		0xa140 -- 0xa3bf	0xa140 -- 0xa3fe
  Frequent (5401)		0xa440 -- 0xc67e	0xa440 -- 0xc67e
  Non-frequent (7651)		0xc940 -- 0xf9d5	0xc6a1 -- 0xf755
  Non-BIG5 supplement		0xf9d6 -- ??		  no

In ET coding there is a "hole" which doesn't not appear in HKU-Ch16.

If what I guess is correct, then the conversion program is trivial.
I've written a prototype in C.  It seems working.  Some Chinese
text I got from ET can be shown correctly in X window using hku-ch16.
The B5 pinyin table from crl.nmsu.edu looks no longer bad.

But I have two questions:

  1) is the conversion only a matter of shifting?  I hope somebody
     who has more knowledge about BIG5, ET, HKU-Ch16, and traditional
     Chinese can answer this question. (I am from mainland China.)

  2) Which one is the *real* BIG5?  So many commercial products from
     Taiwan and Hong Kong are claimed to be BIG5, but few of them are
     really compactable with each other in internal coding.
     Since HKU-Ch16.bdf is currently the most widely spread BIG5 font,
     I assume it is the standard BIG5 coding now.  (If there is any
     objection, you can rename my program from "et2b5" to "et2hku".)

My program is enclosed, but it is *NOT* tested throughoutly.
I hope someone can polish it and put it to public domain.

Thanks.

--ygz

----------------------------------------------------------

/*
 * et2b5 -- convert between ET coding and BIG5 coding (defined by HKU-Ch16)
 *
 * Author:	Yongguang Zhang ([email-masked])
 *
 * Usage:
 *		input from stdin, output to stdout.
 *		ET => BIG5:	et2b5
 *		BIG5 => ET:	et2b5 -r
 */

#include <stdio.h>

/* follow the convention of b2g/HCu, unconverted hanzi is replaced by a box */

#define UNCONV_H	0xa1
#define UNCONV_L	0xbc

main(argc, argv)
     int argc;
     char **argv;
{
  int uncv = 0;

	if (argc == 2) {
		uncv = big2et();
	} else {
		uncv = et2big();	/* by default */
	}
	if (uncv != 0)
	    fprintf (stderr, "Number of nonstandard Big5 (unconverted) = %d\n",
		     uncv );
}

int et2big()
{
  int c;
  unsigned char h, l;
  int uncv = 0;

	while ((c = getchar()) != EOF) {
		if (! (c & 0x80)) {
			putchar (c);
			continue;
		}

		/* begin of hanzi */
		h = c & 0xff;
		c = getchar ();
		if (c == EOF) {
			putchar (h);
			break;
		}
		l = c & 0xff;

		if ((h < 0xc6) || ((h == 0xc6) && (l <= 0x7e))) {
			/* Frequent BIG5 */
			putchar(h);
			putchar(l);
			continue;
		}
		if ((h <= 0xc8) || (h > 0xf9) || ((h == 0xf9) && (l > 0xd5)))
		{
			/* ET added on non-standard codes */
			putchar(UNCONV_H);
			putchar(UNCONV_L);
			uncv ++;
			continue;
		}

		/* Non-frequnt BIG5 */
		if ((l >= 0xc0) && (l <= 0xfe)) {
			putchar (h - 2);
			putchar (l - 0xc0 + 0x40);
		} else if ((l >= 0xa1) && (l <= 0xbf)) {
			putchar (h - 3);
			putchar (l - 0xa1 + 0xe0);
		} else if ((l >= 0x40) && (l <= 0x7e)) {
			putchar (h - 3);
			putchar (l - 0x40 + 0xa1);
		} else {
			putchar(UNCONV_H);
			putchar(UNCONV_L);
			uncv ++;
		}
	}
	return (uncv);
}

int big2et()
{
  int c;
  unsigned char h, l;
  int uncv = 0;

	while ((c = getchar()) != EOF) {
		if (! (c & 0x80)) {
			putchar (c);
			continue;
		}

		/* begin of hanzi */
		h = c & 0xff;
		c = getchar ();
		if (c == EOF) {
			putchar (h);
			break;
		}
		l = c & 0xff;

		if ((h < 0xc6) || ((h == 0xc6) && (l <= 0x7e))) {
			/* Frequent BIG5 */
			putchar(h);
			putchar(l);
			continue;
		}
		if ((h > 0xf7) || ((h == 0xf7) && (l > 0x55))) {
			/* non-standard BIG5 */
			putchar(UNCONV_H);
			putchar(UNCONV_L);
			uncv ++;
			continue;
		}

		/* Non-frequnt BIG5 */
		if ((l >= 0xe0) && (l <= 0xfe)) {
			putchar (h + 3);
			putchar (l - 0xe0 + 0xa1);
		} else if ((l >= 0xa1) && (l <= 0xdf)) {
			putchar (h + 3);
			putchar (l - 0xa1 + 0x40);
		} else if ((l >= 0x40) && (l <= 0x7e)) {
			putchar (h + 2);
			putchar (l - 0x40 + 0xc0);
		} else {
			putchar(UNCONV_H);
			putchar(UNCONV_L);
			uncv ++;
		}
	}
	return (uncv);
}