gecko-dev/lib/libi18n/katakana.c

157 строки
4.7 KiB
C

/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
* katakana.c
*
* Half- to Full-width Katakana Conversion for SJIS and EUC.
* based on the book of Ken Lunde
* (Understanding Japanese Information Processing, Published by O'Reilly; 09/1993; ISBN: 1565920430).
*/
#if defined(MOZ_MAIL_NEWS)
#include "intlpriv.h"
#include "prefapi.h"
#include "katakana.h"
#define ISMARU(A) (A >= 202 && A <= 206)
#define ISNIGORI(A) ((A >= 182 && A <= 196) || (A >= 202 && A <= 206) || (A == 179))
#define HANKATA(c) (c >= 161 && c <= 223) /* 0xa1 - 0xdf */
/* pref related prototype and variables */
PUBLIC int PR_CALLBACK intl_SetSendHankakuKana(const char * newpref, void * data);
static XP_Bool pref_callback_installed = FALSE;
static XP_Bool send_hankaku_kana = FALSE;
static const char *pref_send_hankaku_kana = "mailnews.send_hankaku_kana";
static void han2zen(XP_Bool insjis, unsigned char *inbuf, uint32 inlen,
unsigned char *outbuf, XP_Bool *composite)
{
unsigned char c1 = *inbuf++;
unsigned char c2;
unsigned char tmp = c1;
unsigned char junk;
XP_Bool maru = FALSE;
XP_Bool nigori = FALSE;
unsigned char mtable[][2] = {
{129,66},{129,117},{129,118},{129,65},{129,69},{131,146},{131,64},
{131,66},{131,68},{131,70},{131,72},{131,131},{131,133},{131,135},
{131,98},{129,91},{131,65},{131,67},{131,69},{131,71},{131,73},
{131,74},{131,76},{131,78},{131,80},{131,82},{131,84},{131,86},
{131,88},{131,90},{131,92},{131,94},{131,96},{131,99},{131,101},
{131,103},{131,105},{131,106},{131,107},{131,108},{131,109},
{131,110},{131,113},{131,116},{131,119},{131,122},{131,125},
{131,126},{131,128},{131,129},{131,130},{131,132},{131,134},
{131,136},{131,137},{131,138},{131,139},{131,140},{131,141},
{131,143},{131,147},{131,74},{129,75}
};
if (inlen > 1)
{
if (insjis)
{
c2 = *inbuf;
if (c2 == 222 && ISNIGORI(c1))
nigori = TRUE;
if (c2 == 223 && ISMARU(c1))
maru = TRUE;
}
else /* EUC */
{
junk = *inbuf++;
c2 = *inbuf;
if (junk == SS2) /* If the variable junk is SS2, we have another half-
width katakana. */
{
if (c2 == 222 && ISNIGORI(c1))
nigori = TRUE;
if (c2 == 223 && ISMARU(c1))
maru = TRUE;
}
}
}
if (HANKATA(tmp)) /* Check to see if tmp is in half-width katakana range. */
{
c1 = mtable[tmp - 161][0]; /* Calculate first byte using mapping table */
c2 = mtable[tmp - 161][1]; /* Calculate second byte using mapping table */
}
if (nigori)
{
if ((c2 >= 74 && c2 <= 103) || (c2 >= 110 && c2 <= 122))
c2++;
else if (c1 == 131 && c2 == 69)
c2 = 148;
}
else if (maru && c2 >= 110 && c2 <= 122)
c2 += 2;
*outbuf++ = c1;
*outbuf = c2;
*composite = maru || nigori;
}
/*
* Half to full Katakana conversion for SJIS. Caller need to allocate outbuf (x2 of inbuf).
*/
MODULE_PRIVATE void INTL_SjisHalf2FullKana(unsigned char *inbuf, uint32 inlen, unsigned char *outbuf, uint32 *byteused)
{
XP_Bool composite;
han2zen(TRUE, inbuf, inlen, outbuf, &composite);
*byteused = composite ? 2 : 1;
}
/*
* Half to full Katakana conversion for EUC. Caller need to allocate outbuf (x3 of inbuf).
*/
MODULE_PRIVATE void INTL_EucHalf2FullKana(unsigned char *inbuf, uint32 inlen, unsigned char *outbuf, uint32 *byteused)
{
XP_Bool composite;
han2zen(FALSE, inbuf, inlen, outbuf, &composite);
*byteused = composite ? 3 : 1; /* 2 chars plus SS2 or 1 char */
}
/* callback routine invoked by prefapi when the pref value changes */
PUBLIC int PR_CALLBACK intl_SetSendHankakuKana(const char * newpref, void * data)
{
return PREF_GetBoolPref(pref_send_hankaku_kana, &send_hankaku_kana);
}
MODULE_PRIVATE XP_Bool INTL_GetSendHankakuKana()
{
if (!pref_callback_installed)
{
PREF_GetBoolPref(pref_send_hankaku_kana, &send_hankaku_kana);
PREF_RegisterCallback(pref_send_hankaku_kana, intl_SetSendHankakuKana, NULL);
pref_callback_installed = TRUE;
}
return send_hankaku_kana;
}
#else
#ifdef OSF1
static int dumbcc = 0; /* The 3.2 compiler aborts when there's "nothing to compile", and 4.0 warns. This fixes both problems. */
#endif
#endif /* MOZ_MAIL_NEWS */