/*
* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:
* A utility for providing Japanese Language-specific (UNICODE) functions.
*
*
*/
// INCLUDES FILES
#include "jplangutil.h"
#include "jplangutil.tables.h"
// LOCAL DEFINES
// LOCAL CONSTANTS AND ENUMS
#if defined(_DEBUG)
_LIT( KJPLangUtilPanic, "JPLangUtil" );
enum TJPLangUtilPanicCodes
{
EErrNotKatakana = 0x777,
EErrNotVoicedKatakana
};
#endif
enum TConvDirection
{
EHalfToFullWidth,
EFullToHalfWidth
};
const TInt KHalfWidthKatakanaRange = 59;
const TInt KHalfWidthIndex = 0;
const TInt KFullWidthIndex = 1;
const TInt KFullWidthVoicableKatakanaRange = 23;
const TInt KFullWidthSemiVoicableKatakanaRange = 5;
const TInt KHalfWidthSpecialCharRange = 21;
const TText KHalfWidthKatakanaVoicedSoundMark = 0xff9e;
const TText KHalfWidthKatakanaSemiVoicedSoundMark = 0xff9f;
// The following Full-width (semi-)voiced markers are
// *also* considered Hiragana, per Unicode spec.
const TText KFullWidthKatakanaVoicedSoundMark = 0x309b;
const TText KFullWidthKatakanaSemiVoicedSoundMark = 0x309c;
const TText KHalfWidthKatakanaLowerBound = 0xff65;
const TText KHalfWidthKatakanaUpperBound = 0xff9f;
const TText KFullWidthKatakanaLowerBound = 0x30a0;
const TText KFullWidthKatakanaUpperBound = 0x30ff;
const TText KCJKUnifiedIdiographLowerBound = 0x4e00;
const TText KCJKUnifiedIdiographUpperBound = 0x9fa5;
const TText KCJKUnifiedIdeographExtALowerBound = 0x3400;
const TText KCJKUnifiedIdeographExtAUpperBound = 0x4dbf;
const TText KHalfToFullWidthASCIIOffset = 0xfee0;
const TText KHalfWidthASCIILowerBound = 0x0021; // Leaves out space (0x0020)
const TText KHalfWidthASCIIUpperBound = 0x007e;
const TText KFullWidthASCIILowerBound = 0xff01;
const TText KFullWidthASCIIUpperBound = 0xff5e;
const TUint KFullWidthHiraganaSmallA = 0x3041;
const TUint KFullWidthHiraganaVU = 0x3094;
const TUint KFullWidthHiraganaU = 0x3046;
const TUint KFullWidthHiraganaVoicedSound = 0x309B;
const TUint KFullWidthKatakanaSmallA = 0x30a1;
const TUint KFullWidthKatakanaSmallVU = 0x30F4;
// ============================== LOCAL CLASSES ================================
/**
* This is an internal utility class used by the JPLangUtil class
* and is intended for encapsulation only.
*
* @lib JPLangUtil.lib
* @since 2.6
*/
class UnicodeTextUtil
{
public: // Query Functions
/**
* Determines if aUnicodeChar is a base Katakana that is capable
* of being converted into either a Vioced or Semi-voiced Full-width
* Katakana character.
* If aSemiVoiced is true, then the check is only performed
* for Semi-voiced conversion capability.
*
* @param aUnicodeChar The character to be tested.
* @param aSemiVoiced Whether or not the character is to be tested
* as convertable to a Semi-voiced Full-width
* Katakana, rather than just voiced.
*
* @return ETrue is the character is in fact convertable to either
* a voiced or semi-voiced fullwidth katakana character,
* depending on the aSemiVoiced flag.
*/
static TBool IsFullWidthVoicedConvertableHalfWidthBaseKatakana
( TText aUnicodeChar, TBool aSemiVoiced = EFalse );
/**
* Determines if aUnicodeChar is a Vioced or Semi-voiced Full-width
* Katakana character.
* If aSemiVoiced is true, then the check is only performed
* for Semi-voiced.
*
* @param aUnicodeChar The character to be tested.
* @param aSemiVoiced Whether or not the character is a Semi-voiced
* Full-width Katakana, rather than just voiced.
*
* @return ETrue is the character is in fact a voiced or semi-voiced
* fullwidth katakana character, depending on the aSemiVoiced
* flag.
*/
static TBool IsFullWidthVoicedKatakana( TText aUnicodeChar,
TBool aSemiVoiced = EFalse);
public: // Conversion Functions
/**
* Converts one Katakana character from either Half to Full-width
* or vice versa, depending on the direction specified by aDirection
*
* @param aDirection Direction to convert.
* @param aKatakanaChar The character to convert.
*
* @return The opposite width Katakana character.
*/
static TChar ConvertKatakanaChar( TConvDirection aDirection,
TText aKatakanaChar );
/**
* Converts one voiced Katakana character from either Half to Full-width
* or vice versa, depending on the direction specified by aDirection,
* and appends the converted character to the descriptor aTarget.
* In the case that it is from Full to Half-width, it is necessary to
* convert it into a base-katakana + (semi-)voiced mark pair, thus
* the necessity for passing in the TDes reference return type.
* In the case of converting from Half to Full-width, it is only
* necessary to pass in a base-katakana that has a (semi-)voiced
* Full-width counterpart.
*
* @param aDirection Direction to convert.
* @param aVoicedKatakana The character to convert.
* @param aTarget The descriptor to append the converted character(s) to.
* @param aSemiVoiced ETrue if performing a Semi-voiced conversion.
* Default is EFalse.
*/
static void ConvertVoicedKatakanaCharAndAppendToTarget(
TConvDirection aDirection,
TText aVoicedKatakana,
TDes& aTarget,
TBool aSemiVoiced = EFalse );
/**
* Converts all special characters *in-place* from either Half to
* Full-width or vice versa, depending on the direction specified
* by aDirection
*
* @param aDirection Direction to convert.
* @param aUnicodeText The character to convert.
*
* @return The number of converted special characters.
*/
static TInt ConvertSpecialCharactersInPlace( TConvDirection aDirection,
TDes16& aUnicodeText );
/**
* Converts all ASCII *in-place* from either Half to
* Full-width or vice versa, depending on the direction specified
* by aDirection
*
* @param aDirection Direction to convert.
* @param aUnicodeText The character to convert.
*
* @return The number of converted ASCII-range characters.
*/
static TInt ConvertASCIIInPlace( TConvDirection aDirection,
TDes16& aUnicodeText );
};
// ============================= LOCAL FUNCTIONS ===============================
// -----------------------------------------------------------------------------
// UnicodeTextUtil::IsFullWidthVoicedConvertableHalfWidthBaseKatakana
// Determines if aUnicodeChar is a base Katakana that is capable
// of being converted into either a Vioced or Semi-voiced
// Full-width character.
// If aSemiVoiced is true, then the check is only performed
// for Semi-voiced conversion capability.
// Returns: ETrue if it is convertable.
// -----------------------------------------------------------------------------
//
TBool UnicodeTextUtil::IsFullWidthVoicedConvertableHalfWidthBaseKatakana
( TText aUnicodeChar, TBool aSemiVoiced )
{
if( aSemiVoiced )
{
return ( aUnicodeChar >= 0xff8a && aUnicodeChar <= 0xff8e );
}
else
{
return ( ( aUnicodeChar == 0xff73 ) ||
( aUnicodeChar >= 0xff76 && aUnicodeChar <= 0xff7f ) ||
( aUnicodeChar >= 0xff80 && aUnicodeChar <= 0xff84 ) ||
( aUnicodeChar >= 0xff8a && aUnicodeChar <= 0xff8e ) ||
( aUnicodeChar == 0xff9c ) ||
( aUnicodeChar == 0xff66 ) );
}
}
// -----------------------------------------------------------------------------
// UnicodeTextUtil::IsFullWidthVoicedKatakana
// Determines if aUnicodeChar is Full-width Katakana.
// Returns: ETrue if it is Full-width Katakana.
// -----------------------------------------------------------------------------
//
TBool UnicodeTextUtil::IsFullWidthVoicedKatakana( TText aUnicodeChar,
TBool aSemiVoiced )
{
const TInt voicableRange( aSemiVoiced ?
KFullWidthSemiVoicableKatakanaRange :
KFullWidthVoicableKatakanaRange );
const TText* const (*voicedTable) = aSemiVoiced ?
KHalfWidthBaseToFullWidthSemiVoicedKatakanaTable :
KHalfWidthBaseToFullWidthVoicedKatakanaTable;
for( TInt i( 0 ); i < voicableRange; ++i )
{
if( aUnicodeChar == voicedTable[i][KFullWidthIndex] )
{
return ETrue;
}
}
return EFalse;
}
// -----------------------------------------------------------------------------
// UnicodeTextUtil::ConvertKatakanaChar
// Converts one Katakana Char in the direction specified by aDirection.
// Assumes aKatakanaChar is within range.
// Returns: A TText containing either the varient character or the character
// itself, in the case there is no conversion.
// -----------------------------------------------------------------------------
//
TChar UnicodeTextUtil::ConvertKatakanaChar( TConvDirection aDirection,
TText aKatakanaChar )
{
__ASSERT_DEBUG(
JPLangUtil::IsKatakana( aKatakanaChar ) &&
!IsFullWidthVoicedKatakana( aKatakanaChar ),
User::Panic( KJPLangUtilPanic, EErrNotKatakana )
);
TChar convChar( aKatakanaChar );
const TInt directionIndex( ( aDirection == EHalfToFullWidth ) ?
KHalfWidthIndex : KFullWidthIndex );
for( TInt i( 0 ); i < KHalfWidthKatakanaRange; ++i )
{
if( aKatakanaChar ==
KHalfToFullWidthKatakanaCharTable[i][directionIndex] )
{
convChar = KHalfToFullWidthKatakanaCharTable[i][!directionIndex];
break;
}
}
return convChar;
}
// -----------------------------------------------------------------------------
// UnicodeTextUtil::ConvertVoicedKatakanaChar
// Converts one Voiced Katakana Char in the direction specified by aDirection,
// and appends to the descriptor, aTarget.
// If aSemiVoiced is ETrue, then the code point is converted to the Semi-voiced
// variant.
// Assumes aVoicedKatakana is within range.
// -----------------------------------------------------------------------------
//
void UnicodeTextUtil::ConvertVoicedKatakanaCharAndAppendToTarget(
TConvDirection aDirection,
TText aVoicedKatakana,
TDes& aTarget,
TBool aSemiVoiced )
{
__ASSERT_DEBUG(
IsFullWidthVoicedConvertableHalfWidthBaseKatakana( aVoicedKatakana ) ||
IsFullWidthVoicedKatakana( aVoicedKatakana, aSemiVoiced ),
User::Panic( KJPLangUtilPanic, EErrNotVoicedKatakana )
);
const TInt voicableRange( aSemiVoiced ?
KFullWidthSemiVoicableKatakanaRange :
KFullWidthVoicableKatakanaRange );
const TText* const (*voicedTable) = aSemiVoiced ?
KHalfWidthBaseToFullWidthSemiVoicedKatakanaTable :
KHalfWidthBaseToFullWidthVoicedKatakanaTable;
if( aDirection == EHalfToFullWidth )
{
// In the case of Half Width, only the base character is needed for
// the conversion
for( TInt i( 0 ); i < voicableRange; ++i )
{
if( aVoicedKatakana == voicedTable[i][KHalfWidthIndex] )
{
const TChar uniChar( voicedTable[i][KFullWidthIndex] );
aTarget.Append( uniChar );
break;
}
}
}
else
{
for( TInt i( 0 ); i < voicableRange; ++i )
{
if( aVoicedKatakana == voicedTable[i][KFullWidthIndex] )
{
const TChar uniChar( voicedTable[i][KHalfWidthIndex] );
aTarget.Append( uniChar );
break;
}
}
const TChar voicedSoundMark( aSemiVoiced ?
KHalfWidthKatakanaSemiVoicedSoundMark :
KHalfWidthKatakanaVoicedSoundMark );
aTarget.Append( voicedSoundMark );
}
}
// -----------------------------------------------------------------------------
// UnicodeTextUtil::ConvertSpecialCharactersInPlace
// Converts all special characters in the aUnicodeText descriptor in-place
// that have both Full and Half-width variants.
// Conversion occurs in the direction specified by aDirection.
// Returns: The total number of characters converted.
// -----------------------------------------------------------------------------
//
TInt UnicodeTextUtil::ConvertSpecialCharactersInPlace
( TConvDirection aDirection, TDes16& aUnicodeText )
{
TInt totalConverted( 0 );
const TInt directionIndex( ( aDirection == EHalfToFullWidth ) ?
KHalfWidthIndex : KFullWidthIndex );
for( TInt i( 0 ); i < aUnicodeText.Length(); ++i )
{
const TText uniChar( aUnicodeText[i] );
for( TInt j( 0 ); j < KHalfWidthSpecialCharRange; ++j )
{
if( uniChar == KHalfToFullWidthSpecialCharTable[j][directionIndex] )
{
aUnicodeText[i] =
KHalfToFullWidthSpecialCharTable[j][!directionIndex];
totalConverted++;
break;
}
}
}
return totalConverted;
}
// -----------------------------------------------------------------------------
// UnicodeTextUtil::ConvertASCIIInPlace
// Converts all ASCII *in-place* from either Half to Full-width or vice versa,
// depending on the direction specified by aDirection.
// Returns: The total number of characters converted.
// -----------------------------------------------------------------------------
//
TInt UnicodeTextUtil::ConvertASCIIInPlace( TConvDirection aDirection,
TDes16& aUnicodeText )
{
TInt totalConverted( 0 );
TText lowerBound( ( aDirection == EHalfToFullWidth ) ?
KHalfWidthASCIILowerBound :
KFullWidthASCIILowerBound );
TText upperBound( ( aDirection == EHalfToFullWidth ) ?
KHalfWidthASCIIUpperBound :
KFullWidthASCIIUpperBound );
TInt offset( ( aDirection == EHalfToFullWidth ) ?
KHalfToFullWidthASCIIOffset :
-KHalfToFullWidthASCIIOffset );
for( TInt i( 0 ); i < aUnicodeText.Length(); ++i )
{
const TText uniChar( aUnicodeText[i] );
if( uniChar >= lowerBound && uniChar <= upperBound )
{
TText convertedChar( static_cast<TText>( uniChar + offset ) );
aUnicodeText[i] = convertedChar;
totalConverted++;
}
}
return totalConverted;
}
// EXPORTED FUNCTIONS
// ============================ MEMBER FUNCTIONS ===============================
// -----------------------------------------------------------------------------
// JPLangUtil::ConvertHalfToFullWidth
// Converts all Half-width conformant text (including ASCII, Special Characters
// and Katakana) found in aUnicodeSource to their Full-width counterparts and
// places the resulting text into aUnicodeTarget.
// (detailed information about the parameters and return values can be found
// in the header file)
// -----------------------------------------------------------------------------
//
EXPORT_C TInt JPLangUtil::ConvertHalfToFullWidth( const TDesC16& aUnicodeSource,
TDes16& aUnicodeTarget )
{
TInt totalConverted( 0 );
// Special Characters are handled in the Katakana conversion...
totalConverted = ConvertHalfToFullWidthKatakana( aUnicodeSource,
aUnicodeTarget );
totalConverted += UnicodeTextUtil::ConvertASCIIInPlace( EHalfToFullWidth,
aUnicodeTarget );
return totalConverted;
}
// -----------------------------------------------------------------------------
// JPLangUtil::ConvertFullToHalfWidth
// Converts all Full-width conformant text found in aUnicodeSource to their
// Full-width counterparts and places the resulting text into aUnicodeTarget.
// Only those characters with existing Half-width variants are converted. There
// will be a 2-for-1 conversion for each Full-width Voiced and Semi-voiced
// Katakana character.
// (detailed information about the parameters and return values can be found in
// the header file)
// -----------------------------------------------------------------------------
//
EXPORT_C TInt JPLangUtil::ConvertFullToHalfWidth( const TDesC16& aUnicodeSource,
TDes16& aUnicodeTarget )
{
TInt totalConverted( 0 );
// Special Characters are handled in the Katakana conversion...
totalConverted = ConvertFullToHalfWidthKatakana( aUnicodeSource,
aUnicodeTarget );
totalConverted += UnicodeTextUtil::ConvertASCIIInPlace( EFullToHalfWidth,
aUnicodeTarget );
return totalConverted;
}
// -----------------------------------------------------------------------------
// JPLangUtil::ConvertHalfToFullWidthKatakana
// Converts Half-width Katakana and Special Character text found in
// aUnicodeSource to their Full-width counterparts and places the resulting text
// into aUnicodeTarget.
// (detailed information about the parameters and return values can be found in
// the header file)
// -----------------------------------------------------------------------------
//
EXPORT_C TInt JPLangUtil::ConvertHalfToFullWidthKatakana
( const TDesC16& aUnicodeSource, TDes16& aUnicodeTarget )
{
TInt totalConverted( 0 );
const TInt length( aUnicodeSource.Length() );
if( length > aUnicodeTarget.MaxLength() )
{
return KErrTooBig;
}
aUnicodeTarget.Zero();
for( TInt i( 0 ); i < length; ++i )
{
const TText uniChar( aUnicodeSource[i] );
// Check if the next character is a Half Width Katakana (Semi-)Voiced
// Sound Mark and if the current character + the voiced sound mark have
// a Full Width counterpart
if( i + 1 < length )
{
const TBool isVoiced(
( UnicodeTextUtil::IsFullWidthVoicedConvertableHalfWidthBaseKatakana
( uniChar ) &&
( aUnicodeSource[i + 1] == KHalfWidthKatakanaVoicedSoundMark )
) );
const TBool isSemiVoiced(
( UnicodeTextUtil::IsFullWidthVoicedConvertableHalfWidthBaseKatakana
( uniChar, ETrue ) &&
( aUnicodeSource[i + 1] == KHalfWidthKatakanaSemiVoicedSoundMark )
) );
if( isVoiced || isSemiVoiced )
{
UnicodeTextUtil::ConvertVoicedKatakanaCharAndAppendToTarget(
EHalfToFullWidth,
uniChar,
aUnicodeTarget,
isSemiVoiced
);
i++; // Skip the (semi-)voice marker
totalConverted++;
continue;
}
}
// If not, then just convert directly if in range
if( uniChar >= KHalfWidthKatakanaLowerBound &&
uniChar <= KHalfWidthKatakanaUpperBound )
{
aUnicodeTarget.Append(
UnicodeTextUtil::ConvertKatakanaChar( EHalfToFullWidth,
uniChar )
);
totalConverted++;
}
// Else this is not Half Width Katakana, so copy directly...
else
{
const TChar uniCharacter( uniChar );
aUnicodeTarget.Append( uniCharacter );
}
}
// Now handle special characters
// This logic may be moved into this function to avoid another
// loop over the text.
totalConverted +=
UnicodeTextUtil::ConvertSpecialCharactersInPlace( EHalfToFullWidth,
aUnicodeTarget );
return totalConverted;
}
// -----------------------------------------------------------------------------
// JPLangUtil::ConvertFullToHalfWidthKatakana
// Converts Full-width Katakana and Special Character text found in
// aUnicodeSource to their Half-width counterparts and places the resulting text
// into aUnicodeTarget. There will be a 2-for-1 conversion for each Full-width
// Voiced and Semi-voiced Katakana character.
// (detailed information about the parameters and return values can be found in
// the header file)
// -----------------------------------------------------------------------------
//
EXPORT_C TInt JPLangUtil::ConvertFullToHalfWidthKatakana
( const TDesC16& aUnicodeSource, TDes16& aUnicodeTarget )
{
TInt totalConverted( 0 );
const TInt length( aUnicodeSource.Length() );
const TInt maxLength( aUnicodeTarget.MaxLength() );
if( length > maxLength )
{
return KErrTooBig;
}
aUnicodeTarget.Zero();
for( TInt i( 0 ); i < length; ++i )
{
const TText uniChar( aUnicodeSource[i] );
// First check if this is this Full Width Katakana
if( ( uniChar >= KFullWidthKatakanaLowerBound &&
uniChar <= KFullWidthKatakanaUpperBound ) ||
( uniChar == KFullWidthKatakanaVoicedSoundMark ||
uniChar == KFullWidthKatakanaSemiVoicedSoundMark ) )
{
// Then check if it is (Semi-)Voiced and convert it properly
const TBool isVoiced(
UnicodeTextUtil::IsFullWidthVoicedKatakana( uniChar )
);
const TBool isSemiVoiced(
UnicodeTextUtil::IsFullWidthVoicedKatakana( uniChar, ETrue )
);
if( isVoiced || isSemiVoiced )
{
if( aUnicodeTarget.Length() + 2 > maxLength )
{
// This descriptor can't hold the new data
aUnicodeTarget.Zero();
return KErrTooBig;
}
UnicodeTextUtil::ConvertVoicedKatakanaCharAndAppendToTarget(
EFullToHalfWidth,
uniChar,
aUnicodeTarget,
isSemiVoiced
);
totalConverted++;
}
else
{
if( aUnicodeTarget.Length() + 1 > maxLength )
{
// This descriptor can't hold the new data
aUnicodeTarget.Zero();
return KErrTooBig;
}
aUnicodeTarget.Append(
UnicodeTextUtil::ConvertKatakanaChar(
EFullToHalfWidth,
uniChar
)
);
totalConverted++;
}
}
// This is not Full Width Katakana, so copy directly...
else
{
if( aUnicodeTarget.Length() + 1 > maxLength )
{
// This descriptor can't hold the new data
aUnicodeTarget.Zero();
return KErrTooBig;
}
const TChar uniCharacter( uniChar );
aUnicodeTarget.Append( uniCharacter );
}
}
// Now handle special characters
// This logic may be moved into this function to avoid another loop over
// the text
totalConverted +=
UnicodeTextUtil::ConvertSpecialCharactersInPlace( EFullToHalfWidth,
aUnicodeTarget );
return totalConverted;
}
// -----------------------------------------------------------------------------
// JPLangUtil::ConvertFullHiragnaToFullKatakana
// Converts Full-width Hiragana and Special Character text found in
// aUnicodeSource to their Full-width counterparts and places the
// resulting text into aUnicodeTarget.
// -----------------------------------------------------------------------------
//
EXPORT_C TInt JPLangUtil::ConvertFullHiragnaToFullKatakana
( const TDesC16& aUnicodeSource, TDes16& aUnicodeTarget )
{
TInt totalConverted( 0 );
const TInt length( aUnicodeSource.Length() );
const TInt maxLength( aUnicodeTarget.MaxLength() );
if( length > maxLength )
{
return KErrTooBig;
}
const TUint comp = KFullWidthKatakanaSmallA - KFullWidthHiraganaSmallA;
aUnicodeTarget.Zero();
for( TInt i( 0 ); i < length; ++i )
{
const TText uniChar( aUnicodeSource[i] );
TText uniChar2(0);
if (i + 1 < length)
{
uniChar2 = aUnicodeSource[i+1];
}
// First check if this is this Full Width Katakana
if (KFullWidthHiraganaSmallA <= uniChar && uniChar <= KFullWidthHiraganaVU)
{
if (uniChar == KFullWidthHiraganaU
&& uniChar2 == KFullWidthHiraganaVoicedSound)
{
aUnicodeTarget.Append(KFullWidthKatakanaSmallVU);
totalConverted++;
i++;
}
else
{
TUint katakana = uniChar + comp;
if (IsKatakana(katakana))
{
aUnicodeTarget.Append(katakana);
totalConverted++;
}
}
}
else
{
aUnicodeTarget.Append(uniChar);
totalConverted++;
}
}
// Now handle special characters
// This logic may be moved into this function to avoid another loop over
// the text
totalConverted +=
UnicodeTextUtil::ConvertSpecialCharactersInPlace( EFullToHalfWidth,
aUnicodeTarget );
return totalConverted;
}
// -----------------------------------------------------------------------------
// JPLangUtil::IsKatakana
// Determines whether or not the character is Katakana
// (detailed information about the parameters and return values can be found in
// the header file)
// -----------------------------------------------------------------------------
//
EXPORT_C TBool JPLangUtil::IsKatakana( const TText aUnicodeChar )
{
return ( ( aUnicodeChar >= KFullWidthKatakanaLowerBound &&
aUnicodeChar <= KFullWidthKatakanaUpperBound ) ||
( aUnicodeChar >= KHalfWidthKatakanaLowerBound &&
aUnicodeChar <= KHalfWidthKatakanaUpperBound ) ||
( aUnicodeChar == KFullWidthKatakanaVoicedSoundMark ||
aUnicodeChar == KFullWidthKatakanaSemiVoicedSoundMark ) );
}
// -----------------------------------------------------------------------------
// JPLangUtil::IsHiragana
// Determines whether or not the character is Hiragana
// (detailed information about the parameters and return values can be found in
// the header file)
// -----------------------------------------------------------------------------
//
EXPORT_C TBool JPLangUtil::IsHiragana( const TText aUnicodeChar )
{
return ( ( aUnicodeChar >= 0x3041 && aUnicodeChar <= 0x3096 ) ||
( aUnicodeChar >= 0x3099 && aUnicodeChar <= 0x309f ) );
}
// -----------------------------------------------------------------------------
// JPLangUtil::IsKanji
// Determines whether or not the character is a CJK Unified Ideograph (ExtA)
// (detailed information about the parameters and return values can be found in
// the header file)
// -----------------------------------------------------------------------------
//
EXPORT_C TBool JPLangUtil::IsKanji( const TText aUnicodeChar )
{
return( ( aUnicodeChar >= KCJKUnifiedIdiographLowerBound &&
aUnicodeChar <= KCJKUnifiedIdiographUpperBound ) ||
( aUnicodeChar >= KCJKUnifiedIdeographExtALowerBound &&
aUnicodeChar <= KCJKUnifiedIdeographExtAUpperBound ) );
}
// -----------------------------------------------------------------------------
// JPLangUtil::IsHalfWidth
// Determines whether or not the character is UNICODE defined Half-width.
// (detailed information about the parameters and return values can be found in
// the header file)
// -----------------------------------------------------------------------------
//
EXPORT_C TBool JPLangUtil::IsHalfWidth( const TText aUnicodeChar )
{
return // HW Katakana
( ( aUnicodeChar >= 0xff61 && aUnicodeChar <= 0xff9f ) ||
// ASCII
( aUnicodeChar >= 0x0020 && aUnicodeChar <= 0x007e ) ||
// Special Characters
( aUnicodeChar == 0x00a2 || aUnicodeChar == 0x00a3 ||
aUnicodeChar == 0x00a5 || aUnicodeChar == 0x00a6 ||
aUnicodeChar == 0x00a9 || aUnicodeChar == 0x00ac ||
aUnicodeChar == 0x00af || aUnicodeChar == 0x2985 ||
aUnicodeChar == 0x2986 ) ||
// HW Symbol Variants
( aUnicodeChar >= 0xffe8 && aUnicodeChar <= 0xffee ) );
}
// -----------------------------------------------------------------------------
// JPLangUtil::IsFullWidth
// Determines whether or not the character is UNICODE defined Full-width.
// Essentially, all code values that are not Half-width.
// (detailed information about the parameters and return values can be found in
// the header file)
// -----------------------------------------------------------------------------
//
EXPORT_C TBool JPLangUtil::IsFullWidth( const TText aUnicodeChar )
{
return !IsHalfWidth( aUnicodeChar );
}
// End of File