xref: /plan9/sys/src/cmd/tcs/jis.h (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
13e12c5d1SDavid du Colombier /*
2*219b2ee8SDavid du Colombier 	following astonishing goo courtesy of kogure.
33e12c5d1SDavid du Colombier */
43e12c5d1SDavid du Colombier /*
53e12c5d1SDavid du Colombier  * MicroSoft Kanji Encoding (SJIS) Transformation
63e12c5d1SDavid du Colombier  */
73e12c5d1SDavid du Colombier 
83e12c5d1SDavid du Colombier /*
93e12c5d1SDavid du Colombier  * void
103e12c5d1SDavid du Colombier  * J2S(unsigned char *_h, unsigned char *_l)
11*219b2ee8SDavid du Colombier  *	JIS X 208 to MS kanji transformation.
123e12c5d1SDavid du Colombier  *
133e12c5d1SDavid du Colombier  * Calling/Exit State:
143e12c5d1SDavid du Colombier  *	_h and _l should be in their valid range.
153e12c5d1SDavid du Colombier  *	No return value.
163e12c5d1SDavid du Colombier  */
173e12c5d1SDavid du Colombier #define J2S(_h, _l) { \
183e12c5d1SDavid du Colombier 	/* lower: 21-7e >> 40-9d,9e-fb >> 40-7e,(skip 7f),80-fc */ \
193e12c5d1SDavid du Colombier 	if (((_l) += (((_h)-- % 2) ? 0x1f : 0x7d)) > 0x7e) (_l)++; \
203e12c5d1SDavid du Colombier 	/* upper: 21-7e >> 81-af >> 81-9f,(skip a0-df),e0-ef */ \
213e12c5d1SDavid du Colombier 	if (((_h) = ((_h) / 2 + 0x71)) > 0x9f) (_h) += 0x40; \
223e12c5d1SDavid du Colombier }
233e12c5d1SDavid du Colombier 
243e12c5d1SDavid du Colombier /*
253e12c5d1SDavid du Colombier  * void
263e12c5d1SDavid du Colombier  * S2J(unsigned char *_h, unsigned char *_l)
27*219b2ee8SDavid du Colombier  *	MS kanji to JIS X 208 transformation.
283e12c5d1SDavid du Colombier  *
293e12c5d1SDavid du Colombier  * Calling/Exit State:
303e12c5d1SDavid du Colombier  *	_h and _l should be in valid range.
313e12c5d1SDavid du Colombier  *	No return value.
323e12c5d1SDavid du Colombier  */
333e12c5d1SDavid du Colombier #define S2J(_h, _l) { \
343e12c5d1SDavid du Colombier 	/* lower: 40-7e,80-fc >> 21-5f,61-dd >> 21-7e,7f-dc */ \
353e12c5d1SDavid du Colombier 	if (((_l) -= 0x1f) > 0x60) (_l)--; \
363e12c5d1SDavid du Colombier 	/* upper: 81-9f,e0-ef >> 00-1e,5f-6e >> 00-2e >> 21-7d */ \
373e12c5d1SDavid du Colombier 	if (((_h) -= 0x81) > 0x5e) (_h) -= 0x40; (_h) *= 2, (_h) += 0x21; \
383e12c5d1SDavid du Colombier 	/* upper: ,21-7d >> ,22-7e ; lower: ,7f-dc >> ,21-7e */ \
393e12c5d1SDavid du Colombier 	if ((_l) > 0x7e) (_h)++, (_l) -= 0x5e; \
403e12c5d1SDavid du Colombier }
413e12c5d1SDavid du Colombier 
423e12c5d1SDavid du Colombier /*
433e12c5d1SDavid du Colombier  * int
443e12c5d1SDavid du Colombier  * ISJKANA(const unsigned char *_b)
453e12c5d1SDavid du Colombier  *	Tests given byte is in the range of JIS X 0201 katakana.
463e12c5d1SDavid du Colombier  *
473e12c5d1SDavid du Colombier  * Calling/Exit State:
483e12c5d1SDavid du Colombier  *	Returns 1 if it is, or 0 otherwise.
493e12c5d1SDavid du Colombier  */
503e12c5d1SDavid du Colombier #define	ISJKANA(_b)	(0xa0 <= (_b) && (_b) < 0xe0)
513e12c5d1SDavid du Colombier 
523e12c5d1SDavid du Colombier /*
533e12c5d1SDavid du Colombier  * int
543e12c5d1SDavid du Colombier  * CANS2JH(const unsigned char *_h)
553e12c5d1SDavid du Colombier  *	Tests given byte is in the range of valid first byte of MS
563e12c5d1SDavid du Colombier  *	kanji code; either acts as a subroutine of CANS2J() macro
573e12c5d1SDavid du Colombier  *	or can be used to parse MS kanji encoded strings.
583e12c5d1SDavid du Colombier  *
593e12c5d1SDavid du Colombier  * Calling/Exit State:
603e12c5d1SDavid du Colombier  *	Returns 1 if it is, or 0 otherwise.
613e12c5d1SDavid du Colombier  */
623e12c5d1SDavid du Colombier #define CANS2JH(_h)	((0x81 <= (_h) && (_h) < 0xf0) && !ISJKANA(_h))
633e12c5d1SDavid du Colombier 
643e12c5d1SDavid du Colombier /*
653e12c5d1SDavid du Colombier  * int
663e12c5d1SDavid du Colombier  * CANS2JL(const unsigned char *_l)
673e12c5d1SDavid du Colombier  *	Tests given byte is in the range of valid second byte of MS
683e12c5d1SDavid du Colombier  *	kanji code; acts as a subroutine of CANS2J() macro.
693e12c5d1SDavid du Colombier  *
703e12c5d1SDavid du Colombier  * Calling/Exit State:
713e12c5d1SDavid du Colombier  *	Returns 1 if it is, or 0 otherwise.
723e12c5d1SDavid du Colombier  */
733e12c5d1SDavid du Colombier #define CANS2JL(_l)	(0x40 <= (_l) && (_l) < 0xfd && (_l) != 0x7f)
743e12c5d1SDavid du Colombier 
753e12c5d1SDavid du Colombier /*
763e12c5d1SDavid du Colombier  * int
773e12c5d1SDavid du Colombier  * CANS2J(const unsigned char *_h, const unsinged char *_l)
783e12c5d1SDavid du Colombier  *	Tests given bytes form a MS kanji code point which can be
79*219b2ee8SDavid du Colombier  *	transformed to a valid JIS X 208 code point.
803e12c5d1SDavid du Colombier  *
813e12c5d1SDavid du Colombier  * Calling/Exit State:
823e12c5d1SDavid du Colombier  *	Returns 1 if they are, or 0 otherwise.
833e12c5d1SDavid du Colombier  */
843e12c5d1SDavid du Colombier #define CANS2J(_h, _l)  (CANS2JH(_h) && CANS2JL(_l))
853e12c5d1SDavid du Colombier 
863e12c5d1SDavid du Colombier /*
873e12c5d1SDavid du Colombier  * int
883e12c5d1SDavid du Colombier  * CANJ2SB(const unsigned char *_b)
893e12c5d1SDavid du Colombier  *	Tests given bytes is in the range of valid 94 graphic
903e12c5d1SDavid du Colombier  *	character set; acts as a subroutine of CANJ2S() macro.
913e12c5d1SDavid du Colombier  *
923e12c5d1SDavid du Colombier  * Calling/Exit State:
933e12c5d1SDavid du Colombier  *	Returns 1 if it is, or 0 otherwise.
943e12c5d1SDavid du Colombier  */
953e12c5d1SDavid du Colombier #define CANJ2SB(_b)	(0x21 <= (_b) && (_b) < 0x7f)
963e12c5d1SDavid du Colombier 
973e12c5d1SDavid du Colombier /*
983e12c5d1SDavid du Colombier  * int
993e12c5d1SDavid du Colombier  * CANJ2S(const unsigned char *_h, const unsigned char *_l)
100*219b2ee8SDavid du Colombier  *	Tests given bytes form valid JIS X 208 code points
1013e12c5d1SDavid du Colombier  *	(which can be transformed to MS kanji).
1023e12c5d1SDavid du Colombier  *
1033e12c5d1SDavid du Colombier  * Calling/Exit State:
1043e12c5d1SDavid du Colombier  *	Returns 1 if they are, or 0 otherwise.
1053e12c5d1SDavid du Colombier  */
1063e12c5d1SDavid du Colombier #define CANJ2S(_h, _l)	(CANJ2SB(_h) && CANJ2SB(_l))
1073e12c5d1SDavid du Colombier 
108