4
* All rights reserved. Copyright (C) 1996 by NARITA Tomio.
5
* $Id: big5.c,v 1.5 2003/11/13 03:08:19 nrt Exp $
8
* This program is free software; you can redistribute it and/or modify
9
* it under the terms of the GNU General Public License as published by
10
* the Free Software Foundation; either version 2 of the License, or
11
* (at your option) any later version.
13
* This program is distributed in the hope that it will be useful,
14
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
* GNU General Public License for more details.
18
* You should have received a copy of the GNU General Public License
19
* along with this program; if not, write to the Free Software
20
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32
#include <big5cns.map>
34
private ic_t BinarySearchRange( codes_t *array, int high, ic_t code )
36
int low, mid, distance, tmp;
41
for( ; low <= high ; mid = ( low + high ) >> 1 ){
42
if( ( array[ mid ].code <= code ) && ( array[ mid + 1 ].code > code ) ){
43
if( 0 == array[ mid ].peer )
45
if( code >= 0xa140U ){
47
tmp = ( ( code & 0xff00 ) - ( array[ mid ].code & 0xff00 ) ) >> 8;
49
low = array[ mid ].code & 0x00ff;
51
* NOTE: big5 high_byte: 0xa1-0xfe, low_byte: 0x40-0x7e, 0xa1-0xfe
52
* (radicals: 0x00-0x3e, 0x3f-0x9c)
53
* big5 radix is 0x9d. [region_low, region_high]
54
* We should remember big5 has two different regions (above).
55
* There is a bias for the distance between these regions.
56
* 0xa1 - 0x7e + bias = 1 (Distance between 0xa1 and 0x7e is 1.)
59
distance = tmp * 0x9d + high - low +
60
( high >= 0xa1 ? ( low >= 0xa1 ? 0 : - 0x22 )
61
: ( low >= 0xa1 ? + 0x22 : 0 ) );
63
* NOTE: we have to convert the distance into a code point.
64
* The code point's low_byte is 0x21 plus mod_0x5e.
65
* In the first, we extract the mod_0x5e of the starting
66
* code point, subtracting 0x21, and add distance to it.
67
* Then we calculate again mod_0x5e of them, and restore
68
* the final codepoint, adding 0x21.
70
tmp = ( array[ mid ].peer & 0x00ff ) + distance - 0x21;
71
tmp = ( array[ mid ].peer & 0xff00 ) + ( ( tmp / 0x5e ) << 8 )
76
tmp = ( ( code & 0xff00 ) - ( array[ mid ].code & 0xff00 ) ) >> 8;
78
* NOTE: ISO charsets ranges between 0x21-0xfe (94charset).
79
* Its radix is 0x5e. But there is no distance bias like big5.
82
+ ( (int)( code & 0x00ff ) - (int)( array[ mid ].code & 0x00ff ) );
84
* NOTE: Similar to big5 to cns conversion, we extract mod_0x9d and
85
* restore mod_0x9d into a code point.
87
low = array[ mid ].peer & 0x00ff;
88
tmp = low + distance - ( low >= 0xa1 ? 0x62 : 0x40 );
90
tmp = ( array[ mid ].peer & 0xff00 ) + ( ( tmp / 0x9d ) << 8 )
91
+ ( low > 0x3e ? 0x62 : 0x40 ) + low;
94
} else if( array[ mid ].code > code ){
104
public ic_t BIG5toCNS( ic_t big5, byte *cset )
108
if( big5 < 0xc940U ){
110
if( 0 < (cns = BinarySearchRange( big5Level1ToCnsPlane1, 23, big5 )) )
112
} else if( big5 == 0xc94aU ){
118
if( 0 < (cns = BinarySearchRange( big5Level2ToCnsPlane2, 46, big5 )) )
130
public ic_t CNStoBIG5( ic_t cns, byte *cset )
132
unsigned int big5 = 0;
136
big5 = BinarySearchRange( cnsPlane1ToBig5Level1, 24, cns );
139
big5 = BinarySearchRange( cnsPlane2ToBig5Level2, 47, cns );
153
public void ConvertCNStoBIG5( i_str_t *istr )
158
for( i = 0 ; NOSET != istr[ i ].charset ; i++ ){
159
if( CNS_1 == istr[ i ].charset || CNS_2 == istr[ i ].charset ){
160
cset = istr[ i ].charset;
161
istr[ i ].c = CNStoBIG5( istr[ i ].c, &cset );
162
istr[ i ].charset = cset;
167
public void ConvertBIG5toCNS( i_str_t *istr )
172
for( i = 0 ; NOSET != istr[ i ].charset ; i++ ){
173
if( BIG5 == istr[ i ].charset ){
174
cset = istr[ i ].charset;
175
istr[ i ].c = BIG5toCNS( istr[ i ].c, &cset );
176
istr[ i ].charset = cset;
181
public void DecodeBig5( state_t *state, byte codingSystem )
184
byte c[ ICHAR_WIDTH ];
190
if( FALSE == DecodeEscape( state ) )
192
} else if( HT == ch )
193
DecodeAddTab( state->attr );
194
else if( SO == ch ) /* LS1 for 8bit */
195
state->gset[ GL ] = G1;
196
else if( SI == ch ) /* LS0 for 8bit */
197
state->gset[ GL ] = G0;
201
DecodeAddControl( ch );
203
if( NULL != state->sset ){
204
if( FALSE == DecodeAddShifted( state, ch ) )
208
} else if( IsBig5Byte1( ch ) ){
215
if( !IsBig5Byte2( ch ) ){
216
DecodeAddControl( c[ 0 ] );
217
DecodeAddControl( ch );
225
charset = CSET( G0 );
226
if( !IsGraphicChar( charset, ch ) ){
228
DecodeAddSpace( state->attr );
230
DecodeAddControl( ch );
235
if( TRUE == iTable[ (int)charset ].multi ){
238
if( !IsGraphicChar( charset, ch ) )
243
DecodeAddChar( charset, c, state->attr );
248
public void EncodeBig5( i_str_t *istr, int head, int tail,
249
byte codingSystem, boolean_t binary )
255
for( idx = head ; idx < tail ; idx++ ){
256
cset = istr[ idx ].charset;
258
attr = (int)istr[ idx ].attr << 8;
259
if( CNS_1 == cset || CNS_2 == cset )
260
ic = CNStoBIG5( ic, &cset );
261
#ifndef MSDOS /* IF NOT DEFINED */
262
else if( UNICODE == cset )
263
ic = UNItoBIG5( ic, &cset );
267
EncodeAddChar( attr, ic );
268
} else if( BIG5 == cset ){
269
EncodeAddChar( attr, MakeByte1( ic ) );
270
EncodeAddChar( attr, MakeByte2( ic ) );
272
if( FALSE == EncodeAddInvalid( attr, ic, cset ) )
275
} else if( FALSE == EncodeAddPseudo( attr, ic, cset, binary ) ){