|
1 /* |
|
2 * Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * A utility for providing Japanese Language-specific (UNICODE) functions. |
|
16 * |
|
17 * |
|
18 */ |
|
19 |
|
20 |
|
21 // INCLUDES FILES |
|
22 #include "jplangutil.h" |
|
23 #include "jplangutil.tables.h" |
|
24 |
|
25 // LOCAL DEFINES |
|
26 |
|
27 // LOCAL CONSTANTS AND ENUMS |
|
28 |
|
29 #if defined(_DEBUG) |
|
30 _LIT( KJPLangUtilPanic, "JPLangUtil" ); |
|
31 enum TJPLangUtilPanicCodes |
|
32 { |
|
33 EErrNotKatakana = 0x777, |
|
34 EErrNotVoicedKatakana |
|
35 }; |
|
36 #endif |
|
37 |
|
38 enum TConvDirection |
|
39 { |
|
40 EHalfToFullWidth, |
|
41 EFullToHalfWidth |
|
42 }; |
|
43 |
|
44 const TInt KHalfWidthKatakanaRange = 59; |
|
45 const TInt KHalfWidthIndex = 0; |
|
46 const TInt KFullWidthIndex = 1; |
|
47 const TInt KFullWidthVoicableKatakanaRange = 23; |
|
48 const TInt KFullWidthSemiVoicableKatakanaRange = 5; |
|
49 const TInt KHalfWidthSpecialCharRange = 21; |
|
50 |
|
51 const TText KHalfWidthKatakanaVoicedSoundMark = 0xff9e; |
|
52 const TText KHalfWidthKatakanaSemiVoicedSoundMark = 0xff9f; |
|
53 |
|
54 // The following Full-width (semi-)voiced markers are |
|
55 // *also* considered Hiragana, per Unicode spec. |
|
56 const TText KFullWidthKatakanaVoicedSoundMark = 0x309b; |
|
57 const TText KFullWidthKatakanaSemiVoicedSoundMark = 0x309c; |
|
58 |
|
59 const TText KHalfWidthKatakanaLowerBound = 0xff65; |
|
60 const TText KHalfWidthKatakanaUpperBound = 0xff9f; |
|
61 const TText KFullWidthKatakanaLowerBound = 0x30a0; |
|
62 const TText KFullWidthKatakanaUpperBound = 0x30ff; |
|
63 |
|
64 const TText KCJKUnifiedIdiographLowerBound = 0x4e00; |
|
65 const TText KCJKUnifiedIdiographUpperBound = 0x9fa5; |
|
66 const TText KCJKUnifiedIdeographExtALowerBound = 0x3400; |
|
67 const TText KCJKUnifiedIdeographExtAUpperBound = 0x4dbf; |
|
68 |
|
69 const TText KHalfToFullWidthASCIIOffset = 0xfee0; |
|
70 const TText KHalfWidthASCIILowerBound = 0x0021; // Leaves out space (0x0020) |
|
71 const TText KHalfWidthASCIIUpperBound = 0x007e; |
|
72 const TText KFullWidthASCIILowerBound = 0xff01; |
|
73 const TText KFullWidthASCIIUpperBound = 0xff5e; |
|
74 |
|
75 const TUint KFullWidthHiraganaSmallA = 0x3041; |
|
76 const TUint KFullWidthHiraganaVU = 0x3094; |
|
77 const TUint KFullWidthHiraganaU = 0x3046; |
|
78 const TUint KFullWidthHiraganaVoicedSound = 0x309B; |
|
79 const TUint KFullWidthKatakanaSmallA = 0x30a1; |
|
80 const TUint KFullWidthKatakanaSmallVU = 0x30F4; |
|
81 |
|
82 |
|
83 // ============================== LOCAL CLASSES ================================ |
|
84 |
|
85 /** |
|
86 * This is an internal utility class used by the JPLangUtil class |
|
87 * and is intended for encapsulation only. |
|
88 * |
|
89 * @lib JPLangUtil.lib |
|
90 * @since 2.6 |
|
91 */ |
|
92 class UnicodeTextUtil |
|
93 { |
|
94 public: // Query Functions |
|
95 |
|
96 /** |
|
97 * Determines if aUnicodeChar is a base Katakana that is capable |
|
98 * of being converted into either a Vioced or Semi-voiced Full-width |
|
99 * Katakana character. |
|
100 * If aSemiVoiced is true, then the check is only performed |
|
101 * for Semi-voiced conversion capability. |
|
102 * |
|
103 * @param aUnicodeChar The character to be tested. |
|
104 * @param aSemiVoiced Whether or not the character is to be tested |
|
105 * as convertable to a Semi-voiced Full-width |
|
106 * Katakana, rather than just voiced. |
|
107 * |
|
108 * @return ETrue is the character is in fact convertable to either |
|
109 * a voiced or semi-voiced fullwidth katakana character, |
|
110 * depending on the aSemiVoiced flag. |
|
111 */ |
|
112 static TBool IsFullWidthVoicedConvertableHalfWidthBaseKatakana |
|
113 ( TText aUnicodeChar, TBool aSemiVoiced = EFalse ); |
|
114 |
|
115 /** |
|
116 * Determines if aUnicodeChar is a Vioced or Semi-voiced Full-width |
|
117 * Katakana character. |
|
118 * If aSemiVoiced is true, then the check is only performed |
|
119 * for Semi-voiced. |
|
120 * |
|
121 * @param aUnicodeChar The character to be tested. |
|
122 * @param aSemiVoiced Whether or not the character is a Semi-voiced |
|
123 * Full-width Katakana, rather than just voiced. |
|
124 * |
|
125 * @return ETrue is the character is in fact a voiced or semi-voiced |
|
126 * fullwidth katakana character, depending on the aSemiVoiced |
|
127 * flag. |
|
128 */ |
|
129 static TBool IsFullWidthVoicedKatakana( TText aUnicodeChar, |
|
130 TBool aSemiVoiced = EFalse); |
|
131 |
|
132 public: // Conversion Functions |
|
133 |
|
134 /** |
|
135 * Converts one Katakana character from either Half to Full-width |
|
136 * or vice versa, depending on the direction specified by aDirection |
|
137 * |
|
138 * @param aDirection Direction to convert. |
|
139 * @param aKatakanaChar The character to convert. |
|
140 * |
|
141 * @return The opposite width Katakana character. |
|
142 */ |
|
143 static TChar ConvertKatakanaChar( TConvDirection aDirection, |
|
144 TText aKatakanaChar ); |
|
145 |
|
146 /** |
|
147 * Converts one voiced Katakana character from either Half to Full-width |
|
148 * or vice versa, depending on the direction specified by aDirection, |
|
149 * and appends the converted character to the descriptor aTarget. |
|
150 * In the case that it is from Full to Half-width, it is necessary to |
|
151 * convert it into a base-katakana + (semi-)voiced mark pair, thus |
|
152 * the necessity for passing in the TDes reference return type. |
|
153 * In the case of converting from Half to Full-width, it is only |
|
154 * necessary to pass in a base-katakana that has a (semi-)voiced |
|
155 * Full-width counterpart. |
|
156 * |
|
157 * @param aDirection Direction to convert. |
|
158 * @param aVoicedKatakana The character to convert. |
|
159 * @param aTarget The descriptor to append the converted character(s) to. |
|
160 * @param aSemiVoiced ETrue if performing a Semi-voiced conversion. |
|
161 * Default is EFalse. |
|
162 */ |
|
163 static void ConvertVoicedKatakanaCharAndAppendToTarget( |
|
164 TConvDirection aDirection, |
|
165 TText aVoicedKatakana, |
|
166 TDes& aTarget, |
|
167 TBool aSemiVoiced = EFalse ); |
|
168 |
|
169 /** |
|
170 * Converts all special characters *in-place* from either Half to |
|
171 * Full-width or vice versa, depending on the direction specified |
|
172 * by aDirection |
|
173 * |
|
174 * @param aDirection Direction to convert. |
|
175 * @param aUnicodeText The character to convert. |
|
176 * |
|
177 * @return The number of converted special characters. |
|
178 */ |
|
179 static TInt ConvertSpecialCharactersInPlace( TConvDirection aDirection, |
|
180 TDes16& aUnicodeText ); |
|
181 |
|
182 /** |
|
183 * Converts all ASCII *in-place* from either Half to |
|
184 * Full-width or vice versa, depending on the direction specified |
|
185 * by aDirection |
|
186 * |
|
187 * @param aDirection Direction to convert. |
|
188 * @param aUnicodeText The character to convert. |
|
189 * |
|
190 * @return The number of converted ASCII-range characters. |
|
191 */ |
|
192 static TInt ConvertASCIIInPlace( TConvDirection aDirection, |
|
193 TDes16& aUnicodeText ); |
|
194 }; |
|
195 |
|
196 // ============================= LOCAL FUNCTIONS =============================== |
|
197 |
|
198 // ----------------------------------------------------------------------------- |
|
199 // UnicodeTextUtil::IsFullWidthVoicedConvertableHalfWidthBaseKatakana |
|
200 // Determines if aUnicodeChar is a base Katakana that is capable |
|
201 // of being converted into either a Vioced or Semi-voiced |
|
202 // Full-width character. |
|
203 // If aSemiVoiced is true, then the check is only performed |
|
204 // for Semi-voiced conversion capability. |
|
205 // Returns: ETrue if it is convertable. |
|
206 // ----------------------------------------------------------------------------- |
|
207 // |
|
208 TBool UnicodeTextUtil::IsFullWidthVoicedConvertableHalfWidthBaseKatakana |
|
209 ( TText aUnicodeChar, TBool aSemiVoiced ) |
|
210 { |
|
211 if( aSemiVoiced ) |
|
212 { |
|
213 return ( aUnicodeChar >= 0xff8a && aUnicodeChar <= 0xff8e ); |
|
214 } |
|
215 else |
|
216 { |
|
217 return ( ( aUnicodeChar == 0xff73 ) || |
|
218 ( aUnicodeChar >= 0xff76 && aUnicodeChar <= 0xff7f ) || |
|
219 ( aUnicodeChar >= 0xff80 && aUnicodeChar <= 0xff84 ) || |
|
220 ( aUnicodeChar >= 0xff8a && aUnicodeChar <= 0xff8e ) || |
|
221 ( aUnicodeChar == 0xff9c ) || |
|
222 ( aUnicodeChar == 0xff66 ) ); |
|
223 } |
|
224 } |
|
225 |
|
226 // ----------------------------------------------------------------------------- |
|
227 // UnicodeTextUtil::IsFullWidthVoicedKatakana |
|
228 // Determines if aUnicodeChar is Full-width Katakana. |
|
229 // Returns: ETrue if it is Full-width Katakana. |
|
230 // ----------------------------------------------------------------------------- |
|
231 // |
|
232 TBool UnicodeTextUtil::IsFullWidthVoicedKatakana( TText aUnicodeChar, |
|
233 TBool aSemiVoiced ) |
|
234 { |
|
235 const TInt voicableRange( aSemiVoiced ? |
|
236 KFullWidthSemiVoicableKatakanaRange : |
|
237 KFullWidthVoicableKatakanaRange ); |
|
238 const TText* const (*voicedTable) = aSemiVoiced ? |
|
239 KHalfWidthBaseToFullWidthSemiVoicedKatakanaTable : |
|
240 KHalfWidthBaseToFullWidthVoicedKatakanaTable; |
|
241 for( TInt i( 0 ); i < voicableRange; ++i ) |
|
242 { |
|
243 if( aUnicodeChar == voicedTable[i][KFullWidthIndex] ) |
|
244 { |
|
245 return ETrue; |
|
246 } |
|
247 } |
|
248 return EFalse; |
|
249 } |
|
250 |
|
251 // ----------------------------------------------------------------------------- |
|
252 // UnicodeTextUtil::ConvertKatakanaChar |
|
253 // Converts one Katakana Char in the direction specified by aDirection. |
|
254 // Assumes aKatakanaChar is within range. |
|
255 // Returns: A TText containing either the varient character or the character |
|
256 // itself, in the case there is no conversion. |
|
257 // ----------------------------------------------------------------------------- |
|
258 // |
|
259 TChar UnicodeTextUtil::ConvertKatakanaChar( TConvDirection aDirection, |
|
260 TText aKatakanaChar ) |
|
261 { |
|
262 __ASSERT_DEBUG( |
|
263 JPLangUtil::IsKatakana( aKatakanaChar ) && |
|
264 !IsFullWidthVoicedKatakana( aKatakanaChar ), |
|
265 User::Panic( KJPLangUtilPanic, EErrNotKatakana ) |
|
266 ); |
|
267 TChar convChar( aKatakanaChar ); |
|
268 const TInt directionIndex( ( aDirection == EHalfToFullWidth ) ? |
|
269 KHalfWidthIndex : KFullWidthIndex ); |
|
270 for( TInt i( 0 ); i < KHalfWidthKatakanaRange; ++i ) |
|
271 { |
|
272 if( aKatakanaChar == |
|
273 KHalfToFullWidthKatakanaCharTable[i][directionIndex] ) |
|
274 { |
|
275 convChar = KHalfToFullWidthKatakanaCharTable[i][!directionIndex]; |
|
276 break; |
|
277 } |
|
278 } |
|
279 return convChar; |
|
280 } |
|
281 |
|
282 // ----------------------------------------------------------------------------- |
|
283 // UnicodeTextUtil::ConvertVoicedKatakanaChar |
|
284 // Converts one Voiced Katakana Char in the direction specified by aDirection, |
|
285 // and appends to the descriptor, aTarget. |
|
286 // If aSemiVoiced is ETrue, then the code point is converted to the Semi-voiced |
|
287 // variant. |
|
288 // Assumes aVoicedKatakana is within range. |
|
289 // ----------------------------------------------------------------------------- |
|
290 // |
|
291 void UnicodeTextUtil::ConvertVoicedKatakanaCharAndAppendToTarget( |
|
292 TConvDirection aDirection, |
|
293 TText aVoicedKatakana, |
|
294 TDes& aTarget, |
|
295 TBool aSemiVoiced ) |
|
296 { |
|
297 __ASSERT_DEBUG( |
|
298 IsFullWidthVoicedConvertableHalfWidthBaseKatakana( aVoicedKatakana ) || |
|
299 IsFullWidthVoicedKatakana( aVoicedKatakana, aSemiVoiced ), |
|
300 User::Panic( KJPLangUtilPanic, EErrNotVoicedKatakana ) |
|
301 ); |
|
302 |
|
303 const TInt voicableRange( aSemiVoiced ? |
|
304 KFullWidthSemiVoicableKatakanaRange : |
|
305 KFullWidthVoicableKatakanaRange ); |
|
306 const TText* const (*voicedTable) = aSemiVoiced ? |
|
307 KHalfWidthBaseToFullWidthSemiVoicedKatakanaTable : |
|
308 KHalfWidthBaseToFullWidthVoicedKatakanaTable; |
|
309 if( aDirection == EHalfToFullWidth ) |
|
310 { |
|
311 // In the case of Half Width, only the base character is needed for |
|
312 // the conversion |
|
313 for( TInt i( 0 ); i < voicableRange; ++i ) |
|
314 { |
|
315 if( aVoicedKatakana == voicedTable[i][KHalfWidthIndex] ) |
|
316 { |
|
317 const TChar uniChar( voicedTable[i][KFullWidthIndex] ); |
|
318 aTarget.Append( uniChar ); |
|
319 break; |
|
320 } |
|
321 } |
|
322 } |
|
323 else |
|
324 { |
|
325 for( TInt i( 0 ); i < voicableRange; ++i ) |
|
326 { |
|
327 if( aVoicedKatakana == voicedTable[i][KFullWidthIndex] ) |
|
328 { |
|
329 const TChar uniChar( voicedTable[i][KHalfWidthIndex] ); |
|
330 aTarget.Append( uniChar ); |
|
331 break; |
|
332 } |
|
333 } |
|
334 const TChar voicedSoundMark( aSemiVoiced ? |
|
335 KHalfWidthKatakanaSemiVoicedSoundMark : |
|
336 KHalfWidthKatakanaVoicedSoundMark ); |
|
337 aTarget.Append( voicedSoundMark ); |
|
338 } |
|
339 } |
|
340 |
|
341 // ----------------------------------------------------------------------------- |
|
342 // UnicodeTextUtil::ConvertSpecialCharactersInPlace |
|
343 // Converts all special characters in the aUnicodeText descriptor in-place |
|
344 // that have both Full and Half-width variants. |
|
345 // Conversion occurs in the direction specified by aDirection. |
|
346 // Returns: The total number of characters converted. |
|
347 // ----------------------------------------------------------------------------- |
|
348 // |
|
349 TInt UnicodeTextUtil::ConvertSpecialCharactersInPlace |
|
350 ( TConvDirection aDirection, TDes16& aUnicodeText ) |
|
351 { |
|
352 TInt totalConverted( 0 ); |
|
353 const TInt directionIndex( ( aDirection == EHalfToFullWidth ) ? |
|
354 KHalfWidthIndex : KFullWidthIndex ); |
|
355 for( TInt i( 0 ); i < aUnicodeText.Length(); ++i ) |
|
356 { |
|
357 const TText uniChar( aUnicodeText[i] ); |
|
358 for( TInt j( 0 ); j < KHalfWidthSpecialCharRange; ++j ) |
|
359 { |
|
360 if( uniChar == KHalfToFullWidthSpecialCharTable[j][directionIndex] ) |
|
361 { |
|
362 aUnicodeText[i] = |
|
363 KHalfToFullWidthSpecialCharTable[j][!directionIndex]; |
|
364 totalConverted++; |
|
365 break; |
|
366 } |
|
367 } |
|
368 } |
|
369 return totalConverted; |
|
370 } |
|
371 |
|
372 // ----------------------------------------------------------------------------- |
|
373 // UnicodeTextUtil::ConvertASCIIInPlace |
|
374 // Converts all ASCII *in-place* from either Half to Full-width or vice versa, |
|
375 // depending on the direction specified by aDirection. |
|
376 // Returns: The total number of characters converted. |
|
377 // ----------------------------------------------------------------------------- |
|
378 // |
|
379 TInt UnicodeTextUtil::ConvertASCIIInPlace( TConvDirection aDirection, |
|
380 TDes16& aUnicodeText ) |
|
381 { |
|
382 TInt totalConverted( 0 ); |
|
383 TText lowerBound( ( aDirection == EHalfToFullWidth ) ? |
|
384 KHalfWidthASCIILowerBound : |
|
385 KFullWidthASCIILowerBound ); |
|
386 TText upperBound( ( aDirection == EHalfToFullWidth ) ? |
|
387 KHalfWidthASCIIUpperBound : |
|
388 KFullWidthASCIIUpperBound ); |
|
389 TInt offset( ( aDirection == EHalfToFullWidth ) ? |
|
390 KHalfToFullWidthASCIIOffset : |
|
391 -KHalfToFullWidthASCIIOffset ); |
|
392 for( TInt i( 0 ); i < aUnicodeText.Length(); ++i ) |
|
393 { |
|
394 const TText uniChar( aUnicodeText[i] ); |
|
395 if( uniChar >= lowerBound && uniChar <= upperBound ) |
|
396 { |
|
397 TText convertedChar( static_cast<TText>( uniChar + offset ) ); |
|
398 aUnicodeText[i] = convertedChar; |
|
399 totalConverted++; |
|
400 } |
|
401 } |
|
402 return totalConverted; |
|
403 } |
|
404 |
|
405 // EXPORTED FUNCTIONS |
|
406 |
|
407 // ============================ MEMBER FUNCTIONS =============================== |
|
408 |
|
409 // ----------------------------------------------------------------------------- |
|
410 // JPLangUtil::ConvertHalfToFullWidth |
|
411 // Converts all Half-width conformant text (including ASCII, Special Characters |
|
412 // and Katakana) found in aUnicodeSource to their Full-width counterparts and |
|
413 // places the resulting text into aUnicodeTarget. |
|
414 // (detailed information about the parameters and return values can be found |
|
415 // in the header file) |
|
416 // ----------------------------------------------------------------------------- |
|
417 // |
|
418 EXPORT_C TInt JPLangUtil::ConvertHalfToFullWidth( const TDesC16& aUnicodeSource, |
|
419 TDes16& aUnicodeTarget ) |
|
420 { |
|
421 TInt totalConverted( 0 ); |
|
422 // Special Characters are handled in the Katakana conversion... |
|
423 totalConverted = ConvertHalfToFullWidthKatakana( aUnicodeSource, |
|
424 aUnicodeTarget ); |
|
425 totalConverted += UnicodeTextUtil::ConvertASCIIInPlace( EHalfToFullWidth, |
|
426 aUnicodeTarget ); |
|
427 return totalConverted; |
|
428 } |
|
429 |
|
430 // ----------------------------------------------------------------------------- |
|
431 // JPLangUtil::ConvertFullToHalfWidth |
|
432 // Converts all Full-width conformant text found in aUnicodeSource to their |
|
433 // Full-width counterparts and places the resulting text into aUnicodeTarget. |
|
434 // Only those characters with existing Half-width variants are converted. There |
|
435 // will be a 2-for-1 conversion for each Full-width Voiced and Semi-voiced |
|
436 // Katakana character. |
|
437 // (detailed information about the parameters and return values can be found in |
|
438 // the header file) |
|
439 // ----------------------------------------------------------------------------- |
|
440 // |
|
441 EXPORT_C TInt JPLangUtil::ConvertFullToHalfWidth( const TDesC16& aUnicodeSource, |
|
442 TDes16& aUnicodeTarget ) |
|
443 { |
|
444 TInt totalConverted( 0 ); |
|
445 // Special Characters are handled in the Katakana conversion... |
|
446 totalConverted = ConvertFullToHalfWidthKatakana( aUnicodeSource, |
|
447 aUnicodeTarget ); |
|
448 totalConverted += UnicodeTextUtil::ConvertASCIIInPlace( EFullToHalfWidth, |
|
449 aUnicodeTarget ); |
|
450 return totalConverted; |
|
451 } |
|
452 |
|
453 // ----------------------------------------------------------------------------- |
|
454 // JPLangUtil::ConvertHalfToFullWidthKatakana |
|
455 // Converts Half-width Katakana and Special Character text found in |
|
456 // aUnicodeSource to their Full-width counterparts and places the resulting text |
|
457 // into aUnicodeTarget. |
|
458 // (detailed information about the parameters and return values can be found in |
|
459 // the header file) |
|
460 // ----------------------------------------------------------------------------- |
|
461 // |
|
462 EXPORT_C TInt JPLangUtil::ConvertHalfToFullWidthKatakana |
|
463 ( const TDesC16& aUnicodeSource, TDes16& aUnicodeTarget ) |
|
464 { |
|
465 TInt totalConverted( 0 ); |
|
466 const TInt length( aUnicodeSource.Length() ); |
|
467 if( length > aUnicodeTarget.MaxLength() ) |
|
468 { |
|
469 return KErrTooBig; |
|
470 } |
|
471 aUnicodeTarget.Zero(); |
|
472 for( TInt i( 0 ); i < length; ++i ) |
|
473 { |
|
474 const TText uniChar( aUnicodeSource[i] ); |
|
475 // Check if the next character is a Half Width Katakana (Semi-)Voiced |
|
476 // Sound Mark and if the current character + the voiced sound mark have |
|
477 // a Full Width counterpart |
|
478 if( i + 1 < length ) |
|
479 { |
|
480 const TBool isVoiced( |
|
481 ( UnicodeTextUtil::IsFullWidthVoicedConvertableHalfWidthBaseKatakana |
|
482 ( uniChar ) && |
|
483 ( aUnicodeSource[i + 1] == KHalfWidthKatakanaVoicedSoundMark ) |
|
484 ) ); |
|
485 |
|
486 const TBool isSemiVoiced( |
|
487 ( UnicodeTextUtil::IsFullWidthVoicedConvertableHalfWidthBaseKatakana |
|
488 ( uniChar, ETrue ) && |
|
489 ( aUnicodeSource[i + 1] == KHalfWidthKatakanaSemiVoicedSoundMark ) |
|
490 ) ); |
|
491 |
|
492 if( isVoiced || isSemiVoiced ) |
|
493 { |
|
494 UnicodeTextUtil::ConvertVoicedKatakanaCharAndAppendToTarget( |
|
495 EHalfToFullWidth, |
|
496 uniChar, |
|
497 aUnicodeTarget, |
|
498 isSemiVoiced |
|
499 ); |
|
500 i++; // Skip the (semi-)voice marker |
|
501 totalConverted++; |
|
502 continue; |
|
503 } |
|
504 } |
|
505 // If not, then just convert directly if in range |
|
506 if( uniChar >= KHalfWidthKatakanaLowerBound && |
|
507 uniChar <= KHalfWidthKatakanaUpperBound ) |
|
508 { |
|
509 aUnicodeTarget.Append( |
|
510 UnicodeTextUtil::ConvertKatakanaChar( EHalfToFullWidth, |
|
511 uniChar ) |
|
512 ); |
|
513 totalConverted++; |
|
514 } |
|
515 // Else this is not Half Width Katakana, so copy directly... |
|
516 else |
|
517 { |
|
518 const TChar uniCharacter( uniChar ); |
|
519 aUnicodeTarget.Append( uniCharacter ); |
|
520 } |
|
521 } |
|
522 |
|
523 // Now handle special characters |
|
524 // This logic may be moved into this function to avoid another |
|
525 // loop over the text. |
|
526 totalConverted += |
|
527 UnicodeTextUtil::ConvertSpecialCharactersInPlace( EHalfToFullWidth, |
|
528 aUnicodeTarget ); |
|
529 |
|
530 return totalConverted; |
|
531 } |
|
532 |
|
533 // ----------------------------------------------------------------------------- |
|
534 // JPLangUtil::ConvertFullToHalfWidthKatakana |
|
535 // Converts Full-width Katakana and Special Character text found in |
|
536 // aUnicodeSource to their Half-width counterparts and places the resulting text |
|
537 // into aUnicodeTarget. There will be a 2-for-1 conversion for each Full-width |
|
538 // Voiced and Semi-voiced Katakana character. |
|
539 // (detailed information about the parameters and return values can be found in |
|
540 // the header file) |
|
541 // ----------------------------------------------------------------------------- |
|
542 // |
|
543 EXPORT_C TInt JPLangUtil::ConvertFullToHalfWidthKatakana |
|
544 ( const TDesC16& aUnicodeSource, TDes16& aUnicodeTarget ) |
|
545 { |
|
546 TInt totalConverted( 0 ); |
|
547 const TInt length( aUnicodeSource.Length() ); |
|
548 const TInt maxLength( aUnicodeTarget.MaxLength() ); |
|
549 if( length > maxLength ) |
|
550 { |
|
551 return KErrTooBig; |
|
552 } |
|
553 aUnicodeTarget.Zero(); |
|
554 for( TInt i( 0 ); i < length; ++i ) |
|
555 { |
|
556 const TText uniChar( aUnicodeSource[i] ); |
|
557 // First check if this is this Full Width Katakana |
|
558 if( ( uniChar >= KFullWidthKatakanaLowerBound && |
|
559 uniChar <= KFullWidthKatakanaUpperBound ) || |
|
560 ( uniChar == KFullWidthKatakanaVoicedSoundMark || |
|
561 uniChar == KFullWidthKatakanaSemiVoicedSoundMark ) ) |
|
562 { |
|
563 // Then check if it is (Semi-)Voiced and convert it properly |
|
564 const TBool isVoiced( |
|
565 UnicodeTextUtil::IsFullWidthVoicedKatakana( uniChar ) |
|
566 ); |
|
567 const TBool isSemiVoiced( |
|
568 UnicodeTextUtil::IsFullWidthVoicedKatakana( uniChar, ETrue ) |
|
569 ); |
|
570 if( isVoiced || isSemiVoiced ) |
|
571 { |
|
572 if( aUnicodeTarget.Length() + 2 > maxLength ) |
|
573 { |
|
574 // This descriptor can't hold the new data |
|
575 aUnicodeTarget.Zero(); |
|
576 return KErrTooBig; |
|
577 } |
|
578 UnicodeTextUtil::ConvertVoicedKatakanaCharAndAppendToTarget( |
|
579 EFullToHalfWidth, |
|
580 uniChar, |
|
581 aUnicodeTarget, |
|
582 isSemiVoiced |
|
583 ); |
|
584 totalConverted++; |
|
585 } |
|
586 else |
|
587 { |
|
588 if( aUnicodeTarget.Length() + 1 > maxLength ) |
|
589 { |
|
590 // This descriptor can't hold the new data |
|
591 aUnicodeTarget.Zero(); |
|
592 return KErrTooBig; |
|
593 } |
|
594 aUnicodeTarget.Append( |
|
595 UnicodeTextUtil::ConvertKatakanaChar( |
|
596 EFullToHalfWidth, |
|
597 uniChar |
|
598 ) |
|
599 ); |
|
600 totalConverted++; |
|
601 } |
|
602 } |
|
603 // This is not Full Width Katakana, so copy directly... |
|
604 else |
|
605 { |
|
606 if( aUnicodeTarget.Length() + 1 > maxLength ) |
|
607 { |
|
608 // This descriptor can't hold the new data |
|
609 aUnicodeTarget.Zero(); |
|
610 return KErrTooBig; |
|
611 } |
|
612 const TChar uniCharacter( uniChar ); |
|
613 aUnicodeTarget.Append( uniCharacter ); |
|
614 } |
|
615 } |
|
616 |
|
617 // Now handle special characters |
|
618 // This logic may be moved into this function to avoid another loop over |
|
619 // the text |
|
620 totalConverted += |
|
621 UnicodeTextUtil::ConvertSpecialCharactersInPlace( EFullToHalfWidth, |
|
622 aUnicodeTarget ); |
|
623 |
|
624 return totalConverted; |
|
625 } |
|
626 |
|
627 // ----------------------------------------------------------------------------- |
|
628 // JPLangUtil::ConvertFullHiragnaToFullKatakana |
|
629 // Converts Full-width Hiragana and Special Character text found in |
|
630 // aUnicodeSource to their Full-width counterparts and places the |
|
631 // resulting text into aUnicodeTarget. |
|
632 // ----------------------------------------------------------------------------- |
|
633 // |
|
634 EXPORT_C TInt JPLangUtil::ConvertFullHiragnaToFullKatakana |
|
635 ( const TDesC16& aUnicodeSource, TDes16& aUnicodeTarget ) |
|
636 { |
|
637 TInt totalConverted( 0 ); |
|
638 const TInt length( aUnicodeSource.Length() ); |
|
639 const TInt maxLength( aUnicodeTarget.MaxLength() ); |
|
640 if( length > maxLength ) |
|
641 { |
|
642 return KErrTooBig; |
|
643 } |
|
644 |
|
645 const TUint comp = KFullWidthKatakanaSmallA - KFullWidthHiraganaSmallA; |
|
646 |
|
647 aUnicodeTarget.Zero(); |
|
648 for( TInt i( 0 ); i < length; ++i ) |
|
649 { |
|
650 const TText uniChar( aUnicodeSource[i] ); |
|
651 TText uniChar2(0); |
|
652 if (i + 1 < length) |
|
653 { |
|
654 uniChar2 = aUnicodeSource[i+1]; |
|
655 } |
|
656 // First check if this is this Full Width Katakana |
|
657 if (KFullWidthHiraganaSmallA <= uniChar && uniChar <= KFullWidthHiraganaVU) |
|
658 { |
|
659 if (uniChar == KFullWidthHiraganaU |
|
660 && uniChar2 == KFullWidthHiraganaVoicedSound) |
|
661 { |
|
662 aUnicodeTarget.Append(KFullWidthKatakanaSmallVU); |
|
663 totalConverted++; |
|
664 i++; |
|
665 } |
|
666 else |
|
667 { |
|
668 TUint katakana = uniChar + comp; |
|
669 if (IsKatakana(katakana)) |
|
670 { |
|
671 aUnicodeTarget.Append(katakana); |
|
672 totalConverted++; |
|
673 } |
|
674 } |
|
675 } |
|
676 else |
|
677 { |
|
678 aUnicodeTarget.Append(uniChar); |
|
679 totalConverted++; |
|
680 } |
|
681 } |
|
682 |
|
683 // Now handle special characters |
|
684 // This logic may be moved into this function to avoid another loop over |
|
685 // the text |
|
686 totalConverted += |
|
687 UnicodeTextUtil::ConvertSpecialCharactersInPlace( EFullToHalfWidth, |
|
688 aUnicodeTarget ); |
|
689 |
|
690 return totalConverted; |
|
691 } |
|
692 |
|
693 // ----------------------------------------------------------------------------- |
|
694 // JPLangUtil::IsKatakana |
|
695 // Determines whether or not the character is Katakana |
|
696 // (detailed information about the parameters and return values can be found in |
|
697 // the header file) |
|
698 // ----------------------------------------------------------------------------- |
|
699 // |
|
700 EXPORT_C TBool JPLangUtil::IsKatakana( const TText aUnicodeChar ) |
|
701 { |
|
702 return ( ( aUnicodeChar >= KFullWidthKatakanaLowerBound && |
|
703 aUnicodeChar <= KFullWidthKatakanaUpperBound ) || |
|
704 ( aUnicodeChar >= KHalfWidthKatakanaLowerBound && |
|
705 aUnicodeChar <= KHalfWidthKatakanaUpperBound ) || |
|
706 ( aUnicodeChar == KFullWidthKatakanaVoicedSoundMark || |
|
707 aUnicodeChar == KFullWidthKatakanaSemiVoicedSoundMark ) ); |
|
708 } |
|
709 |
|
710 // ----------------------------------------------------------------------------- |
|
711 // JPLangUtil::IsHiragana |
|
712 // Determines whether or not the character is Hiragana |
|
713 // (detailed information about the parameters and return values can be found in |
|
714 // the header file) |
|
715 // ----------------------------------------------------------------------------- |
|
716 // |
|
717 EXPORT_C TBool JPLangUtil::IsHiragana( const TText aUnicodeChar ) |
|
718 { |
|
719 return ( ( aUnicodeChar >= 0x3041 && aUnicodeChar <= 0x3096 ) || |
|
720 ( aUnicodeChar >= 0x3099 && aUnicodeChar <= 0x309f ) ); |
|
721 } |
|
722 |
|
723 // ----------------------------------------------------------------------------- |
|
724 // JPLangUtil::IsKanji |
|
725 // Determines whether or not the character is a CJK Unified Ideograph (ExtA) |
|
726 // (detailed information about the parameters and return values can be found in |
|
727 // the header file) |
|
728 // ----------------------------------------------------------------------------- |
|
729 // |
|
730 EXPORT_C TBool JPLangUtil::IsKanji( const TText aUnicodeChar ) |
|
731 { |
|
732 return( ( aUnicodeChar >= KCJKUnifiedIdiographLowerBound && |
|
733 aUnicodeChar <= KCJKUnifiedIdiographUpperBound ) || |
|
734 ( aUnicodeChar >= KCJKUnifiedIdeographExtALowerBound && |
|
735 aUnicodeChar <= KCJKUnifiedIdeographExtAUpperBound ) ); |
|
736 } |
|
737 |
|
738 // ----------------------------------------------------------------------------- |
|
739 // JPLangUtil::IsHalfWidth |
|
740 // Determines whether or not the character is UNICODE defined Half-width. |
|
741 // (detailed information about the parameters and return values can be found in |
|
742 // the header file) |
|
743 // ----------------------------------------------------------------------------- |
|
744 // |
|
745 EXPORT_C TBool JPLangUtil::IsHalfWidth( const TText aUnicodeChar ) |
|
746 { |
|
747 return // HW Katakana |
|
748 ( ( aUnicodeChar >= 0xff61 && aUnicodeChar <= 0xff9f ) || |
|
749 // ASCII |
|
750 ( aUnicodeChar >= 0x0020 && aUnicodeChar <= 0x007e ) || |
|
751 // Special Characters |
|
752 ( aUnicodeChar == 0x00a2 || aUnicodeChar == 0x00a3 || |
|
753 aUnicodeChar == 0x00a5 || aUnicodeChar == 0x00a6 || |
|
754 aUnicodeChar == 0x00a9 || aUnicodeChar == 0x00ac || |
|
755 aUnicodeChar == 0x00af || aUnicodeChar == 0x2985 || |
|
756 aUnicodeChar == 0x2986 ) || |
|
757 // HW Symbol Variants |
|
758 ( aUnicodeChar >= 0xffe8 && aUnicodeChar <= 0xffee ) ); |
|
759 } |
|
760 |
|
761 // ----------------------------------------------------------------------------- |
|
762 // JPLangUtil::IsFullWidth |
|
763 // Determines whether or not the character is UNICODE defined Full-width. |
|
764 // Essentially, all code values that are not Half-width. |
|
765 // (detailed information about the parameters and return values can be found in |
|
766 // the header file) |
|
767 // ----------------------------------------------------------------------------- |
|
768 // |
|
769 EXPORT_C TBool JPLangUtil::IsFullWidth( const TText aUnicodeChar ) |
|
770 { |
|
771 return !IsHalfWidth( aUnicodeChar ); |
|
772 } |
|
773 |
|
774 // End of File |