2 *******************************************************************************
\r
3 * Copyright (C) 2001, International Business Machines
\r
4 * Corporation and others. All Rights Reserved.
\r
5 *******************************************************************************
\r
8 package com.ibm.icu.dev.test.shaping;
\r
10 import com.ibm.icu.text.ArabicShaping;
\r
11 import com.ibm.icu.text.ArabicShapingException;
\r
14 * Interactive test for Arabic shaping.
\r
15 * Invoke from a command line passing args and strings. Use '-help' to see description of arguments.
\r
17 public class ArabicShapingTest {
\r
18 private static final int COPY = 0;
\r
19 private static final int INPLACE = 1;
\r
20 private static final int STRING = 2;
\r
22 public static final void main(String[] args) {
\r
23 int testtype = COPY;
\r
29 String text = "$22.4 test 123 \ufef6\u0644\u0622 456 \u0664\u0665\u0666!";
\r
31 for (int i = 0; i < args.length; ++i) {
\r
32 String arg = args[i];
\r
33 if (arg.charAt(0) == '-') {
\r
34 String opt = arg.substring(1);
\r
36 int index = arg.indexOf(':');
\r
38 opt = opt.substring(0, Math.min(index, 3));
\r
39 val = arg.substring(index + 1);
\r
42 if (opt.equalsIgnoreCase("len")) {
\r
43 options &= ~ArabicShaping.LENGTH_MASK;
\r
44 if (val.equalsIgnoreCase("gs")) {
\r
45 options |= ArabicShaping.LENGTH_GROW_SHRINK;
\r
46 } else if (val.equalsIgnoreCase("sn")) {
\r
47 options |= ArabicShaping.LENGTH_FIXED_SPACES_NEAR;
\r
48 } else if (val.equalsIgnoreCase("se")) {
\r
49 options |= ArabicShaping.LENGTH_FIXED_SPACES_AT_END;
\r
50 } else if (val.equalsIgnoreCase("sb")) {
\r
51 options |= ArabicShaping.LENGTH_FIXED_SPACES_AT_BEGINNING;
\r
53 throwValError(opt, val);
\r
55 } else if (opt.equalsIgnoreCase("dir")) {
\r
56 options &= ~ArabicShaping.TEXT_DIRECTION_MASK;
\r
57 if (val.equalsIgnoreCase("log")) {
\r
58 options |= ArabicShaping.TEXT_DIRECTION_LOGICAL;
\r
59 } else if (val.equalsIgnoreCase("vis")) {
\r
60 options |= ArabicShaping.TEXT_DIRECTION_VISUAL_LTR;
\r
62 throwValError(opt, val);
\r
64 } else if (opt.equalsIgnoreCase("let")) {
\r
65 options &= ~ArabicShaping.LETTERS_MASK;
\r
66 if (val.equalsIgnoreCase("no")) {
\r
67 options |= ArabicShaping.LETTERS_NOOP;
\r
68 } else if (val.equalsIgnoreCase("sh")) {
\r
69 options |= ArabicShaping.LETTERS_SHAPE;
\r
70 } else if (val.equalsIgnoreCase("un")) {
\r
71 options |= ArabicShaping.LETTERS_UNSHAPE;
\r
72 } else if (val.equalsIgnoreCase("ta")) {
\r
73 options |= ArabicShaping.LETTERS_SHAPE_TASHKEEL_ISOLATED;
\r
75 throwValError(opt, val);
\r
77 } else if (opt.equalsIgnoreCase("dig")) {
\r
78 options &= ~ArabicShaping.DIGITS_MASK;
\r
79 if (val.equalsIgnoreCase("no")) {
\r
80 options |= ArabicShaping.DIGITS_NOOP;
\r
81 } else if (val.equalsIgnoreCase("ea")) {
\r
82 options |= ArabicShaping.DIGITS_EN2AN;
\r
83 } else if (val.equalsIgnoreCase("ae")) {
\r
84 options |= ArabicShaping.DIGITS_AN2EN;
\r
85 } else if (val.equalsIgnoreCase("lr")) {
\r
86 options |= ArabicShaping.DIGITS_EN2AN_INIT_LR;
\r
87 } else if (val.equalsIgnoreCase("al")) {
\r
88 options |= ArabicShaping.DIGITS_EN2AN_INIT_AL;
\r
90 throwValError(opt, val);
\r
92 } else if (opt.equalsIgnoreCase("typ")) {
\r
93 options &= ~ArabicShaping.DIGIT_TYPE_MASK;
\r
94 if (val.equalsIgnoreCase("an")) {
\r
95 options |= ArabicShaping.DIGIT_TYPE_AN;
\r
96 } else if (val.equalsIgnoreCase("ex")) {
\r
97 options |= ArabicShaping.DIGIT_TYPE_AN_EXTENDED;
\r
99 throwValError(opt, val);
\r
101 } else if (opt.equalsIgnoreCase("dst")) {
\r
103 ds = Integer.parseInt(val);
\r
105 catch (Exception e) {
\r
106 throwValError(opt, val);
\r
108 } else if (opt.equalsIgnoreCase("dln")) {
\r
110 dl = Integer.parseInt(val);
\r
112 catch (Exception e) {
\r
113 throwValError(opt, val);
\r
115 } else if (opt.equalsIgnoreCase("sst")) {
\r
117 ss = Integer.parseInt(val);
\r
119 catch (Exception e) {
\r
120 throwValError(opt, val);
\r
122 } else if (opt.equalsIgnoreCase("sln")) {
\r
124 sl = Integer.parseInt(val);
\r
126 catch (Exception e) {
\r
127 throwValError(opt, val);
\r
129 } else if (opt.equalsIgnoreCase("tes")) {
\r
130 if (val.equalsIgnoreCase("cp")) {
\r
132 } else if (val.equalsIgnoreCase("ip")) {
\r
133 testtype = INPLACE;
\r
134 } else if (val.equalsIgnoreCase("st")) {
\r
137 throwValError(opt, val);
\r
139 } else if (opt.equalsIgnoreCase("help")) {
\r
140 System.out.println(usage);
\r
142 throwOptError(opt);
\r
146 text = parseText(arg);
\r
151 sl = text.length() - ss;
\r
152 System.out.println("sl defaulting to " + sl);
\r
156 System.out.println("dl defaulting to " + dl);
\r
159 ArabicShaping shaper = new ArabicShaping(options);
\r
160 System.out.println("shaper: " + shaper);
\r
162 char[] src = text.toCharArray();
\r
163 System.out.println(" input: '" + escapedText(src, ss, sl) + "'");
\r
164 if (testtype != STRING) {
\r
165 System.out.println("start: " + ss + " length: " + sl + " total length: " + src.length);
\r
169 char[] dest = null;
\r
172 switch (testtype) {
\r
174 dest = new char[ds + dl];
\r
175 result = shaper.shape(src, ss, sl, dest, ds, dl);
\r
179 shaper.shape(src, ss, sl);
\r
186 dest = shaper.shape(text).toCharArray();
\r
188 result = dest.length;
\r
192 System.out.println("output: '" + escapedText(dest, ds, result) + "'");
\r
193 System.out.println("length: " + result);
\r
194 if (ds != 0 || result != dest.length) {
\r
195 System.out.println("full output: '" + escapedText(dest, 0, dest.length) + "'");
\r
198 catch (ArabicShapingException e) {
\r
199 System.out.println("Caught ArabicShapingException");
\r
200 System.out.println(e);
\r
202 catch (Exception e) {
\r
203 System.out.println("Caught Exception");
\r
204 System.out.println(e);
\r
208 private static void throwOptError(String opt) {
\r
209 throwUsageError("unknown option: " + opt);
\r
212 private static void throwValError(String opt, String val) {
\r
213 throwUsageError("unknown value: " + val + " for option: " + opt);
\r
216 private static void throwUsageError(String message) {
\r
217 StringBuffer buf = new StringBuffer("*** usage error ***\n");
\r
218 buf.append(message);
\r
221 throw new Error(buf.toString());
\r
224 private static final String usage =
\r
225 "Usage: [option]* [text]\n" +
\r
226 " where option is in the format '-opt[:val]'\n" +
\r
227 " options are:\n" +
\r
228 " -len:[gs|sn|se|sb] (length: grow/shrink, spaces near, spaces end, spaces beginning)\n" +
\r
229 " -dir:[log|vis] (direction: logical, visual)\n" +
\r
230 " -let:[no|sh|un|ta] (letters: noop, shape, unshape, tashkeel)\n" +
\r
231 // " -let:[no|sh|un] (letters: noop, shape, unshape)\n" +
\r
232 " -dig:[no|ea|ae|lr|al] (digits: noop, en2an, an2en, en2an_lr, en2an_al)\n" +
\r
233 " -typ:[an|ex] (digit type: arabic, arabic extended)\n" +
\r
234 " -dst:# (dest start: [integer])\n" +
\r
235 " -dln:# (dest length (max size): [integer])\n" +
\r
236 " -sst:# (source start: [integer])\n" +
\r
237 " -sln:# (source length: [integer])\n" +
\r
238 " -tes:[cp|ip|st] (test type: copy, in place, string)\n" +
\r
239 " -help (print this help message)\n" +
\r
240 " text can contain unicode escape values in the format '\\uXXXX' only\n";
\r
242 private static String escapedText(char[] text, int start, int length) {
\r
243 StringBuffer buf = new StringBuffer();
\r
244 for (int i = start, e = start + length; i < e; ++i) {
\r
246 if (ch < 0x20 || ch > 0x7e) {
\r
257 buf.append(Integer.toHexString(ch));
\r
262 return buf.toString();
\r
265 private static String parseText(String text) {
\r
266 // process unicode escapes (only)
\r
267 StringBuffer buf = new StringBuffer();
\r
268 char[] chars = text.toCharArray();
\r
269 for (int i = 0; i < chars.length; ++i) {
\r
270 char ch = chars[i];
\r
272 if ((i < chars.length - 1) &&
\r
273 (chars[i+1] == 'u')) {
\r
274 int val = Integer.parseInt(text.substring(i+2, i+6), 16);
\r
275 buf.append((char)val);
\r
284 return buf.toString();
\r