Source Code Cross Referenced for ArabicTextHandler.java in  » Graphic-Library » batik » org » apache » batik » gvt » text » 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 » Graphic Library » batik » org.apache.batik.gvt.text 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:
003:           Licensed to the Apache Software Foundation (ASF) under one or more
004:           contributor license agreements.  See the NOTICE file distributed with
005:           this work for additional information regarding copyright ownership.
006:           The ASF licenses this file to You under the Apache License, Version 2.0
007:           (the "License"); you may not use this file except in compliance with
008:           the License.  You may obtain a copy of the License at
009:
010:               http://www.apache.org/licenses/LICENSE-2.0
011:
012:           Unless required by applicable law or agreed to in writing, software
013:           distributed under the License is distributed on an "AS IS" BASIS,
014:           WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015:           See the License for the specific language governing permissions and
016:           limitations under the License.
017:
018:         */
019:        package org.apache.batik.gvt.text;
020:
021:        import java.text.AttributedCharacterIterator;
022:        import java.text.AttributedString;
023:        import java.util.Map;
024:
025:        /**
026:         * Handles the processing of arabic text. In particular it determines the
027:         * form each arabic char should take. It also contains methods for substituting
028:         * plain arabic glyphs with their shaped forms. This is needed when the arabic
029:         * text is rendered using an AWT font.
030:         *
031:         * @author <a href="mailto:bella.robinson@cmis.csiro.au">Bella Robinson</a>
032:         * @version $Id: ArabicTextHandler.java 491229 2006-12-30 14:37:28Z dvholten $
033:         */
034:        public class ArabicTextHandler {
035:
036:            private static final int arabicStart = 0x0600;
037:            private static final int arabicEnd = 0x06FF;
038:
039:            private static final AttributedCharacterIterator.Attribute ARABIC_FORM = GVTAttributedCharacterIterator.TextAttribute.ARABIC_FORM;
040:            private static final Integer ARABIC_NONE = GVTAttributedCharacterIterator.TextAttribute.ARABIC_NONE;
041:            private static final Integer ARABIC_ISOLATED = GVTAttributedCharacterIterator.TextAttribute.ARABIC_ISOLATED;
042:            private static final Integer ARABIC_TERMINAL = GVTAttributedCharacterIterator.TextAttribute.ARABIC_TERMINAL;
043:            private static final Integer ARABIC_INITIAL = GVTAttributedCharacterIterator.TextAttribute.ARABIC_INITIAL;
044:            private static final Integer ARABIC_MEDIAL = GVTAttributedCharacterIterator.TextAttribute.ARABIC_MEDIAL;
045:
046:            /**
047:             * private ctor prevents unnecessary instantiation of this class.
048:             */
049:            private ArabicTextHandler() {
050:
051:            }
052:
053:            /**
054:             * If the AttributedString contains any arabic chars, assigns an
055:             * arabic form attribute, i&#x2e;e&#x2e; initial|medial|terminal|isolated,
056:             * to each arabic char.
057:             *
058:             * @param as The string to attach the arabic form attributes to.
059:             * @return An attributed string with arabic form attributes.
060:             */
061:            public static AttributedString assignArabicForms(AttributedString as) {
062:
063:                // first check to see if the string contains any arabic chars
064:                // if not, then don't need to do anything
065:                if (!containsArabic(as)) {
066:                    return as;
067:                }
068:
069:                // if the string contains any ligatures with transparent chars
070:                // eg. AtB where AB form a ligature and t is transparent, then
071:                // reorder that part of the string so that it becomes tAB
072:                // construct the reordered ACI
073:                AttributedCharacterIterator aci = as.getIterator();
074:                int numChars = aci.getEndIndex() - aci.getBeginIndex();
075:                int[] charOrder = null;
076:                if (numChars >= 3) {
077:                    char prevChar = aci.first();
078:                    char c = aci.next();
079:                    int i = 1;
080:                    for (char nextChar = aci.next(); nextChar != AttributedCharacterIterator.DONE; prevChar = c, c = nextChar, nextChar = aci
081:                            .next(), i++) {
082:                        if (arabicCharTransparent(c)) {
083:                            if (hasSubstitute(prevChar, nextChar)) {
084:                                // found a ligature, separated by a transparent char
085:                                if (charOrder == null) {
086:                                    charOrder = new int[numChars];
087:                                    for (int j = 0; j < numChars; j++) {
088:                                        charOrder[j] = j + aci.getBeginIndex();
089:                                    }
090:                                }
091:                                int temp = charOrder[i];
092:                                charOrder[i] = charOrder[i - 1];
093:                                charOrder[i - 1] = temp;
094:                            }
095:                        }
096:                    }
097:                }
098:
099:                if (charOrder != null) {
100:                    // need to reconstruct the reordered attributed string
101:                    StringBuffer reorderedString = new StringBuffer(numChars);
102:                    char c;
103:                    for (int i = 0; i < numChars; i++) {
104:                        c = aci.setIndex(charOrder[i]);
105:                        reorderedString.append(c);
106:                    }
107:                    AttributedString reorderedAS;
108:                    reorderedAS = new AttributedString(reorderedString
109:                            .toString());
110:
111:                    for (int i = 0; i < numChars; i++) {
112:                        aci.setIndex(charOrder[i]);
113:                        Map attributes = aci.getAttributes();
114:                        reorderedAS.addAttributes(attributes, i, i + 1);
115:                    }
116:
117:                    if (charOrder[0] != aci.getBeginIndex()) {
118:                        // have swapped the first char. Need to move
119:                        // any position attributes
120:
121:                        aci.setIndex(charOrder[0]);
122:                        Float x = (Float) aci
123:                                .getAttribute(GVTAttributedCharacterIterator.TextAttribute.X);
124:                        Float y = (Float) aci
125:                                .getAttribute(GVTAttributedCharacterIterator.TextAttribute.Y);
126:
127:                        if (x != null && !x.isNaN()) {
128:                            reorderedAS
129:                                    .addAttribute(
130:                                            GVTAttributedCharacterIterator.TextAttribute.X,
131:                                            new Float(Float.NaN), charOrder[0],
132:                                            charOrder[0] + 1);
133:                            reorderedAS
134:                                    .addAttribute(
135:                                            GVTAttributedCharacterIterator.TextAttribute.X,
136:                                            x, 0, 1);
137:                        }
138:                        if (y != null && !y.isNaN()) {
139:                            reorderedAS
140:                                    .addAttribute(
141:                                            GVTAttributedCharacterIterator.TextAttribute.Y,
142:                                            new Float(Float.NaN), charOrder[0],
143:                                            charOrder[0] + 1);
144:                            reorderedAS
145:                                    .addAttribute(
146:                                            GVTAttributedCharacterIterator.TextAttribute.Y,
147:                                            y, 0, 1);
148:                        }
149:                    }
150:                    as = reorderedAS;
151:                }
152:
153:                // first assign none to all arabic letters
154:                aci = as.getIterator();
155:                int runStart = -1;
156:                int idx = aci.getBeginIndex();
157:                for (int c = aci.first(); c != AttributedCharacterIterator.DONE; c = aci
158:                        .next(), idx++) {
159:                    if ((c >= arabicStart) && (c <= arabicEnd)) {
160:                        if (runStart == -1)
161:                            runStart = idx;
162:                    } else if (runStart != -1) {
163:                        as
164:                                .addAttribute(ARABIC_FORM, ARABIC_NONE,
165:                                        runStart, idx);
166:                        runStart = -1;
167:                    }
168:                }
169:                if (runStart != -1)
170:                    as.addAttribute(ARABIC_FORM, ARABIC_NONE, runStart, idx);
171:
172:                aci = as.getIterator(); // Make sure ACI tracks ARABIC_FORM
173:                int end = aci.getBeginIndex();
174:
175:                Integer currentForm = ARABIC_NONE;
176:                // for each run of arabic chars, assign the appropriate form
177:                while (aci.setIndex(end) != AttributedCharacterIterator.DONE) {
178:                    int start = aci.getRunStart(ARABIC_FORM);
179:                    end = aci.getRunLimit(ARABIC_FORM);
180:                    char currentChar = aci.setIndex(start);
181:                    currentForm = (Integer) aci.getAttribute(ARABIC_FORM);
182:
183:                    if (currentForm == null) {
184:                        // only modify if the chars in the run are arabic
185:                        continue;
186:                    }
187:
188:                    int currentIndex = start;
189:                    int prevCharIndex = start - 1;
190:                    while (currentIndex < end) {
191:                        char prevChar = currentChar;
192:                        currentChar = aci.setIndex(currentIndex);
193:                        while (arabicCharTransparent(currentChar)
194:                                && (currentIndex < end)) {
195:                            currentIndex++;
196:                            currentChar = aci.setIndex(currentIndex);
197:                        }
198:                        if (currentIndex >= end) {
199:                            break;
200:                        }
201:
202:                        Integer prevForm = currentForm;
203:                        currentForm = ARABIC_NONE;
204:                        if (prevCharIndex >= start) { // if not at the start
205:                            // if prev char right AND current char left
206:                            if (arabicCharShapesRight(prevChar)
207:                                    && arabicCharShapesLeft(currentChar)) {
208:                                // Increment the form of the previous char
209:                                prevForm = new Integer(prevForm.intValue() + 1);
210:                                as.addAttribute(ARABIC_FORM, prevForm,
211:                                        prevCharIndex, prevCharIndex + 1);
212:
213:                                // and set the form of the current char to INITIAL
214:                                currentForm = ARABIC_INITIAL;
215:                            } else if (arabicCharShaped(currentChar)) {
216:                                // set the form of the current char to ISOLATE
217:                                currentForm = ARABIC_ISOLATED;
218:                            }
219:
220:                            // if this is the first arabic char and its
221:                            // shaped, set to ISOLATE
222:                        } else if (arabicCharShaped(currentChar)) {
223:                            // set the form of the current char to ISOLATE
224:                            currentForm = ARABIC_ISOLATED;
225:                        }
226:                        if (currentForm != ARABIC_NONE)
227:                            as.addAttribute(ARABIC_FORM, currentForm,
228:                                    currentIndex, currentIndex + 1);
229:                        prevCharIndex = currentIndex;
230:                        currentIndex++;
231:                    }
232:                }
233:                return as;
234:            }
235:
236:            /**
237:             * Returns true if the char is a standard arabic char.
238:             * (ie. within the range U+0600 - U+6FF)
239:             *
240:             * @param c The character to test.
241:             * @return True if the char is arabic, false otherwise.
242:             */
243:            public static boolean arabicChar(char c) {
244:                if (c >= arabicStart && c <= arabicEnd) {
245:                    return true;
246:                }
247:                return false;
248:            }
249:
250:            /**
251:             * Returns true if the string contains any arabic characters.
252:             *
253:             * @param as The string to test.
254:             * @return True if at least one char is arabic, false otherwise.
255:             */
256:            public static boolean containsArabic(AttributedString as) {
257:                return containsArabic(as.getIterator());
258:            }
259:
260:            /**
261:             * Returns true if the ACI contains any arabic characters.
262:             *
263:             * @param aci The AttributedCharacterIterator to test.
264:             * @return True if at least one char is arabic, false otherwise.
265:             */
266:            public static boolean containsArabic(AttributedCharacterIterator aci) {
267:                for (char c = aci.first(); c != AttributedCharacterIterator.DONE; c = aci
268:                        .next()) {
269:                    if (arabicChar(c)) {
270:                        return true;
271:                    }
272:                }
273:                return false;
274:            }
275:
276:            /**
277:             * Returns true if the char is transparent.
278:             *
279:             * @param c The character to test.
280:             * @return True if the character is transparent, false otherwise.
281:             */
282:            public static boolean arabicCharTransparent(char c) {
283:                int charVal = c;
284:                if ((charVal < 0x064B) || (charVal > 0x06ED))
285:                    return false;
286:
287:                if ((charVal <= 0x0655) || (charVal == 0x0670)
288:                        || (charVal >= 0x06D6 && charVal <= 0x06E4)
289:                        || (charVal >= 0x06E7 && charVal <= 0x06E8)
290:                        || (charVal >= 0x06EA)) {
291:                    return true;
292:                }
293:                return false;
294:            }
295:
296:            /**
297:             * Returns true if the character shapes to the right. Note that duel
298:             * shaping characters also shape to the right and so will return true.
299:             *
300:             * @param c The character to test.
301:             * @return True if the character shapes to the right, false otherwise.
302:             */
303:            private static boolean arabicCharShapesRight(char c) {
304:                int charVal = c;
305:                if ((charVal >= 0x0622 && charVal <= 0x0625)
306:                        || (charVal == 0x0627) || (charVal == 0x0629)
307:                        || (charVal >= 0x062F && charVal <= 0x0632)
308:                        || (charVal == 0x0648)
309:                        || (charVal >= 0x0671 && charVal <= 0x0673)
310:                        || (charVal >= 0x0675 && charVal <= 0x0677)
311:                        || (charVal >= 0x0688 && charVal <= 0x0699)
312:                        || (charVal == 0x06C0)
313:                        || (charVal >= 0x06C2 && charVal <= 0x06CB)
314:                        || (charVal == 0x06CD) || (charVal == 0x06CF)
315:                        || (charVal >= 0x06D2 && charVal <= 0x06D3)
316:                        // check for duel shaping too
317:                        || arabicCharShapesDuel(c)) {
318:                    return true;
319:                }
320:                return false;
321:            }
322:
323:            /**
324:             * Returns true if character has duel shaping.
325:             *
326:             * @param c The character to test.
327:             * @return True if the character is duel shaping, false otherwise.
328:             */
329:            private static boolean arabicCharShapesDuel(char c) {
330:                int charVal = c;
331:
332:                if ((charVal == 0x0626) || (charVal == 0x0628)
333:                        || (charVal >= 0x062A && charVal <= 0x062E)
334:                        || (charVal >= 0x0633 && charVal <= 0x063A)
335:                        || (charVal >= 0x0641 && charVal <= 0x0647)
336:                        || (charVal >= 0x0649 && charVal <= 0x064A)
337:                        || (charVal >= 0x0678 && charVal <= 0x0687)
338:                        || (charVal >= 0x069A && charVal <= 0x06BF)
339:                        || (charVal == 0x6C1) || (charVal == 0x6CC)
340:                        || (charVal == 0x6CE)
341:                        || (charVal >= 0x06D0 && charVal <= 0x06D1)
342:                        || (charVal >= 0x06FA && charVal <= 0x06FC)) {
343:                    return true;
344:                }
345:                return false;
346:            }
347:
348:            /**
349:             * Returns true if character shapes to the left. Note that duel
350:             * shaping characters also shape to the left and so will return true.
351:             *
352:             * @param c The character to test.
353:             * @return True if the character shapes to the left, false otherwise.
354:             */
355:            private static boolean arabicCharShapesLeft(char c) {
356:                return arabicCharShapesDuel(c);
357:            }
358:
359:            /**
360:             * Returns true if character is shaped.
361:             *
362:             * @param c The character to test.
363:             * @return True if the character is shaped, false otherwise.
364:             */
365:            private static boolean arabicCharShaped(char c) {
366:                return arabicCharShapesRight(c);
367:            }
368:
369:            public static boolean hasSubstitute(char ch1, char ch2) {
370:                if ((ch1 < doubleCharFirst) || (ch1 > doubleCharLast))
371:                    return false;
372:
373:                int[][] remaps = doubleCharRemappings[ch1 - doubleCharFirst];
374:                if (remaps == null)
375:                    return false;
376:                for (int i = 0; i < remaps.length; i++) {
377:                    if (remaps[i][0] == ch2)
378:                        return true;
379:                }
380:                return false;
381:            }
382:
383:            /**
384:             * Will try and find a substitute character of the specified form.
385:             *
386:             * @param ch1 The first character of two to replace.
387:             * @param ch2 The second character of two to replace.
388:             * @param form Indicates the required arabic form.
389:             * (isolated = 1, final = 2, initial = 3, medial = 4)
390:             *
391:             * @return The unicode value of the substutute char, or -1 if no substitute
392:             * exists.
393:             */
394:            public static int getSubstituteChar(char ch1, char ch2, int form) {
395:                if (form == 0)
396:                    return -1;
397:                if ((ch1 < doubleCharFirst) || (ch1 > doubleCharLast))
398:                    return -1;
399:
400:                int[][] remaps = doubleCharRemappings[ch1 - doubleCharFirst];
401:                if (remaps == null)
402:                    return -1;
403:                for (int i = 0; i < remaps.length; i++) {
404:                    if (remaps[i][0] == ch2)
405:                        return remaps[i][form];
406:                }
407:                return -1;
408:            }
409:
410:            public static int getSubstituteChar(char ch, int form) {
411:                if (form == 0)
412:                    return -1;
413:                if ((ch < singleCharFirst) || (ch > singleCharLast))
414:                    return -1;
415:
416:                int[] chars = singleCharRemappings[ch - singleCharFirst];
417:                if (chars == null)
418:                    return -1;
419:
420:                return chars[form - 1];
421:            }
422:
423:            /**
424:             * Where possible substitues plain arabic glyphs with their shaped
425:             * forms.  This is needed when the arabic text is rendered using
426:             * an AWT font.  Simple arabic ligatures will also be recognised
427:             * and replaced by a single character so the length of the
428:             * resulting string may be shorter than the number of characters
429:             * in the aci.
430:             *
431:             * @param aci Contains the text to process. Arabic form attributes
432:             * should already be assigned to each arabic character.
433:             * @return A String containing the shaped versions of the arabic characters
434:             */
435:            public static String createSubstituteString(
436:                    AttributedCharacterIterator aci) {
437:                int start = aci.getBeginIndex();
438:                int end = aci.getEndIndex();
439:                int numChar = end - start;
440:                StringBuffer substString = new StringBuffer(numChar);
441:                for (int i = start; i < end; i++) {
442:                    char c = aci.setIndex(i);
443:                    if (!arabicChar(c)) {
444:                        substString.append(c);
445:                        continue;
446:                    }
447:
448:                    Integer form = (Integer) aci.getAttribute(ARABIC_FORM);
449:                    // see if the c is the start of a ligature
450:                    if (charStartsLigature(c) && (i + 1 < end)) {
451:                        char nextChar = aci.setIndex(i + 1);
452:                        Integer nextForm = (Integer) aci
453:                                .getAttribute(ARABIC_FORM);
454:                        if (form != null && nextForm != null) {
455:                            if (form.equals(ARABIC_TERMINAL)
456:                                    && nextForm.equals(ARABIC_INITIAL)) {
457:                                // look for an isolated ligature
458:                                int substChar = ArabicTextHandler
459:                                        .getSubstituteChar(c, nextChar,
460:                                                ARABIC_ISOLATED.intValue());
461:                                if (substChar > -1) {
462:                                    substString.append((char) substChar);
463:                                    i++;
464:                                    continue;
465:                                }
466:                            } else if (form.equals(ARABIC_TERMINAL)) {
467:                                // look for a terminal ligature
468:                                int substChar = ArabicTextHandler
469:                                        .getSubstituteChar(c, nextChar,
470:                                                ARABIC_TERMINAL.intValue());
471:                                if (substChar > -1) {
472:                                    substString.append((char) substChar);
473:                                    i++;
474:                                    continue;
475:                                }
476:                            } else if (form.equals(ARABIC_MEDIAL)
477:                                    && nextForm.equals(ARABIC_MEDIAL)) {
478:                                // look for a medial ligature
479:                                int substChar = ArabicTextHandler
480:                                        .getSubstituteChar(c, nextChar,
481:                                                ARABIC_MEDIAL.intValue());
482:                                if (substChar > -1) {
483:                                    substString.append((char) substChar);
484:                                    i++;
485:                                    continue;
486:                                }
487:                            }
488:                        }
489:                    }
490:
491:                    // couldn't find a matching ligature so just look for a
492:                    // simple substitution
493:                    if (form != null && form.intValue() > 0) {
494:                        int substChar = getSubstituteChar(c, form.intValue());
495:                        if (substChar > -1) {
496:                            c = (char) substChar;
497:                        }
498:                    }
499:                    substString.append(c);
500:                }
501:
502:                return substString.toString();
503:            }
504:
505:            /**
506:             * Returns true if a ligature exists that starts with the
507:             * specified character.
508:             *
509:             * @param c The character to test.
510:             * @return True if there is a ligature that starts with c, false otherwise.
511:             */
512:            public static boolean charStartsLigature(char c) {
513:                int charVal = c;
514:                if (charVal == 0x064B || charVal == 0x064C || charVal == 0x064D
515:                        || charVal == 0x064E || charVal == 0x064F
516:                        || charVal == 0x0650 || charVal == 0x0651
517:                        || charVal == 0x0652 || charVal == 0x0622
518:                        || charVal == 0x0623 || charVal == 0x0625
519:                        || charVal == 0x0627) {
520:                    return true;
521:                }
522:                return false;
523:            }
524:
525:            /**
526:             * Returns the number of characters the glyph for the specified
527:             * character represents. If the glyph represents a ligature this
528:             * will be 2, otherwise 1.
529:             *
530:             * @param c The character to test.
531:             * @return The number of characters the glyph for c represents.
532:             */
533:            public static int getNumChars(char c) {
534:                // if c is a ligature returns 2, else returns 1
535:                if (isLigature(c))
536:                    // at the moment only support ligatures with two chars
537:                    return 2;
538:                return 1;
539:            }
540:
541:            /**
542:             * Returns true if the glyph for the specified character
543:             * respresents a ligature.
544:             *
545:             * @param c The character to test.
546:             * @return True if c is a ligature, false otherwise.
547:             */
548:            public static boolean isLigature(char c) {
549:                int charVal = c;
550:                if ((charVal < 0xFE70) || (charVal > 0xFEFC))
551:                    return false;
552:
553:                if ((charVal <= 0xFE72) || (charVal == 0xFE74)
554:                        || (charVal >= 0xFE76 && charVal <= 0xFE7F)
555:                        || (charVal >= 0xFEF5)) {
556:                    return true;
557:                }
558:                return false;
559:            }
560:
561:            // constructs the character map that maps arabic characters and
562:            // ligature to their various forms
563:            // NOTE: the unicode values for ligatures are stored here in
564:            // visual order (not logical order)
565:
566:            // Single char remappings:
567:            static int singleCharFirst = 0x0621;
568:            static int singleCharLast = 0x064A;
569:            static int[][] singleCharRemappings = {
570:            // isolated, final, initial, medial
571:                    { 0xFE80, -1, -1, -1 }, // 0x0621
572:                    { 0xFE81, 0xFE82, -1, -1 }, // 0x0622
573:                    { 0xFE83, 0xFE84, -1, -1 }, // 0x0623
574:                    { 0xFE85, 0xFE86, -1, -1 }, // 0x0624
575:                    { 0xFE87, 0xFE88, -1, -1 }, // 0x0625
576:                    { 0xFE89, 0xFE8A, 0xFE8B, 0xFE8C }, // 0x0626
577:                    { 0xFE8D, 0xFE8E, -1, -1 }, // 0x0627
578:                    { 0xFE8F, 0xFE90, 0xFE91, 0xFE92 }, // 0x0628
579:                    { 0xFE93, 0xFE94, -1, -1 }, // 0x0629
580:                    { 0xFE95, 0xFE96, 0xFE97, 0xFE98 }, // 0x062A
581:                    { 0xFE99, 0xFE9A, 0xFE9B, 0xFE9C }, // 0x062B
582:                    { 0xFE9D, 0xFE9E, 0xFE9F, 0xFEA0 }, // 0x062C
583:                    { 0xFEA1, 0xFEA2, 0xFEA3, 0xFEA4 }, // 0x062D
584:                    { 0xFEA5, 0xFEA6, 0xFEA7, 0xFEA8 }, // 0x062E
585:                    { 0xFEA9, 0xFEAA, -1, -1 }, // 0x062F
586:                    { 0xFEAB, 0xFEAC, -1, -1 }, // 0x0630
587:                    { 0xFEAD, 0xFEAE, -1, -1 }, // 0x0631
588:                    { 0xFEAF, 0xFEB0, -1, -1 }, // 0x0632
589:                    { 0xFEB1, 0xFEB2, 0xFEB3, 0xFEB4 }, // 0x0633
590:                    { 0xFEB5, 0xFEB6, 0xFEB7, 0xFEB8 }, // 0x0634
591:                    { 0xFEB9, 0xFEBA, 0xFEBB, 0xFEBC }, // 0x0635
592:                    { 0xFEBD, 0xFEBE, 0xFEBF, 0xFEC0 }, // 0x0636
593:                    { 0xFEC1, 0xFEC2, 0xFEC3, 0xFEC4 }, // 0x0637
594:                    { 0xFEC5, 0xFEC6, 0xFEC7, 0xFEC8 }, // 0x0638
595:                    { 0xFEC9, 0xFECA, 0xFECB, 0xFECC }, // 0x0639
596:                    { 0xFECD, 0xFECE, 0xFECF, 0xFED0 }, // 0x063A
597:
598:                    null, // 0x063B
599:                    null, // 0x063C
600:                    null, // 0x063D
601:                    null, // 0x063E
602:                    null, // 0x063F
603:                    null, // 0x0640
604:
605:                    { 0xFED1, 0xFED2, 0xFED3, 0xFED4 }, // 0x0641
606:                    { 0xFED5, 0xFED6, 0xFED7, 0xFED8 }, // 0x0642
607:                    { 0xFED9, 0xFEDA, 0xFEDB, 0xFEDC }, // 0x0643
608:                    { 0xFEDD, 0xFEDE, 0xFEDF, 0xFEE0 }, // 0x0644
609:                    { 0xFEE1, 0xFEE2, 0xFEE3, 0xFEE4 }, // 0x0645
610:                    { 0xFEE5, 0xFEE6, 0xFEE7, 0xFEE8 }, // 0x0646
611:                    { 0xFEE9, 0xFEEA, 0xFEEB, 0xFEEC }, // 0x0647
612:                    { 0xFEED, 0xFEEE, -1, -1 }, // 0x0648
613:                    { 0xFEEF, 0xFEF0, -1, -1 }, // 0x0649
614:                    { 0xFEF1, 0xFEF2, 0xFEF3, 0xFEF4 } }; // 0x064A
615:
616:            static int doubleCharFirst = 0x0622;
617:            static int doubleCharLast = 0x0652;
618:            static int[][][] doubleCharRemappings = {
619:                    // 2nd Char, isolated, final, initial, medial
620:                    { { 0x0644, 0xFEF5, 0xFEF6, -1, -1 } }, // 0x0622
621:                    { { 0x0644, 0xFEF7, 0xFEF8, -1, -1 } }, // 0x0623
622:                    null, // 0x0624
623:                    { { 0x0644, 0xFEF9, 0xFEFA, -1, -1 } }, // 0x0625
624:                    null, // 0x0626
625:                    { { 0x0644, 0xFEFB, 0xFEFC, -1, -1 } }, // 0x0627
626:
627:                    null, // 0x0628
628:                    null, // 0x0629
629:                    null, // 0x0630
630:                    null, // 0x0631
631:                    null, // 0x0632
632:                    null, // 0x0633
633:                    null, // 0x0634
634:                    null, // 0x0635
635:                    null, // 0x0636
636:                    null, // 0x0637
637:                    null, // 0x0638
638:                    null, // 0x0639
639:                    null, // 0x063A
640:                    null, // 0x063B
641:                    null, // 0x063C
642:                    null, // 0x063D
643:                    null, // 0x063E
644:                    null, // 0x063F
645:                    null, // 0x0640
646:                    null, // 0x0641
647:                    null, // 0x0642
648:                    null, // 0x0643
649:                    null, // 0x0644
650:                    null, // 0x0645
651:                    null, // 0x0646
652:                    null, // 0x0647
653:                    null, // 0x0648
654:                    null, // 0x0649
655:                    null, // 0x064A
656:
657:                    { { 0x0020, 0xFE70, -1, -1, -1 }, // 0x064B
658:                            { 0x0640, -1, -1, -1, 0xFE71 } },
659:                    { { 0x0020, 0xFE72, -1, -1, -1 } }, // 0x064C
660:                    { { 0x0020, 0xFE74, -1, -1, -1 } }, // 0x064D
661:                    { { 0x0020, 0xFE76, -1, -1, -1 }, // 0x064E
662:                            { 0x0640, -1, -1, -1, 0xFE77 } },
663:                    { { 0x0020, 0xFE78, -1, -1, -1 }, // 0x064F
664:                            { 0x0640, -1, -1, -1, 0xFE79 } },
665:                    { { 0x0020, 0xFE7A, -1, -1, -1 }, // 0x0650
666:                            { 0x0640, -1, -1, -1, 0xFE7B } },
667:                    { { 0x0020, 0xFE7C, -1, -1, -1 }, // 0x0651
668:                            { 0x0640, -1, -1, -1, 0xFE7D } },
669:                    { { 0x0020, 0xFE7E, -1, -1, -1 }, // 0x0652
670:                            { 0x0640, -1, -1, -1, 0xFE7F } } };
671:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.