Source Code Cross Referenced for IndicInputMethodImpl.java in  » Internationalization-Localization » icu4j » com » ibm » icu » dev » tool » ime » indic » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Internationalization Localization » icu4j » com.ibm.icu.dev.tool.ime.indic 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         *******************************************************************************
003:         * Copyright (C) 2000-2006, International Business Machines Corporation and    *
004:         * others. All Rights Reserved.                                                *
005:         *******************************************************************************
006:         */
007:
008:        package com.ibm.icu.dev.tool.ime.indic;
009:
010:        import java.awt.im.spi.InputMethodContext;
011:
012:        import java.awt.event.KeyEvent;
013:        import java.awt.event.InputMethodEvent;
014:        import java.awt.font.TextAttribute;
015:        import java.awt.font.TextHitInfo;
016:        import java.text.AttributedCharacterIterator;
017:        import java.util.Hashtable;
018:        import java.util.HashSet;
019:        import java.util.Map;
020:        import java.util.Set;
021:
022:        class IndicInputMethodImpl {
023:
024:            protected char[] KBD_MAP;
025:
026:            private static final char SUBSTITUTION_BASE = '\uff00';
027:
028:            // Indexed by map value - SUBSTITUTION_BASE
029:            protected char[][] SUBSTITUTION_TABLE;
030:
031:            // Invalid character.
032:            private static final char INVALID_CHAR = '\uffff';
033:
034:            // Unmapped versions of some interesting characters.
035:            private static final char KEY_SIGN_VIRAMA = '\u0064'; // or just 'd'??
036:            private static final char KEY_SIGN_NUKTA = '\u005d'; // or just ']'??
037:
038:            // Two succeeding viramas are replaced by one virama and one ZWNJ.
039:            // Viram followed by Nukta is replaced by one VIRAMA and one ZWJ
040:            private static final char ZWJ = '\u200d';
041:            private static final char ZWNJ = '\u200c';
042:
043:            // Backspace
044:            private static final char BACKSPACE = '\u0008';
045:
046:            // Sorted list of characters which can be followed by Nukta
047:            protected char[] JOIN_WITH_NUKTA;
048:
049:            // Nukta form of the above characters
050:            protected char[] NUKTA_FORM;
051:
052:            private int log2;
053:            private int power;
054:            private int extra;
055:
056:            // cached TextHitInfo. Only one type of TextHitInfo is required.
057:            private static final TextHitInfo ZERO_TRAILING_HIT_INFO = TextHitInfo
058:                    .trailing(0);
059:
060:            /**
061:             * Returns the index of the given character in the JOIN_WITH_NUKTA array.
062:             * If character is not found, -1 is returned.
063:             */
064:            private int nuktaIndex(char ch) {
065:                if (JOIN_WITH_NUKTA == null) {
066:                    return -1;
067:                }
068:
069:                int probe = power;
070:                int index = 0;
071:
072:                if (JOIN_WITH_NUKTA[extra] <= ch) {
073:                    index = extra;
074:                }
075:
076:                while (probe > (1 << 0)) {
077:                    probe >>= 1;
078:
079:                    if (JOIN_WITH_NUKTA[index + probe] <= ch) {
080:                        index += probe;
081:                    }
082:                }
083:
084:                if (JOIN_WITH_NUKTA[index] != ch) {
085:                    index = -1;
086:                }
087:
088:                return index;
089:            }
090:
091:            /**
092:             * Returns the equivalent character for hindi locale.
093:             * @param originalChar The original character.
094:             */
095:            private char getMappedChar(char originalChar) {
096:                if (originalChar <= KBD_MAP.length) {
097:                    return KBD_MAP[originalChar];
098:                }
099:
100:                return originalChar;
101:            }
102:
103:            // Array used to hold the text to be sent.
104:            // If the last character was not committed it is stored in text[0].
105:            // The variable totalChars give an indication of whether the last
106:            // character was committed or not. If at any time ( but not within a
107:            // a call to dispatchEvent ) totalChars is not equal to 0 ( it can
108:            // only be 1 otherwise ) the last character was not committed.
109:            private char[] text = new char[4];
110:
111:            // this is always 0 before and after call to dispatchEvent. This character assumes
112:            // significance only within a call to dispatchEvent.
113:            private int committedChars = 0;// number of committed characters
114:
115:            // the total valid characters in variable text currently.
116:            private int totalChars = 0;//number of total characters ( committed + composed )
117:
118:            private boolean lastCharWasVirama = false;
119:
120:            private InputMethodContext context;
121:
122:            //
123:            // Finds the high bit by binary searching
124:            // through the bits in n.
125:            //
126:            private static byte highBit(int n) {
127:                if (n <= 0) {
128:                    return -32;
129:                }
130:
131:                byte bit = 0;
132:
133:                if (n >= 1 << 16) {
134:                    n >>= 16;
135:                    bit += 16;
136:                }
137:
138:                if (n >= 1 << 8) {
139:                    n >>= 8;
140:                    bit += 8;
141:                }
142:
143:                if (n >= 1 << 4) {
144:                    n >>= 4;
145:                    bit += 4;
146:                }
147:
148:                if (n >= 1 << 2) {
149:                    n >>= 2;
150:                    bit += 2;
151:                }
152:
153:                if (n >= 1 << 1) {
154:                    n >>= 1;
155:                    bit += 1;
156:                }
157:
158:                return bit;
159:            }
160:
161:            IndicInputMethodImpl(char[] keyboardMap, char[] joinWithNukta,
162:                    char[] nuktaForm, char[][] substitutionTable) {
163:                KBD_MAP = keyboardMap;
164:                JOIN_WITH_NUKTA = joinWithNukta;
165:                NUKTA_FORM = nuktaForm;
166:                SUBSTITUTION_TABLE = substitutionTable;
167:
168:                if (JOIN_WITH_NUKTA != null) {
169:                    int log2 = highBit(JOIN_WITH_NUKTA.length);
170:
171:                    power = 1 << log2;
172:                    extra = JOIN_WITH_NUKTA.length - power;
173:                } else {
174:                    power = extra = 0;
175:                }
176:
177:            }
178:
179:            void setInputMethodContext(InputMethodContext context) {
180:                this .context = context;
181:            }
182:
183:            void handleKeyTyped(KeyEvent kevent) {
184:                char keyChar = kevent.getKeyChar();
185:                char currentChar = getMappedChar(keyChar);
186:
187:                // The Explicit and Soft Halanta case.
188:                if (lastCharWasVirama) {
189:                    switch (keyChar) {
190:                    case KEY_SIGN_NUKTA:
191:                        currentChar = ZWJ;
192:                        break;
193:                    case KEY_SIGN_VIRAMA:
194:                        currentChar = ZWNJ;
195:                        break;
196:                    default:
197:                    }//endSwitch
198:                }//endif
199:
200:                if (currentChar == INVALID_CHAR) {
201:                    kevent.consume();
202:                    return;
203:                }
204:
205:                if (currentChar == BACKSPACE) {
206:                    lastCharWasVirama = false;
207:
208:                    if (totalChars > 0) {
209:                        totalChars = committedChars = 0;
210:                    } else {
211:                        return;
212:                    }
213:                } else if (keyChar == KEY_SIGN_NUKTA) {
214:                    int nuktaIndex = nuktaIndex(text[0]);
215:
216:                    if (nuktaIndex != -1) {
217:                        text[0] = NUKTA_FORM[nuktaIndex];
218:                    } else {
219:                        // the last character was committed, commit just Nukta.
220:                        // Note : the lastChar must have been committed if it is not one of
221:                        // the characters which combine with nukta.
222:                        // the state must be totalChars = committedChars = 0;
223:                        text[totalChars++] = currentChar;
224:                    }
225:
226:                    committedChars += 1;
227:                } else {
228:                    int nuktaIndex = nuktaIndex(currentChar);
229:
230:                    if (nuktaIndex != -1) {
231:                        // Commit everything but currentChar
232:                        text[totalChars++] = currentChar;
233:                        committedChars = totalChars - 1;
234:                    } else {
235:                        if (currentChar >= SUBSTITUTION_BASE) {
236:                            char[] sub = SUBSTITUTION_TABLE[currentChar
237:                                    - SUBSTITUTION_BASE];
238:
239:                            System.arraycopy(sub, 0, text, totalChars,
240:                                    sub.length);
241:                            totalChars += sub.length;
242:                        } else {
243:                            text[totalChars++] = currentChar;
244:                        }
245:
246:                        committedChars = totalChars;
247:                    }
248:                }
249:
250:                ACIText aText = new ACIText(text, 0, totalChars, committedChars);
251:                int composedCharLength = totalChars - committedChars;
252:                TextHitInfo caret = null, visiblePosition = null;
253:                switch (composedCharLength) {
254:                case 0:
255:                    break;
256:                case 1:
257:                    visiblePosition = caret = ZERO_TRAILING_HIT_INFO;
258:                    break;
259:                default:
260:                    // The code should not reach here. There is no case where there can be
261:                    // more than one character pending.
262:                }
263:
264:                context.dispatchInputMethodEvent(
265:                        InputMethodEvent.INPUT_METHOD_TEXT_CHANGED, aText,
266:                        committedChars, caret, visiblePosition);
267:
268:                if (totalChars == 0) {
269:                    text[0] = INVALID_CHAR;
270:                } else {
271:                    text[0] = text[totalChars - 1];// make text[0] hold the last character
272:                }
273:
274:                lastCharWasVirama = keyChar == KEY_SIGN_VIRAMA
275:                        && !lastCharWasVirama;
276:
277:                totalChars -= committedChars;
278:                committedChars = 0;
279:                // state now text[0] = last character
280:                // totalChars = ( last character committed )? 0 : 1;
281:                // committedChars = 0;
282:
283:                kevent.consume();// prevent client from getting this event.
284:            }
285:
286:            void endComposition() {
287:                if (totalChars != 0) {// if some character is not committed.
288:                    ACIText aText = new ACIText(text, 0, totalChars, totalChars);
289:                    context.dispatchInputMethodEvent(
290:                            InputMethodEvent.INPUT_METHOD_TEXT_CHANGED, aText,
291:                            totalChars, null, null);
292:                    totalChars = committedChars = 0;
293:                    text[0] = INVALID_CHAR;
294:                    lastCharWasVirama = false;
295:                }
296:            }
297:
298:            // custom AttributedCharacterIterator -- much lightweight since currently there is no
299:            // attribute defined on the text being generated by the input method.
300:            private class ACIText implements  AttributedCharacterIterator {
301:                private char[] text = null;
302:                private int committed = 0;
303:                private int index = 0;
304:
305:                ACIText(char[] chArray, int offset, int length, int committed) {
306:                    this .text = new char[length];
307:                    this .committed = committed;
308:                    System.arraycopy(chArray, offset, text, 0, length);
309:                }
310:
311:                // CharacterIterator methods.
312:                public char first() {
313:                    return _setIndex(0);
314:                }
315:
316:                public char last() {
317:                    if (text.length == 0) {
318:                        return _setIndex(text.length);
319:                    }
320:                    return _setIndex(text.length - 1);
321:                }
322:
323:                public char current() {
324:                    if (index == text.length)
325:                        return DONE;
326:                    return text[index];
327:                }
328:
329:                public char next() {
330:                    if (index == text.length) {
331:                        return DONE;
332:                    }
333:                    return _setIndex(index + 1);
334:                }
335:
336:                public char previous() {
337:                    if (index == 0)
338:                        return DONE;
339:                    return _setIndex(index - 1);
340:                }
341:
342:                public char setIndex(int position) {
343:                    if (position < 0 || position > text.length) {
344:                        throw new IllegalArgumentException();
345:                    }
346:                    return _setIndex(position);
347:                }
348:
349:                public int getBeginIndex() {
350:                    return 0;
351:                }
352:
353:                public int getEndIndex() {
354:                    return text.length;
355:                }
356:
357:                public int getIndex() {
358:                    return index;
359:                }
360:
361:                public Object clone() {
362:                    try {
363:                        ACIText clone = (ACIText) super .clone();
364:                        return clone;
365:                    } catch (CloneNotSupportedException e) {
366:                        throw new IllegalStateException();
367:                    }
368:                }
369:
370:                // AttributedCharacterIterator methods.
371:                public int getRunStart() {
372:                    return index >= committed ? committed : 0;
373:                }
374:
375:                public int getRunStart(
376:                        AttributedCharacterIterator.Attribute attribute) {
377:                    return (index >= committed && attribute == TextAttribute.INPUT_METHOD_UNDERLINE) ? committed
378:                            : 0;
379:                }
380:
381:                public int getRunStart(Set attributes) {
382:                    return (index >= committed && attributes
383:                            .contains(TextAttribute.INPUT_METHOD_UNDERLINE)) ? committed
384:                            : 0;
385:                }
386:
387:                public int getRunLimit() {
388:                    return index < committed ? committed : text.length;
389:                }
390:
391:                public int getRunLimit(
392:                        AttributedCharacterIterator.Attribute attribute) {
393:                    return (index < committed && attribute == TextAttribute.INPUT_METHOD_UNDERLINE) ? committed
394:                            : text.length;
395:                }
396:
397:                public int getRunLimit(Set attributes) {
398:                    return (index < committed && attributes
399:                            .contains(TextAttribute.INPUT_METHOD_UNDERLINE)) ? committed
400:                            : text.length;
401:                }
402:
403:                public Map getAttributes() {
404:                    Hashtable result = new Hashtable();
405:                    if (index >= committed && committed < text.length) {
406:                        result.put(TextAttribute.INPUT_METHOD_UNDERLINE,
407:                                TextAttribute.UNDERLINE_LOW_ONE_PIXEL);
408:                    }
409:                    return result;
410:                }
411:
412:                public Object getAttribute(
413:                        AttributedCharacterIterator.Attribute attribute) {
414:                    if (index >= committed
415:                            && committed < text.length
416:                            && attribute == TextAttribute.INPUT_METHOD_UNDERLINE) {
417:
418:                        return TextAttribute.UNDERLINE_LOW_ONE_PIXEL;
419:                    }
420:                    return null;
421:                }
422:
423:                public Set getAllAttributeKeys() {
424:                    HashSet result = new HashSet();
425:                    if (committed < text.length) {
426:                        result.add(TextAttribute.INPUT_METHOD_UNDERLINE);
427:                    }
428:                    return result;
429:                }
430:
431:                // private methods
432:
433:                /**
434:                 * This is always called with valid i ( 0 < i <= text.length )
435:                 */
436:                private char _setIndex(int i) {
437:                    index = i;
438:                    if (i == text.length) {
439:                        return DONE;
440:                    }
441:                    return text[i];
442:                }
443:
444:            }
445:        }
w_ww__.___j_a_v_a___2__s._c___o_m | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.