other.c revision a8fdb4bc
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*/ 22a8fdb4bcSmrg/* $XFree86: xc/programs/luit/other.c,v 1.1 2002/10/17 01:06:09 dawes Exp $ */ 23a8fdb4bcSmrg 24a8fdb4bcSmrg#include <stdlib.h> 25a8fdb4bcSmrg#include <stdio.h> 26a8fdb4bcSmrg#include <string.h> 27a8fdb4bcSmrg#include <ctype.h> 28a8fdb4bcSmrg#include <X11/fonts/fontenc.h> 29a8fdb4bcSmrg#include "other.h" 30a8fdb4bcSmrg#include "charset.h" 31a8fdb4bcSmrg 32a8fdb4bcSmrg#ifndef NULL 33a8fdb4bcSmrg#define NULL 0 34a8fdb4bcSmrg#endif 35a8fdb4bcSmrg 36a8fdb4bcSmrg#define EURO_10646 0x20AC 37a8fdb4bcSmrg 38a8fdb4bcSmrgint 39a8fdb4bcSmrginit_gbk(OtherStatePtr s) 40a8fdb4bcSmrg{ 41a8fdb4bcSmrg s->gbk.mapping = 42a8fdb4bcSmrg FontEncMapFind("gbk-0", FONT_ENCODING_UNICODE, -1, -1, NULL); 43a8fdb4bcSmrg if(!s->gbk.mapping) return 0; 44a8fdb4bcSmrg 45a8fdb4bcSmrg s->gbk.reverse = FontMapReverse(s->gbk.mapping); 46a8fdb4bcSmrg if(!s->gbk.reverse) return 0; 47a8fdb4bcSmrg 48a8fdb4bcSmrg s->gbk.buf = -1; 49a8fdb4bcSmrg return 1; 50a8fdb4bcSmrg} 51a8fdb4bcSmrg 52a8fdb4bcSmrgunsigned int 53a8fdb4bcSmrgmapping_gbk(unsigned int n, OtherStatePtr s) 54a8fdb4bcSmrg{ 55a8fdb4bcSmrg unsigned int r; 56a8fdb4bcSmrg if(n < 128) return n; 57a8fdb4bcSmrg if(n == 128) return EURO_10646; 58a8fdb4bcSmrg r = FontEncRecode(n, s->gbk.mapping); 59a8fdb4bcSmrg return r; 60a8fdb4bcSmrg} 61a8fdb4bcSmrg 62a8fdb4bcSmrgunsigned int 63a8fdb4bcSmrgreverse_gbk(unsigned int n, OtherStatePtr s) 64a8fdb4bcSmrg{ 65a8fdb4bcSmrg if(n < 128) return n; 66a8fdb4bcSmrg if(n == EURO_10646) return 128; 67a8fdb4bcSmrg return s->gbk.reverse->reverse(n, s->gbk.reverse->data); 68a8fdb4bcSmrg} 69a8fdb4bcSmrg 70a8fdb4bcSmrgint 71a8fdb4bcSmrgstack_gbk(unsigned char c, OtherStatePtr s) 72a8fdb4bcSmrg{ 73a8fdb4bcSmrg if(s->gbk.buf < 0) { 74a8fdb4bcSmrg if(c < 129) return c; 75a8fdb4bcSmrg s->gbk.buf = c; 76a8fdb4bcSmrg return -1; 77a8fdb4bcSmrg } else { 78a8fdb4bcSmrg int b; 79a8fdb4bcSmrg if(c < 0x40 || c == 0x7F) { 80a8fdb4bcSmrg s->gbk.buf = -1; 81a8fdb4bcSmrg return c; 82a8fdb4bcSmrg } 83a8fdb4bcSmrg if(s->gbk.buf < 0xFF && c < 0xFF) 84a8fdb4bcSmrg b = (s->gbk.buf << 8) + c; 85a8fdb4bcSmrg else 86a8fdb4bcSmrg b = -1; 87a8fdb4bcSmrg s->gbk.buf = -1; 88a8fdb4bcSmrg return b; 89a8fdb4bcSmrg } 90a8fdb4bcSmrg} 91a8fdb4bcSmrg 92a8fdb4bcSmrgint 93a8fdb4bcSmrginit_utf8(OtherStatePtr s) 94a8fdb4bcSmrg{ 95a8fdb4bcSmrg s->utf8.buf_ptr = 0; 96a8fdb4bcSmrg return 1; 97a8fdb4bcSmrg} 98a8fdb4bcSmrg 99a8fdb4bcSmrgunsigned int 100a8fdb4bcSmrgmapping_utf8(unsigned int n, OtherStatePtr s) 101a8fdb4bcSmrg{ 102a8fdb4bcSmrg return n; 103a8fdb4bcSmrg} 104a8fdb4bcSmrg 105a8fdb4bcSmrgunsigned int 106a8fdb4bcSmrgreverse_utf8(unsigned int n, OtherStatePtr s) 107a8fdb4bcSmrg{ 108a8fdb4bcSmrg if(n < 0x80) 109a8fdb4bcSmrg return n; 110a8fdb4bcSmrg if(n < 0x800) 111a8fdb4bcSmrg return 0xC080 + ((n&0x7C0)<<2) + (n&0x3F); 112a8fdb4bcSmrg if(n < 0x10000) 113a8fdb4bcSmrg return 0xE08080 + ((n&0xF000)<<4) + ((n&0xFC0)<<2) + (n&0x3F); 114a8fdb4bcSmrg return 0xF0808080 + ((n&0x1C0000)<<6) + ((n&0x3F000)<<4) + 115a8fdb4bcSmrg ((n&0xFC0)<<2) + (n&0x3F); 116a8fdb4bcSmrg} 117a8fdb4bcSmrg 118a8fdb4bcSmrgint 119a8fdb4bcSmrgstack_utf8(unsigned char c, OtherStatePtr s) 120a8fdb4bcSmrg{ 121a8fdb4bcSmrg int u; 122a8fdb4bcSmrg 123a8fdb4bcSmrg if(c < 0x80) { 124a8fdb4bcSmrg s->utf8.buf_ptr = 0; 125a8fdb4bcSmrg return c; 126a8fdb4bcSmrg } 127a8fdb4bcSmrg if(s->utf8.buf_ptr == 0) { 128a8fdb4bcSmrg if((c & 0x40) == 0) return -1; 129a8fdb4bcSmrg s->utf8.buf[s->utf8.buf_ptr++] = c; 130a8fdb4bcSmrg if((c & 0x60) == 0x40) s->utf8.len = 2; 131a8fdb4bcSmrg else if((c & 0x70) == 0x60) s->utf8.len = 3; 132a8fdb4bcSmrg else if((c & 0x78) == 0x70) s->utf8.len = 4; 133a8fdb4bcSmrg else s->utf8.buf_ptr = 0; 134a8fdb4bcSmrg return -1; 135a8fdb4bcSmrg } 136a8fdb4bcSmrg if((c & 0x40) != 0) { 137a8fdb4bcSmrg s->utf8.buf_ptr = 0; 138a8fdb4bcSmrg return -1; 139a8fdb4bcSmrg } 140a8fdb4bcSmrg s->utf8.buf[s->utf8.buf_ptr++] = c; 141a8fdb4bcSmrg if(s->utf8.buf_ptr < s->utf8.len) return -1; 142a8fdb4bcSmrg switch(s->utf8.len) { 143a8fdb4bcSmrg case 2: 144a8fdb4bcSmrg u = ((s->utf8.buf[0] & 0x1F) << 6) | (s->utf8.buf[1] & 0x3F); 145a8fdb4bcSmrg s->utf8.buf_ptr = 0; 146a8fdb4bcSmrg if(u < 0x80) return -1; else return u; 147a8fdb4bcSmrg case 3: 148a8fdb4bcSmrg u = ((s->utf8.buf[0] & 0x0F) << 12) 149a8fdb4bcSmrg | ((s->utf8.buf[1] & 0x3F) << 6) 150a8fdb4bcSmrg | (s->utf8.buf[2] & 0x3F); 151a8fdb4bcSmrg s->utf8.buf_ptr = 0; 152a8fdb4bcSmrg if(u < 0x800) return -1; else return u; 153a8fdb4bcSmrg case 4: 154a8fdb4bcSmrg u = ((s->utf8.buf[0] & 0x03) << 18) 155a8fdb4bcSmrg | ((s->utf8.buf[1] & 0x3F) << 12) 156a8fdb4bcSmrg | ((s->utf8.buf[2] & 0x3F) << 6) 157a8fdb4bcSmrg | ((s->utf8.buf[3] & 0x3F)); 158a8fdb4bcSmrg s->utf8.buf_ptr = 0; 159a8fdb4bcSmrg if(u < 0x10000) return -1; else return u; 160a8fdb4bcSmrg } 161a8fdb4bcSmrg s->utf8.buf_ptr = 0; 162a8fdb4bcSmrg return -1; 163a8fdb4bcSmrg} 164a8fdb4bcSmrg 165a8fdb4bcSmrg 166a8fdb4bcSmrg#define HALFWIDTH_10646 0xFF61 167a8fdb4bcSmrg#define YEN_SJIS 0x5C 168a8fdb4bcSmrg#define YEN_10646 0x00A5 169a8fdb4bcSmrg#define OVERLINE_SJIS 0x7E 170a8fdb4bcSmrg#define OVERLINE_10646 0x203E 171a8fdb4bcSmrg 172a8fdb4bcSmrgint 173a8fdb4bcSmrginit_sjis(OtherStatePtr s) 174a8fdb4bcSmrg{ 175a8fdb4bcSmrg s->sjis.x0208mapping = 176a8fdb4bcSmrg FontEncMapFind("jisx0208.1990-0", FONT_ENCODING_UNICODE, -1, -1, NULL); 177a8fdb4bcSmrg if(!s->sjis.x0208mapping) return 0; 178a8fdb4bcSmrg 179a8fdb4bcSmrg s->sjis.x0208reverse = FontMapReverse(s->sjis.x0208mapping); 180a8fdb4bcSmrg if(!s->sjis.x0208reverse) return 0; 181a8fdb4bcSmrg 182a8fdb4bcSmrg s->sjis.x0201mapping = 183a8fdb4bcSmrg FontEncMapFind("jisx0201.1976-0", FONT_ENCODING_UNICODE, -1, -1, NULL); 184a8fdb4bcSmrg if(!s->sjis.x0201mapping) return 0; 185a8fdb4bcSmrg 186a8fdb4bcSmrg s->sjis.x0201reverse = FontMapReverse(s->sjis.x0201mapping); 187a8fdb4bcSmrg if(!s->sjis.x0201reverse) return 0; 188a8fdb4bcSmrg 189a8fdb4bcSmrg s->sjis.buf = -1; 190a8fdb4bcSmrg return 1; 191a8fdb4bcSmrg} 192a8fdb4bcSmrg 193a8fdb4bcSmrgunsigned int 194a8fdb4bcSmrgmapping_sjis(unsigned int n, OtherStatePtr s) 195a8fdb4bcSmrg{ 196a8fdb4bcSmrg unsigned int j1, j2, s1, s2; 197a8fdb4bcSmrg if(n == YEN_SJIS) return YEN_10646; 198a8fdb4bcSmrg if(n == OVERLINE_SJIS) return OVERLINE_10646; 199a8fdb4bcSmrg if(n < 0x80) return n; 200a8fdb4bcSmrg if(n >= 0xA0 && n <= 0xDF) return FontEncRecode(n, s->sjis.x0201mapping); 201a8fdb4bcSmrg s1 = ((n>>8)&0xFF); 202a8fdb4bcSmrg s2 = (n&0xFF); 203a8fdb4bcSmrg j1 = (s1 << 1) - (s1 <= 0x9F ? 0xE0 : 0x160) - (s2 < 0x9F ? 1 : 0); 204a8fdb4bcSmrg j2 = s2 - 0x1F - (s2 >= 0x7F ? 1 : 0) - (s2 >= 0x9F ? 0x5E : 0); 205a8fdb4bcSmrg return FontEncRecode((j1<<8) + j2, s->sjis.x0208mapping); 206a8fdb4bcSmrg} 207a8fdb4bcSmrg 208a8fdb4bcSmrgunsigned int 209a8fdb4bcSmrgreverse_sjis(unsigned int n, OtherStatePtr s) 210a8fdb4bcSmrg{ 211a8fdb4bcSmrg unsigned int j, j1, j2, s1, s2; 212a8fdb4bcSmrg if(n == YEN_10646) return YEN_SJIS; 213a8fdb4bcSmrg if(n == OVERLINE_10646) return OVERLINE_SJIS; 214a8fdb4bcSmrg if(n < 0x80) return n; 215a8fdb4bcSmrg if(n >= HALFWIDTH_10646) 216a8fdb4bcSmrg return s->sjis.x0201reverse->reverse(n, s->sjis.x0201reverse->data); 217a8fdb4bcSmrg j = s->sjis.x0208reverse->reverse(n, s->sjis.x0208reverse->data); 218a8fdb4bcSmrg j1 = ((j>>8)&0xFF); 219a8fdb4bcSmrg j2 = (j&0xFF); 220a8fdb4bcSmrg s1 = ((j1 - 1) >> 1) + ((j1 <= 0x5E) ? 0x71 : 0xB1); 221a8fdb4bcSmrg s2 = j2 + ((j1 & 1) ? ((j2 < 0x60) ? 0x1F : 0x20) : 0x7E); 222a8fdb4bcSmrg return (s1<<8) + s2; 223a8fdb4bcSmrg} 224a8fdb4bcSmrg 225a8fdb4bcSmrgint 226a8fdb4bcSmrgstack_sjis(unsigned char c, OtherStatePtr s) 227a8fdb4bcSmrg{ 228a8fdb4bcSmrg if(s->sjis.buf < 0) { 229a8fdb4bcSmrg if(c < 128 || (c >= 0xA0 && c <= 0xDF)) return c; 230a8fdb4bcSmrg s->sjis.buf = c; 231a8fdb4bcSmrg return -1; 232a8fdb4bcSmrg } else { 233a8fdb4bcSmrg int b; 234a8fdb4bcSmrg if(c < 0x40 || c == 0x7F) { 235a8fdb4bcSmrg s->sjis.buf = -1; 236a8fdb4bcSmrg return c; 237a8fdb4bcSmrg } 238a8fdb4bcSmrg if(s->sjis.buf < 0xFF && c < 0xFF) 239a8fdb4bcSmrg b = (s->sjis.buf << 8) + c; 240a8fdb4bcSmrg else 241a8fdb4bcSmrg b = -1; 242a8fdb4bcSmrg s->sjis.buf = -1; 243a8fdb4bcSmrg return b; 244a8fdb4bcSmrg } 245a8fdb4bcSmrg} 246a8fdb4bcSmrg 247a8fdb4bcSmrgint 248a8fdb4bcSmrginit_hkscs(OtherStatePtr s) 249a8fdb4bcSmrg{ 250a8fdb4bcSmrg s->hkscs.mapping = 251a8fdb4bcSmrg FontEncMapFind("big5hkscs-0", FONT_ENCODING_UNICODE, -1, -1, NULL); 252a8fdb4bcSmrg if(!s->hkscs.mapping) return 0; 253a8fdb4bcSmrg 254a8fdb4bcSmrg s->hkscs.reverse = FontMapReverse(s->hkscs.mapping); 255a8fdb4bcSmrg if(!s->hkscs.reverse) return 0; 256a8fdb4bcSmrg 257a8fdb4bcSmrg s->hkscs.buf = -1; 258a8fdb4bcSmrg return 1; 259a8fdb4bcSmrg} 260a8fdb4bcSmrg 261a8fdb4bcSmrgunsigned int 262a8fdb4bcSmrgmapping_hkscs(unsigned int n, OtherStatePtr s) 263a8fdb4bcSmrg{ 264a8fdb4bcSmrg unsigned int r; 265a8fdb4bcSmrg if(n < 128) return n; 266a8fdb4bcSmrg if(n == 128) return EURO_10646; 267a8fdb4bcSmrg r = FontEncRecode(n, s->hkscs.mapping); 268a8fdb4bcSmrg return r; 269a8fdb4bcSmrg} 270a8fdb4bcSmrg 271a8fdb4bcSmrgunsigned int 272a8fdb4bcSmrgreverse_hkscs(unsigned int n, OtherStatePtr s) 273a8fdb4bcSmrg{ 274a8fdb4bcSmrg if(n < 128) return n; 275a8fdb4bcSmrg if(n == EURO_10646) return 128; 276a8fdb4bcSmrg return s->hkscs.reverse->reverse(n, s->hkscs.reverse->data); 277a8fdb4bcSmrg} 278a8fdb4bcSmrg 279a8fdb4bcSmrgint 280a8fdb4bcSmrgstack_hkscs(unsigned char c, OtherStatePtr s) 281a8fdb4bcSmrg{ 282a8fdb4bcSmrg if(s->hkscs.buf < 0) { 283a8fdb4bcSmrg if(c < 129) return c; 284a8fdb4bcSmrg s->hkscs.buf = c; 285a8fdb4bcSmrg return -1; 286a8fdb4bcSmrg } else { 287a8fdb4bcSmrg int b; 288a8fdb4bcSmrg if(c < 0x40 || c == 0x7F) { 289a8fdb4bcSmrg s->hkscs.buf = -1; 290a8fdb4bcSmrg return c; 291a8fdb4bcSmrg } 292a8fdb4bcSmrg if(s->hkscs.buf < 0xFF && c < 0xFF) 293a8fdb4bcSmrg b = (s->hkscs.buf << 8) + c; 294a8fdb4bcSmrg else 295a8fdb4bcSmrg b = -1; 296a8fdb4bcSmrg s->hkscs.buf = -1; 297a8fdb4bcSmrg return b; 298a8fdb4bcSmrg } 299a8fdb4bcSmrg} 300a8fdb4bcSmrg 301a8fdb4bcSmrg 302a8fdb4bcSmrg/* 303a8fdb4bcSmrg * Because of the 1 ~ 4 multi-bytes nature of GB18030. 304a8fdb4bcSmrg * CharSet encoding is split to 2 subset (besides latin) 305a8fdb4bcSmrg * The 2Bytes MB char is defined in gb18030.2000-0 306a8fdb4bcSmrg * The 4Bytes MB char is defined in gb18030.2000-1 307a8fdb4bcSmrg * Please note that the mapping in 2000-1 is not a 4Bytes seq => 2Bytes value 308a8fdb4bcSmrg * mapping. 309a8fdb4bcSmrg * To use the 2000-1 we need to 'linear' the 4Bytes sequence and 'lookup' the 310a8fdb4bcSmrg * unicode value after that. 311a8fdb4bcSmrg * 312a8fdb4bcSmrg * For more info on GB18030 standard pls check: 313a8fdb4bcSmrg * http://oss.software.ibm.com/icu/docs/papers/gb18030.html 314a8fdb4bcSmrg * 315a8fdb4bcSmrg * For more info on GB18030 implementation issues in XFree86 pls check: 316a8fdb4bcSmrg * http://www.ibm.com/developerWorks/cn/linux/i18n/gb18030/xfree86/part1 317a8fdb4bcSmrg */ 318a8fdb4bcSmrgint 319a8fdb4bcSmrginit_gb18030(OtherStatePtr s) 320a8fdb4bcSmrg{ 321a8fdb4bcSmrg s->gb18030.cs0_mapping = 322a8fdb4bcSmrg FontEncMapFind("gb18030.2000-0", FONT_ENCODING_UNICODE, -1, -1, NULL); 323a8fdb4bcSmrg if(!s->gb18030.cs0_mapping) return 0; 324a8fdb4bcSmrg 325a8fdb4bcSmrg s->gb18030.cs0_reverse = FontMapReverse(s->gb18030.cs0_mapping); 326a8fdb4bcSmrg if(!s->gb18030.cs0_reverse) return 0; 327a8fdb4bcSmrg 328a8fdb4bcSmrg s->gb18030.cs1_mapping = 329a8fdb4bcSmrg FontEncMapFind("gb18030.2000-1", FONT_ENCODING_UNICODE, -1, -1, NULL); 330a8fdb4bcSmrg if(!s->gb18030.cs1_mapping) return 0; 331a8fdb4bcSmrg 332a8fdb4bcSmrg s->gb18030.cs1_reverse = FontMapReverse(s->gb18030.cs1_mapping); 333a8fdb4bcSmrg if(!s->gb18030.cs1_reverse) return 0; 334a8fdb4bcSmrg 335a8fdb4bcSmrg s->gb18030.linear = 0; 336a8fdb4bcSmrg s->gb18030.buf_ptr = 0; 337a8fdb4bcSmrg return 1; 338a8fdb4bcSmrg} 339a8fdb4bcSmrg 340a8fdb4bcSmrgunsigned int 341a8fdb4bcSmrgmapping_gb18030(unsigned int n, OtherStatePtr s) 342a8fdb4bcSmrg{ 343a8fdb4bcSmrg if(n <= 0x80) return n; /* 0x80 is valid but unassigned codepoint */ 344a8fdb4bcSmrg if(n >= 0xFFFF) return '?'; 345a8fdb4bcSmrg 346a8fdb4bcSmrg return FontEncRecode(n, 347a8fdb4bcSmrg (s->gb18030.linear)?s->gb18030.cs1_mapping:s->gb18030.cs0_mapping); 348a8fdb4bcSmrg} 349a8fdb4bcSmrg 350a8fdb4bcSmrgunsigned int 351a8fdb4bcSmrgreverse_gb18030(unsigned int n, OtherStatePtr s) 352a8fdb4bcSmrg{ 353a8fdb4bcSmrg /* when lookup in 2000-0 failed. */ 354a8fdb4bcSmrg /* lookup in 2000-1 and then try to unlinear'd */ 355a8fdb4bcSmrg unsigned int r; 356a8fdb4bcSmrg if(n <= 0x80) return n; 357a8fdb4bcSmrg 358a8fdb4bcSmrg r = s->gb18030.cs0_reverse->reverse(n, s->gb18030.cs0_reverse->data); 359a8fdb4bcSmrg if (r != 0) 360a8fdb4bcSmrg return r; 361a8fdb4bcSmrg 362a8fdb4bcSmrg r = s->gb18030.cs1_reverse->reverse(n, s->gb18030.cs1_reverse->data); 363a8fdb4bcSmrg if (r != 0) { 364a8fdb4bcSmrg unsigned char bytes[4]; 365a8fdb4bcSmrg 366a8fdb4bcSmrg bytes[3] = 0x30 + r % 10; r /= 10; 367a8fdb4bcSmrg bytes[2] = 0x81 + r % 126; r /= 126; 368a8fdb4bcSmrg bytes[1] = 0x30 + r % 10; r /= 10; 369a8fdb4bcSmrg bytes[0] = 0x81 + r; 370a8fdb4bcSmrg 371a8fdb4bcSmrg r = (unsigned int)bytes[0] << 24; 372a8fdb4bcSmrg r |= (unsigned int)bytes[1] << 16; 373a8fdb4bcSmrg r |= (unsigned int)bytes[2] << 8; 374a8fdb4bcSmrg r |= (unsigned int)bytes[3]; 375a8fdb4bcSmrg } 376a8fdb4bcSmrg return r; 377a8fdb4bcSmrg} 378a8fdb4bcSmrg 379a8fdb4bcSmrgint 380a8fdb4bcSmrgstack_gb18030(unsigned char c, OtherStatePtr s) 381a8fdb4bcSmrg{ 382a8fdb4bcSmrg /* if set gb18030.linear => True. the return value is "linear'd" */ 383a8fdb4bcSmrg if(s->gb18030.buf_ptr == 0) { 384a8fdb4bcSmrg if(c <= 0x80) return c; 385a8fdb4bcSmrg if (c == 0xFF) return -1; 386a8fdb4bcSmrg s->gb18030.linear = 0; 387a8fdb4bcSmrg s->gb18030.buf[s->gb18030.buf_ptr++] = c; 388a8fdb4bcSmrg return -1; 389a8fdb4bcSmrg } else if (s->gb18030.buf_ptr == 1) { 390a8fdb4bcSmrg if (c >= 0x40) { 391a8fdb4bcSmrg s->gb18030.buf_ptr = 0; 392a8fdb4bcSmrg if ((c == 0x80) || (c == 0xFF)) 393a8fdb4bcSmrg return -1; 394a8fdb4bcSmrg else 395a8fdb4bcSmrg return (s->gb18030.buf[0] << 8) + c; 396a8fdb4bcSmrg } else if (c >= 30) { /* 2Byte is (0x30 -> 0x39) */ 397a8fdb4bcSmrg s->gb18030.buf[s->gb18030.buf_ptr++] = c; 398a8fdb4bcSmrg return -1; 399a8fdb4bcSmrg } else { 400a8fdb4bcSmrg s->gb18030.buf_ptr = 0; 401a8fdb4bcSmrg return c; 402a8fdb4bcSmrg } 403a8fdb4bcSmrg } else if (s->gb18030.buf_ptr == 2) { 404a8fdb4bcSmrg if ((c >= 0x81) && (c <= 0xFE)) { 405a8fdb4bcSmrg s->gb18030.buf[s->gb18030.buf_ptr++] = c; 406a8fdb4bcSmrg return -1; 407a8fdb4bcSmrg } else { 408a8fdb4bcSmrg s->gb18030.buf_ptr = 0; 409a8fdb4bcSmrg return c; 410a8fdb4bcSmrg } 411a8fdb4bcSmrg } else { 412a8fdb4bcSmrg int r = 0; 413a8fdb4bcSmrg s->gb18030.buf_ptr = 0; 414a8fdb4bcSmrg if ((c >= 0x30) && (c <= 0x39)) { 415a8fdb4bcSmrg s->gb18030.linear = 1; 416a8fdb4bcSmrg r = (((s->gb18030.buf[0] - 0x81) * 10 417a8fdb4bcSmrg + (s->gb18030.buf[1] - 0x30)) * 126 418a8fdb4bcSmrg + (s->gb18030.buf[2] - 0x81)) * 10 419a8fdb4bcSmrg + (c - 0x30); 420a8fdb4bcSmrg return r; 421a8fdb4bcSmrg } 422a8fdb4bcSmrg return -1; 423a8fdb4bcSmrg } 424a8fdb4bcSmrg} 425a8fdb4bcSmrg 426