1a8fdb4bcSmrg/*
2a8fdb4bcSmrgCopyright (c) 2002 by Tomohiro KUBOTA
3a8fdb4bcSmrg
4a8fdb4bcSmrgPermission is hereby granted, free of charge, to any person obtaining a copy
5a8fdb4bcSmrgof this software and associated documentation files (the "Software"), to deal
6a8fdb4bcSmrgin the Software without restriction, including without limitation the rights
7a8fdb4bcSmrgto use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8a8fdb4bcSmrgcopies of the Software, and to permit persons to whom the Software is
9a8fdb4bcSmrgfurnished to do so, subject to the following conditions:
10a8fdb4bcSmrg
11a8fdb4bcSmrgThe above copyright notice and this permission notice shall be included in
12a8fdb4bcSmrgall copies or substantial portions of the Software.
13a8fdb4bcSmrg
14a8fdb4bcSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15a8fdb4bcSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16a8fdb4bcSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
17a8fdb4bcSmrgAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18a8fdb4bcSmrgLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19a8fdb4bcSmrgOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20a8fdb4bcSmrgTHE SOFTWARE.
21a8fdb4bcSmrg*/
2277683534Smrg
2377683534Smrg#ifdef HAVE_CONFIG_H
2477683534Smrg# include "config.h"
2577683534Smrg#endif
26a8fdb4bcSmrg
27a8fdb4bcSmrg#include <stdlib.h>
28a8fdb4bcSmrg#include <stdio.h>
29a8fdb4bcSmrg#include <string.h>
30a8fdb4bcSmrg#include <ctype.h>
31a8fdb4bcSmrg#include "other.h"
32a8fdb4bcSmrg
33a8fdb4bcSmrg#ifndef NULL
34a8fdb4bcSmrg#define NULL 0
35a8fdb4bcSmrg#endif
36a8fdb4bcSmrg
37a8fdb4bcSmrg#define EURO_10646 0x20AC
38a8fdb4bcSmrg
39a8fdb4bcSmrgint
40a8fdb4bcSmrginit_gbk(OtherStatePtr s)
41a8fdb4bcSmrg{
42a8fdb4bcSmrg    s->gbk.mapping =
4377683534Smrg	FontEncMapFind("gbk-0", FONT_ENCODING_UNICODE, -1, -1, NULL);
4477683534Smrg    if (!s->gbk.mapping)
4577683534Smrg	return 0;
46a8fdb4bcSmrg
47a8fdb4bcSmrg    s->gbk.reverse = FontMapReverse(s->gbk.mapping);
4877683534Smrg    if (!s->gbk.reverse)
4977683534Smrg	return 0;
50a8fdb4bcSmrg
51a8fdb4bcSmrg    s->gbk.buf = -1;
52a8fdb4bcSmrg    return 1;
53a8fdb4bcSmrg}
54a8fdb4bcSmrg
55a8fdb4bcSmrgunsigned int
56a8fdb4bcSmrgmapping_gbk(unsigned int n, OtherStatePtr s)
57a8fdb4bcSmrg{
58a8fdb4bcSmrg    unsigned int r;
5977683534Smrg    if (n < 128)
6077683534Smrg	return n;
6177683534Smrg    if (n == 128)
6277683534Smrg	return EURO_10646;
63a8fdb4bcSmrg    r = FontEncRecode(n, s->gbk.mapping);
64a8fdb4bcSmrg    return r;
65a8fdb4bcSmrg}
66a8fdb4bcSmrg
67a8fdb4bcSmrgunsigned int
68a8fdb4bcSmrgreverse_gbk(unsigned int n, OtherStatePtr s)
69a8fdb4bcSmrg{
7077683534Smrg    if (n < 128)
7177683534Smrg	return n;
7277683534Smrg    if (n == EURO_10646)
7377683534Smrg	return 128;
74a8fdb4bcSmrg    return s->gbk.reverse->reverse(n, s->gbk.reverse->data);
75a8fdb4bcSmrg}
76a8fdb4bcSmrg
77a8fdb4bcSmrgint
7877683534Smrgstack_gbk(unsigned c, OtherStatePtr s)
79a8fdb4bcSmrg{
8077683534Smrg    if (s->gbk.buf < 0) {
8177683534Smrg	if (c < 129)
8277683534Smrg	    return (int) c;
8377683534Smrg	s->gbk.buf = (int) c;
84a8fdb4bcSmrg	return -1;
85a8fdb4bcSmrg    } else {
8677683534Smrg	int b;
8777683534Smrg	if (c < 0x40 || c == 0x7F) {
8877683534Smrg	    s->gbk.buf = -1;
8977683534Smrg	    return (int) c;
9077683534Smrg	}
9177683534Smrg	if (s->gbk.buf < 0xFF && c < 0xFF)
9277683534Smrg	    b = (int) ((unsigned) (s->gbk.buf << 8) + c);
9377683534Smrg	else
9477683534Smrg	    b = -1;
9577683534Smrg	s->gbk.buf = -1;
9677683534Smrg	return b;
97a8fdb4bcSmrg    }
98a8fdb4bcSmrg}
99a8fdb4bcSmrg
100a8fdb4bcSmrgint
101a8fdb4bcSmrginit_utf8(OtherStatePtr s)
102a8fdb4bcSmrg{
103a8fdb4bcSmrg    s->utf8.buf_ptr = 0;
104a8fdb4bcSmrg    return 1;
105a8fdb4bcSmrg}
106a8fdb4bcSmrg
107a8fdb4bcSmrgunsigned int
10877683534Smrgmapping_utf8(unsigned int n, OtherStatePtr s GCC_UNUSED)
109a8fdb4bcSmrg{
110a8fdb4bcSmrg    return n;
111a8fdb4bcSmrg}
112a8fdb4bcSmrg
113a8fdb4bcSmrgunsigned int
11477683534Smrgreverse_utf8(unsigned int n, OtherStatePtr s GCC_UNUSED)
115a8fdb4bcSmrg{
11677683534Smrg    if (n < 0x80)
11777683534Smrg	return n;
11877683534Smrg    if (n < 0x800)
11977683534Smrg	return 0xC080 + ((n & 0x7C0) << 2) + (n & 0x3F);
12077683534Smrg    if (n < 0x10000)
12177683534Smrg	return 0xE08080 + ((n & 0xF000) << 4) + ((n & 0xFC0) << 2) + (n & 0x3F);
12277683534Smrg    return 0xF0808080 + ((n & 0x1C0000) << 6) + ((n & 0x3F000) << 4) +
12377683534Smrg	((n & 0xFC0) << 2) + (n & 0x3F);
124a8fdb4bcSmrg}
125a8fdb4bcSmrg
126a8fdb4bcSmrgint
12777683534Smrgstack_utf8(unsigned c, OtherStatePtr s)
128a8fdb4bcSmrg{
129a8fdb4bcSmrg    int u;
130a8fdb4bcSmrg
13177683534Smrg    if (c < 0x80) {
13277683534Smrg	s->utf8.buf_ptr = 0;
13377683534Smrg	return (int) c;
134a8fdb4bcSmrg    }
13577683534Smrg    if (s->utf8.buf_ptr == 0) {
13677683534Smrg	if ((c & 0x40) == 0)
13777683534Smrg	    return -1;
13877683534Smrg	s->utf8.buf[s->utf8.buf_ptr++] = UChar(c);
13977683534Smrg	if ((c & 0x60) == 0x40)
14077683534Smrg	    s->utf8.len = 2;
14177683534Smrg	else if ((c & 0x70) == 0x60)
14277683534Smrg	    s->utf8.len = 3;
14377683534Smrg	else if ((c & 0x78) == 0x70)
14477683534Smrg	    s->utf8.len = 4;
14577683534Smrg	else
14677683534Smrg	    s->utf8.buf_ptr = 0;
14777683534Smrg	return -1;
148a8fdb4bcSmrg    }
14977683534Smrg    if ((c & 0x40) != 0) {
15077683534Smrg	s->utf8.buf_ptr = 0;
15177683534Smrg	return -1;
152a8fdb4bcSmrg    }
15377683534Smrg    s->utf8.buf[s->utf8.buf_ptr++] = UChar(c);
15477683534Smrg    if (s->utf8.buf_ptr < s->utf8.len)
15577683534Smrg	return -1;
15677683534Smrg    switch (s->utf8.len) {
157a8fdb4bcSmrg    case 2:
15877683534Smrg	u = ((s->utf8.buf[0] & 0x1F) << 6) | (s->utf8.buf[1] & 0x3F);
15977683534Smrg	s->utf8.buf_ptr = 0;
16077683534Smrg	if (u < 0x80)
16177683534Smrg	    return -1;
16277683534Smrg	else
16377683534Smrg	    return u;
164a8fdb4bcSmrg    case 3:
16577683534Smrg	u = ((s->utf8.buf[0] & 0x0F) << 12)
16677683534Smrg	    | ((s->utf8.buf[1] & 0x3F) << 6)
16777683534Smrg	    | (s->utf8.buf[2] & 0x3F);
16877683534Smrg	s->utf8.buf_ptr = 0;
16977683534Smrg	if (u < 0x800)
17077683534Smrg	    return -1;
17177683534Smrg	else
17277683534Smrg	    return u;
173a8fdb4bcSmrg    case 4:
17477683534Smrg	u = ((s->utf8.buf[0] & 0x03) << 18)
17577683534Smrg	    | ((s->utf8.buf[1] & 0x3F) << 12)
17677683534Smrg	    | ((s->utf8.buf[2] & 0x3F) << 6)
17777683534Smrg	    | ((s->utf8.buf[3] & 0x3F));
17877683534Smrg	s->utf8.buf_ptr = 0;
17977683534Smrg	if (u < 0x10000)
18077683534Smrg	    return -1;
18177683534Smrg	else
18277683534Smrg	    return u;
183a8fdb4bcSmrg    }
184a8fdb4bcSmrg    s->utf8.buf_ptr = 0;
185a8fdb4bcSmrg    return -1;
186a8fdb4bcSmrg}
187a8fdb4bcSmrg
188a8fdb4bcSmrg#define HALFWIDTH_10646 0xFF61
189a8fdb4bcSmrg#define YEN_SJIS 0x5C
190a8fdb4bcSmrg#define YEN_10646 0x00A5
191a8fdb4bcSmrg#define OVERLINE_SJIS 0x7E
192a8fdb4bcSmrg#define OVERLINE_10646 0x203E
193a8fdb4bcSmrg
194a8fdb4bcSmrgint
195a8fdb4bcSmrginit_sjis(OtherStatePtr s)
196a8fdb4bcSmrg{
197a8fdb4bcSmrg    s->sjis.x0208mapping =
19877683534Smrg	FontEncMapFind("jisx0208.1990-0", FONT_ENCODING_UNICODE, -1, -1, NULL);
19977683534Smrg    if (!s->sjis.x0208mapping)
20077683534Smrg	return 0;
201a8fdb4bcSmrg
202a8fdb4bcSmrg    s->sjis.x0208reverse = FontMapReverse(s->sjis.x0208mapping);
20377683534Smrg    if (!s->sjis.x0208reverse)
20477683534Smrg	return 0;
205a8fdb4bcSmrg
206a8fdb4bcSmrg    s->sjis.x0201mapping =
20777683534Smrg	FontEncMapFind("jisx0201.1976-0", FONT_ENCODING_UNICODE, -1, -1, NULL);
20877683534Smrg    if (!s->sjis.x0201mapping)
20977683534Smrg	return 0;
210a8fdb4bcSmrg
211a8fdb4bcSmrg    s->sjis.x0201reverse = FontMapReverse(s->sjis.x0201mapping);
21277683534Smrg    if (!s->sjis.x0201reverse)
21377683534Smrg	return 0;
214a8fdb4bcSmrg
215a8fdb4bcSmrg    s->sjis.buf = -1;
216a8fdb4bcSmrg    return 1;
217a8fdb4bcSmrg}
218a8fdb4bcSmrg
219a8fdb4bcSmrgunsigned int
220a8fdb4bcSmrgmapping_sjis(unsigned int n, OtherStatePtr s)
221a8fdb4bcSmrg{
222a8fdb4bcSmrg    unsigned int j1, j2, s1, s2;
22377683534Smrg    if (n == YEN_SJIS)
22477683534Smrg	return YEN_10646;
22577683534Smrg    if (n == OVERLINE_SJIS)
22677683534Smrg	return OVERLINE_10646;
22777683534Smrg    if (n < 0x80)
22877683534Smrg	return n;
22977683534Smrg    if (n >= 0xA0 && n <= 0xDF)
23077683534Smrg	return FontEncRecode(n, s->sjis.x0201mapping);
23177683534Smrg    s1 = ((n >> 8) & 0xFF);
23277683534Smrg    s2 = (n & 0xFF);
23377683534Smrg    j1 = (s1 << 1)
23477683534Smrg	- (unsigned) (s1 <= 0x9F ? 0xE0 : 0x160)
23577683534Smrg	- (unsigned) (s2 < 0x9F ? 1 : 0);
23677683534Smrg    j2 = s2
23777683534Smrg	- 0x1F
23877683534Smrg	- (unsigned) (s2 >= 0x7F ? 1 : 0)
23977683534Smrg	- (unsigned) (s2 >= 0x9F ? 0x5E : 0);
24077683534Smrg    return FontEncRecode((j1 << 8) + j2, s->sjis.x0208mapping);
241a8fdb4bcSmrg}
242a8fdb4bcSmrg
243a8fdb4bcSmrgunsigned int
244a8fdb4bcSmrgreverse_sjis(unsigned int n, OtherStatePtr s)
245a8fdb4bcSmrg{
246a8fdb4bcSmrg    unsigned int j, j1, j2, s1, s2;
24777683534Smrg    if (n == YEN_10646)
24877683534Smrg	return YEN_SJIS;
24977683534Smrg    if (n == OVERLINE_10646)
25077683534Smrg	return OVERLINE_SJIS;
25177683534Smrg    if (n < 0x80)
25277683534Smrg	return n;
25377683534Smrg    if (n >= HALFWIDTH_10646)
25477683534Smrg	return s->sjis.x0201reverse->reverse(n, s->sjis.x0201reverse->data);
255a8fdb4bcSmrg    j = s->sjis.x0208reverse->reverse(n, s->sjis.x0208reverse->data);
25677683534Smrg    j1 = ((j >> 8) & 0xFF);
25777683534Smrg    j2 = (j & 0xFF);
25877683534Smrg    s1 = ((j1 - 1) >> 1)
25977683534Smrg	+ (unsigned) ((j1 <= 0x5E) ? 0x71 : 0xB1);
26077683534Smrg    s2 = j2
26177683534Smrg	+ (unsigned) ((j1 & 1) ? ((j2 < 0x60) ? 0x1F : 0x20) : 0x7E);
26277683534Smrg    return (s1 << 8) + s2;
263a8fdb4bcSmrg}
264a8fdb4bcSmrg
265a8fdb4bcSmrgint
26677683534Smrgstack_sjis(unsigned c, OtherStatePtr s)
267a8fdb4bcSmrg{
26877683534Smrg    if (s->sjis.buf < 0) {
26977683534Smrg	if (c < 128 || (c >= 0xA0 && c <= 0xDF))
27077683534Smrg	    return (int) c;
27177683534Smrg	s->sjis.buf = (int) c;
272a8fdb4bcSmrg	return -1;
273a8fdb4bcSmrg    } else {
27477683534Smrg	int b;
27577683534Smrg	if (c < 0x40 || c == 0x7F) {
27677683534Smrg	    s->sjis.buf = -1;
27777683534Smrg	    return (int) c;
27877683534Smrg	}
27977683534Smrg	if (s->sjis.buf < 0xFF && c < 0xFF)
28077683534Smrg	    b = (int) ((unsigned) (s->sjis.buf << 8) + c);
28177683534Smrg	else
28277683534Smrg	    b = -1;
28377683534Smrg	s->sjis.buf = -1;
28477683534Smrg	return b;
285a8fdb4bcSmrg    }
286a8fdb4bcSmrg}
287a8fdb4bcSmrg
288a8fdb4bcSmrgint
289a8fdb4bcSmrginit_hkscs(OtherStatePtr s)
290a8fdb4bcSmrg{
291a8fdb4bcSmrg    s->hkscs.mapping =
29277683534Smrg	FontEncMapFind("big5hkscs-0", FONT_ENCODING_UNICODE, -1, -1, NULL);
29377683534Smrg    if (!s->hkscs.mapping)
29477683534Smrg	return 0;
295a8fdb4bcSmrg
296a8fdb4bcSmrg    s->hkscs.reverse = FontMapReverse(s->hkscs.mapping);
29777683534Smrg    if (!s->hkscs.reverse)
29877683534Smrg	return 0;
299a8fdb4bcSmrg
300a8fdb4bcSmrg    s->hkscs.buf = -1;
301a8fdb4bcSmrg    return 1;
302a8fdb4bcSmrg}
303a8fdb4bcSmrg
304a8fdb4bcSmrgunsigned int
305a8fdb4bcSmrgmapping_hkscs(unsigned int n, OtherStatePtr s)
306a8fdb4bcSmrg{
307a8fdb4bcSmrg    unsigned int r;
30877683534Smrg    if (n < 128)
30977683534Smrg	return n;
31077683534Smrg    if (n == 128)
31177683534Smrg	return EURO_10646;
312a8fdb4bcSmrg    r = FontEncRecode(n, s->hkscs.mapping);
313a8fdb4bcSmrg    return r;
314a8fdb4bcSmrg}
315a8fdb4bcSmrg
316a8fdb4bcSmrgunsigned int
317a8fdb4bcSmrgreverse_hkscs(unsigned int n, OtherStatePtr s)
318a8fdb4bcSmrg{
31977683534Smrg    if (n < 128)
32077683534Smrg	return n;
32177683534Smrg    if (n == EURO_10646)
32277683534Smrg	return 128;
323a8fdb4bcSmrg    return s->hkscs.reverse->reverse(n, s->hkscs.reverse->data);
324a8fdb4bcSmrg}
325a8fdb4bcSmrg
326a8fdb4bcSmrgint
32777683534Smrgstack_hkscs(unsigned c, OtherStatePtr s)
328a8fdb4bcSmrg{
32977683534Smrg    if (s->hkscs.buf < 0) {
33077683534Smrg	if (c < 129)
33177683534Smrg	    return (int) c;
33277683534Smrg	s->hkscs.buf = (int) c;
333a8fdb4bcSmrg	return -1;
334a8fdb4bcSmrg    } else {
33577683534Smrg	int b;
33677683534Smrg	if (c < 0x40 || c == 0x7F) {
33777683534Smrg	    s->hkscs.buf = -1;
33877683534Smrg	    return (int) c;
33977683534Smrg	}
34077683534Smrg	if (s->hkscs.buf < 0xFF && c < 0xFF)
34177683534Smrg	    b = (int) ((unsigned) (s->hkscs.buf << 8) + c);
34277683534Smrg	else
34377683534Smrg	    b = -1;
34477683534Smrg	s->hkscs.buf = -1;
34577683534Smrg	return b;
346a8fdb4bcSmrg    }
347a8fdb4bcSmrg}
348a8fdb4bcSmrg
349a8fdb4bcSmrg/*
350a8fdb4bcSmrg *  Because of the 1 ~ 4 multi-bytes nature of GB18030.
351a8fdb4bcSmrg *  CharSet encoding is split to 2 subset (besides latin)
352a8fdb4bcSmrg *  The 2Bytes MB char is defined in gb18030.2000-0
353a8fdb4bcSmrg *  The 4Bytes MB char is defined in gb18030.2000-1
354a8fdb4bcSmrg *  Please note that the mapping in 2000-1 is not a 4Bytes seq => 2Bytes value
355a8fdb4bcSmrg *  mapping.
356a8fdb4bcSmrg *  To use the 2000-1 we need to 'linear' the 4Bytes sequence and 'lookup' the
357a8fdb4bcSmrg *  unicode value after that.
358a8fdb4bcSmrg *
359a8fdb4bcSmrg *  For more info on GB18030 standard pls check:
360a8fdb4bcSmrg *    http://oss.software.ibm.com/icu/docs/papers/gb18030.html
361a8fdb4bcSmrg *
362a8fdb4bcSmrg *  For more info on GB18030 implementation issues in XFree86 pls check:
363a8fdb4bcSmrg *    http://www.ibm.com/developerWorks/cn/linux/i18n/gb18030/xfree86/part1
364a8fdb4bcSmrg */
365a8fdb4bcSmrgint
366a8fdb4bcSmrginit_gb18030(OtherStatePtr s)
367a8fdb4bcSmrg{
368a8fdb4bcSmrg    s->gb18030.cs0_mapping =
36977683534Smrg	FontEncMapFind("gb18030.2000-0", FONT_ENCODING_UNICODE, -1, -1, NULL);
37077683534Smrg    if (!s->gb18030.cs0_mapping)
37177683534Smrg	return 0;
372a8fdb4bcSmrg
373a8fdb4bcSmrg    s->gb18030.cs0_reverse = FontMapReverse(s->gb18030.cs0_mapping);
37477683534Smrg    if (!s->gb18030.cs0_reverse)
37577683534Smrg	return 0;
376a8fdb4bcSmrg
377a8fdb4bcSmrg    s->gb18030.cs1_mapping =
37877683534Smrg	FontEncMapFind("gb18030.2000-1", FONT_ENCODING_UNICODE, -1, -1, NULL);
37977683534Smrg    if (!s->gb18030.cs1_mapping)
38077683534Smrg	return 0;
381a8fdb4bcSmrg
382a8fdb4bcSmrg    s->gb18030.cs1_reverse = FontMapReverse(s->gb18030.cs1_mapping);
38377683534Smrg    if (!s->gb18030.cs1_reverse)
38477683534Smrg	return 0;
385a8fdb4bcSmrg
38677683534Smrg    s->gb18030.linear = 0;
387a8fdb4bcSmrg    s->gb18030.buf_ptr = 0;
388a8fdb4bcSmrg    return 1;
389a8fdb4bcSmrg}
390a8fdb4bcSmrg
391a8fdb4bcSmrgunsigned int
392a8fdb4bcSmrgmapping_gb18030(unsigned int n, OtherStatePtr s)
393a8fdb4bcSmrg{
39477683534Smrg    if (n <= 0x80)
39577683534Smrg	return n;		/* 0x80 is valid but unassigned codepoint */
39677683534Smrg    if (n >= 0xFFFF)
39777683534Smrg	return '?';
39877683534Smrg
399a8fdb4bcSmrg    return FontEncRecode(n,
40077683534Smrg			 (s->gb18030.linear) ? s->gb18030.cs1_mapping : s->gb18030.cs0_mapping);
401a8fdb4bcSmrg}
402a8fdb4bcSmrg
403a8fdb4bcSmrgunsigned int
404a8fdb4bcSmrgreverse_gb18030(unsigned int n, OtherStatePtr s)
405a8fdb4bcSmrg{
406a8fdb4bcSmrg    /* when lookup in 2000-0 failed. */
407a8fdb4bcSmrg    /* lookup in 2000-1 and then try to unlinear'd */
408a8fdb4bcSmrg    unsigned int r;
40977683534Smrg    if (n <= 0x80)
41077683534Smrg	return n;
411a8fdb4bcSmrg
412a8fdb4bcSmrg    r = s->gb18030.cs0_reverse->reverse(n, s->gb18030.cs0_reverse->data);
413a8fdb4bcSmrg    if (r != 0)
41477683534Smrg	return r;
415a8fdb4bcSmrg
416a8fdb4bcSmrg    r = s->gb18030.cs1_reverse->reverse(n, s->gb18030.cs1_reverse->data);
417a8fdb4bcSmrg    if (r != 0) {
41877683534Smrg	unsigned char bytes[4];
41977683534Smrg
42077683534Smrg	bytes[3] = UChar(0x30 + r % 10);
42177683534Smrg	r /= 10;
42277683534Smrg	bytes[2] = UChar(0x81 + r % 126);
42377683534Smrg	r /= 126;
42477683534Smrg	bytes[1] = UChar(0x30 + r % 10);
42577683534Smrg	r /= 10;
42677683534Smrg	bytes[0] = UChar(0x81 + r);
42777683534Smrg
42877683534Smrg	r = (unsigned int) bytes[0] << 24;
42977683534Smrg	r |= (unsigned int) bytes[1] << 16;
43077683534Smrg	r |= (unsigned int) bytes[2] << 8;
43177683534Smrg	r |= (unsigned int) bytes[3];
432a8fdb4bcSmrg    }
433a8fdb4bcSmrg    return r;
434a8fdb4bcSmrg}
435a8fdb4bcSmrg
436a8fdb4bcSmrgint
43777683534Smrgstack_gb18030(unsigned c, OtherStatePtr s)
438a8fdb4bcSmrg{
439a8fdb4bcSmrg    /* if set gb18030.linear => True. the return value is "linear'd" */
44077683534Smrg    if (s->gb18030.buf_ptr == 0) {
44177683534Smrg	if (c <= 0x80)
44277683534Smrg	    return (int) c;
44377683534Smrg	if (c == 0xFF)
44477683534Smrg	    return -1;
44577683534Smrg	s->gb18030.linear = 0;
44677683534Smrg	s->gb18030.buf[s->gb18030.buf_ptr++] = (int) c;
44777683534Smrg	return -1;
448a8fdb4bcSmrg    } else if (s->gb18030.buf_ptr == 1) {
44977683534Smrg	if (c >= 0x40) {
45077683534Smrg	    s->gb18030.buf_ptr = 0;
45177683534Smrg	    if ((c == 0x80) || (c == 0xFF))
45277683534Smrg		return -1;
45377683534Smrg	    else
45477683534Smrg		return (int) ((unsigned) (s->gb18030.buf[0] << 8) + c);
45577683534Smrg	} else if (c >= 30) {	/* 2Byte is (0x30 -> 0x39) */
45677683534Smrg	    s->gb18030.buf[s->gb18030.buf_ptr++] = (int) c;
45777683534Smrg	    return -1;
45877683534Smrg	} else {
45977683534Smrg	    s->gb18030.buf_ptr = 0;
46077683534Smrg	    return (int) c;
46177683534Smrg	}
462a8fdb4bcSmrg    } else if (s->gb18030.buf_ptr == 2) {
46377683534Smrg	if ((c >= 0x81) && (c <= 0xFE)) {
46477683534Smrg	    s->gb18030.buf[s->gb18030.buf_ptr++] = (int) c;
46577683534Smrg	    return -1;
46677683534Smrg	} else {
46777683534Smrg	    s->gb18030.buf_ptr = 0;
46877683534Smrg	    return (int) c;
46977683534Smrg	}
470a8fdb4bcSmrg    } else {
47177683534Smrg	int r = 0;
47277683534Smrg	s->gb18030.buf_ptr = 0;
47377683534Smrg	if ((c >= 0x30) && (c <= 0x39)) {
47477683534Smrg	    s->gb18030.linear = 1;
47577683534Smrg	    r = (((s->gb18030.buf[0] - 0x81) * 10
47677683534Smrg		  + (s->gb18030.buf[1] - 0x30)) * 126
47777683534Smrg		 + (s->gb18030.buf[2] - 0x81)) * 10
47877683534Smrg		+ ((int) c - 0x30);
47977683534Smrg	    return r;
48077683534Smrg	}
48177683534Smrg	return -1;
482a8fdb4bcSmrg    }
483a8fdb4bcSmrg}
484