--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/charconvfw/JPLangUtil/src/jplangutil.cpp Wed Sep 01 12:39:40 2010 +0100
@@ -0,0 +1,774 @@
+/*
+* 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