1.1 --- a/make/java/text/FILES_java.gmk Sun Jun 21 23:52:58 2009 -0700
1.2 +++ b/make/java/text/FILES_java.gmk Tue Jun 23 23:09:49 2009 -0700
1.3 @@ -76,6 +76,10 @@
1.4 sun/text/Normalizer.java \
1.5 sun/text/SupplementaryCharacterData.java \
1.6 sun/text/UCompactIntArray.java \
1.7 + sun/text/bidi/BidiBase.java \
1.8 + sun/text/bidi/BidiLine.java \
1.9 + sun/text/bidi/BidiRun.java \
1.10 + \
1.11 sun/text/normalizer/CharTrie.java \
1.12 sun/text/normalizer/CharacterIteratorWrapper.java \
1.13 sun/text/normalizer/ICUBinary.java \
2.1 --- a/make/sun/font/FILES_c.gmk Sun Jun 21 23:52:58 2009 -0700
2.2 +++ b/make/sun/font/FILES_c.gmk Tue Jun 23 23:09:49 2009 -0700
2.3 @@ -24,10 +24,6 @@
2.4 #
2.5
2.6 FILES_c_shared = \
2.7 - jbidi.c \
2.8 - ubidi.c \
2.9 - ubidiln.c \
2.10 - uchardir.c \
2.11 DrawGlyphList.c \
2.12 sunFont.c
2.13
3.1 --- a/make/sun/font/Makefile Sun Jun 21 23:52:58 2009 -0700
3.2 +++ b/make/sun/font/Makefile Tue Jun 23 23:09:49 2009 -0700
3.3 @@ -145,7 +145,6 @@
3.4 # Add to the ambient vpath to pick up files in subdirectories
3.5 #
3.6 vpath %.c $(PLATFORM_SRC)/native/$(PKGDIR)
3.7 -vpath %.c $(SHARE_SRC)/native/$(PKGDIR)/bidi
3.8 vpath %.cpp $(SHARE_SRC)/native/$(PKGDIR)/layout
3.9 vpath %.cpp $(SHARE_SRC)/native/$(PKGDIR)
3.10
3.11 @@ -187,7 +186,6 @@
3.12
3.13 CPPFLAGS += -I$(SHARE_SRC)/native/$(PKGDIR) \
3.14 -I$(SHARE_SRC)/native/$(PKGDIR)/layout \
3.15 - -I$(SHARE_SRC)/native/$(PKGDIR)/bidi \
3.16 -I$(SHARE_SRC)/native/sun/awt/image/cvutils \
3.17 -I$(PLATFORM_SRC)/native/sun/awt \
3.18 -I$(SHARE_SRC)/native/sun/awt/debug \
4.1 --- a/make/sun/font/mapfile-vers Sun Jun 21 23:52:58 2009 -0700
4.2 +++ b/make/sun/font/mapfile-vers Tue Jun 23 23:09:49 2009 -0700
4.3 @@ -31,8 +31,6 @@
4.4 newLayoutTableCache;
4.5 freeLayoutTableCache;
4.6 isNullScalerContext;
4.7 - Java_java_text_Bidi_nativeBidiChars;
4.8 - Java_java_text_Bidi_nativeGetDirectionCode;
4.9 Java_sun_font_NullFontScaler_getNullScalerContext;
4.10 Java_sun_font_NullFontScaler_getGlyphImage;
4.11 Java_sun_font_FontManager_getPlatformFontVar;
5.1 --- a/make/sun/font/mapfile-vers.openjdk Sun Jun 21 23:52:58 2009 -0700
5.2 +++ b/make/sun/font/mapfile-vers.openjdk Tue Jun 23 23:09:49 2009 -0700
5.3 @@ -33,8 +33,6 @@
5.4 newLayoutTableCache;
5.5 freeLayoutTableCache;
5.6 isNullScalerContext;
5.7 - Java_java_text_Bidi_nativeBidiChars;
5.8 - Java_java_text_Bidi_nativeGetDirectionCode;
5.9 Java_sun_font_NullFontScaler_getNullScalerContext;
5.10 Java_sun_font_NullFontScaler_getGlyphImage;
5.11 Java_sun_font_FontManager_getPlatformFontVar;
6.1 --- a/src/share/classes/java/text/Bidi.java Sun Jun 21 23:52:58 2009 -0700
6.2 +++ b/src/share/classes/java/text/Bidi.java Tue Jun 23 23:09:49 2009 -0700
6.3 @@ -1,5 +1,5 @@
6.4 /*
6.5 - * Copyright 2000-2003 Sun Microsystems, Inc. All Rights Reserved.
6.6 + * Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved.
6.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6.8 *
6.9 * This code is free software; you can redistribute it and/or modify it
6.10 @@ -35,10 +35,7 @@
6.11
6.12 package java.text;
6.13
6.14 -import java.awt.Toolkit;
6.15 -import java.awt.font.TextAttribute;
6.16 -import java.awt.font.NumericShaper;
6.17 -import sun.text.CodePointIterator;
6.18 +import sun.text.bidi.BidiBase;
6.19
6.20 /**
6.21 * This class implements the Unicode Bidirectional Algorithm.
6.22 @@ -62,15 +59,6 @@
6.23 * @since 1.4
6.24 */
6.25 public final class Bidi {
6.26 - byte dir;
6.27 - byte baselevel;
6.28 - int length;
6.29 - int[] runs;
6.30 - int[] cws;
6.31 -
6.32 - static {
6.33 - sun.font.FontManagerNativeLibrary.load();
6.34 - }
6.35
6.36 /** Constant indicating base direction is left-to-right. */
6.37 public static final int DIRECTION_LEFT_TO_RIGHT = 0;
6.38 @@ -94,7 +82,7 @@
6.39 */
6.40 public static final int DIRECTION_DEFAULT_RIGHT_TO_LEFT = -1;
6.41
6.42 - private static final int DIR_MIXED = 2;
6.43 + private BidiBase bidiBase;
6.44
6.45 /**
6.46 * Create Bidi from the given paragraph of text and base direction.
6.47 @@ -109,7 +97,7 @@
6.48 throw new IllegalArgumentException("paragraph is null");
6.49 }
6.50
6.51 - nativeBidiChars(this, paragraph.toCharArray(), 0, null, 0, paragraph.length(), flags);
6.52 + bidiBase = new BidiBase(paragraph.toCharArray(), 0, null, 0, paragraph.length(), flags);
6.53 }
6.54
6.55 /**
6.56 @@ -142,67 +130,8 @@
6.57 throw new IllegalArgumentException("paragraph is null");
6.58 }
6.59
6.60 - int flags = DIRECTION_DEFAULT_LEFT_TO_RIGHT;
6.61 - byte[] embeddings = null;
6.62 -
6.63 - int start = paragraph.getBeginIndex();
6.64 - int limit = paragraph.getEndIndex();
6.65 - int length = limit - start;
6.66 - int n = 0;
6.67 - char[] text = new char[length];
6.68 - for (char c = paragraph.first(); c != paragraph.DONE; c = paragraph.next()) {
6.69 - text[n++] = c;
6.70 - }
6.71 -
6.72 - paragraph.first();
6.73 - try {
6.74 - Boolean runDirection = (Boolean)paragraph.getAttribute(TextAttribute.RUN_DIRECTION);
6.75 - if (runDirection != null) {
6.76 - if (TextAttribute.RUN_DIRECTION_LTR.equals(runDirection)) {
6.77 - flags = DIRECTION_LEFT_TO_RIGHT; // clears default setting
6.78 - } else {
6.79 - flags = DIRECTION_RIGHT_TO_LEFT;
6.80 - }
6.81 - }
6.82 - }
6.83 - catch (ClassCastException e) {
6.84 - }
6.85 -
6.86 - try {
6.87 - NumericShaper shaper = (NumericShaper)paragraph.getAttribute(TextAttribute.NUMERIC_SHAPING);
6.88 - if (shaper != null) {
6.89 - shaper.shape(text, 0, text.length);
6.90 - }
6.91 - }
6.92 - catch (ClassCastException e) {
6.93 - }
6.94 -
6.95 - int pos = start;
6.96 - do {
6.97 - paragraph.setIndex(pos);
6.98 - Object embeddingLevel = paragraph.getAttribute(TextAttribute.BIDI_EMBEDDING);
6.99 - int newpos = paragraph.getRunLimit(TextAttribute.BIDI_EMBEDDING);
6.100 -
6.101 - if (embeddingLevel != null) {
6.102 - try {
6.103 - int intLevel = ((Integer)embeddingLevel).intValue();
6.104 - if (intLevel >= -61 && intLevel < 61) {
6.105 - byte level = (byte)(intLevel < 0 ? (-intLevel | 0x80) : intLevel);
6.106 - if (embeddings == null) {
6.107 - embeddings = new byte[length];
6.108 - }
6.109 - for (int i = pos - start; i < newpos - start; ++i) {
6.110 - embeddings[i] = level;
6.111 - }
6.112 - }
6.113 - }
6.114 - catch (ClassCastException e) {
6.115 - }
6.116 - }
6.117 - pos = newpos;
6.118 - } while (pos < limit);
6.119 -
6.120 - nativeBidiChars(this, text, 0, embeddings, 0, text.length, flags);
6.121 + bidiBase = new BidiBase(0, 0);
6.122 + bidiBase.setPara(paragraph);
6.123 }
6.124
6.125 /**
6.126 @@ -240,46 +169,7 @@
6.127 " for embeddings of length: " + text.length);
6.128 }
6.129
6.130 - if (embeddings != null) {
6.131 - // native uses high bit to indicate override, not negative value, sigh
6.132 -
6.133 - for (int i = embStart, embLimit = embStart + paragraphLength; i < embLimit; ++i) {
6.134 - if (embeddings[i] < 0) {
6.135 - byte[] temp = new byte[paragraphLength];
6.136 - System.arraycopy(embeddings, embStart, temp, 0, paragraphLength);
6.137 -
6.138 - for (i -= embStart; i < paragraphLength; ++i) {
6.139 - if (temp[i] < 0) {
6.140 - temp[i] = (byte)(-temp[i] | 0x80);
6.141 - }
6.142 - }
6.143 -
6.144 - embeddings = temp;
6.145 - embStart = 0;
6.146 - break;
6.147 - }
6.148 - }
6.149 - }
6.150 -
6.151 - nativeBidiChars(this, text, textStart, embeddings, embStart, paragraphLength, flags);
6.152 - }
6.153 -
6.154 - /**
6.155 - * Private constructor used by line bidi.
6.156 - */
6.157 - private Bidi(int dir, int baseLevel, int length, int[] data, int[] cws) {
6.158 - reset(dir, baseLevel, length, data, cws);
6.159 - }
6.160 -
6.161 - /**
6.162 - * Private mutator used by native code.
6.163 - */
6.164 - private void reset(int dir, int baselevel, int length, int[] data, int[] cws) {
6.165 - this.dir = (byte)dir;
6.166 - this.baselevel = (byte)baselevel;
6.167 - this.length = length;
6.168 - this.runs = data;
6.169 - this.cws = cws;
6.170 + bidiBase = new BidiBase(text, textStart, embeddings, embStart, paragraphLength, flags);
6.171 }
6.172
6.173 /**
6.174 @@ -290,96 +180,10 @@
6.175 * @param lineLimit the offset from the start of the paragraph to the limit of the line.
6.176 */
6.177 public Bidi createLineBidi(int lineStart, int lineLimit) {
6.178 - if (lineStart == 0 && lineLimit == length) {
6.179 - return this;
6.180 - }
6.181 + AttributedString astr = new AttributedString("");
6.182 + Bidi newBidi = new Bidi(astr.getIterator());
6.183
6.184 - int lineLength = lineLimit - lineStart;
6.185 - if (lineStart < 0 ||
6.186 - lineLimit < lineStart ||
6.187 - lineLimit > length) {
6.188 - throw new IllegalArgumentException("range " + lineStart +
6.189 - " to " + lineLimit +
6.190 - " is invalid for paragraph of length " + length);
6.191 - }
6.192 -
6.193 - if (runs == null) {
6.194 - return new Bidi(dir, baselevel, lineLength, null, null);
6.195 - } else {
6.196 - int cwspos = -1;
6.197 - int[] ncws = null;
6.198 - if (cws != null) {
6.199 - int cwss = 0;
6.200 - int cwsl = cws.length;
6.201 - while (cwss < cwsl) {
6.202 - if (cws[cwss] >= lineStart) {
6.203 - cwsl = cwss;
6.204 - while (cwsl < cws.length && cws[cwsl] < lineLimit) {
6.205 - cwsl++;
6.206 - }
6.207 - int ll = lineLimit-1;
6.208 - while (cwsl > cwss && cws[cwsl-1] == ll) {
6.209 - cwspos = ll; // record start of counter-directional whitespace
6.210 - --cwsl;
6.211 - --ll;
6.212 - }
6.213 -
6.214 - if (cwspos == lineStart) { // entire line is cws, so ignore
6.215 - return new Bidi(dir, baselevel, lineLength, null, null);
6.216 - }
6.217 -
6.218 - int ncwslen = cwsl - cwss;
6.219 - if (ncwslen > 0) {
6.220 - ncws = new int[ncwslen];
6.221 - for (int i = 0; i < ncwslen; ++i) {
6.222 - ncws[i] = cws[cwss+i] - lineStart;
6.223 - }
6.224 - }
6.225 - break;
6.226 - }
6.227 - ++cwss;
6.228 - }
6.229 - }
6.230 -
6.231 - int[] nruns = null;
6.232 - int nlevel = baselevel;
6.233 - int limit = cwspos == -1 ? lineLimit : cwspos;
6.234 - int rs = 0;
6.235 - int rl = runs.length;
6.236 - int ndir = dir;
6.237 - for (; rs < runs.length; rs += 2) {
6.238 - if (runs[rs] > lineStart) {
6.239 - rl = rs;
6.240 - while (rl < runs.length && runs[rl] < limit) {
6.241 - rl += 2;
6.242 - }
6.243 - if ((rl > rs) || (runs[rs+1] != baselevel)) {
6.244 - rl += 2;
6.245 -
6.246 - if (cwspos != -1 && rl > rs && runs[rl-1] != baselevel) { // add level for cws
6.247 - nruns = new int[rl - rs + 2];
6.248 - nruns[rl - rs] = lineLength;
6.249 - nruns[rl - rs + 1] = baselevel;
6.250 - } else {
6.251 - limit = lineLimit;
6.252 - nruns = new int[rl - rs];
6.253 - }
6.254 -
6.255 - int n = 0;
6.256 - for (int i = rs; i < rl; i += 2) {
6.257 - nruns[n++] = runs[i] - lineStart;
6.258 - nruns[n++] = runs[i+1];
6.259 - }
6.260 - nruns[n-2] = limit - lineStart;
6.261 - } else {
6.262 - ndir = (runs[rs+1] & 0x1) == 0 ? DIRECTION_LEFT_TO_RIGHT : DIRECTION_RIGHT_TO_LEFT;
6.263 - }
6.264 - break;
6.265 - }
6.266 - }
6.267 -
6.268 - return new Bidi(ndir, baselevel, lineLength, nruns, ncws);
6.269 - }
6.270 + return bidiBase.setLine(this, bidiBase, newBidi, newBidi.bidiBase,lineStart, lineLimit);
6.271 }
6.272
6.273 /**
6.274 @@ -388,7 +192,7 @@
6.275 * @return true if the line is not left-to-right or right-to-left.
6.276 */
6.277 public boolean isMixed() {
6.278 - return dir == DIR_MIXED;
6.279 + return bidiBase.isMixed();
6.280 }
6.281
6.282 /**
6.283 @@ -396,7 +200,7 @@
6.284 * @return true if the line is all left-to-right text and the base direction is left-to-right
6.285 */
6.286 public boolean isLeftToRight() {
6.287 - return dir == DIRECTION_LEFT_TO_RIGHT;
6.288 + return bidiBase.isLeftToRight();
6.289 }
6.290
6.291 /**
6.292 @@ -404,7 +208,7 @@
6.293 * @return true if the line is all right-to-left text, and the base direction is right-to-left
6.294 */
6.295 public boolean isRightToLeft() {
6.296 - return dir == DIRECTION_RIGHT_TO_LEFT;
6.297 + return bidiBase.isRightToLeft();
6.298 }
6.299
6.300 /**
6.301 @@ -412,7 +216,7 @@
6.302 * @return the length of text in the line
6.303 */
6.304 public int getLength() {
6.305 - return length;
6.306 + return bidiBase.getLength();
6.307 }
6.308
6.309 /**
6.310 @@ -420,7 +224,7 @@
6.311 * @return true if the base direction is left-to-right
6.312 */
6.313 public boolean baseIsLeftToRight() {
6.314 - return (baselevel & 0x1) == 0;
6.315 + return bidiBase.baseIsLeftToRight();
6.316 }
6.317
6.318 /**
6.319 @@ -428,7 +232,7 @@
6.320 * @return the base level
6.321 */
6.322 public int getBaseLevel() {
6.323 - return baselevel;
6.324 + return bidiBase.getParaLevel();
6.325 }
6.326
6.327 /**
6.328 @@ -438,17 +242,7 @@
6.329 * @return the resolved level of the character at offset
6.330 */
6.331 public int getLevelAt(int offset) {
6.332 - if (runs == null || offset < 0 || offset >= length) {
6.333 - return baselevel;
6.334 - } else {
6.335 - int i = 0;
6.336 - do {
6.337 - if (offset < runs[i]) {
6.338 - return runs[i+1];
6.339 - }
6.340 - i += 2;
6.341 - } while (true);
6.342 - }
6.343 + return bidiBase.getLevelAt(offset);
6.344 }
6.345
6.346 /**
6.347 @@ -456,7 +250,7 @@
6.348 * @return the number of level runs
6.349 */
6.350 public int getRunCount() {
6.351 - return runs == null ? 1 : runs.length / 2;
6.352 + return bidiBase.countRuns();
6.353 }
6.354
6.355 /**
6.356 @@ -465,7 +259,7 @@
6.357 * @return the level of the run
6.358 */
6.359 public int getRunLevel(int run) {
6.360 - return runs == null ? baselevel : runs[run * 2 + 1];
6.361 + return bidiBase.getRunLevel(run);
6.362 }
6.363
6.364 /**
6.365 @@ -475,7 +269,7 @@
6.366 * @return the start of the run
6.367 */
6.368 public int getRunStart(int run) {
6.369 - return (runs == null || run == 0) ? 0 : runs[run * 2 - 2];
6.370 + return bidiBase.getRunStart(run);
6.371 }
6.372
6.373 /**
6.374 @@ -486,7 +280,7 @@
6.375 * @return limit the limit of the run
6.376 */
6.377 public int getRunLimit(int run) {
6.378 - return runs == null ? length : runs[run * 2];
6.379 + return bidiBase.getRunLimit(run);
6.380 }
6.381
6.382 /**
6.383 @@ -501,16 +295,7 @@
6.384 * @return true if the range of characters requires bidi analysis
6.385 */
6.386 public static boolean requiresBidi(char[] text, int start, int limit) {
6.387 - CodePointIterator cpi = CodePointIterator.create(text, start, limit);
6.388 - for (int cp = cpi.next(); cp != CodePointIterator.DONE; cp = cpi.next()) {
6.389 - if (cp > 0x0590) {
6.390 - int dc = nativeGetDirectionCode(cp);
6.391 - if ((RMASK & (1 << dc)) != 0) {
6.392 - return true;
6.393 - }
6.394 - }
6.395 - }
6.396 - return false;
6.397 + return BidiBase.requiresBidi(text, start, limit);
6.398 }
6.399
6.400 /**
6.401 @@ -530,124 +315,14 @@
6.402 * @param count the number of objects to reorder
6.403 */
6.404 public static void reorderVisually(byte[] levels, int levelStart, Object[] objects, int objectStart, int count) {
6.405 -
6.406 - if (count < 0) {
6.407 - throw new IllegalArgumentException("count " + count + " must be >= 0");
6.408 - }
6.409 - if (levelStart < 0 || levelStart + count > levels.length) {
6.410 - throw new IllegalArgumentException("levelStart " + levelStart + " and count " + count +
6.411 - " out of range [0, " + levels.length + "]");
6.412 - }
6.413 - if (objectStart < 0 || objectStart + count > objects.length) {
6.414 - throw new IllegalArgumentException("objectStart " + objectStart + " and count " + count +
6.415 - " out of range [0, " + objects.length + "]");
6.416 - }
6.417 -
6.418 - byte lowestOddLevel = (byte)(NUMLEVELS + 1);
6.419 - byte highestLevel = 0;
6.420 -
6.421 - // initialize mapping and levels
6.422 -
6.423 - int levelLimit = levelStart + count;
6.424 - for (int i = levelStart; i < levelLimit; i++) {
6.425 - byte level = levels[i];
6.426 - if (level > highestLevel) {
6.427 - highestLevel = level;
6.428 - }
6.429 -
6.430 - if ((level & 0x01) != 0 && level < lowestOddLevel) {
6.431 - lowestOddLevel = level;
6.432 - }
6.433 - }
6.434 -
6.435 - int delta = objectStart - levelStart;
6.436 -
6.437 - while (highestLevel >= lowestOddLevel) {
6.438 - int i = levelStart;
6.439 -
6.440 - for (;;) {
6.441 - while (i < levelLimit && levels[i] < highestLevel) {
6.442 - i++;
6.443 - }
6.444 - int begin = i++;
6.445 -
6.446 - if (begin == levelLimit) {
6.447 - break; // no more runs at this level
6.448 - }
6.449 -
6.450 - while (i < levelLimit && levels[i] >= highestLevel) {
6.451 - i++;
6.452 - }
6.453 - int end = i - 1;
6.454 -
6.455 - begin += delta;
6.456 - end += delta;
6.457 - while (begin < end) {
6.458 - Object temp = objects[begin];
6.459 - objects[begin] = objects[end];
6.460 - objects[end] = temp;
6.461 - ++begin;
6.462 - --end;
6.463 - }
6.464 - }
6.465 -
6.466 - --highestLevel;
6.467 - }
6.468 + BidiBase.reorderVisually(levels, levelStart, objects, objectStart, count);
6.469 }
6.470
6.471 - private static final char NUMLEVELS = 62;
6.472 -
6.473 - private static final int RMASK =
6.474 - (1 << 1 /* U_RIGHT_TO_LEFT */) |
6.475 - (1 << 5 /* U_ARABIC_NUMBER */) |
6.476 - (1 << 13 /* U_RIGHT_TO_LEFT_ARABIC */) |
6.477 - (1 << 14 /* U_RIGHT_TO_LEFT_EMBEDDING */) |
6.478 - (1 << 15 /* U_RIGHT_TO_LEFT_OVERRIDE */);
6.479 -
6.480 - /** Access native bidi implementation. */
6.481 - private static native int nativeGetDirectionCode(int cp);
6.482 -
6.483 - /** Access native bidi implementation. */
6.484 - private static synchronized native void nativeBidiChars(Bidi bidi, char[] text, int textStart,
6.485 - byte[] embeddings, int embeddingStart,
6.486 - int length, int flags);
6.487 -
6.488 /**
6.489 * Display the bidi internal state, used in debugging.
6.490 */
6.491 public String toString() {
6.492 - StringBuffer buf = new StringBuffer(super.toString());
6.493 - buf.append("[dir: " + dir);
6.494 - buf.append(" baselevel: " + baselevel);
6.495 - buf.append(" length: " + length);
6.496 - if (runs == null) {
6.497 - buf.append(" runs: null");
6.498 - } else {
6.499 - buf.append(" runs: [");
6.500 - for (int i = 0; i < runs.length; i += 2) {
6.501 - if (i != 0) {
6.502 - buf.append(' ');
6.503 - }
6.504 - buf.append(runs[i]); // limit
6.505 - buf.append('/');
6.506 - buf.append(runs[i+1]); // level
6.507 - }
6.508 - buf.append(']');
6.509 - }
6.510 - if (cws == null) {
6.511 - buf.append(" cws: null");
6.512 - } else {
6.513 - buf.append(" cws: [");
6.514 - for (int i = 0; i < cws.length; ++i) {
6.515 - if (i != 0) {
6.516 - buf.append(' ');
6.517 - }
6.518 - buf.append(Integer.toHexString(cws[i]));
6.519 - }
6.520 - buf.append(']');
6.521 - }
6.522 - buf.append(']');
6.523 + return bidiBase.toString();
6.524 + }
6.525
6.526 - return buf.toString();
6.527 - }
6.528 }
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/src/share/classes/sun/text/bidi/BidiBase.java Tue Jun 23 23:09:49 2009 -0700
7.3 @@ -0,0 +1,3444 @@
7.4 +/*
7.5 + * Portions Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
7.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7.7 + *
7.8 + * This code is free software; you can redistribute it and/or modify it
7.9 + * under the terms of the GNU General Public License version 2 only, as
7.10 + * published by the Free Software Foundation. Sun designates this
7.11 + * particular file as subject to the "Classpath" exception as provided
7.12 + * by Sun in the LICENSE file that accompanied this code.
7.13 + *
7.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
7.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
7.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
7.17 + * version 2 for more details (a copy is included in the LICENSE file that
7.18 + * accompanied this code).
7.19 + *
7.20 + * You should have received a copy of the GNU General Public License version
7.21 + * 2 along with this work; if not, write to the Free Software Foundation,
7.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
7.23 + *
7.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
7.25 + * CA 95054 USA or visit www.sun.com if you need additional information or
7.26 + * have any questions.
7.27 + */
7.28 +/*
7.29 + *******************************************************************************
7.30 + * (C) Copyright IBM Corp. and others, 1996-2009 - All Rights Reserved *
7.31 + * *
7.32 + * The original version of this source code and documentation is copyrighted *
7.33 + * and owned by IBM, These materials are provided under terms of a License *
7.34 + * Agreement between IBM and Sun. This technology is protected by multiple *
7.35 + * US and International patents. This notice and attribution to IBM may not *
7.36 + * to removed. *
7.37 + *******************************************************************************
7.38 + */
7.39 +
7.40 +/* FOOD FOR THOUGHT: currently the reordering modes are a mixture of
7.41 + * algorithm for direct BiDi, algorithm for inverse Bidi and the bizarre
7.42 + * concept of RUNS_ONLY which is a double operation.
7.43 + * It could be advantageous to divide this into 3 concepts:
7.44 + * a) Operation: direct / inverse / RUNS_ONLY
7.45 + * b) Direct algorithm: default / NUMBERS_SPECIAL / GROUP_NUMBERS_WITH_L
7.46 + * c) Inverse algorithm: default / INVERSE_LIKE_DIRECT / NUMBERS_SPECIAL
7.47 + * This would allow combinations not possible today like RUNS_ONLY with
7.48 + * NUMBERS_SPECIAL.
7.49 + * Also allow to set INSERT_MARKS for the direct step of RUNS_ONLY and
7.50 + * REMOVE_CONTROLS for the inverse step.
7.51 + * Not all combinations would be supported, and probably not all do make sense.
7.52 + * This would need to document which ones are supported and what are the
7.53 + * fallbacks for unsupported combinations.
7.54 + */
7.55 +
7.56 +package sun.text.bidi;
7.57 +
7.58 +import java.awt.font.TextAttribute;
7.59 +import java.awt.font.NumericShaper;
7.60 +import java.io.IOException;
7.61 +import java.lang.reflect.Array;
7.62 +import java.text.AttributedCharacterIterator;
7.63 +import java.text.Bidi;
7.64 +import java.util.Arrays;
7.65 +import java.util.MissingResourceException;
7.66 +import sun.text.normalizer.UBiDiProps;
7.67 +import sun.text.normalizer.UCharacter;
7.68 +import sun.text.normalizer.UTF16;
7.69 +
7.70 +/**
7.71 + *
7.72 + * <h2>Bidi algorithm for ICU</h2>
7.73 + *
7.74 + * This is an implementation of the Unicode Bidirectional algorithm. The
7.75 + * algorithm is defined in the <a
7.76 + * href="http://www.unicode.org/unicode/reports/tr9/">Unicode Standard Annex #9</a>,
7.77 + * version 13, also described in The Unicode Standard, Version 4.0 .
7.78 + * <p>
7.79 + *
7.80 + * Note: Libraries that perform a bidirectional algorithm and reorder strings
7.81 + * accordingly are sometimes called "Storage Layout Engines". ICU's Bidi and
7.82 + * shaping (ArabicShaping) classes can be used at the core of such "Storage
7.83 + * Layout Engines".
7.84 + *
7.85 + * <h3>General remarks about the API:</h3>
7.86 + *
7.87 + * The "limit" of a sequence of characters is the position just after
7.88 + * their last character, i.e., one more than that position.
7.89 + * <p>
7.90 + *
7.91 + * Some of the API methods provide access to "runs". Such a
7.92 + * "run" is defined as a sequence of characters that are at the same
7.93 + * embedding level after performing the Bidi algorithm.
7.94 + * <p>
7.95 + *
7.96 + * <h3>Basic concept: paragraph</h3>
7.97 + * A piece of text can be divided into several paragraphs by characters
7.98 + * with the Bidi class <code>Block Separator</code>. For handling of
7.99 + * paragraphs, see:
7.100 + * <ul>
7.101 + * <li>{@link #countParagraphs}
7.102 + * <li>{@link #getParaLevel}
7.103 + * <li>{@link #getParagraph}
7.104 + * <li>{@link #getParagraphByIndex}
7.105 + * </ul>
7.106 + *
7.107 + * <h3>Basic concept: text direction</h3>
7.108 + * The direction of a piece of text may be:
7.109 + * <ul>
7.110 + * <li>{@link #LTR}
7.111 + * <li>{@link #RTL}
7.112 + * <li>{@link #MIXED}
7.113 + * </ul>
7.114 + *
7.115 + * <h3>Basic concept: levels</h3>
7.116 + *
7.117 + * Levels in this API represent embedding levels according to the Unicode
7.118 + * Bidirectional Algorithm.
7.119 + * Their low-order bit (even/odd value) indicates the visual direction.<p>
7.120 + *
7.121 + * Levels can be abstract values when used for the
7.122 + * <code>paraLevel</code> and <code>embeddingLevels</code>
7.123 + * arguments of <code>setPara()</code>; there:
7.124 + * <ul>
7.125 + * <li>the high-order bit of an <code>embeddingLevels[]</code>
7.126 + * value indicates whether the using application is
7.127 + * specifying the level of a character to <i>override</i> whatever the
7.128 + * Bidi implementation would resolve it to.</li>
7.129 + * <li><code>paraLevel</code> can be set to the
7.130 + * pseudo-level values <code>LEVEL_DEFAULT_LTR</code>
7.131 + * and <code>LEVEL_DEFAULT_RTL</code>.</li>
7.132 + * </ul>
7.133 + *
7.134 + * <p>The related constants are not real, valid level values.
7.135 + * <code>DEFAULT_XXX</code> can be used to specify
7.136 + * a default for the paragraph level for
7.137 + * when the <code>setPara()</code> method
7.138 + * shall determine it but there is no
7.139 + * strongly typed character in the input.<p>
7.140 + *
7.141 + * Note that the value for <code>LEVEL_DEFAULT_LTR</code> is even
7.142 + * and the one for <code>LEVEL_DEFAULT_RTL</code> is odd,
7.143 + * just like with normal LTR and RTL level values -
7.144 + * these special values are designed that way. Also, the implementation
7.145 + * assumes that MAX_EXPLICIT_LEVEL is odd.
7.146 + *
7.147 + * <ul><b>See Also:</b>
7.148 + * <li>{@link #LEVEL_DEFAULT_LTR}
7.149 + * <li>{@link #LEVEL_DEFAULT_RTL}
7.150 + * <li>{@link #LEVEL_OVERRIDE}
7.151 + * <li>{@link #MAX_EXPLICIT_LEVEL}
7.152 + * <li>{@link #setPara}
7.153 + * </ul>
7.154 + *
7.155 + * <h3>Basic concept: Reordering Mode</h3>
7.156 + * Reordering mode values indicate which variant of the Bidi algorithm to
7.157 + * use.
7.158 + *
7.159 + * <ul><b>See Also:</b>
7.160 + * <li>{@link #setReorderingMode}
7.161 + * <li>{@link #REORDER_DEFAULT}
7.162 + * <li>{@link #REORDER_NUMBERS_SPECIAL}
7.163 + * <li>{@link #REORDER_GROUP_NUMBERS_WITH_R}
7.164 + * <li>{@link #REORDER_RUNS_ONLY}
7.165 + * <li>{@link #REORDER_INVERSE_NUMBERS_AS_L}
7.166 + * <li>{@link #REORDER_INVERSE_LIKE_DIRECT}
7.167 + * <li>{@link #REORDER_INVERSE_FOR_NUMBERS_SPECIAL}
7.168 + * </ul>
7.169 + *
7.170 + * <h3>Basic concept: Reordering Options</h3>
7.171 + * Reordering options can be applied during Bidi text transformations.
7.172 + * <ul><b>See Also:</b>
7.173 + * <li>{@link #setReorderingOptions}
7.174 + * <li>{@link #OPTION_DEFAULT}
7.175 + * <li>{@link #OPTION_INSERT_MARKS}
7.176 + * <li>{@link #OPTION_REMOVE_CONTROLS}
7.177 + * <li>{@link #OPTION_STREAMING}
7.178 + * </ul>
7.179 + *
7.180 + *
7.181 + * @author Simon Montagu, Matitiahu Allouche (ported from C code written by Markus W. Scherer)
7.182 + * @stable ICU 3.8
7.183 + *
7.184 + *
7.185 + * <h4> Sample code for the ICU Bidi API </h4>
7.186 + *
7.187 + * <h5>Rendering a paragraph with the ICU Bidi API</h5>
7.188 + *
7.189 + * This is (hypothetical) sample code that illustrates how the ICU Bidi API
7.190 + * could be used to render a paragraph of text. Rendering code depends highly on
7.191 + * the graphics system, therefore this sample code must make a lot of
7.192 + * assumptions, which may or may not match any existing graphics system's
7.193 + * properties.
7.194 + *
7.195 + * <p>
7.196 + * The basic assumptions are:
7.197 + * </p>
7.198 + * <ul>
7.199 + * <li>Rendering is done from left to right on a horizontal line.</li>
7.200 + * <li>A run of single-style, unidirectional text can be rendered at once.
7.201 + * </li>
7.202 + * <li>Such a run of text is passed to the graphics system with characters
7.203 + * (code units) in logical order.</li>
7.204 + * <li>The line-breaking algorithm is very complicated and Locale-dependent -
7.205 + * and therefore its implementation omitted from this sample code.</li>
7.206 + * </ul>
7.207 + *
7.208 + * <pre>
7.209 + *
7.210 + * package com.ibm.icu.dev.test.bidi;
7.211 + *
7.212 + * import com.ibm.icu.text.Bidi;
7.213 + * import com.ibm.icu.text.BidiRun;
7.214 + *
7.215 + * public class Sample {
7.216 + *
7.217 + * static final int styleNormal = 0;
7.218 + * static final int styleSelected = 1;
7.219 + * static final int styleBold = 2;
7.220 + * static final int styleItalics = 4;
7.221 + * static final int styleSuper=8;
7.222 + * static final int styleSub = 16;
7.223 + *
7.224 + * static class StyleRun {
7.225 + * int limit;
7.226 + * int style;
7.227 + *
7.228 + * public StyleRun(int limit, int style) {
7.229 + * this.limit = limit;
7.230 + * this.style = style;
7.231 + * }
7.232 + * }
7.233 + *
7.234 + * static class Bounds {
7.235 + * int start;
7.236 + * int limit;
7.237 + *
7.238 + * public Bounds(int start, int limit) {
7.239 + * this.start = start;
7.240 + * this.limit = limit;
7.241 + * }
7.242 + * }
7.243 + *
7.244 + * static int getTextWidth(String text, int start, int limit,
7.245 + * StyleRun[] styleRuns, int styleRunCount) {
7.246 + * // simplistic way to compute the width
7.247 + * return limit - start;
7.248 + * }
7.249 + *
7.250 + * // set limit and StyleRun limit for a line
7.251 + * // from text[start] and from styleRuns[styleRunStart]
7.252 + * // using Bidi.getLogicalRun(...)
7.253 + * // returns line width
7.254 + * static int getLineBreak(String text, Bounds line, Bidi para,
7.255 + * StyleRun styleRuns[], Bounds styleRun) {
7.256 + * // dummy return
7.257 + * return 0;
7.258 + * }
7.259 + *
7.260 + * // render runs on a line sequentially, always from left to right
7.261 + *
7.262 + * // prepare rendering a new line
7.263 + * static void startLine(byte textDirection, int lineWidth) {
7.264 + * System.out.println();
7.265 + * }
7.266 + *
7.267 + * // render a run of text and advance to the right by the run width
7.268 + * // the text[start..limit-1] is always in logical order
7.269 + * static void renderRun(String text, int start, int limit,
7.270 + * byte textDirection, int style) {
7.271 + * }
7.272 + *
7.273 + * // We could compute a cross-product
7.274 + * // from the style runs with the directional runs
7.275 + * // and then reorder it.
7.276 + * // Instead, here we iterate over each run type
7.277 + * // and render the intersections -
7.278 + * // with shortcuts in simple (and common) cases.
7.279 + * // renderParagraph() is the main function.
7.280 + *
7.281 + * // render a directional run with
7.282 + * // (possibly) multiple style runs intersecting with it
7.283 + * static void renderDirectionalRun(String text, int start, int limit,
7.284 + * byte direction, StyleRun styleRuns[],
7.285 + * int styleRunCount) {
7.286 + * int i;
7.287 + *
7.288 + * // iterate over style runs
7.289 + * if (direction == Bidi.LTR) {
7.290 + * int styleLimit;
7.291 + * for (i = 0; i < styleRunCount; ++i) {
7.292 + * styleLimit = styleRuns[i].limit;
7.293 + * if (start < styleLimit) {
7.294 + * if (styleLimit > limit) {
7.295 + * styleLimit = limit;
7.296 + * }
7.297 + * renderRun(text, start, styleLimit,
7.298 + * direction, styleRuns[i].style);
7.299 + * if (styleLimit == limit) {
7.300 + * break;
7.301 + * }
7.302 + * start = styleLimit;
7.303 + * }
7.304 + * }
7.305 + * } else {
7.306 + * int styleStart;
7.307 + *
7.308 + * for (i = styleRunCount-1; i >= 0; --i) {
7.309 + * if (i > 0) {
7.310 + * styleStart = styleRuns[i-1].limit;
7.311 + * } else {
7.312 + * styleStart = 0;
7.313 + * }
7.314 + * if (limit >= styleStart) {
7.315 + * if (styleStart < start) {
7.316 + * styleStart = start;
7.317 + * }
7.318 + * renderRun(text, styleStart, limit, direction,
7.319 + * styleRuns[i].style);
7.320 + * if (styleStart == start) {
7.321 + * break;
7.322 + * }
7.323 + * limit = styleStart;
7.324 + * }
7.325 + * }
7.326 + * }
7.327 + * }
7.328 + *
7.329 + * // the line object represents text[start..limit-1]
7.330 + * static void renderLine(Bidi line, String text, int start, int limit,
7.331 + * StyleRun styleRuns[], int styleRunCount) {
7.332 + * byte direction = line.getDirection();
7.333 + * if (direction != Bidi.MIXED) {
7.334 + * // unidirectional
7.335 + * if (styleRunCount <= 1) {
7.336 + * renderRun(text, start, limit, direction, styleRuns[0].style);
7.337 + * } else {
7.338 + * renderDirectionalRun(text, start, limit, direction,
7.339 + * styleRuns, styleRunCount);
7.340 + * }
7.341 + * } else {
7.342 + * // mixed-directional
7.343 + * int count, i;
7.344 + * BidiRun run;
7.345 + *
7.346 + * try {
7.347 + * count = line.countRuns();
7.348 + * } catch (IllegalStateException e) {
7.349 + * e.printStackTrace();
7.350 + * return;
7.351 + * }
7.352 + * if (styleRunCount <= 1) {
7.353 + * int style = styleRuns[0].style;
7.354 + *
7.355 + * // iterate over directional runs
7.356 + * for (i = 0; i < count; ++i) {
7.357 + * run = line.getVisualRun(i);
7.358 + * renderRun(text, run.getStart(), run.getLimit(),
7.359 + * run.getDirection(), style);
7.360 + * }
7.361 + * } else {
7.362 + * // iterate over both directional and style runs
7.363 + * for (i = 0; i < count; ++i) {
7.364 + * run = line.getVisualRun(i);
7.365 + * renderDirectionalRun(text, run.getStart(),
7.366 + * run.getLimit(), run.getDirection(),
7.367 + * styleRuns, styleRunCount);
7.368 + * }
7.369 + * }
7.370 + * }
7.371 + * }
7.372 + *
7.373 + * static void renderParagraph(String text, byte textDirection,
7.374 + * StyleRun styleRuns[], int styleRunCount,
7.375 + * int lineWidth) {
7.376 + * int length = text.length();
7.377 + * Bidi para = new Bidi();
7.378 + * try {
7.379 + * para.setPara(text,
7.380 + * textDirection != 0 ? Bidi.LEVEL_DEFAULT_RTL
7.381 + * : Bidi.LEVEL_DEFAULT_LTR,
7.382 + * null);
7.383 + * } catch (Exception e) {
7.384 + * e.printStackTrace();
7.385 + * return;
7.386 + * }
7.387 + * byte paraLevel = (byte)(1 & para.getParaLevel());
7.388 + * StyleRun styleRun = new StyleRun(length, styleNormal);
7.389 + *
7.390 + * if (styleRuns == null || styleRunCount <= 0) {
7.391 + * styleRuns = new StyleRun[1];
7.392 + * styleRunCount = 1;
7.393 + * styleRuns[0] = styleRun;
7.394 + * }
7.395 + * // assume styleRuns[styleRunCount-1].limit>=length
7.396 + *
7.397 + * int width = getTextWidth(text, 0, length, styleRuns, styleRunCount);
7.398 + * if (width <= lineWidth) {
7.399 + * // everything fits onto one line
7.400 + *
7.401 + * // prepare rendering a new line from either left or right
7.402 + * startLine(paraLevel, width);
7.403 + *
7.404 + * renderLine(para, text, 0, length, styleRuns, styleRunCount);
7.405 + * } else {
7.406 + * // we need to render several lines
7.407 + * Bidi line = new Bidi(length, 0);
7.408 + * int start = 0, limit;
7.409 + * int styleRunStart = 0, styleRunLimit;
7.410 + *
7.411 + * for (;;) {
7.412 + * limit = length;
7.413 + * styleRunLimit = styleRunCount;
7.414 + * width = getLineBreak(text, new Bounds(start, limit),
7.415 + * para, styleRuns,
7.416 + * new Bounds(styleRunStart, styleRunLimit));
7.417 + * try {
7.418 + * line = para.setLine(start, limit);
7.419 + * } catch (Exception e) {
7.420 + * e.printStackTrace();
7.421 + * return;
7.422 + * }
7.423 + * // prepare rendering a new line
7.424 + * // from either left or right
7.425 + * startLine(paraLevel, width);
7.426 + *
7.427 + * if (styleRunStart > 0) {
7.428 + * int newRunCount = styleRuns.length - styleRunStart;
7.429 + * StyleRun[] newRuns = new StyleRun[newRunCount];
7.430 + * System.arraycopy(styleRuns, styleRunStart, newRuns, 0,
7.431 + * newRunCount);
7.432 + * renderLine(line, text, start, limit, newRuns,
7.433 + * styleRunLimit - styleRunStart);
7.434 + * } else {
7.435 + * renderLine(line, text, start, limit, styleRuns,
7.436 + * styleRunLimit - styleRunStart);
7.437 + * }
7.438 + * if (limit == length) {
7.439 + * break;
7.440 + * }
7.441 + * start = limit;
7.442 + * styleRunStart = styleRunLimit - 1;
7.443 + * if (start >= styleRuns[styleRunStart].limit) {
7.444 + * ++styleRunStart;
7.445 + * }
7.446 + * }
7.447 + * }
7.448 + * }
7.449 + *
7.450 + * public static void main(String[] args)
7.451 + * {
7.452 + * renderParagraph("Some Latin text...", Bidi.LTR, null, 0, 80);
7.453 + * renderParagraph("Some Hebrew text...", Bidi.RTL, null, 0, 60);
7.454 + * }
7.455 + * }
7.456 + *
7.457 + * </pre>
7.458 + */
7.459 +
7.460 +public class BidiBase {
7.461 +
7.462 + class Point {
7.463 + int pos; /* position in text */
7.464 + int flag; /* flag for LRM/RLM, before/after */
7.465 + }
7.466 +
7.467 + class InsertPoints {
7.468 + int size;
7.469 + int confirmed;
7.470 + Point[] points = new Point[0];
7.471 + }
7.472 +
7.473 + /** Paragraph level setting<p>
7.474 + *
7.475 + * Constant indicating that the base direction depends on the first strong
7.476 + * directional character in the text according to the Unicode Bidirectional
7.477 + * Algorithm. If no strong directional character is present,
7.478 + * then set the paragraph level to 0 (left-to-right).<p>
7.479 + *
7.480 + * If this value is used in conjunction with reordering modes
7.481 + * <code>REORDER_INVERSE_LIKE_DIRECT</code> or
7.482 + * <code>REORDER_INVERSE_FOR_NUMBERS_SPECIAL</code>, the text to reorder
7.483 + * is assumed to be visual LTR, and the text after reordering is required
7.484 + * to be the corresponding logical string with appropriate contextual
7.485 + * direction. The direction of the result string will be RTL if either
7.486 + * the righmost or leftmost strong character of the source text is RTL
7.487 + * or Arabic Letter, the direction will be LTR otherwise.<p>
7.488 + *
7.489 + * If reordering option <code>OPTION_INSERT_MARKS</code> is set, an RLM may
7.490 + * be added at the beginning of the result string to ensure round trip
7.491 + * (that the result string, when reordered back to visual, will produce
7.492 + * the original source text).
7.493 + * @see #REORDER_INVERSE_LIKE_DIRECT
7.494 + * @see #REORDER_INVERSE_FOR_NUMBERS_SPECIAL
7.495 + * @stable ICU 3.8
7.496 + */
7.497 + public static final byte INTERNAL_LEVEL_DEFAULT_LTR = (byte)0x7e;
7.498 +
7.499 + /** Paragraph level setting<p>
7.500 + *
7.501 + * Constant indicating that the base direction depends on the first strong
7.502 + * directional character in the text according to the Unicode Bidirectional
7.503 + * Algorithm. If no strong directional character is present,
7.504 + * then set the paragraph level to 1 (right-to-left).<p>
7.505 + *
7.506 + * If this value is used in conjunction with reordering modes
7.507 + * <code>REORDER_INVERSE_LIKE_DIRECT</code> or
7.508 + * <code>REORDER_INVERSE_FOR_NUMBERS_SPECIAL</code>, the text to reorder
7.509 + * is assumed to be visual LTR, and the text after reordering is required
7.510 + * to be the corresponding logical string with appropriate contextual
7.511 + * direction. The direction of the result string will be RTL if either
7.512 + * the righmost or leftmost strong character of the source text is RTL
7.513 + * or Arabic Letter, or if the text contains no strong character;
7.514 + * the direction will be LTR otherwise.<p>
7.515 + *
7.516 + * If reordering option <code>OPTION_INSERT_MARKS</code> is set, an RLM may
7.517 + * be added at the beginning of the result string to ensure round trip
7.518 + * (that the result string, when reordered back to visual, will produce
7.519 + * the original source text).
7.520 + * @see #REORDER_INVERSE_LIKE_DIRECT
7.521 + * @see #REORDER_INVERSE_FOR_NUMBERS_SPECIAL
7.522 + * @stable ICU 3.8
7.523 + */
7.524 + public static final byte INTERNAL_LEVEL_DEFAULT_RTL = (byte)0x7f;
7.525 +
7.526 + /**
7.527 + * Maximum explicit embedding level.
7.528 + * (The maximum resolved level can be up to <code>MAX_EXPLICIT_LEVEL+1</code>).
7.529 + * @stable ICU 3.8
7.530 + */
7.531 + public static final byte MAX_EXPLICIT_LEVEL = 61;
7.532 +
7.533 + /**
7.534 + * Bit flag for level input.
7.535 + * Overrides directional properties.
7.536 + * @stable ICU 3.8
7.537 + */
7.538 + public static final byte INTERNAL_LEVEL_OVERRIDE = (byte)0x80;
7.539 +
7.540 + /**
7.541 + * Special value which can be returned by the mapping methods when a
7.542 + * logical index has no corresponding visual index or vice-versa. This may
7.543 + * happen for the logical-to-visual mapping of a Bidi control when option
7.544 + * <code>OPTION_REMOVE_CONTROLS</code> is
7.545 + * specified. This can also happen for the visual-to-logical mapping of a
7.546 + * Bidi mark (LRM or RLM) inserted by option
7.547 + * <code>OPTION_INSERT_MARKS</code>.
7.548 + * @see #getVisualIndex
7.549 + * @see #getVisualMap
7.550 + * @see #getLogicalIndex
7.551 + * @see #getLogicalMap
7.552 + * @see #OPTION_INSERT_MARKS
7.553 + * @see #OPTION_REMOVE_CONTROLS
7.554 + * @stable ICU 3.8
7.555 + */
7.556 + public static final int MAP_NOWHERE = -1;
7.557 +
7.558 + /**
7.559 + * Mixed-directional text.
7.560 + * @stable ICU 3.8
7.561 + */
7.562 + public static final byte MIXED = 2;
7.563 +
7.564 + /**
7.565 + * option bit for writeReordered():
7.566 + * replace characters with the "mirrored" property in RTL runs
7.567 + * by their mirror-image mappings
7.568 + *
7.569 + * @see #writeReordered
7.570 + * @stable ICU 3.8
7.571 + */
7.572 + public static final short DO_MIRRORING = 2;
7.573 +
7.574 + /** Reordering mode: Regular Logical to Visual Bidi algorithm according to Unicode.
7.575 + * @see #setReorderingMode
7.576 + * @stable ICU 3.8
7.577 + */
7.578 + private static final short REORDER_DEFAULT = 0;
7.579 +
7.580 + /** Reordering mode: Logical to Visual algorithm which handles numbers in
7.581 + * a way which mimicks the behavior of Windows XP.
7.582 + * @see #setReorderingMode
7.583 + * @stable ICU 3.8
7.584 + */
7.585 + private static final short REORDER_NUMBERS_SPECIAL = 1;
7.586 +
7.587 + /** Reordering mode: Logical to Visual algorithm grouping numbers with
7.588 + * adjacent R characters (reversible algorithm).
7.589 + * @see #setReorderingMode
7.590 + * @stable ICU 3.8
7.591 + */
7.592 + private static final short REORDER_GROUP_NUMBERS_WITH_R = 2;
7.593 +
7.594 + /** Reordering mode: Reorder runs only to transform a Logical LTR string
7.595 + * to the logical RTL string with the same display, or vice-versa.<br>
7.596 + * If this mode is set together with option
7.597 + * <code>OPTION_INSERT_MARKS</code>, some Bidi controls in the source
7.598 + * text may be removed and other controls may be added to produce the
7.599 + * minimum combination which has the required display.
7.600 + * @see #OPTION_INSERT_MARKS
7.601 + * @see #setReorderingMode
7.602 + * @stable ICU 3.8
7.603 + */
7.604 + private static final short REORDER_RUNS_ONLY = 3;
7.605 +
7.606 + /** Reordering mode: Visual to Logical algorithm which handles numbers
7.607 + * like L (same algorithm as selected by <code>setInverse(true)</code>.
7.608 + * @see #setInverse
7.609 + * @see #setReorderingMode
7.610 + * @stable ICU 3.8
7.611 + */
7.612 + private static final short REORDER_INVERSE_NUMBERS_AS_L = 4;
7.613 +
7.614 + /** Reordering mode: Visual to Logical algorithm equivalent to the regular
7.615 + * Logical to Visual algorithm.
7.616 + * @see #setReorderingMode
7.617 + * @stable ICU 3.8
7.618 + */
7.619 + private static final short REORDER_INVERSE_LIKE_DIRECT = 5;
7.620 +
7.621 + /** Reordering mode: Inverse Bidi (Visual to Logical) algorithm for the
7.622 + * <code>REORDER_NUMBERS_SPECIAL</code> Bidi algorithm.
7.623 + * @see #setReorderingMode
7.624 + * @stable ICU 3.8
7.625 + */
7.626 + private static final short REORDER_INVERSE_FOR_NUMBERS_SPECIAL = 6;
7.627 +
7.628 + /* Reordering mode values must be ordered so that all the regular logical to
7.629 + * visual modes come first, and all inverse Bidi modes come last.
7.630 + */
7.631 + private static final short REORDER_LAST_LOGICAL_TO_VISUAL =
7.632 + REORDER_NUMBERS_SPECIAL;
7.633 +
7.634 + /**
7.635 + * Option bit for <code>setReorderingOptions</code>:
7.636 + * insert Bidi marks (LRM or RLM) when needed to ensure correct result of
7.637 + * a reordering to a Logical order
7.638 + *
7.639 + * <p>This option must be set or reset before calling
7.640 + * <code>setPara</code>.</p>
7.641 + *
7.642 + * <p>This option is significant only with reordering modes which generate
7.643 + * a result with Logical order, specifically.</p>
7.644 + * <ul>
7.645 + * <li><code>REORDER_RUNS_ONLY</code></li>
7.646 + * <li><code>REORDER_INVERSE_NUMBERS_AS_L</code></li>
7.647 + * <li><code>REORDER_INVERSE_LIKE_DIRECT</code></li>
7.648 + * <li><code>REORDER_INVERSE_FOR_NUMBERS_SPECIAL</code></li>
7.649 + * </ul>
7.650 + *
7.651 + * <p>If this option is set in conjunction with reordering mode
7.652 + * <code>REORDER_INVERSE_NUMBERS_AS_L</code> or with calling
7.653 + * <code>setInverse(true)</code>, it implies option
7.654 + * <code>INSERT_LRM_FOR_NUMERIC</code> in calls to method
7.655 + * <code>writeReordered()</code>.</p>
7.656 + *
7.657 + * <p>For other reordering modes, a minimum number of LRM or RLM characters
7.658 + * will be added to the source text after reordering it so as to ensure
7.659 + * round trip, i.e. when applying the inverse reordering mode on the
7.660 + * resulting logical text with removal of Bidi marks
7.661 + * (option <code>OPTION_REMOVE_CONTROLS</code> set before calling
7.662 + * <code>setPara()</code> or option
7.663 + * <code>REMOVE_BIDI_CONTROLS</code> in
7.664 + * <code>writeReordered</code>), the result will be identical to the
7.665 + * source text in the first transformation.
7.666 + *
7.667 + * <p>This option will be ignored if specified together with option
7.668 + * <code>OPTION_REMOVE_CONTROLS</code>. It inhibits option
7.669 + * <code>REMOVE_BIDI_CONTROLS</code> in calls to method
7.670 + * <code>writeReordered()</code> and it implies option
7.671 + * <code>INSERT_LRM_FOR_NUMERIC</code> in calls to method
7.672 + * <code>writeReordered()</code> if the reordering mode is
7.673 + * <code>REORDER_INVERSE_NUMBERS_AS_L</code>.</p>
7.674 + *
7.675 + * @see #setReorderingMode
7.676 + * @see #setReorderingOptions
7.677 + * @see #INSERT_LRM_FOR_NUMERIC
7.678 + * @see #REMOVE_BIDI_CONTROLS
7.679 + * @see #OPTION_REMOVE_CONTROLS
7.680 + * @see #REORDER_RUNS_ONLY
7.681 + * @see #REORDER_INVERSE_NUMBERS_AS_L
7.682 + * @see #REORDER_INVERSE_LIKE_DIRECT
7.683 + * @see #REORDER_INVERSE_FOR_NUMBERS_SPECIAL
7.684 + * @stable ICU 3.8
7.685 + */
7.686 + private static final int OPTION_INSERT_MARKS = 1;
7.687 +
7.688 + /**
7.689 + * Option bit for <code>setReorderingOptions</code>:
7.690 + * remove Bidi control characters
7.691 + *
7.692 + * <p>This option must be set or reset before calling
7.693 + * <code>setPara</code>.</p>
7.694 + *
7.695 + * <p>This option nullifies option
7.696 + * <code>OPTION_INSERT_MARKS</code>. It inhibits option
7.697 + * <code>INSERT_LRM_FOR_NUMERIC</code> in calls to method
7.698 + * <code>writeReordered()</code> and it implies option
7.699 + * <code>REMOVE_BIDI_CONTROLS</code> in calls to that method.</p>
7.700 + *
7.701 + * @see #setReorderingMode
7.702 + * @see #setReorderingOptions
7.703 + * @see #OPTION_INSERT_MARKS
7.704 + * @see #INSERT_LRM_FOR_NUMERIC
7.705 + * @see #REMOVE_BIDI_CONTROLS
7.706 + * @stable ICU 3.8
7.707 + */
7.708 + private static final int OPTION_REMOVE_CONTROLS = 2;
7.709 +
7.710 + /**
7.711 + * Option bit for <code>setReorderingOptions</code>:
7.712 + * process the output as part of a stream to be continued
7.713 + *
7.714 + * <p>This option must be set or reset before calling
7.715 + * <code>setPara</code>.</p>
7.716 + *
7.717 + * <p>This option specifies that the caller is interested in processing
7.718 + * large text object in parts. The results of the successive calls are
7.719 + * expected to be concatenated by the caller. Only the call for the last
7.720 + * part will have this option bit off.</p>
7.721 + *
7.722 + * <p>When this option bit is on, <code>setPara()</code> may process
7.723 + * less than the full source text in order to truncate the text at a
7.724 + * meaningful boundary. The caller should call
7.725 + * <code>getProcessedLength()</code> immediately after calling
7.726 + * <code>setPara()</code> in order to determine how much of the source
7.727 + * text has been processed. Source text beyond that length should be
7.728 + * resubmitted in following calls to <code>setPara</code>. The
7.729 + * processed length may be less than the length of the source text if a
7.730 + * character preceding the last character of the source text constitutes a
7.731 + * reasonable boundary (like a block separator) for text to be continued.<br>
7.732 + * If the last character of the source text constitutes a reasonable
7.733 + * boundary, the whole text will be processed at once.<br>
7.734 + * If nowhere in the source text there exists
7.735 + * such a reasonable boundary, the processed length will be zero.<br>
7.736 + * The caller should check for such an occurrence and do one of the following:
7.737 + * <ul><li>submit a larger amount of text with a better chance to include
7.738 + * a reasonable boundary.</li>
7.739 + * <li>resubmit the same text after turning off option
7.740 + * <code>OPTION_STREAMING</code>.</li></ul>
7.741 + * In all cases, this option should be turned off before processing the last
7.742 + * part of the text.</p>
7.743 + *
7.744 + * <p>When the <code>OPTION_STREAMING</code> option is used, it is
7.745 + * recommended to call <code>orderParagraphsLTR()</code> with argument
7.746 + * <code>orderParagraphsLTR</code> set to <code>true</code> before calling
7.747 + * <code>setPara()</code> so that later paragraphs may be concatenated to
7.748 + * previous paragraphs on the right.
7.749 + * </p>
7.750 + *
7.751 + * @see #setReorderingMode
7.752 + * @see #setReorderingOptions
7.753 + * @see #getProcessedLength
7.754 + * @see #orderParagraphsLTR
7.755 + * @stable ICU 3.8
7.756 + */
7.757 + private static final int OPTION_STREAMING = 4;
7.758 +
7.759 + /*
7.760 + * Comparing the description of the Bidi algorithm with this implementation
7.761 + * is easier with the same names for the Bidi types in the code as there.
7.762 + * See UCharacterDirection
7.763 + */
7.764 + private static final byte L = 0;
7.765 + private static final byte R = 1;
7.766 + private static final byte EN = 2;
7.767 + private static final byte ES = 3;
7.768 + private static final byte ET = 4;
7.769 + private static final byte AN = 5;
7.770 + private static final byte CS = 6;
7.771 + static final byte B = 7;
7.772 + private static final byte S = 8;
7.773 + private static final byte WS = 9;
7.774 + private static final byte ON = 10;
7.775 + private static final byte LRE = 11;
7.776 + private static final byte LRO = 12;
7.777 + private static final byte AL = 13;
7.778 + private static final byte RLE = 14;
7.779 + private static final byte RLO = 15;
7.780 + private static final byte PDF = 16;
7.781 + private static final byte NSM = 17;
7.782 + private static final byte BN = 18;
7.783 +
7.784 + private static final int MASK_R_AL = (1 << R | 1 << AL);
7.785 +
7.786 + private static final char CR = '\r';
7.787 + private static final char LF = '\n';
7.788 +
7.789 + static final int LRM_BEFORE = 1;
7.790 + static final int LRM_AFTER = 2;
7.791 + static final int RLM_BEFORE = 4;
7.792 + static final int RLM_AFTER = 8;
7.793 +
7.794 + /*
7.795 + * reference to parent paragraph object (reference to self if this object is
7.796 + * a paragraph object); set to null in a newly opened object; set to a
7.797 + * real value after a successful execution of setPara or setLine
7.798 + */
7.799 + BidiBase paraBidi;
7.800 +
7.801 + final UBiDiProps bdp;
7.802 +
7.803 + /* character array representing the current text */
7.804 + char[] text;
7.805 +
7.806 + /* length of the current text */
7.807 + int originalLength;
7.808 +
7.809 + /* if the option OPTION_STREAMING is set, this is the length of
7.810 + * text actually processed by <code>setPara</code>, which may be shorter
7.811 + * than the original length. Otherwise, it is identical to the original
7.812 + * length.
7.813 + */
7.814 + public int length;
7.815 +
7.816 + /* if option OPTION_REMOVE_CONTROLS is set, and/or Bidi
7.817 + * marks are allowed to be inserted in one of the reordering modes, the
7.818 + * length of the result string may be different from the processed length.
7.819 + */
7.820 + int resultLength;
7.821 +
7.822 + /* indicators for whether memory may be allocated after construction */
7.823 + boolean mayAllocateText;
7.824 + boolean mayAllocateRuns;
7.825 +
7.826 + /* arrays with one value per text-character */
7.827 + byte[] dirPropsMemory = new byte[1];
7.828 + byte[] levelsMemory = new byte[1];
7.829 + byte[] dirProps;
7.830 + byte[] levels;
7.831 +
7.832 + /* must block separators receive level 0? */
7.833 + boolean orderParagraphsLTR;
7.834 +
7.835 + /* the paragraph level */
7.836 + byte paraLevel;
7.837 +
7.838 + /* original paraLevel when contextual */
7.839 + /* must be one of DEFAULT_xxx or 0 if not contextual */
7.840 + byte defaultParaLevel;
7.841 +
7.842 + /* the following is set in setPara, used in processPropertySeq */
7.843 +
7.844 + ImpTabPair impTabPair; /* reference to levels state table pair */
7.845 +
7.846 + /* the overall paragraph or line directionality*/
7.847 + byte direction;
7.848 +
7.849 + /* flags is a bit set for which directional properties are in the text */
7.850 + int flags;
7.851 +
7.852 + /* lastArabicPos is index to the last AL in the text, -1 if none */
7.853 + int lastArabicPos;
7.854 +
7.855 + /* characters after trailingWSStart are WS and are */
7.856 + /* implicitly at the paraLevel (rule (L1)) - levels may not reflect that */
7.857 + int trailingWSStart;
7.858 +
7.859 + /* fields for paragraph handling */
7.860 + int paraCount; /* set in getDirProps() */
7.861 + int[] parasMemory = new int[1];
7.862 + int[] paras; /* limits of paragraphs, filled in
7.863 + ResolveExplicitLevels() or CheckExplicitLevels() */
7.864 +
7.865 + /* for single paragraph text, we only need a tiny array of paras (no allocation) */
7.866 + int[] simpleParas = {0};
7.867 +
7.868 + /* fields for line reordering */
7.869 + int runCount; /* ==-1: runs not set up yet */
7.870 + BidiRun[] runsMemory = new BidiRun[0];
7.871 + BidiRun[] runs;
7.872 +
7.873 + /* for non-mixed text, we only need a tiny array of runs (no allocation) */
7.874 + BidiRun[] simpleRuns = {new BidiRun()};
7.875 +
7.876 + /* mapping of runs in logical order to visual order */
7.877 + int[] logicalToVisualRunsMap;
7.878 +
7.879 + /* flag to indicate that the map has been updated */
7.880 + boolean isGoodLogicalToVisualRunsMap;
7.881 +
7.882 + /* for inverse Bidi with insertion of directional marks */
7.883 + InsertPoints insertPoints = new InsertPoints();
7.884 +
7.885 + /* for option OPTION_REMOVE_CONTROLS */
7.886 + int controlCount;
7.887 +
7.888 + /*
7.889 + * Sometimes, bit values are more appropriate
7.890 + * to deal with directionality properties.
7.891 + * Abbreviations in these method names refer to names
7.892 + * used in the Bidi algorithm.
7.893 + */
7.894 + static int DirPropFlag(byte dir) {
7.895 + return (1 << dir);
7.896 + }
7.897 +
7.898 + /*
7.899 + * The following bit is ORed to the property of characters in paragraphs
7.900 + * with contextual RTL direction when paraLevel is contextual.
7.901 + */
7.902 + static final byte CONTEXT_RTL_SHIFT = 6;
7.903 + static final byte CONTEXT_RTL = (byte)(1<<CONTEXT_RTL_SHIFT); // 0x40
7.904 + static byte NoContextRTL(byte dir)
7.905 + {
7.906 + return (byte)(dir & ~CONTEXT_RTL);
7.907 + }
7.908 +
7.909 + /*
7.910 + * The following is a variant of DirProp.DirPropFlag() which ignores the
7.911 + * CONTEXT_RTL bit.
7.912 + */
7.913 + static int DirPropFlagNC(byte dir) {
7.914 + return (1<<(dir & ~CONTEXT_RTL));
7.915 + }
7.916 +
7.917 + static final int DirPropFlagMultiRuns = DirPropFlag((byte)31);
7.918 +
7.919 + /* to avoid some conditional statements, use tiny constant arrays */
7.920 + static final int DirPropFlagLR[] = { DirPropFlag(L), DirPropFlag(R) };
7.921 + static final int DirPropFlagE[] = { DirPropFlag(LRE), DirPropFlag(RLE) };
7.922 + static final int DirPropFlagO[] = { DirPropFlag(LRO), DirPropFlag(RLO) };
7.923 +
7.924 + static final int DirPropFlagLR(byte level) { return DirPropFlagLR[level & 1]; }
7.925 + static final int DirPropFlagE(byte level) { return DirPropFlagE[level & 1]; }
7.926 + static final int DirPropFlagO(byte level) { return DirPropFlagO[level & 1]; }
7.927 +
7.928 + /*
7.929 + * are there any characters that are LTR?
7.930 + */
7.931 + static final int MASK_LTR =
7.932 + DirPropFlag(L)|DirPropFlag(EN)|DirPropFlag(AN)|DirPropFlag(LRE)|DirPropFlag(LRO);
7.933 +
7.934 + /*
7.935 + * are there any characters that are RTL?
7.936 + */
7.937 + static final int MASK_RTL = DirPropFlag(R)|DirPropFlag(AL)|DirPropFlag(RLE)|DirPropFlag(RLO);
7.938 +
7.939 + /* explicit embedding codes */
7.940 + private static final int MASK_LRX = DirPropFlag(LRE)|DirPropFlag(LRO);
7.941 + private static final int MASK_RLX = DirPropFlag(RLE)|DirPropFlag(RLO);
7.942 + private static final int MASK_EXPLICIT = MASK_LRX|MASK_RLX|DirPropFlag(PDF);
7.943 + private static final int MASK_BN_EXPLICIT = DirPropFlag(BN)|MASK_EXPLICIT;
7.944 +
7.945 + /* paragraph and segment separators */
7.946 + private static final int MASK_B_S = DirPropFlag(B)|DirPropFlag(S);
7.947 +
7.948 + /* all types that are counted as White Space or Neutral in some steps */
7.949 + static final int MASK_WS = MASK_B_S|DirPropFlag(WS)|MASK_BN_EXPLICIT;
7.950 + private static final int MASK_N = DirPropFlag(ON)|MASK_WS;
7.951 +
7.952 + /* types that are neutrals or could becomes neutrals in (Wn) */
7.953 + private static final int MASK_POSSIBLE_N = DirPropFlag(CS)|DirPropFlag(ES)|DirPropFlag(ET)|MASK_N;
7.954 +
7.955 + /*
7.956 + * These types may be changed to "e",
7.957 + * the embedding type (L or R) of the run,
7.958 + * in the Bidi algorithm (N2)
7.959 + */
7.960 + static final int MASK_EMBEDDING = DirPropFlag(NSM)|MASK_POSSIBLE_N;
7.961 +
7.962 + /*
7.963 + * the dirProp's L and R are defined to 0 and 1 values in UCharacterDirection.java
7.964 + */
7.965 + private static byte GetLRFromLevel(byte level)
7.966 + {
7.967 + return (byte)(level & 1);
7.968 + }
7.969 +
7.970 + private static boolean IsDefaultLevel(byte level)
7.971 + {
7.972 + return ((level & INTERNAL_LEVEL_DEFAULT_LTR) == INTERNAL_LEVEL_DEFAULT_LTR);
7.973 + }
7.974 +
7.975 + byte GetParaLevelAt(int index)
7.976 + {
7.977 + return (defaultParaLevel != 0) ?
7.978 + (byte)(dirProps[index]>>CONTEXT_RTL_SHIFT) : paraLevel;
7.979 + }
7.980 +
7.981 + static boolean IsBidiControlChar(int c)
7.982 + {
7.983 + /* check for range 0x200c to 0x200f (ZWNJ, ZWJ, LRM, RLM) or
7.984 + 0x202a to 0x202e (LRE, RLE, PDF, LRO, RLO) */
7.985 + return (((c & 0xfffffffc) == 0x200c) || ((c >= 0x202a) && (c <= 0x202e)));
7.986 + }
7.987 +
7.988 + public void verifyValidPara()
7.989 + {
7.990 + if (this != this.paraBidi) {
7.991 + throw new IllegalStateException("");
7.992 + }
7.993 + }
7.994 +
7.995 + public void verifyValidParaOrLine()
7.996 + {
7.997 + BidiBase para = this.paraBidi;
7.998 + /* verify Para */
7.999 + if (this == para) {
7.1000 + return;
7.1001 + }
7.1002 + /* verify Line */
7.1003 + if ((para == null) || (para != para.paraBidi)) {
7.1004 + throw new IllegalStateException();
7.1005 + }
7.1006 + }
7.1007 +
7.1008 + public void verifyRange(int index, int start, int limit)
7.1009 + {
7.1010 + if (index < start || index >= limit) {
7.1011 + throw new IllegalArgumentException("Value " + index +
7.1012 + " is out of range " + start + " to " + limit);
7.1013 + }
7.1014 + }
7.1015 +
7.1016 + public void verifyIndex(int index, int start, int limit)
7.1017 + {
7.1018 + if (index < start || index >= limit) {
7.1019 + throw new ArrayIndexOutOfBoundsException("Index " + index +
7.1020 + " is out of range " + start + " to " + limit);
7.1021 + }
7.1022 + }
7.1023 +
7.1024 + /**
7.1025 + * Allocate a <code>Bidi</code> object with preallocated memory
7.1026 + * for internal structures.
7.1027 + * This method provides a <code>Bidi</code> object like the default constructor
7.1028 + * but it also preallocates memory for internal structures
7.1029 + * according to the sizings supplied by the caller.<p>
7.1030 + * The preallocation can be limited to some of the internal memory
7.1031 + * by setting some values to 0 here. That means that if, e.g.,
7.1032 + * <code>maxRunCount</code> cannot be reasonably predetermined and should not
7.1033 + * be set to <code>maxLength</code> (the only failproof value) to avoid
7.1034 + * wasting memory, then <code>maxRunCount</code> could be set to 0 here
7.1035 + * and the internal structures that are associated with it will be allocated
7.1036 + * on demand, just like with the default constructor.
7.1037 + *
7.1038 + * @param maxLength is the maximum text or line length that internal memory
7.1039 + * will be preallocated for. An attempt to associate this object with a
7.1040 + * longer text will fail, unless this value is 0, which leaves the allocation
7.1041 + * up to the implementation.
7.1042 + *
7.1043 + * @param maxRunCount is the maximum anticipated number of same-level runs
7.1044 + * that internal memory will be preallocated for. An attempt to access
7.1045 + * visual runs on an object that was not preallocated for as many runs
7.1046 + * as the text was actually resolved to will fail,
7.1047 + * unless this value is 0, which leaves the allocation up to the implementation.<br><br>
7.1048 + * The number of runs depends on the actual text and maybe anywhere between
7.1049 + * 1 and <code>maxLength</code>. It is typically small.
7.1050 + *
7.1051 + * @throws IllegalArgumentException if maxLength or maxRunCount is less than 0
7.1052 + * @stable ICU 3.8
7.1053 + */
7.1054 + public BidiBase(int maxLength, int maxRunCount)
7.1055 + {
7.1056 + /* check the argument values */
7.1057 + if (maxLength < 0 || maxRunCount < 0) {
7.1058 + throw new IllegalArgumentException();
7.1059 + }
7.1060 +
7.1061 + /* reset the object, all reference variables null, all flags false,
7.1062 + all sizes 0.
7.1063 + In fact, we don't need to do anything, since class members are
7.1064 + initialized as zero when an instance is created.
7.1065 + */
7.1066 + /*
7.1067 + mayAllocateText = false;
7.1068 + mayAllocateRuns = false;
7.1069 + orderParagraphsLTR = false;
7.1070 + paraCount = 0;
7.1071 + runCount = 0;
7.1072 + trailingWSStart = 0;
7.1073 + flags = 0;
7.1074 + paraLevel = 0;
7.1075 + defaultParaLevel = 0;
7.1076 + direction = 0;
7.1077 + */
7.1078 + /* get Bidi properties */
7.1079 + try {
7.1080 + bdp = UBiDiProps.getSingleton();
7.1081 + }
7.1082 + catch (IOException e) {
7.1083 + throw new MissingResourceException(e.getMessage(), "(BidiProps)", "");
7.1084 + }
7.1085 +
7.1086 + /* allocate memory for arrays as requested */
7.1087 + if (maxLength > 0) {
7.1088 + getInitialDirPropsMemory(maxLength);
7.1089 + getInitialLevelsMemory(maxLength);
7.1090 + } else {
7.1091 + mayAllocateText = true;
7.1092 + }
7.1093 +
7.1094 + if (maxRunCount > 0) {
7.1095 + // if maxRunCount == 1, use simpleRuns[]
7.1096 + if (maxRunCount > 1) {
7.1097 + getInitialRunsMemory(maxRunCount);
7.1098 + }
7.1099 + } else {
7.1100 + mayAllocateRuns = true;
7.1101 + }
7.1102 + }
7.1103 +
7.1104 + /*
7.1105 + * We are allowed to allocate memory if object==null or
7.1106 + * mayAllocate==true for each array that we need.
7.1107 + *
7.1108 + * Assume sizeNeeded>0.
7.1109 + * If object != null, then assume size > 0.
7.1110 + */
7.1111 + private Object getMemory(String label, Object array, Class arrayClass,
7.1112 + boolean mayAllocate, int sizeNeeded)
7.1113 + {
7.1114 + int len = Array.getLength(array);
7.1115 +
7.1116 + /* we have at least enough memory and must not allocate */
7.1117 + if (sizeNeeded == len) {
7.1118 + return array;
7.1119 + }
7.1120 + if (!mayAllocate) {
7.1121 + /* we must not allocate */
7.1122 + if (sizeNeeded <= len) {
7.1123 + return array;
7.1124 + }
7.1125 + throw new OutOfMemoryError("Failed to allocate memory for "
7.1126 + + label);
7.1127 + }
7.1128 + /* we may try to grow or shrink */
7.1129 + /* FOOD FOR THOUGHT: when shrinking it should be possible to avoid
7.1130 + the allocation altogether and rely on this.length */
7.1131 + try {
7.1132 + return Array.newInstance(arrayClass, sizeNeeded);
7.1133 + } catch (Exception e) {
7.1134 + throw new OutOfMemoryError("Failed to allocate memory for "
7.1135 + + label);
7.1136 + }
7.1137 + }
7.1138 +
7.1139 + /* helper methods for each allocated array */
7.1140 + private void getDirPropsMemory(boolean mayAllocate, int len)
7.1141 + {
7.1142 + Object array = getMemory("DirProps", dirPropsMemory, Byte.TYPE, mayAllocate, len);
7.1143 + dirPropsMemory = (byte[]) array;
7.1144 + }
7.1145 +
7.1146 + void getDirPropsMemory(int len)
7.1147 + {
7.1148 + getDirPropsMemory(mayAllocateText, len);
7.1149 + }
7.1150 +
7.1151 + private void getLevelsMemory(boolean mayAllocate, int len)
7.1152 + {
7.1153 + Object array = getMemory("Levels", levelsMemory, Byte.TYPE, mayAllocate, len);
7.1154 + levelsMemory = (byte[]) array;
7.1155 + }
7.1156 +
7.1157 + void getLevelsMemory(int len)
7.1158 + {
7.1159 + getLevelsMemory(mayAllocateText, len);
7.1160 + }
7.1161 +
7.1162 + private void getRunsMemory(boolean mayAllocate, int len)
7.1163 + {
7.1164 + Object array = getMemory("Runs", runsMemory, BidiRun.class, mayAllocate, len);
7.1165 + runsMemory = (BidiRun[]) array;
7.1166 + }
7.1167 +
7.1168 + void getRunsMemory(int len)
7.1169 + {
7.1170 + getRunsMemory(mayAllocateRuns, len);
7.1171 + }
7.1172 +
7.1173 + /* additional methods used by constructor - always allow allocation */
7.1174 + private void getInitialDirPropsMemory(int len)
7.1175 + {
7.1176 + getDirPropsMemory(true, len);
7.1177 + }
7.1178 +
7.1179 + private void getInitialLevelsMemory(int len)
7.1180 + {
7.1181 + getLevelsMemory(true, len);
7.1182 + }
7.1183 +
7.1184 + private void getInitialParasMemory(int len)
7.1185 + {
7.1186 + Object array = getMemory("Paras", parasMemory, Integer.TYPE, true, len);
7.1187 + parasMemory = (int[]) array;
7.1188 + }
7.1189 +
7.1190 + private void getInitialRunsMemory(int len)
7.1191 + {
7.1192 + getRunsMemory(true, len);
7.1193 + }
7.1194 +
7.1195 +/* perform (P2)..(P3) ------------------------------------------------------- */
7.1196 +
7.1197 + private void getDirProps()
7.1198 + {
7.1199 + int i = 0, i0, i1;
7.1200 + flags = 0; /* collect all directionalities in the text */
7.1201 + int uchar;
7.1202 + byte dirProp;
7.1203 + byte paraDirDefault = 0; /* initialize to avoid compiler warnings */
7.1204 + boolean isDefaultLevel = IsDefaultLevel(paraLevel);
7.1205 + /* for inverse Bidi, the default para level is set to RTL if there is a
7.1206 + strong R or AL character at either end of the text */
7.1207 + lastArabicPos = -1;
7.1208 + controlCount = 0;
7.1209 +
7.1210 + final int NOT_CONTEXTUAL = 0; /* 0: not contextual paraLevel */
7.1211 + final int LOOKING_FOR_STRONG = 1; /* 1: looking for first strong char */
7.1212 + final int FOUND_STRONG_CHAR = 2; /* 2: found first strong char */
7.1213 +
7.1214 + int state;
7.1215 + int paraStart = 0; /* index of first char in paragraph */
7.1216 + byte paraDir; /* == CONTEXT_RTL within paragraphs
7.1217 + starting with strong R char */
7.1218 + byte lastStrongDir=0; /* for default level & inverse Bidi */
7.1219 + int lastStrongLTR=0; /* for STREAMING option */
7.1220 +
7.1221 + if (isDefaultLevel) {
7.1222 + paraDirDefault = ((paraLevel & 1) != 0) ? CONTEXT_RTL : 0;
7.1223 + paraDir = paraDirDefault;
7.1224 + lastStrongDir = paraDirDefault;
7.1225 + state = LOOKING_FOR_STRONG;
7.1226 + } else {
7.1227 + state = NOT_CONTEXTUAL;
7.1228 + paraDir = 0;
7.1229 + }
7.1230 + /* count paragraphs and determine the paragraph level (P2..P3) */
7.1231 + /*
7.1232 + * see comment on constant fields:
7.1233 + * the LEVEL_DEFAULT_XXX values are designed so that
7.1234 + * their low-order bit alone yields the intended default
7.1235 + */
7.1236 +
7.1237 + for (i = 0; i < originalLength; /* i is incremented in the loop */) {
7.1238 + i0 = i; /* index of first code unit */
7.1239 + uchar = UTF16.charAt(text, 0, originalLength, i);
7.1240 + i += Character.charCount(uchar);
7.1241 + i1 = i - 1; /* index of last code unit, gets the directional property */
7.1242 +
7.1243 + dirProp = (byte)bdp.getClass(uchar);
7.1244 +
7.1245 + flags |= DirPropFlag(dirProp);
7.1246 + dirProps[i1] = (byte)(dirProp | paraDir);
7.1247 + if (i1 > i0) { /* set previous code units' properties to BN */
7.1248 + flags |= DirPropFlag(BN);
7.1249 + do {
7.1250 + dirProps[--i1] = (byte)(BN | paraDir);
7.1251 + } while (i1 > i0);
7.1252 + }
7.1253 + if (state == LOOKING_FOR_STRONG) {
7.1254 + if (dirProp == L) {
7.1255 + state = FOUND_STRONG_CHAR;
7.1256 + if (paraDir != 0) {
7.1257 + paraDir = 0;
7.1258 + for (i1 = paraStart; i1 < i; i1++) {
7.1259 + dirProps[i1] &= ~CONTEXT_RTL;
7.1260 + }
7.1261 + }
7.1262 + continue;
7.1263 + }
7.1264 + if (dirProp == R || dirProp == AL) {
7.1265 + state = FOUND_STRONG_CHAR;
7.1266 + if (paraDir == 0) {
7.1267 + paraDir = CONTEXT_RTL;
7.1268 + for (i1 = paraStart; i1 < i; i1++) {
7.1269 + dirProps[i1] |= CONTEXT_RTL;
7.1270 + }
7.1271 + }
7.1272 + continue;
7.1273 + }
7.1274 + }
7.1275 + if (dirProp == L) {
7.1276 + lastStrongDir = 0;
7.1277 + lastStrongLTR = i; /* i is index to next character */
7.1278 + }
7.1279 + else if (dirProp == R) {
7.1280 + lastStrongDir = CONTEXT_RTL;
7.1281 + }
7.1282 + else if (dirProp == AL) {
7.1283 + lastStrongDir = CONTEXT_RTL;
7.1284 + lastArabicPos = i-1;
7.1285 + }
7.1286 + else if (dirProp == B) {
7.1287 + if (i < originalLength) { /* B not last char in text */
7.1288 + if (!((uchar == (int)CR) && (text[i] == (int)LF))) {
7.1289 + paraCount++;
7.1290 + }
7.1291 + if (isDefaultLevel) {
7.1292 + state=LOOKING_FOR_STRONG;
7.1293 + paraStart = i; /* i is index to next character */
7.1294 + paraDir = paraDirDefault;
7.1295 + lastStrongDir = paraDirDefault;
7.1296 + }
7.1297 + }
7.1298 + }
7.1299 + }
7.1300 + if (isDefaultLevel) {
7.1301 + paraLevel = GetParaLevelAt(0);
7.1302 + }
7.1303 +
7.1304 + /* The following line does nothing new for contextual paraLevel, but is
7.1305 + needed for absolute paraLevel. */
7.1306 + flags |= DirPropFlagLR(paraLevel);
7.1307 +
7.1308 + if (orderParagraphsLTR && (flags & DirPropFlag(B)) != 0) {
7.1309 + flags |= DirPropFlag(L);
7.1310 + }
7.1311 + }
7.1312 +
7.1313 + /* perform (X1)..(X9) ------------------------------------------------------- */
7.1314 +
7.1315 + /* determine if the text is mixed-directional or single-directional */
7.1316 + private byte directionFromFlags() {
7.1317 + /* if the text contains AN and neutrals, then some neutrals may become RTL */
7.1318 + if (!((flags & MASK_RTL) != 0 ||
7.1319 + ((flags & DirPropFlag(AN)) != 0 &&
7.1320 + (flags & MASK_POSSIBLE_N) != 0))) {
7.1321 + return Bidi.DIRECTION_LEFT_TO_RIGHT;
7.1322 + } else if ((flags & MASK_LTR) == 0) {
7.1323 + return Bidi.DIRECTION_RIGHT_TO_LEFT;
7.1324 + } else {
7.1325 + return MIXED;
7.1326 + }
7.1327 + }
7.1328 +
7.1329 + /*
7.1330 + * Resolve the explicit levels as specified by explicit embedding codes.
7.1331 + * Recalculate the flags to have them reflect the real properties
7.1332 + * after taking the explicit embeddings into account.
7.1333 + *
7.1334 + * The Bidi algorithm is designed to result in the same behavior whether embedding
7.1335 + * levels are externally specified (from "styled text", supposedly the preferred
7.1336 + * method) or set by explicit embedding codes (LRx, RLx, PDF) in the plain text.
7.1337 + * That is why (X9) instructs to remove all explicit codes (and BN).
7.1338 + * However, in a real implementation, this removal of these codes and their index
7.1339 + * positions in the plain text is undesirable since it would result in
7.1340 + * reallocated, reindexed text.
7.1341 + * Instead, this implementation leaves the codes in there and just ignores them
7.1342 + * in the subsequent processing.
7.1343 + * In order to get the same reordering behavior, positions with a BN or an
7.1344 + * explicit embedding code just get the same level assigned as the last "real"
7.1345 + * character.
7.1346 + *
7.1347 + * Some implementations, not this one, then overwrite some of these
7.1348 + * directionality properties at "real" same-level-run boundaries by
7.1349 + * L or R codes so that the resolution of weak types can be performed on the
7.1350 + * entire paragraph at once instead of having to parse it once more and
7.1351 + * perform that resolution on same-level-runs.
7.1352 + * This limits the scope of the implicit rules in effectively
7.1353 + * the same way as the run limits.
7.1354 + *
7.1355 + * Instead, this implementation does not modify these codes.
7.1356 + * On one hand, the paragraph has to be scanned for same-level-runs, but
7.1357 + * on the other hand, this saves another loop to reset these codes,
7.1358 + * or saves making and modifying a copy of dirProps[].
7.1359 + *
7.1360 + *
7.1361 + * Note that (Pn) and (Xn) changed significantly from version 4 of the Bidi algorithm.
7.1362 + *
7.1363 + *
7.1364 + * Handling the stack of explicit levels (Xn):
7.1365 + *
7.1366 + * With the Bidi stack of explicit levels,
7.1367 + * as pushed with each LRE, RLE, LRO, and RLO and popped with each PDF,
7.1368 + * the explicit level must never exceed MAX_EXPLICIT_LEVEL==61.
7.1369 + *
7.1370 + * In order to have a correct push-pop semantics even in the case of overflows,
7.1371 + * there are two overflow counters:
7.1372 + * - countOver60 is incremented with each LRx at level 60
7.1373 + * - from level 60, one RLx increases the level to 61
7.1374 + * - countOver61 is incremented with each LRx and RLx at level 61
7.1375 + *
7.1376 + * Popping levels with PDF must work in the opposite order so that level 61
7.1377 + * is correct at the correct point. Underflows (too many PDFs) must be checked.
7.1378 + *
7.1379 + * This implementation assumes that MAX_EXPLICIT_LEVEL is odd.
7.1380 + */
7.1381 + private byte resolveExplicitLevels() {
7.1382 + int i = 0;
7.1383 + byte dirProp;
7.1384 + byte level = GetParaLevelAt(0);
7.1385 +
7.1386 + byte dirct;
7.1387 + int paraIndex = 0;
7.1388 +
7.1389 + /* determine if the text is mixed-directional or single-directional */
7.1390 + dirct = directionFromFlags();
7.1391 +
7.1392 + /* we may not need to resolve any explicit levels, but for multiple
7.1393 + paragraphs we want to loop on all chars to set the para boundaries */
7.1394 + if ((dirct != MIXED) && (paraCount == 1)) {
7.1395 + /* not mixed directionality: levels don't matter - trailingWSStart will be 0 */
7.1396 + } else if ((paraCount == 1) &&
7.1397 + ((flags & MASK_EXPLICIT) == 0)) {
7.1398 + /* mixed, but all characters are at the same embedding level */
7.1399 + /* or we are in "inverse Bidi" */
7.1400 + /* and we don't have contextual multiple paragraphs with some B char */
7.1401 + /* set all levels to the paragraph level */
7.1402 + for (i = 0; i < length; ++i) {
7.1403 + levels[i] = level;
7.1404 + }
7.1405 + } else {
7.1406 + /* continue to perform (Xn) */
7.1407 +
7.1408 + /* (X1) level is set for all codes, embeddingLevel keeps track of the push/pop operations */
7.1409 + /* both variables may carry the LEVEL_OVERRIDE flag to indicate the override status */
7.1410 + byte embeddingLevel = level;
7.1411 + byte newLevel;
7.1412 + byte stackTop = 0;
7.1413 +
7.1414 + byte[] stack = new byte[MAX_EXPLICIT_LEVEL]; /* we never push anything >=MAX_EXPLICIT_LEVEL */
7.1415 + int countOver60 = 0;
7.1416 + int countOver61 = 0; /* count overflows of explicit levels */
7.1417 +
7.1418 + /* recalculate the flags */
7.1419 + flags = 0;
7.1420 +
7.1421 + for (i = 0; i < length; ++i) {
7.1422 + dirProp = NoContextRTL(dirProps[i]);
7.1423 + switch(dirProp) {
7.1424 + case LRE:
7.1425 + case LRO:
7.1426 + /* (X3, X5) */
7.1427 + newLevel = (byte)((embeddingLevel+2) & ~(INTERNAL_LEVEL_OVERRIDE | 1)); /* least greater even level */
7.1428 + if (newLevel <= MAX_EXPLICIT_LEVEL) {
7.1429 + stack[stackTop] = embeddingLevel;
7.1430 + ++stackTop;
7.1431 + embeddingLevel = newLevel;
7.1432 + if (dirProp == LRO) {
7.1433 + embeddingLevel |= INTERNAL_LEVEL_OVERRIDE;
7.1434 + }
7.1435 + /* we don't need to set LEVEL_OVERRIDE off for LRE
7.1436 + since this has already been done for newLevel which is
7.1437 + the source for embeddingLevel.
7.1438 + */
7.1439 + } else if ((embeddingLevel & ~INTERNAL_LEVEL_OVERRIDE) == MAX_EXPLICIT_LEVEL) {
7.1440 + ++countOver61;
7.1441 + } else /* (embeddingLevel & ~INTERNAL_LEVEL_OVERRIDE) == MAX_EXPLICIT_LEVEL-1 */ {
7.1442 + ++countOver60;
7.1443 + }
7.1444 + flags |= DirPropFlag(BN);
7.1445 + break;
7.1446 + case RLE:
7.1447 + case RLO:
7.1448 + /* (X2, X4) */
7.1449 + newLevel=(byte)(((embeddingLevel & ~INTERNAL_LEVEL_OVERRIDE) + 1) | 1); /* least greater odd level */
7.1450 + if (newLevel<=MAX_EXPLICIT_LEVEL) {
7.1451 + stack[stackTop] = embeddingLevel;
7.1452 + ++stackTop;
7.1453 + embeddingLevel = newLevel;
7.1454 + if (dirProp == RLO) {
7.1455 + embeddingLevel |= INTERNAL_LEVEL_OVERRIDE;
7.1456 + }
7.1457 + /* we don't need to set LEVEL_OVERRIDE off for RLE
7.1458 + since this has already been done for newLevel which is
7.1459 + the source for embeddingLevel.
7.1460 + */
7.1461 + } else {
7.1462 + ++countOver61;
7.1463 + }
7.1464 + flags |= DirPropFlag(BN);
7.1465 + break;
7.1466 + case PDF:
7.1467 + /* (X7) */
7.1468 + /* handle all the overflow cases first */
7.1469 + if (countOver61 > 0) {
7.1470 + --countOver61;
7.1471 + } else if (countOver60 > 0 && (embeddingLevel & ~INTERNAL_LEVEL_OVERRIDE) != MAX_EXPLICIT_LEVEL) {
7.1472 + /* handle LRx overflows from level 60 */
7.1473 + --countOver60;
7.1474 + } else if (stackTop > 0) {
7.1475 + /* this is the pop operation; it also pops level 61 while countOver60>0 */
7.1476 + --stackTop;
7.1477 + embeddingLevel = stack[stackTop];
7.1478 + /* } else { (underflow) */
7.1479 + }
7.1480 + flags |= DirPropFlag(BN);
7.1481 + break;
7.1482 + case B:
7.1483 + stackTop = 0;
7.1484 + countOver60 = 0;
7.1485 + countOver61 = 0;
7.1486 + level = GetParaLevelAt(i);
7.1487 + if ((i + 1) < length) {
7.1488 + embeddingLevel = GetParaLevelAt(i+1);
7.1489 + if (!((text[i] == CR) && (text[i + 1] == LF))) {
7.1490 + paras[paraIndex++] = i+1;
7.1491 + }
7.1492 + }
7.1493 + flags |= DirPropFlag(B);
7.1494 + break;
7.1495 + case BN:
7.1496 + /* BN, LRE, RLE, and PDF are supposed to be removed (X9) */
7.1497 + /* they will get their levels set correctly in adjustWSLevels() */
7.1498 + flags |= DirPropFlag(BN);
7.1499 + break;
7.1500 + default:
7.1501 + /* all other types get the "real" level */
7.1502 + if (level != embeddingLevel) {
7.1503 + level = embeddingLevel;
7.1504 + if ((level & INTERNAL_LEVEL_OVERRIDE) != 0) {
7.1505 + flags |= DirPropFlagO(level) | DirPropFlagMultiRuns;
7.1506 + } else {
7.1507 + flags |= DirPropFlagE(level) | DirPropFlagMultiRuns;
7.1508 + }
7.1509 + }
7.1510 + if ((level & INTERNAL_LEVEL_OVERRIDE) == 0) {
7.1511 + flags |= DirPropFlag(dirProp);
7.1512 + }
7.1513 + break;
7.1514 + }
7.1515 +
7.1516 + /*
7.1517 + * We need to set reasonable levels even on BN codes and
7.1518 + * explicit codes because we will later look at same-level runs (X10).
7.1519 + */
7.1520 + levels[i] = level;
7.1521 + }
7.1522 + if ((flags & MASK_EMBEDDING) != 0) {
7.1523 + flags |= DirPropFlagLR(paraLevel);
7.1524 + }
7.1525 + if (orderParagraphsLTR && (flags & DirPropFlag(B)) != 0) {
7.1526 + flags |= DirPropFlag(L);
7.1527 + }
7.1528 +
7.1529 + /* subsequently, ignore the explicit codes and BN (X9) */
7.1530 +
7.1531 + /* again, determine if the text is mixed-directional or single-directional */
7.1532 + dirct = directionFromFlags();
7.1533 + }
7.1534 +
7.1535 + return dirct;
7.1536 + }
7.1537 +
7.1538 + /*
7.1539 + * Use a pre-specified embedding levels array:
7.1540 + *
7.1541 + * Adjust the directional properties for overrides (->LEVEL_OVERRIDE),
7.1542 + * ignore all explicit codes (X9),
7.1543 + * and check all the preset levels.
7.1544 + *
7.1545 + * Recalculate the flags to have them reflect the real properties
7.1546 + * after taking the explicit embeddings into account.
7.1547 + */
7.1548 + private byte checkExplicitLevels() {
7.1549 + byte dirProp;
7.1550 + int i;
7.1551 + this.flags = 0; /* collect all directionalities in the text */
7.1552 + byte level;
7.1553 + int paraIndex = 0;
7.1554 +
7.1555 + for (i = 0; i < length; ++i) {
7.1556 + if (levels[i] == 0) {
7.1557 + levels[i] = paraLevel;
7.1558 + }
7.1559 + if (MAX_EXPLICIT_LEVEL < (levels[i]&0x7f)) {
7.1560 + if ((levels[i] & INTERNAL_LEVEL_OVERRIDE) != 0) {
7.1561 + levels[i] = (byte)(paraLevel|INTERNAL_LEVEL_OVERRIDE);
7.1562 + } else {
7.1563 + levels[i] = paraLevel;
7.1564 + }
7.1565 + }
7.1566 + level = levels[i];
7.1567 + dirProp = NoContextRTL(dirProps[i]);
7.1568 + if ((level & INTERNAL_LEVEL_OVERRIDE) != 0) {
7.1569 + /* keep the override flag in levels[i] but adjust the flags */
7.1570 + level &= ~INTERNAL_LEVEL_OVERRIDE; /* make the range check below simpler */
7.1571 + flags |= DirPropFlagO(level);
7.1572 + } else {
7.1573 + /* set the flags */
7.1574 + flags |= DirPropFlagE(level) | DirPropFlag(dirProp);
7.1575 + }
7.1576 +
7.1577 + if ((level < GetParaLevelAt(i) &&
7.1578 + !((0 == level) && (dirProp == B))) ||
7.1579 + (MAX_EXPLICIT_LEVEL <level)) {
7.1580 + /* level out of bounds */
7.1581 + throw new IllegalArgumentException("level " + level +
7.1582 + " out of bounds at index " + i);
7.1583 + }
7.1584 + if ((dirProp == B) && ((i + 1) < length)) {
7.1585 + if (!((text[i] == CR) && (text[i + 1] == LF))) {
7.1586 + paras[paraIndex++] = i + 1;
7.1587 + }
7.1588 + }
7.1589 + }
7.1590 + if ((flags&MASK_EMBEDDING) != 0) {
7.1591 + flags |= DirPropFlagLR(paraLevel);
7.1592 + }
7.1593 +
7.1594 + /* determine if the text is mixed-directional or single-directional */
7.1595 + return directionFromFlags();
7.1596 + }
7.1597 +
7.1598 + /*********************************************************************/
7.1599 + /* The Properties state machine table */
7.1600 + /*********************************************************************/
7.1601 + /* */
7.1602 + /* All table cells are 8 bits: */
7.1603 + /* bits 0..4: next state */
7.1604 + /* bits 5..7: action to perform (if > 0) */
7.1605 + /* */
7.1606 + /* Cells may be of format "n" where n represents the next state */
7.1607 + /* (except for the rightmost column). */
7.1608 + /* Cells may also be of format "_(x,y)" where x represents an action */
7.1609 + /* to perform and y represents the next state. */
7.1610 + /* */
7.1611 + /*********************************************************************/
7.1612 + /* Definitions and type for properties state tables */
7.1613 + /*********************************************************************/
7.1614 + private static final int IMPTABPROPS_COLUMNS = 14;
7.1615 + private static final int IMPTABPROPS_RES = IMPTABPROPS_COLUMNS - 1;
7.1616 + private static short GetStateProps(short cell) {
7.1617 + return (short)(cell & 0x1f);
7.1618 + }
7.1619 + private static short GetActionProps(short cell) {
7.1620 + return (short)(cell >> 5);
7.1621 + }
7.1622 +
7.1623 + private static final short groupProp[] = /* dirProp regrouped */
7.1624 + {
7.1625 + /* L R EN ES ET AN CS B S WS ON LRE LRO AL RLE RLO PDF NSM BN */
7.1626 + 0, 1, 2, 7, 8, 3, 9, 6, 5, 4, 4, 10, 10, 12, 10, 10, 10, 11, 10
7.1627 + };
7.1628 + private static final short _L = 0;
7.1629 + private static final short _R = 1;
7.1630 + private static final short _EN = 2;
7.1631 + private static final short _AN = 3;
7.1632 + private static final short _ON = 4;
7.1633 + private static final short _S = 5;
7.1634 + private static final short _B = 6; /* reduced dirProp */
7.1635 +
7.1636 + /*********************************************************************/
7.1637 + /* */
7.1638 + /* PROPERTIES STATE TABLE */
7.1639 + /* */
7.1640 + /* In table impTabProps, */
7.1641 + /* - the ON column regroups ON and WS */
7.1642 + /* - the BN column regroups BN, LRE, RLE, LRO, RLO, PDF */
7.1643 + /* - the Res column is the reduced property assigned to a run */
7.1644 + /* */
7.1645 + /* Action 1: process current run1, init new run1 */
7.1646 + /* 2: init new run2 */
7.1647 + /* 3: process run1, process run2, init new run1 */
7.1648 + /* 4: process run1, set run1=run2, init new run2 */
7.1649 + /* */
7.1650 + /* Notes: */
7.1651 + /* 1) This table is used in resolveImplicitLevels(). */
7.1652 + /* 2) This table triggers actions when there is a change in the Bidi*/
7.1653 + /* property of incoming characters (action 1). */
7.1654 + /* 3) Most such property sequences are processed immediately (in */
7.1655 + /* fact, passed to processPropertySeq(). */
7.1656 + /* 4) However, numbers are assembled as one sequence. This means */
7.1657 + /* that undefined situations (like CS following digits, until */
7.1658 + /* it is known if the next char will be a digit) are held until */
7.1659 + /* following chars define them. */
7.1660 + /* Example: digits followed by CS, then comes another CS or ON; */
7.1661 + /* the digits will be processed, then the CS assigned */
7.1662 + /* as the start of an ON sequence (action 3). */
7.1663 + /* 5) There are cases where more than one sequence must be */
7.1664 + /* processed, for instance digits followed by CS followed by L: */
7.1665 + /* the digits must be processed as one sequence, and the CS */
7.1666 + /* must be processed as an ON sequence, all this before starting */
7.1667 + /* assembling chars for the opening L sequence. */
7.1668 + /* */
7.1669 + /* */
7.1670 + private static final short impTabProps[][] =
7.1671 + {
7.1672 +/* L, R, EN, AN, ON, S, B, ES, ET, CS, BN, NSM, AL, Res */
7.1673 +/* 0 Init */ { 1, 2, 4, 5, 7, 15, 17, 7, 9, 7, 0, 7, 3, _ON },
7.1674 +/* 1 L */ { 1, 32+2, 32+4, 32+5, 32+7, 32+15, 32+17, 32+7, 32+9, 32+7, 1, 1, 32+3, _L },
7.1675 +/* 2 R */ { 32+1, 2, 32+4, 32+5, 32+7, 32+15, 32+17, 32+7, 32+9, 32+7, 2, 2, 32+3, _R },
7.1676 +/* 3 AL */ { 32+1, 32+2, 32+6, 32+6, 32+8, 32+16, 32+17, 32+8, 32+8, 32+8, 3, 3, 3, _R },
7.1677 +/* 4 EN */ { 32+1, 32+2, 4, 32+5, 32+7, 32+15, 32+17, 64+10, 11, 64+10, 4, 4, 32+3, _EN },
7.1678 +/* 5 AN */ { 32+1, 32+2, 32+4, 5, 32+7, 32+15, 32+17, 32+7, 32+9, 64+12, 5, 5, 32+3, _AN },
7.1679 +/* 6 AL:EN/AN */ { 32+1, 32+2, 6, 6, 32+8, 32+16, 32+17, 32+8, 32+8, 64+13, 6, 6, 32+3, _AN },
7.1680 +/* 7 ON */ { 32+1, 32+2, 32+4, 32+5, 7, 32+15, 32+17, 7, 64+14, 7, 7, 7, 32+3, _ON },
7.1681 +/* 8 AL:ON */ { 32+1, 32+2, 32+6, 32+6, 8, 32+16, 32+17, 8, 8, 8, 8, 8, 32+3, _ON },
7.1682 +/* 9 ET */ { 32+1, 32+2, 4, 32+5, 7, 32+15, 32+17, 7, 9, 7, 9, 9, 32+3, _ON },
7.1683 +/*10 EN+ES/CS */ { 96+1, 96+2, 4, 96+5, 128+7, 96+15, 96+17, 128+7,128+14, 128+7, 10, 128+7, 96+3, _EN },
7.1684 +/*11 EN+ET */ { 32+1, 32+2, 4, 32+5, 32+7, 32+15, 32+17, 32+7, 11, 32+7, 11, 11, 32+3, _EN },
7.1685 +/*12 AN+CS */ { 96+1, 96+2, 96+4, 5, 128+7, 96+15, 96+17, 128+7,128+14, 128+7, 12, 128+7, 96+3, _AN },
7.1686 +/*13 AL:EN/AN+CS */ { 96+1, 96+2, 6, 6, 128+8, 96+16, 96+17, 128+8, 128+8, 128+8, 13, 128+8, 96+3, _AN },
7.1687 +/*14 ON+ET */ { 32+1, 32+2, 128+4, 32+5, 7, 32+15, 32+17, 7, 14, 7, 14, 14, 32+3, _ON },
7.1688 +/*15 S */ { 32+1, 32+2, 32+4, 32+5, 32+7, 15, 32+17, 32+7, 32+9, 32+7, 15, 32+7, 32+3, _S },
7.1689 +/*16 AL:S */ { 32+1, 32+2, 32+6, 32+6, 32+8, 16, 32+17, 32+8, 32+8, 32+8, 16, 32+8, 32+3, _S },
7.1690 +/*17 B */ { 32+1, 32+2, 32+4, 32+5, 32+7, 32+15, 17, 32+7, 32+9, 32+7, 17, 32+7, 32+3, _B }
7.1691 + };
7.1692 +
7.1693 + /*********************************************************************/
7.1694 + /* The levels state machine tables */
7.1695 + /*********************************************************************/
7.1696 + /* */
7.1697 + /* All table cells are 8 bits: */
7.1698 + /* bits 0..3: next state */
7.1699 + /* bits 4..7: action to perform (if > 0) */
7.1700 + /* */
7.1701 + /* Cells may be of format "n" where n represents the next state */
7.1702 + /* (except for the rightmost column). */
7.1703 + /* Cells may also be of format "_(x,y)" where x represents an action */
7.1704 + /* to perform and y represents the next state. */
7.1705 + /* */
7.1706 + /* This format limits each table to 16 states each and to 15 actions.*/
7.1707 + /* */
7.1708 + /*********************************************************************/
7.1709 + /* Definitions and type for levels state tables */
7.1710 + /*********************************************************************/
7.1711 + private static final int IMPTABLEVELS_COLUMNS = _B + 2;
7.1712 + private static final int IMPTABLEVELS_RES = IMPTABLEVELS_COLUMNS - 1;
7.1713 + private static short GetState(byte cell) { return (short)(cell & 0x0f); }
7.1714 + private static short GetAction(byte cell) { return (short)(cell >> 4); }
7.1715 +
7.1716 + private static class ImpTabPair {
7.1717 + byte[][][] imptab;
7.1718 + short[][] impact;
7.1719 +
7.1720 + ImpTabPair(byte[][] table1, byte[][] table2,
7.1721 + short[] act1, short[] act2) {
7.1722 + imptab = new byte[][][] {table1, table2};
7.1723 + impact = new short[][] {act1, act2};
7.1724 + }
7.1725 + }
7.1726 +
7.1727 + /*********************************************************************/
7.1728 + /* */
7.1729 + /* LEVELS STATE TABLES */
7.1730 + /* */
7.1731 + /* In all levels state tables, */
7.1732 + /* - state 0 is the initial state */
7.1733 + /* - the Res column is the increment to add to the text level */
7.1734 + /* for this property sequence. */
7.1735 + /* */
7.1736 + /* The impact arrays for each table of a pair map the local action */
7.1737 + /* numbers of the table to the total list of actions. For instance, */
7.1738 + /* action 2 in a given table corresponds to the action number which */
7.1739 + /* appears in entry [2] of the impact array for that table. */
7.1740 + /* The first entry of all impact arrays must be 0. */
7.1741 + /* */
7.1742 + /* Action 1: init conditional sequence */
7.1743 + /* 2: prepend conditional sequence to current sequence */
7.1744 + /* 3: set ON sequence to new level - 1 */
7.1745 + /* 4: init EN/AN/ON sequence */
7.1746 + /* 5: fix EN/AN/ON sequence followed by R */
7.1747 + /* 6: set previous level sequence to level 2 */
7.1748 + /* */
7.1749 + /* Notes: */
7.1750 + /* 1) These tables are used in processPropertySeq(). The input */
7.1751 + /* is property sequences as determined by resolveImplicitLevels. */
7.1752 + /* 2) Most such property sequences are processed immediately */
7.1753 + /* (levels are assigned). */
7.1754 + /* 3) However, some sequences cannot be assigned a final level till */
7.1755 + /* one or more following sequences are received. For instance, */
7.1756 + /* ON following an R sequence within an even-level paragraph. */
7.1757 + /* If the following sequence is R, the ON sequence will be */
7.1758 + /* assigned basic run level+1, and so will the R sequence. */
7.1759 + /* 4) S is generally handled like ON, since its level will be fixed */
7.1760 + /* to paragraph level in adjustWSLevels(). */
7.1761 + /* */
7.1762 +
7.1763 + private static final byte impTabL_DEFAULT[][] = /* Even paragraph level */
7.1764 + /* In this table, conditional sequences receive the higher possible level
7.1765 + until proven otherwise.
7.1766 + */
7.1767 + {
7.1768 + /* L, R, EN, AN, ON, S, B, Res */
7.1769 + /* 0 : init */ { 0, 1, 0, 2, 0, 0, 0, 0 },
7.1770 + /* 1 : R */ { 0, 1, 3, 3, 0x14, 0x14, 0, 1 },
7.1771 + /* 2 : AN */ { 0, 1, 0, 2, 0x15, 0x15, 0, 2 },
7.1772 + /* 3 : R+EN/AN */ { 0, 1, 3, 3, 0x14, 0x14, 0, 2 },
7.1773 + /* 4 : R+ON */ { 0x20, 1, 3, 3, 4, 4, 0x20, 1 },
7.1774 + /* 5 : AN+ON */ { 0x20, 1, 0x20, 2, 5, 5, 0x20, 1 }
7.1775 + };
7.1776 +
7.1777 + private static final byte impTabR_DEFAULT[][] = /* Odd paragraph level */
7.1778 + /* In this table, conditional sequences receive the lower possible level
7.1779 + until proven otherwise.
7.1780 + */
7.1781 + {
7.1782 + /* L, R, EN, AN, ON, S, B, Res */
7.1783 + /* 0 : init */ { 1, 0, 2, 2, 0, 0, 0, 0 },
7.1784 + /* 1 : L */ { 1, 0, 1, 3, 0x14, 0x14, 0, 1 },
7.1785 + /* 2 : EN/AN */ { 1, 0, 2, 2, 0, 0, 0, 1 },
7.1786 + /* 3 : L+AN */ { 1, 0, 1, 3, 5, 5, 0, 1 },
7.1787 + /* 4 : L+ON */ { 0x21, 0, 0x21, 3, 4, 4, 0, 0 },
7.1788 + /* 5 : L+AN+ON */ { 1, 0, 1, 3, 5, 5, 0, 0 }
7.1789 + };
7.1790 +
7.1791 + private static final short[] impAct0 = {0,1,2,3,4,5,6};
7.1792 +
7.1793 + private static final ImpTabPair impTab_DEFAULT = new ImpTabPair(
7.1794 + impTabL_DEFAULT, impTabR_DEFAULT, impAct0, impAct0);
7.1795 +
7.1796 + private static final byte impTabL_NUMBERS_SPECIAL[][] = { /* Even paragraph level */
7.1797 + /* In this table, conditional sequences receive the higher possible
7.1798 + level until proven otherwise.
7.1799 + */
7.1800 + /* L, R, EN, AN, ON, S, B, Res */
7.1801 + /* 0 : init */ { 0, 2, 1, 1, 0, 0, 0, 0 },
7.1802 + /* 1 : L+EN/AN */ { 0, 2, 1, 1, 0, 0, 0, 2 },
7.1803 + /* 2 : R */ { 0, 2, 4, 4, 0x13, 0, 0, 1 },
7.1804 + /* 3 : R+ON */ { 0x20, 2, 4, 4, 3, 3, 0x20, 1 },
7.1805 + /* 4 : R+EN/AN */ { 0, 2, 4, 4, 0x13, 0x13, 0, 2 }
7.1806 + };
7.1807 + private static final ImpTabPair impTab_NUMBERS_SPECIAL = new ImpTabPair(
7.1808 + impTabL_NUMBERS_SPECIAL, impTabR_DEFAULT, impAct0, impAct0);
7.1809 +
7.1810 + private static final byte impTabL_GROUP_NUMBERS_WITH_R[][] = {
7.1811 + /* In this table, EN/AN+ON sequences receive levels as if associated with R
7.1812 + until proven that there is L or sor/eor on both sides. AN is handled like EN.
7.1813 + */
7.1814 + /* L, R, EN, AN, ON, S, B, Res */
7.1815 + /* 0 init */ { 0, 3, 0x11, 0x11, 0, 0, 0, 0 },
7.1816 + /* 1 EN/AN */ { 0x20, 3, 1, 1, 2, 0x20, 0x20, 2 },
7.1817 + /* 2 EN/AN+ON */ { 0x20, 3, 1, 1, 2, 0x20, 0x20, 1 },
7.1818 + /* 3 R */ { 0, 3, 5, 5, 0x14, 0, 0, 1 },
7.1819 + /* 4 R+ON */ { 0x20, 3, 5, 5, 4, 0x20, 0x20, 1 },
7.1820 + /* 5 R+EN/AN */ { 0, 3, 5, 5, 0x14, 0, 0, 2 }
7.1821 + };
7.1822 + private static final byte impTabR_GROUP_NUMBERS_WITH_R[][] = {
7.1823 + /* In this table, EN/AN+ON sequences receive levels as if associated with R
7.1824 + until proven that there is L on both sides. AN is handled like EN.
7.1825 + */
7.1826 + /* L, R, EN, AN, ON, S, B, Res */
7.1827 + /* 0 init */ { 2, 0, 1, 1, 0, 0, 0, 0 },
7.1828 + /* 1 EN/AN */ { 2, 0, 1, 1, 0, 0, 0, 1 },
7.1829 + /* 2 L */ { 2, 0, 0x14, 0x14, 0x13, 0, 0, 1 },
7.1830 + /* 3 L+ON */ { 0x22, 0, 4, 4, 3, 0, 0, 0 },
7.1831 + /* 4 L+EN/AN */ { 0x22, 0, 4, 4, 3, 0, 0, 1 }
7.1832 + };
7.1833 + private static final ImpTabPair impTab_GROUP_NUMBERS_WITH_R = new
7.1834 + ImpTabPair(impTabL_GROUP_NUMBERS_WITH_R,
7.1835 + impTabR_GROUP_NUMBERS_WITH_R, impAct0, impAct0);
7.1836 +
7.1837 + private static final byte impTabL_INVERSE_NUMBERS_AS_L[][] = {
7.1838 + /* This table is identical to the Default LTR table except that EN and AN
7.1839 + are handled like L.
7.1840 + */
7.1841 + /* L, R, EN, AN, ON, S, B, Res */
7.1842 + /* 0 : init */ { 0, 1, 0, 0, 0, 0, 0, 0 },
7.1843 + /* 1 : R */ { 0, 1, 0, 0, 0x14, 0x14, 0, 1 },
7.1844 + /* 2 : AN */ { 0, 1, 0, 0, 0x15, 0x15, 0, 2 },
7.1845 + /* 3 : R+EN/AN */ { 0, 1, 0, 0, 0x14, 0x14, 0, 2 },
7.1846 + /* 4 : R+ON */ { 0x20, 1, 0x20, 0x20, 4, 4, 0x20, 1 },
7.1847 + /* 5 : AN+ON */ { 0x20, 1, 0x20, 0x20, 5, 5, 0x20, 1 }
7.1848 + };
7.1849 + private static final byte impTabR_INVERSE_NUMBERS_AS_L[][] = {
7.1850 + /* This table is identical to the Default RTL table except that EN and AN
7.1851 + are handled like L.
7.1852 + */
7.1853 + /* L, R, EN, AN, ON, S, B, Res */
7.1854 + /* 0 : init */ { 1, 0, 1, 1, 0, 0, 0, 0 },
7.1855 + /* 1 : L */ { 1, 0, 1, 1, 0x14, 0x14, 0, 1 },
7.1856 + /* 2 : EN/AN */ { 1, 0, 1, 1, 0, 0, 0, 1 },
7.1857 + /* 3 : L+AN */ { 1, 0, 1, 1, 5, 5, 0, 1 },
7.1858 + /* 4 : L+ON */ { 0x21, 0, 0x21, 0x21, 4, 4, 0, 0 },
7.1859 + /* 5 : L+AN+ON */ { 1, 0, 1, 1, 5, 5, 0, 0 }
7.1860 + };
7.1861 + private static final ImpTabPair impTab_INVERSE_NUMBERS_AS_L = new ImpTabPair
7.1862 + (impTabL_INVERSE_NUMBERS_AS_L, impTabR_INVERSE_NUMBERS_AS_L,
7.1863 + impAct0, impAct0);
7.1864 +
7.1865 + private static final byte impTabR_INVERSE_LIKE_DIRECT[][] = { /* Odd paragraph level */
7.1866 + /* In this table, conditional sequences receive the lower possible level
7.1867 + until proven otherwise.
7.1868 + */
7.1869 + /* L, R, EN, AN, ON, S, B, Res */
7.1870 + /* 0 : init */ { 1, 0, 2, 2, 0, 0, 0, 0 },
7.1871 + /* 1 : L */ { 1, 0, 1, 2, 0x13, 0x13, 0, 1 },
7.1872 + /* 2 : EN/AN */ { 1, 0, 2, 2, 0, 0, 0, 1 },
7.1873 + /* 3 : L+ON */ { 0x21, 0x30, 6, 4, 3, 3, 0x30, 0 },
7.1874 + /* 4 : L+ON+AN */ { 0x21, 0x30, 6, 4, 5, 5, 0x30, 3 },
7.1875 + /* 5 : L+AN+ON */ { 0x21, 0x30, 6, 4, 5, 5, 0x30, 2 },
7.1876 + /* 6 : L+ON+EN */ { 0x21, 0x30, 6, 4, 3, 3, 0x30, 1 }
7.1877 + };
7.1878 + private static final short[] impAct1 = {0,1,11,12};
7.1879 + private static final ImpTabPair impTab_INVERSE_LIKE_DIRECT = new ImpTabPair(
7.1880 + impTabL_DEFAULT, impTabR_INVERSE_LIKE_DIRECT, impAct0, impAct1);
7.1881 +
7.1882 + private static final byte impTabL_INVERSE_LIKE_DIRECT_WITH_MARKS[][] = {
7.1883 + /* The case handled in this table is (visually): R EN L
7.1884 + */
7.1885 + /* L, R, EN, AN, ON, S, B, Res */
7.1886 + /* 0 : init */ { 0, 0x63, 0, 1, 0, 0, 0, 0 },
7.1887 + /* 1 : L+AN */ { 0, 0x63, 0, 1, 0x12, 0x30, 0, 4 },
7.1888 + /* 2 : L+AN+ON */ { 0x20, 0x63, 0x20, 1, 2, 0x30, 0x20, 3 },
7.1889 + /* 3 : R */ { 0, 0x63, 0x55, 0x56, 0x14, 0x30, 0, 3 },
7.1890 + /* 4 : R+ON */ { 0x30, 0x43, 0x55, 0x56, 4, 0x30, 0x30, 3 },
7.1891 + /* 5 : R+EN */ { 0x30, 0x43, 5, 0x56, 0x14, 0x30, 0x30, 4 },
7.1892 + /* 6 : R+AN */ { 0x30, 0x43, 0x55, 6, 0x14, 0x30, 0x30, 4 }
7.1893 + };
7.1894 + private static final byte impTabR_INVERSE_LIKE_DIRECT_WITH_MARKS[][] = {
7.1895 + /* The cases handled in this table are (visually): R EN L
7.1896 + R L AN L
7.1897 + */
7.1898 + /* L, R, EN, AN, ON, S, B, Res */
7.1899 + /* 0 : init */ { 0x13, 0, 1, 1, 0, 0, 0, 0 },
7.1900 + /* 1 : R+EN/AN */ { 0x23, 0, 1, 1, 2, 0x40, 0, 1 },
7.1901 + /* 2 : R+EN/AN+ON */ { 0x23, 0, 1, 1, 2, 0x40, 0, 0 },
7.1902 + /* 3 : L */ { 3 , 0, 3, 0x36, 0x14, 0x40, 0, 1 },
7.1903 + /* 4 : L+ON */ { 0x53, 0x40, 5, 0x36, 4, 0x40, 0x40, 0 },
7.1904 + /* 5 : L+ON+EN */ { 0x53, 0x40, 5, 0x36, 4, 0x40, 0x40, 1 },
7.1905 + /* 6 : L+AN */ { 0x53, 0x40, 6, 6, 4, 0x40, 0x40, 3 }
7.1906 + };
7.1907 + private static final short impAct2[] = {0,1,7,8,9,10};
7.1908 + private static final ImpTabPair impTab_INVERSE_LIKE_DIRECT_WITH_MARKS =
7.1909 + new ImpTabPair(impTabL_INVERSE_LIKE_DIRECT_WITH_MARKS,
7.1910 + impTabR_INVERSE_LIKE_DIRECT_WITH_MARKS, impAct0, impAct2);
7.1911 +
7.1912 + private static final ImpTabPair impTab_INVERSE_FOR_NUMBERS_SPECIAL = new ImpTabPair(
7.1913 + impTabL_NUMBERS_SPECIAL, impTabR_INVERSE_LIKE_DIRECT, impAct0, impAct1);
7.1914 +
7.1915 + private static final byte impTabL_INVERSE_FOR_NUMBERS_SPECIAL_WITH_MARKS[][] = {
7.1916 + /* The case handled in this table is (visually): R EN L
7.1917 + */
7.1918 + /* L, R, EN, AN, ON, S, B, Res */
7.1919 + /* 0 : init */ { 0, 0x62, 1, 1, 0, 0, 0, 0 },
7.1920 + /* 1 : L+EN/AN */ { 0, 0x62, 1, 1, 0, 0x30, 0, 4 },
7.1921 + /* 2 : R */ { 0, 0x62, 0x54, 0x54, 0x13, 0x30, 0, 3 },
7.1922 + /* 3 : R+ON */ { 0x30, 0x42, 0x54, 0x54, 3, 0x30, 0x30, 3 },
7.1923 + /* 4 : R+EN/AN */ { 0x30, 0x42, 4, 4, 0x13, 0x30, 0x30, 4 }
7.1924 + };
7.1925 + private static final ImpTabPair impTab_INVERSE_FOR_NUMBERS_SPECIAL_WITH_MARKS = new
7.1926 + ImpTabPair(impTabL_INVERSE_FOR_NUMBERS_SPECIAL_WITH_MARKS,
7.1927 + impTabR_INVERSE_LIKE_DIRECT_WITH_MARKS, impAct0, impAct2);
7.1928 +
7.1929 + private class LevState {
7.1930 + byte[][] impTab; /* level table pointer */
7.1931 + short[] impAct; /* action map array */
7.1932 + int startON; /* start of ON sequence */
7.1933 + int startL2EN; /* start of level 2 sequence */
7.1934 + int lastStrongRTL; /* index of last found R or AL */
7.1935 + short state; /* current state */
7.1936 + byte runLevel; /* run level before implicit solving */
7.1937 + }
7.1938 +
7.1939 + /*------------------------------------------------------------------------*/
7.1940 +
7.1941 + static final int FIRSTALLOC = 10;
7.1942 + /*
7.1943 + * param pos: position where to insert
7.1944 + * param flag: one of LRM_BEFORE, LRM_AFTER, RLM_BEFORE, RLM_AFTER
7.1945 + */
7.1946 + private void addPoint(int pos, int flag)
7.1947 + {
7.1948 + Point point = new Point();
7.1949 +
7.1950 + int len = insertPoints.points.length;
7.1951 + if (len == 0) {
7.1952 + insertPoints.points = new Point[FIRSTALLOC];
7.1953 + len = FIRSTALLOC;
7.1954 + }
7.1955 + if (insertPoints.size >= len) { /* no room for new point */
7.1956 + Point[] savePoints = insertPoints.points;
7.1957 + insertPoints.points = new Point[len * 2];
7.1958 + System.arraycopy(savePoints, 0, insertPoints.points, 0, len);
7.1959 + }
7.1960 + point.pos = pos;
7.1961 + point.flag = flag;
7.1962 + insertPoints.points[insertPoints.size] = point;
7.1963 + insertPoints.size++;
7.1964 + }
7.1965 +
7.1966 + /* perform rules (Wn), (Nn), and (In) on a run of the text ------------------ */
7.1967 +
7.1968 + /*
7.1969 + * This implementation of the (Wn) rules applies all rules in one pass.
7.1970 + * In order to do so, it needs a look-ahead of typically 1 character
7.1971 + * (except for W5: sequences of ET) and keeps track of changes
7.1972 + * in a rule Wp that affect a later Wq (p<q).
7.1973 + *
7.1974 + * The (Nn) and (In) rules are also performed in that same single loop,
7.1975 + * but effectively one iteration behind for white space.
7.1976 + *
7.1977 + * Since all implicit rules are performed in one step, it is not necessary
7.1978 + * to actually store the intermediate directional properties in dirProps[].
7.1979 + */
7.1980 +
7.1981 + private void processPropertySeq(LevState levState, short _prop,
7.1982 + int start, int limit) {
7.1983 + byte cell;
7.1984 + byte[][] impTab = levState.impTab;
7.1985 + short[] impAct = levState.impAct;
7.1986 + short oldStateSeq,actionSeq;
7.1987 + byte level, addLevel;
7.1988 + int start0, k;
7.1989 +
7.1990 + start0 = start; /* save original start position */
7.1991 + oldStateSeq = levState.state;
7.1992 + cell = impTab[oldStateSeq][_prop];
7.1993 + levState.state = GetState(cell); /* isolate the new state */
7.1994 + actionSeq = impAct[GetAction(cell)]; /* isolate the action */
7.1995 + addLevel = (byte)impTab[levState.state][IMPTABLEVELS_RES];
7.1996 +
7.1997 + if (actionSeq != 0) {
7.1998 + switch (actionSeq) {
7.1999 + case 1: /* init ON seq */
7.2000 + levState.startON = start0;
7.2001 + break;
7.2002 +
7.2003 + case 2: /* prepend ON seq to current seq */
7.2004 + start = levState.startON;
7.2005 + break;
7.2006 +
7.2007 + case 3: /* L or S after possible relevant EN/AN */
7.2008 + /* check if we had EN after R/AL */
7.2009 + if (levState.startL2EN >= 0) {
7.2010 + addPoint(levState.startL2EN, LRM_BEFORE);
7.2011 + }
7.2012 + levState.startL2EN = -1; /* not within previous if since could also be -2 */
7.2013 + /* check if we had any relevant EN/AN after R/AL */
7.2014 + if ((insertPoints.points.length == 0) ||
7.2015 + (insertPoints.size <= insertPoints.confirmed)) {
7.2016 + /* nothing, just clean up */
7.2017 + levState.lastStrongRTL = -1;
7.2018 + /* check if we have a pending conditional segment */
7.2019 + level = (byte)impTab[oldStateSeq][IMPTABLEVELS_RES];
7.2020 + if ((level & 1) != 0 && levState.startON > 0) { /* after ON */
7.2021 + start = levState.startON; /* reset to basic run level */
7.2022 + }
7.2023 + if (_prop == _S) { /* add LRM before S */
7.2024 + addPoint(start0, LRM_BEFORE);
7.2025 + insertPoints.confirmed = insertPoints.size;
7.2026 + }
7.2027 + break;
7.2028 + }
7.2029 + /* reset previous RTL cont to level for LTR text */
7.2030 + for (k = levState.lastStrongRTL + 1; k < start0; k++) {
7.2031 + /* reset odd level, leave runLevel+2 as is */
7.2032 + levels[k] = (byte)((levels[k] - 2) & ~1);
7.2033 + }
7.2034 + /* mark insert points as confirmed */
7.2035 + insertPoints.confirmed = insertPoints.size;
7.2036 + levState.lastStrongRTL = -1;
7.2037 + if (_prop == _S) { /* add LRM before S */
7.2038 + addPoint(start0, LRM_BEFORE);
7.2039 + insertPoints.confirmed = insertPoints.size;
7.2040 + }
7.2041 + break;
7.2042 +
7.2043 + case 4: /* R/AL after possible relevant EN/AN */
7.2044 + /* just clean up */
7.2045 + if (insertPoints.points.length > 0)
7.2046 + /* remove all non confirmed insert points */
7.2047 + insertPoints.size = insertPoints.confirmed;
7.2048 + levState.startON = -1;
7.2049 + levState.startL2EN = -1;
7.2050 + levState.lastStrongRTL = limit - 1;
7.2051 + break;
7.2052 +
7.2053 + case 5: /* EN/AN after R/AL + possible cont */
7.2054 + /* check for real AN */
7.2055 + if ((_prop == _AN) && (NoContextRTL(dirProps[start0]) == AN)) {
7.2056 + /* real AN */
7.2057 + if (levState.startL2EN == -1) { /* if no relevant EN already found */
7.2058 + /* just note the righmost digit as a strong RTL */
7.2059 + levState.lastStrongRTL = limit - 1;
7.2060 + break;
7.2061 + }
7.2062 + if (levState.startL2EN >= 0) { /* after EN, no AN */
7.2063 + addPoint(levState.startL2EN, LRM_BEFORE);
7.2064 + levState.startL2EN = -2;
7.2065 + }
7.2066 + /* note AN */
7.2067 + addPoint(start0, LRM_BEFORE);
7.2068 + break;
7.2069 + }
7.2070 + /* if first EN/AN after R/AL */
7.2071 + if (levState.startL2EN == -1) {
7.2072 + levState.startL2EN = start0;
7.2073 + }
7.2074 + break;
7.2075 +
7.2076 + case 6: /* note location of latest R/AL */
7.2077 + levState.lastStrongRTL = limit - 1;
7.2078 + levState.startON = -1;
7.2079 + break;
7.2080 +
7.2081 + case 7: /* L after R+ON/EN/AN */
7.2082 + /* include possible adjacent number on the left */
7.2083 + for (k = start0-1; k >= 0 && ((levels[k] & 1) == 0); k--) {
7.2084 + }
7.2085 + if (k >= 0) {
7.2086 + addPoint(k, RLM_BEFORE); /* add RLM before */
7.2087 + insertPoints.confirmed = insertPoints.size; /* confirm it */
7.2088 + }
7.2089 + levState.startON = start0;
7.2090 + break;
7.2091 +
7.2092 + case 8: /* AN after L */
7.2093 + /* AN numbers between L text on both sides may be trouble. */
7.2094 + /* tentatively bracket with LRMs; will be confirmed if followed by L */
7.2095 + addPoint(start0, LRM_BEFORE); /* add LRM before */
7.2096 + addPoint(start0, LRM_AFTER); /* add LRM after */
7.2097 + break;
7.2098 +
7.2099 + case 9: /* R after L+ON/EN/AN */
7.2100 + /* false alert, infirm LRMs around previous AN */
7.2101 + insertPoints.size=insertPoints.confirmed;
7.2102 + if (_prop == _S) { /* add RLM before S */
7.2103 + addPoint(start0, RLM_BEFORE);
7.2104 + insertPoints.confirmed = insertPoints.size;
7.2105 + }
7.2106 + break;
7.2107 +
7.2108 + case 10: /* L after L+ON/AN */
7.2109 + level = (byte)(levState.runLevel + addLevel);
7.2110 + for (k=levState.startON; k < start0; k++) {
7.2111 + if (levels[k] < level) {
7.2112 + levels[k] = level;
7.2113 + }
7.2114 + }
7.2115 + insertPoints.confirmed = insertPoints.size; /* confirm inserts */
7.2116 + levState.startON = start0;
7.2117 + break;
7.2118 +
7.2119 + case 11: /* L after L+ON+EN/AN/ON */
7.2120 + level = (byte)levState.runLevel;
7.2121 + for (k = start0-1; k >= levState.startON; k--) {
7.2122 + if (levels[k] == level+3) {
7.2123 + while (levels[k] == level+3) {
7.2124 + levels[k--] -= 2;
7.2125 + }
7.2126 + while (levels[k] == level) {
7.2127 + k--;
7.2128 + }
7.2129 + }
7.2130 + if (levels[k] == level+2) {
7.2131 + levels[k] = level;
7.2132 + continue;
7.2133 + }
7.2134 + levels[k] = (byte)(level+1);
7.2135 + }
7.2136 + break;
7.2137 +
7.2138 + case 12: /* R after L+ON+EN/AN/ON */
7.2139 + level = (byte)(levState.runLevel+1);
7.2140 + for (k = start0-1; k >= levState.startON; k--) {
7.2141 + if (levels[k] > level) {
7.2142 + levels[k] -= 2;
7.2143 + }
7.2144 + }
7.2145 + break;
7.2146 +
7.2147 + default: /* we should never get here */
7.2148 + throw new IllegalStateException("Internal ICU error in processPropertySeq");
7.2149 + }
7.2150 + }
7.2151 + if ((addLevel) != 0 || (start < start0)) {
7.2152 + level = (byte)(levState.runLevel + addLevel);
7.2153 + for (k = start; k < limit; k++) {
7.2154 + levels[k] = level;
7.2155 + }
7.2156 + }
7.2157 + }
7.2158 +
7.2159 + private void resolveImplicitLevels(int start, int limit, short sor, short eor)
7.2160 + {
7.2161 + LevState levState = new LevState();
7.2162 + int i, start1, start2;
7.2163 + short oldStateImp, stateImp, actionImp;
7.2164 + short gprop, resProp, cell;
7.2165 + short nextStrongProp = R;
7.2166 + int nextStrongPos = -1;
7.2167 +
7.2168 +
7.2169 + /* check for RTL inverse Bidi mode */
7.2170 + /* FOOD FOR THOUGHT: in case of RTL inverse Bidi, it would make sense to
7.2171 + * loop on the text characters from end to start.
7.2172 + * This would need a different properties state table (at least different
7.2173 + * actions) and different levels state tables (maybe very similar to the
7.2174 + * LTR corresponding ones.
7.2175 + */
7.2176 + /* initialize for levels state table */
7.2177 + levState.startL2EN = -1; /* used for INVERSE_LIKE_DIRECT_WITH_MARKS */
7.2178 + levState.lastStrongRTL = -1; /* used for INVERSE_LIKE_DIRECT_WITH_MARKS */
7.2179 + levState.state = 0;
7.2180 + levState.runLevel = levels[start];
7.2181 + levState.impTab = impTabPair.imptab[levState.runLevel & 1];
7.2182 + levState.impAct = impTabPair.impact[levState.runLevel & 1];
7.2183 + processPropertySeq(levState, (short)sor, start, start);
7.2184 + /* initialize for property state table */
7.2185 + if (dirProps[start] == NSM) {
7.2186 + stateImp = (short)(1 + sor);
7.2187 + } else {
7.2188 + stateImp = 0;
7.2189 + }
7.2190 + start1 = start;
7.2191 + start2 = 0;
7.2192 +
7.2193 + for (i = start; i <= limit; i++) {
7.2194 + if (i >= limit) {
7.2195 + gprop = eor;
7.2196 + } else {
7.2197 + short prop, prop1;
7.2198 + prop = NoContextRTL(dirProps[i]);
7.2199 + gprop = groupProp[prop];
7.2200 + }
7.2201 + oldStateImp = stateImp;
7.2202 + cell = impTabProps[oldStateImp][gprop];
7.2203 + stateImp = GetStateProps(cell); /* isolate the new state */
7.2204 + actionImp = GetActionProps(cell); /* isolate the action */
7.2205 + if ((i == limit) && (actionImp == 0)) {
7.2206 + /* there is an unprocessed sequence if its property == eor */
7.2207 + actionImp = 1; /* process the last sequence */
7.2208 + }
7.2209 + if (actionImp != 0) {
7.2210 + resProp = impTabProps[oldStateImp][IMPTABPROPS_RES];
7.2211 + switch (actionImp) {
7.2212 + case 1: /* process current seq1, init new seq1 */
7.2213 + processPropertySeq(levState, resProp, start1, i);
7.2214 + start1 = i;
7.2215 + break;
7.2216 + case 2: /* init new seq2 */
7.2217 + start2 = i;
7.2218 + break;
7.2219 + case 3: /* process seq1, process seq2, init new seq1 */
7.2220 + processPropertySeq(levState, resProp, start1, start2);
7.2221 + processPropertySeq(levState, _ON, start2, i);
7.2222 + start1 = i;
7.2223 + break;
7.2224 + case 4: /* process seq1, set seq1=seq2, init new seq2 */
7.2225 + processPropertySeq(levState, resProp, start1, start2);
7.2226 + start1 = start2;
7.2227 + start2 = i;
7.2228 + break;
7.2229 + default: /* we should never get here */
7.2230 + throw new IllegalStateException("Internal ICU error in resolveImplicitLevels");
7.2231 + }
7.2232 + }
7.2233 + }
7.2234 + /* flush possible pending sequence, e.g. ON */
7.2235 + processPropertySeq(levState, (short)eor, limit, limit);
7.2236 + }
7.2237 +
7.2238 + /* perform (L1) and (X9) ---------------------------------------------------- */
7.2239 +
7.2240 + /*
7.2241 + * Reset the embedding levels for some non-graphic characters (L1).
7.2242 + * This method also sets appropriate levels for BN, and
7.2243 + * explicit embedding types that are supposed to have been removed
7.2244 + * from the paragraph in (X9).
7.2245 + */
7.2246 + private void adjustWSLevels() {
7.2247 + int i;
7.2248 +
7.2249 + if ((flags & MASK_WS) != 0) {
7.2250 + int flag;
7.2251 + i = trailingWSStart;
7.2252 + while (i > 0) {
7.2253 + /* reset a sequence of WS/BN before eop and B/S to the paragraph paraLevel */
7.2254 + while (i > 0 && ((flag = DirPropFlagNC(dirProps[--i])) & MASK_WS) != 0) {
7.2255 + if (orderParagraphsLTR && (flag & DirPropFlag(B)) != 0) {
7.2256 + levels[i] = 0;
7.2257 + } else {
7.2258 + levels[i] = GetParaLevelAt(i);
7.2259 + }
7.2260 + }
7.2261 +
7.2262 + /* reset BN to the next character's paraLevel until B/S, which restarts above loop */
7.2263 + /* here, i+1 is guaranteed to be <length */
7.2264 + while (i > 0) {
7.2265 + flag = DirPropFlagNC(dirProps[--i]);
7.2266 + if ((flag & MASK_BN_EXPLICIT) != 0) {
7.2267 + levels[i] = levels[i + 1];
7.2268 + } else if (orderParagraphsLTR && (flag & DirPropFlag(B)) != 0) {
7.2269 + levels[i] = 0;
7.2270 + break;
7.2271 + } else if ((flag & MASK_B_S) != 0){
7.2272 + levels[i] = GetParaLevelAt(i);
7.2273 + break;
7.2274 + }
7.2275 + }
7.2276 + }
7.2277 + }
7.2278 + }
7.2279 +
7.2280 + private int Bidi_Min(int x, int y) {
7.2281 + return x < y ? x : y;
7.2282 + }
7.2283 +
7.2284 + private int Bidi_Abs(int x) {
7.2285 + return x >= 0 ? x : -x;
7.2286 + }
7.2287 +
7.2288 + /**
7.2289 + * Perform the Unicode Bidi algorithm. It is defined in the
7.2290 + * <a href="http://www.unicode.org/unicode/reports/tr9/">Unicode Standard Annex #9</a>,
7.2291 + * version 13,
7.2292 + * also described in The Unicode Standard, Version 4.0 .<p>
7.2293 + *
7.2294 + * This method takes a piece of plain text containing one or more paragraphs,
7.2295 + * with or without externally specified embedding levels from <i>styled</i>
7.2296 + * text and computes the left-right-directionality of each character.<p>
7.2297 + *
7.2298 + * If the entire text is all of the same directionality, then
7.2299 + * the method may not perform all the steps described by the algorithm,
7.2300 + * i.e., some levels may not be the same as if all steps were performed.
7.2301 + * This is not relevant for unidirectional text.<br>
7.2302 + * For example, in pure LTR text with numbers the numbers would get
7.2303 + * a resolved level of 2 higher than the surrounding text according to
7.2304 + * the algorithm. This implementation may set all resolved levels to
7.2305 + * the same value in such a case.<p>
7.2306 + *
7.2307 + * The text can be composed of multiple paragraphs. Occurrence of a block
7.2308 + * separator in the text terminates a paragraph, and whatever comes next starts
7.2309 + * a new paragraph. The exception to this rule is when a Carriage Return (CR)
7.2310 + * is followed by a Line Feed (LF). Both CR and LF are block separators, but
7.2311 + * in that case, the pair of characters is considered as terminating the
7.2312 + * preceding paragraph, and a new paragraph will be started by a character
7.2313 + * coming after the LF.
7.2314 + *
7.2315 + * Although the text is passed here as a <code>String</code>, it is
7.2316 + * stored internally as an array of characters. Therefore the
7.2317 + * documentation will refer to indexes of the characters in the text.
7.2318 + *
7.2319 + * @param text contains the text that the Bidi algorithm will be performed
7.2320 + * on. This text can be retrieved with <code>getText()</code> or
7.2321 + * <code>getTextAsString</code>.<br>
7.2322 + *
7.2323 + * @param paraLevel specifies the default level for the text;
7.2324 + * it is typically 0 (LTR) or 1 (RTL).
7.2325 + * If the method shall determine the paragraph level from the text,
7.2326 + * then <code>paraLevel</code> can be set to
7.2327 + * either <code>LEVEL_DEFAULT_LTR</code>
7.2328 + * or <code>LEVEL_DEFAULT_RTL</code>; if the text contains multiple
7.2329 + * paragraphs, the paragraph level shall be determined separately for
7.2330 + * each paragraph; if a paragraph does not include any strongly typed
7.2331 + * character, then the desired default is used (0 for LTR or 1 for RTL).
7.2332 + * Any other value between 0 and <code>MAX_EXPLICIT_LEVEL</code>
7.2333 + * is also valid, with odd levels indicating RTL.
7.2334 + *
7.2335 + * @param embeddingLevels (in) may be used to preset the embedding and override levels,
7.2336 + * ignoring characters like LRE and PDF in the text.
7.2337 + * A level overrides the directional property of its corresponding
7.2338 + * (same index) character if the level has the
7.2339 + * <code>LEVEL_OVERRIDE</code> bit set.<br><br>
7.2340 + * Except for that bit, it must be
7.2341 + * <code>paraLevel<=embeddingLevels[]<=MAX_EXPLICIT_LEVEL</code>,
7.2342 + * with one exception: a level of zero may be specified for a
7.2343 + * paragraph separator even if <code>paraLevel>0</code> when multiple
7.2344 + * paragraphs are submitted in the same call to <code>setPara()</code>.<br><br>
7.2345 + * <strong>Caution: </strong>A reference to this array, not a copy
7.2346 + * of the levels, will be stored in the <code>Bidi</code> object;
7.2347 + * the <code>embeddingLevels</code>
7.2348 + * should not be modified to avoid unexpected results on subsequent
7.2349 + * Bidi operations. However, the <code>setPara()</code> and
7.2350 + * <code>setLine()</code> methods may modify some or all of the
7.2351 + * levels.<br><br>
7.2352 + * <strong>Note:</strong> the <code>embeddingLevels</code> array must
7.2353 + * have one entry for each character in <code>text</code>.
7.2354 + *
7.2355 + * @throws IllegalArgumentException if the values in embeddingLevels are
7.2356 + * not within the allowed range
7.2357 + *
7.2358 + * @see #LEVEL_DEFAULT_LTR
7.2359 + * @see #LEVEL_DEFAULT_RTL
7.2360 + * @see #LEVEL_OVERRIDE
7.2361 + * @see #MAX_EXPLICIT_LEVEL
7.2362 + * @stable ICU 3.8
7.2363 + */
7.2364 + void setPara(String text, byte paraLevel, byte[] embeddingLevels)
7.2365 + {
7.2366 + if (text == null) {
7.2367 + setPara(new char[0], paraLevel, embeddingLevels);
7.2368 + } else {
7.2369 + setPara(text.toCharArray(), paraLevel, embeddingLevels);
7.2370 + }
7.2371 + }
7.2372 +
7.2373 + /**
7.2374 + * Perform the Unicode Bidi algorithm. It is defined in the
7.2375 + * <a href="http://www.unicode.org/unicode/reports/tr9/">Unicode Standard Annex #9</a>,
7.2376 + * version 13,
7.2377 + * also described in The Unicode Standard, Version 4.0 .<p>
7.2378 + *
7.2379 + * This method takes a piece of plain text containing one or more paragraphs,
7.2380 + * with or without externally specified embedding levels from <i>styled</i>
7.2381 + * text and computes the left-right-directionality of each character.<p>
7.2382 + *
7.2383 + * If the entire text is all of the same directionality, then
7.2384 + * the method may not perform all the steps described by the algorithm,
7.2385 + * i.e., some levels may not be the same as if all steps were performed.
7.2386 + * This is not relevant for unidirectional text.<br>
7.2387 + * For example, in pure LTR text with numbers the numbers would get
7.2388 + * a resolved level of 2 higher than the surrounding text according to
7.2389 + * the algorithm. This implementation may set all resolved levels to
7.2390 + * the same value in such a case.<p>
7.2391 + *
7.2392 + * The text can be composed of multiple paragraphs. Occurrence of a block
7.2393 + * separator in the text terminates a paragraph, and whatever comes next starts
7.2394 + * a new paragraph. The exception to this rule is when a Carriage Return (CR)
7.2395 + * is followed by a Line Feed (LF). Both CR and LF are block separators, but
7.2396 + * in that case, the pair of characters is considered as terminating the
7.2397 + * preceding paragraph, and a new paragraph will be started by a character
7.2398 + * coming after the LF.
7.2399 + *
7.2400 + * The text is stored internally as an array of characters. Therefore the
7.2401 + * documentation will refer to indexes of the characters in the text.
7.2402 + *
7.2403 + * @param chars contains the text that the Bidi algorithm will be performed
7.2404 + * on. This text can be retrieved with <code>getText()</code> or
7.2405 + * <code>getTextAsString</code>.<br>
7.2406 + *
7.2407 + * @param paraLevel specifies the default level for the text;
7.2408 + * it is typically 0 (LTR) or 1 (RTL).
7.2409 + * If the method shall determine the paragraph level from the text,
7.2410 + * then <code>paraLevel</code> can be set to
7.2411 + * either <code>LEVEL_DEFAULT_LTR</code>
7.2412 + * or <code>LEVEL_DEFAULT_RTL</code>; if the text contains multiple
7.2413 + * paragraphs, the paragraph level shall be determined separately for
7.2414 + * each paragraph; if a paragraph does not include any strongly typed
7.2415 + * character, then the desired default is used (0 for LTR or 1 for RTL).
7.2416 + * Any other value between 0 and <code>MAX_EXPLICIT_LEVEL</code>
7.2417 + * is also valid, with odd levels indicating RTL.
7.2418 + *
7.2419 + * @param embeddingLevels (in) may be used to preset the embedding and
7.2420 + * override levels, ignoring characters like LRE and PDF in the text.
7.2421 + * A level overrides the directional property of its corresponding
7.2422 + * (same index) character if the level has the
7.2423 + * <code>LEVEL_OVERRIDE</code> bit set.<br><br>
7.2424 + * Except for that bit, it must be
7.2425 + * <code>paraLevel<=embeddingLevels[]<=MAX_EXPLICIT_LEVEL</code>,
7.2426 + * with one exception: a level of zero may be specified for a
7.2427 + * paragraph separator even if <code>paraLevel>0</code> when multiple
7.2428 + * paragraphs are submitted in the same call to <code>setPara()</code>.<br><br>
7.2429 + * <strong>Caution: </strong>A reference to this array, not a copy
7.2430 + * of the levels, will be stored in the <code>Bidi</code> object;
7.2431 + * the <code>embeddingLevels</code>
7.2432 + * should not be modified to avoid unexpected results on subsequent
7.2433 + * Bidi operations. However, the <code>setPara()</code> and
7.2434 + * <code>setLine()</code> methods may modify some or all of the
7.2435 + * levels.<br><br>
7.2436 + * <strong>Note:</strong> the <code>embeddingLevels</code> array must
7.2437 + * have one entry for each character in <code>text</code>.
7.2438 + *
7.2439 + * @throws IllegalArgumentException if the values in embeddingLevels are
7.2440 + * not within the allowed range
7.2441 + *
7.2442 + * @see #LEVEL_DEFAULT_LTR
7.2443 + * @see #LEVEL_DEFAULT_RTL
7.2444 + * @see #LEVEL_OVERRIDE
7.2445 + * @see #MAX_EXPLICIT_LEVEL
7.2446 + * @stable ICU 3.8
7.2447 + */
7.2448 + public void setPara(char[] chars, byte paraLevel, byte[] embeddingLevels)
7.2449 + {
7.2450 + /* check the argument values */
7.2451 + if (paraLevel < INTERNAL_LEVEL_DEFAULT_LTR) {
7.2452 + verifyRange(paraLevel, 0, MAX_EXPLICIT_LEVEL + 1);
7.2453 + }
7.2454 + if (chars == null) {
7.2455 + chars = new char[0];
7.2456 + }
7.2457 +
7.2458 + /* initialize the Bidi object */
7.2459 + this.paraBidi = null; /* mark unfinished setPara */
7.2460 + this.text = chars;
7.2461 + this.length = this.originalLength = this.resultLength = text.length;
7.2462 + this.paraLevel = paraLevel;
7.2463 + this.direction = Bidi.DIRECTION_LEFT_TO_RIGHT;
7.2464 + this.paraCount = 1;
7.2465 +
7.2466 + /* Allocate zero-length arrays instead of setting to null here; then
7.2467 + * checks for null in various places can be eliminated.
7.2468 + */
7.2469 + dirProps = new byte[0];
7.2470 + levels = new byte[0];
7.2471 + runs = new BidiRun[0];
7.2472 + isGoodLogicalToVisualRunsMap = false;
7.2473 + insertPoints.size = 0; /* clean up from last call */
7.2474 + insertPoints.confirmed = 0; /* clean up from last call */
7.2475 +
7.2476 + /*
7.2477 + * Save the original paraLevel if contextual; otherwise, set to 0.
7.2478 + */
7.2479 + if (IsDefaultLevel(paraLevel)) {
7.2480 + defaultParaLevel = paraLevel;
7.2481 + } else {
7.2482 + defaultParaLevel = 0;
7.2483 + }
7.2484 +
7.2485 + if (length == 0) {
7.2486 + /*
7.2487 + * For an empty paragraph, create a Bidi object with the paraLevel and
7.2488 + * the flags and the direction set but without allocating zero-length arrays.
7.2489 + * There is nothing more to do.
7.2490 + */
7.2491 + if (IsDefaultLevel(paraLevel)) {
7.2492 + this.paraLevel &= 1;
7.2493 + defaultParaLevel = 0;
7.2494 + }
7.2495 + if ((this.paraLevel & 1) != 0) {
7.2496 + flags = DirPropFlag(R);
7.2497 + direction = Bidi.DIRECTION_RIGHT_TO_LEFT;
7.2498 + } else {
7.2499 + flags = DirPropFlag(L);
7.2500 + direction = Bidi.DIRECTION_LEFT_TO_RIGHT;
7.2501 + }
7.2502 +
7.2503 + runCount = 0;
7.2504 + paraCount = 0;
7.2505 + paraBidi = this; /* mark successful setPara */
7.2506 + return;
7.2507 + }
7.2508 +
7.2509 + runCount = -1;
7.2510 +
7.2511 + /*
7.2512 + * Get the directional properties,
7.2513 + * the flags bit-set, and
7.2514 + * determine the paragraph level if necessary.
7.2515 + */
7.2516 + getDirPropsMemory(length);
7.2517 + dirProps = dirPropsMemory;
7.2518 + getDirProps();
7.2519 +
7.2520 + /* the processed length may have changed if OPTION_STREAMING is set */
7.2521 + trailingWSStart = length; /* the levels[] will reflect the WS run */
7.2522 +
7.2523 + /* allocate paras memory */
7.2524 + if (paraCount > 1) {
7.2525 + getInitialParasMemory(paraCount);
7.2526 + paras = parasMemory;
7.2527 + paras[paraCount - 1] = length;
7.2528 + } else {
7.2529 + /* initialize paras for single paragraph */
7.2530 + paras = simpleParas;
7.2531 + simpleParas[0] = length;
7.2532 + }
7.2533 +
7.2534 + /* are explicit levels specified? */
7.2535 + if (embeddingLevels == null) {
7.2536 + /* no: determine explicit levels according to the (Xn) rules */
7.2537 + getLevelsMemory(length);
7.2538 + levels = levelsMemory;
7.2539 + direction = resolveExplicitLevels();
7.2540 + } else {
7.2541 + /* set BN for all explicit codes, check that all levels are 0 or paraLevel..MAX_EXPLICIT_LEVEL */
7.2542 + levels = embeddingLevels;
7.2543 + direction = checkExplicitLevels();
7.2544 + }
7.2545 +
7.2546 + /*
7.2547 + * The steps after (X9) in the Bidi algorithm are performed only if
7.2548 + * the paragraph text has mixed directionality!
7.2549 + */
7.2550 + switch (direction) {
7.2551 + case Bidi.DIRECTION_LEFT_TO_RIGHT:
7.2552 + /* make sure paraLevel is even */
7.2553 + paraLevel = (byte)((paraLevel + 1) & ~1);
7.2554 +
7.2555 + /* all levels are implicitly at paraLevel (important for getLevels()) */
7.2556 + trailingWSStart = 0;
7.2557 + break;
7.2558 + case Bidi.DIRECTION_RIGHT_TO_LEFT:
7.2559 + /* make sure paraLevel is odd */
7.2560 + paraLevel |= 1;
7.2561 +
7.2562 + /* all levels are implicitly at paraLevel (important for getLevels()) */
7.2563 + trailingWSStart = 0;
7.2564 + break;
7.2565 + default:
7.2566 + this.impTabPair = impTab_DEFAULT;
7.2567 +
7.2568 + /*
7.2569 + * If there are no external levels specified and there
7.2570 + * are no significant explicit level codes in the text,
7.2571 + * then we can treat the entire paragraph as one run.
7.2572 + * Otherwise, we need to perform the following rules on runs of
7.2573 + * the text with the same embedding levels. (X10)
7.2574 + * "Significant" explicit level codes are ones that actually
7.2575 + * affect non-BN characters.
7.2576 + * Examples for "insignificant" ones are empty embeddings
7.2577 + * LRE-PDF, LRE-RLE-PDF-PDF, etc.
7.2578 + */
7.2579 + if (embeddingLevels == null && paraCount <= 1 &&
7.2580 + (flags & DirPropFlagMultiRuns) == 0) {
7.2581 + resolveImplicitLevels(0, length,
7.2582 + GetLRFromLevel(GetParaLevelAt(0)),
7.2583 + GetLRFromLevel(GetParaLevelAt(length - 1)));
7.2584 + } else {
7.2585 + /* sor, eor: start and end types of same-level-run */
7.2586 + int start, limit = 0;
7.2587 + byte level, nextLevel;
7.2588 + short sor, eor;
7.2589 +
7.2590 + /* determine the first sor and set eor to it because of the loop body (sor=eor there) */
7.2591 + level = GetParaLevelAt(0);
7.2592 + nextLevel = levels[0];
7.2593 + if (level < nextLevel) {
7.2594 + eor = GetLRFromLevel(nextLevel);
7.2595 + } else {
7.2596 + eor = GetLRFromLevel(level);
7.2597 + }
7.2598 +
7.2599 + do {
7.2600 + /* determine start and limit of the run (end points just behind the run) */
7.2601 +
7.2602 + /* the values for this run's start are the same as for the previous run's end */
7.2603 + start = limit;
7.2604 + level = nextLevel;
7.2605 + if ((start > 0) && (NoContextRTL(dirProps[start - 1]) == B)) {
7.2606 + /* except if this is a new paragraph, then set sor = para level */
7.2607 + sor = GetLRFromLevel(GetParaLevelAt(start));
7.2608 + } else {
7.2609 + sor = eor;
7.2610 + }
7.2611 +
7.2612 + /* search for the limit of this run */
7.2613 + while (++limit < length && levels[limit] == level) {}
7.2614 +
7.2615 + /* get the correct level of the next run */
7.2616 + if (limit < length) {
7.2617 + nextLevel = levels[limit];
7.2618 + } else {
7.2619 + nextLevel = GetParaLevelAt(length - 1);
7.2620 + }
7.2621 +
7.2622 + /* determine eor from max(level, nextLevel); sor is last run's eor */
7.2623 + if ((level & ~INTERNAL_LEVEL_OVERRIDE) < (nextLevel & ~INTERNAL_LEVEL_OVERRIDE)) {
7.2624 + eor = GetLRFromLevel(nextLevel);
7.2625 + } else {
7.2626 + eor = GetLRFromLevel(level);
7.2627 + }
7.2628 +
7.2629 + /* if the run consists of overridden directional types, then there
7.2630 + are no implicit types to be resolved */
7.2631 + if ((level & INTERNAL_LEVEL_OVERRIDE) == 0) {
7.2632 + resolveImplicitLevels(start, limit, sor, eor);
7.2633 + } else {
7.2634 + /* remove the LEVEL_OVERRIDE flags */
7.2635 + do {
7.2636 + levels[start++] &= ~INTERNAL_LEVEL_OVERRIDE;
7.2637 + } while (start < limit);
7.2638 + }
7.2639 + } while (limit < length);
7.2640 + }
7.2641 +
7.2642 + /* reset the embedding levels for some non-graphic characters (L1), (X9) */
7.2643 + adjustWSLevels();
7.2644 +
7.2645 + break;
7.2646 + }
7.2647 +
7.2648 + resultLength += insertPoints.size;
7.2649 + paraBidi = this; /* mark successful setPara */
7.2650 + }
7.2651 +
7.2652 + /**
7.2653 + * Perform the Unicode Bidi algorithm on a given paragraph, as defined in the
7.2654 + * <a href="http://www.unicode.org/unicode/reports/tr9/">Unicode Standard Annex #9</a>,
7.2655 + * version 13,
7.2656 + * also described in The Unicode Standard, Version 4.0 .<p>
7.2657 + *
7.2658 + * This method takes a paragraph of text and computes the
7.2659 + * left-right-directionality of each character. The text should not
7.2660 + * contain any Unicode block separators.<p>
7.2661 + *
7.2662 + * The RUN_DIRECTION attribute in the text, if present, determines the base
7.2663 + * direction (left-to-right or right-to-left). If not present, the base
7.2664 + * direction is computed using the Unicode Bidirectional Algorithm,
7.2665 + * defaulting to left-to-right if there are no strong directional characters
7.2666 + * in the text. This attribute, if present, must be applied to all the text
7.2667 + * in the paragraph.<p>
7.2668 + *
7.2669 + * The BIDI_EMBEDDING attribute in the text, if present, represents
7.2670 + * embedding level information. Negative values from -1 to -62 indicate
7.2671 + * overrides at the absolute value of the level. Positive values from 1 to
7.2672 + * 62 indicate embeddings. Where values are zero or not defined, the base
7.2673 + * embedding level as determined by the base direction is assumed.<p>
7.2674 + *
7.2675 + * The NUMERIC_SHAPING attribute in the text, if present, converts European
7.2676 + * digits to other decimal digits before running the bidi algorithm. This
7.2677 + * attribute, if present, must be applied to all the text in the paragraph.
7.2678 + *
7.2679 + * If the entire text is all of the same directionality, then
7.2680 + * the method may not perform all the steps described by the algorithm,
7.2681 + * i.e., some levels may not be the same as if all steps were performed.
7.2682 + * This is not relevant for unidirectional text.<br>
7.2683 + * For example, in pure LTR text with numbers the numbers would get
7.2684 + * a resolved level of 2 higher than the surrounding text according to
7.2685 + * the algorithm. This implementation may set all resolved levels to
7.2686 + * the same value in such a case.<p>
7.2687 + *
7.2688 + * @param paragraph a paragraph of text with optional character and
7.2689 + * paragraph attribute information
7.2690 + * @stable ICU 3.8
7.2691 + */
7.2692 + public void setPara(AttributedCharacterIterator paragraph)
7.2693 + {
7.2694 + byte paraLvl;
7.2695 + Boolean runDirection = (Boolean) paragraph.getAttribute(TextAttribute.RUN_DIRECTION);
7.2696 + NumericShaper shaper = (NumericShaper) paragraph.getAttribute(TextAttribute.NUMERIC_SHAPING);
7.2697 + if (runDirection == null) {
7.2698 + paraLvl = INTERNAL_LEVEL_DEFAULT_LTR;
7.2699 + } else {
7.2700 + paraLvl = (runDirection.equals(TextAttribute.RUN_DIRECTION_LTR)) ?
7.2701 + (byte)Bidi.DIRECTION_LEFT_TO_RIGHT : (byte)Bidi.DIRECTION_RIGHT_TO_LEFT;
7.2702 + }
7.2703 +
7.2704 + byte[] lvls = null;
7.2705 + int len = paragraph.getEndIndex() - paragraph.getBeginIndex();
7.2706 + byte[] embeddingLevels = new byte[len];
7.2707 + char[] txt = new char[len];
7.2708 + int i = 0;
7.2709 + char ch = paragraph.first();
7.2710 + while (ch != AttributedCharacterIterator.DONE) {
7.2711 + txt[i] = ch;
7.2712 + Integer embedding = (Integer) paragraph.getAttribute(TextAttribute.BIDI_EMBEDDING);
7.2713 + if (embedding != null) {
7.2714 + byte level = embedding.byteValue();
7.2715 + if (level == 0) {
7.2716 + /* no-op */
7.2717 + } else if (level < 0) {
7.2718 + lvls = embeddingLevels;
7.2719 + embeddingLevels[i] = (byte)((0 - level) | INTERNAL_LEVEL_OVERRIDE);
7.2720 + } else {
7.2721 + lvls = embeddingLevels;
7.2722 + embeddingLevels[i] = level;
7.2723 + }
7.2724 + }
7.2725 + ch = paragraph.next();
7.2726 + ++i;
7.2727 + }
7.2728 +
7.2729 + if (shaper != null) {
7.2730 + shaper.shape(txt, 0, len);
7.2731 + }
7.2732 + setPara(txt, paraLvl, lvls);
7.2733 + }
7.2734 +
7.2735 + /**
7.2736 + * Specify whether block separators must be allocated level zero,
7.2737 + * so that successive paragraphs will progress from left to right.
7.2738 + * This method must be called before <code>setPara()</code>.
7.2739 + * Paragraph separators (B) may appear in the text. Setting them to level zero
7.2740 + * means that all paragraph separators (including one possibly appearing
7.2741 + * in the last text position) are kept in the reordered text after the text
7.2742 + * that they follow in the source text.
7.2743 + * When this feature is not enabled, a paragraph separator at the last
7.2744 + * position of the text before reordering will go to the first position
7.2745 + * of the reordered text when the paragraph level is odd.
7.2746 + *
7.2747 + * @param ordarParaLTR specifies whether paragraph separators (B) must
7.2748 + * receive level 0, so that successive paragraphs progress from left to right.
7.2749 + *
7.2750 + * @see #setPara
7.2751 + * @stable ICU 3.8
7.2752 + */
7.2753 + private void orderParagraphsLTR(boolean ordarParaLTR) {
7.2754 + orderParagraphsLTR = ordarParaLTR;
7.2755 + }
7.2756 +
7.2757 + /**
7.2758 + * Get the directionality of the text.
7.2759 + *
7.2760 + * @return a value of <code>LTR</code>, <code>RTL</code> or <code>MIXED</code>
7.2761 + * that indicates if the entire text
7.2762 + * represented by this object is unidirectional,
7.2763 + * and which direction, or if it is mixed-directional.
7.2764 + *
7.2765 + * @throws IllegalStateException if this call is not preceded by a successful
7.2766 + * call to <code>setPara</code> or <code>setLine</code>
7.2767 + *
7.2768 + * @see #LTR
7.2769 + * @see #RTL
7.2770 + * @see #MIXED
7.2771 + * @stable ICU 3.8
7.2772 + */
7.2773 + private byte getDirection()
7.2774 + {
7.2775 + verifyValidParaOrLine();
7.2776 + return direction;
7.2777 + }
7.2778 +
7.2779 + /**
7.2780 + * Get the length of the text.
7.2781 + *
7.2782 + * @return The length of the text that the <code>Bidi</code> object was
7.2783 + * created for.
7.2784 + *
7.2785 + * @throws IllegalStateException if this call is not preceded by a successful
7.2786 + * call to <code>setPara</code> or <code>setLine</code>
7.2787 + * @stable ICU 3.8
7.2788 + */
7.2789 + public int getLength()
7.2790 + {
7.2791 + verifyValidParaOrLine();
7.2792 + return originalLength;
7.2793 + }
7.2794 +
7.2795 + /* paragraphs API methods ------------------------------------------------- */
7.2796 +
7.2797 + /**
7.2798 + * Get the paragraph level of the text.
7.2799 + *
7.2800 + * @return The paragraph level. If there are multiple paragraphs, their
7.2801 + * level may vary if the required paraLevel is LEVEL_DEFAULT_LTR or
7.2802 + * LEVEL_DEFAULT_RTL. In that case, the level of the first paragraph
7.2803 + * is returned.
7.2804 + *
7.2805 + * @throws IllegalStateException if this call is not preceded by a successful
7.2806 + * call to <code>setPara</code> or <code>setLine</code>
7.2807 + *
7.2808 + * @see #LEVEL_DEFAULT_LTR
7.2809 + * @see #LEVEL_DEFAULT_RTL
7.2810 + * @see #getParagraph
7.2811 + * @see #getParagraphByIndex
7.2812 + * @stable ICU 3.8
7.2813 + */
7.2814 + public byte getParaLevel()
7.2815 + {
7.2816 + verifyValidParaOrLine();
7.2817 + return paraLevel;
7.2818 + }
7.2819 +
7.2820 + /**
7.2821 + * Get the index of a paragraph, given a position within the text.<p>
7.2822 + *
7.2823 + * @param charIndex is the index of a character within the text, in the
7.2824 + * range <code>[0..getProcessedLength()-1]</code>.
7.2825 + *
7.2826 + * @return The index of the paragraph containing the specified position,
7.2827 + * starting from 0.
7.2828 + *
7.2829 + * @throws IllegalStateException if this call is not preceded by a successful
7.2830 + * call to <code>setPara</code> or <code>setLine</code>
7.2831 + * @throws IllegalArgumentException if charIndex is not within the legal range
7.2832 + *
7.2833 + * @see com.ibm.icu.text.BidiRun
7.2834 + * @see #getProcessedLength
7.2835 + * @stable ICU 3.8
7.2836 + */
7.2837 + public int getParagraphIndex(int charIndex)
7.2838 + {
7.2839 + verifyValidParaOrLine();
7.2840 + BidiBase bidi = paraBidi; /* get Para object if Line object */
7.2841 + verifyRange(charIndex, 0, bidi.length);
7.2842 + int paraIndex;
7.2843 + for (paraIndex = 0; charIndex >= bidi.paras[paraIndex]; paraIndex++) {
7.2844 + }
7.2845 + return paraIndex;
7.2846 + }
7.2847 +
7.2848 + /**
7.2849 + * <code>setLine()</code> returns a <code>Bidi</code> object to
7.2850 + * contain the reordering information, especially the resolved levels,
7.2851 + * for all the characters in a line of text. This line of text is
7.2852 + * specified by referring to a <code>Bidi</code> object representing
7.2853 + * this information for a piece of text containing one or more paragraphs,
7.2854 + * and by specifying a range of indexes in this text.<p>
7.2855 + * In the new line object, the indexes will range from 0 to <code>limit-start-1</code>.<p>
7.2856 + *
7.2857 + * This is used after calling <code>setPara()</code>
7.2858 + * for a piece of text, and after line-breaking on that text.
7.2859 + * It is not necessary if each paragraph is treated as a single line.<p>
7.2860 + *
7.2861 + * After line-breaking, rules (L1) and (L2) for the treatment of
7.2862 + * trailing WS and for reordering are performed on
7.2863 + * a <code>Bidi</code> object that represents a line.<p>
7.2864 + *
7.2865 + * <strong>Important: </strong>the line <code>Bidi</code> object may
7.2866 + * reference data within the global text <code>Bidi</code> object.
7.2867 + * You should not alter the content of the global text object until
7.2868 + * you are finished using the line object.
7.2869 + *
7.2870 + * @param start is the line's first index into the text.
7.2871 + *
7.2872 + * @param limit is just behind the line's last index into the text
7.2873 + * (its last index +1).
7.2874 + *
7.2875 + * @return a <code>Bidi</code> object that will now represent a line of the text.
7.2876 + *
7.2877 + * @throws IllegalStateException if this call is not preceded by a successful
7.2878 + * call to <code>setPara</code>
7.2879 + * @throws IllegalArgumentException if start and limit are not in the range
7.2880 + * <code>0<=start<limit<=getProcessedLength()</code>,
7.2881 + * or if the specified line crosses a paragraph boundary
7.2882 + *
7.2883 + * @see #setPara
7.2884 + * @see #getProcessedLength
7.2885 + * @stable ICU 3.8
7.2886 + */
7.2887 + public Bidi setLine(Bidi bidi, BidiBase bidiBase, Bidi newBidi, BidiBase newBidiBase, int start, int limit)
7.2888 + {
7.2889 + verifyValidPara();
7.2890 + verifyRange(start, 0, limit);
7.2891 + verifyRange(limit, 0, length+1);
7.2892 + if (getParagraphIndex(start) != getParagraphIndex(limit - 1)) {
7.2893 + /* the line crosses a paragraph boundary */
7.2894 + throw new IllegalArgumentException();
7.2895 + }
7.2896 +
7.2897 + return BidiLine.setLine(bidi, this, newBidi, newBidiBase, start, limit);
7.2898 + }
7.2899 +
7.2900 + /**
7.2901 + * Get the level for one character.
7.2902 + *
7.2903 + * @param charIndex the index of a character.
7.2904 + *
7.2905 + * @return The level for the character at <code>charIndex</code>.
7.2906 + *
7.2907 + * @throws IllegalStateException if this call is not preceded by a successful
7.2908 + * call to <code>setPara</code> or <code>setLine</code>
7.2909 + * @throws IllegalArgumentException if charIndex is not in the range
7.2910 + * <code>0<=charIndex<getProcessedLength()</code>
7.2911 + *
7.2912 + * @see #getProcessedLength
7.2913 + * @stable ICU 3.8
7.2914 + */
7.2915 + public byte getLevelAt(int charIndex)
7.2916 + {
7.2917 + if (charIndex < 0 || charIndex >= length) {
7.2918 + return (byte)getBaseLevel();
7.2919 + }
7.2920 + verifyValidParaOrLine();
7.2921 + verifyRange(charIndex, 0, length);
7.2922 + return BidiLine.getLevelAt(this, charIndex);
7.2923 + }
7.2924 +
7.2925 + /**
7.2926 + * Get an array of levels for each character.<p>
7.2927 + *
7.2928 + * Note that this method may allocate memory under some
7.2929 + * circumstances, unlike <code>getLevelAt()</code>.
7.2930 + *
7.2931 + * @return The levels array for the text,
7.2932 + * or <code>null</code> if an error occurs.
7.2933 + *
7.2934 + * @throws IllegalStateException if this call is not preceded by a successful
7.2935 + * call to <code>setPara</code> or <code>setLine</code>
7.2936 + * @stable ICU 3.8
7.2937 + */
7.2938 + private byte[] getLevels()
7.2939 + {
7.2940 + verifyValidParaOrLine();
7.2941 + if (length <= 0) {
7.2942 + return new byte[0];
7.2943 + }
7.2944 + return BidiLine.getLevels(this);
7.2945 + }
7.2946 +
7.2947 + /**
7.2948 + * Get the number of runs.
7.2949 + * This method may invoke the actual reordering on the
7.2950 + * <code>Bidi</code> object, after <code>setPara()</code>
7.2951 + * may have resolved only the levels of the text. Therefore,
7.2952 + * <code>countRuns()</code> may have to allocate memory,
7.2953 + * and may throw an exception if it fails to do so.
7.2954 + *
7.2955 + * @return The number of runs.
7.2956 + *
7.2957 + * @throws IllegalStateException if this call is not preceded by a successful
7.2958 + * call to <code>setPara</code> or <code>setLine</code>
7.2959 + * @stable ICU 3.8
7.2960 + */
7.2961 + public int countRuns()
7.2962 + {
7.2963 + verifyValidParaOrLine();
7.2964 + BidiLine.getRuns(this);
7.2965 + return runCount;
7.2966 + }
7.2967 +
7.2968 + /**
7.2969 + * Get a visual-to-logical index map (array) for the characters in the
7.2970 + * <code>Bidi</code> (paragraph or line) object.
7.2971 + * <p>
7.2972 + * Some values in the map may be <code>MAP_NOWHERE</code> if the
7.2973 + * corresponding text characters are Bidi marks inserted in the visual
7.2974 + * output by the option <code>OPTION_INSERT_MARKS</code>.
7.2975 + * <p>
7.2976 + * When the visual output is altered by using options of
7.2977 + * <code>writeReordered()</code> such as <code>INSERT_LRM_FOR_NUMERIC</code>,
7.2978 + * <code>KEEP_BASE_COMBINING</code>, <code>OUTPUT_REVERSE</code>,
7.2979 + * <code>REMOVE_BIDI_CONTROLS</code>, the logical positions returned may not
7.2980 + * be correct. It is advised to use, when possible, reordering options
7.2981 + * such as {@link #OPTION_INSERT_MARKS} and {@link #OPTION_REMOVE_CONTROLS}.
7.2982 + *
7.2983 + * @return an array of <code>getResultLength()</code>
7.2984 + * indexes which will reflect the reordering of the characters.<br><br>
7.2985 + * The index map will result in
7.2986 + * <code>indexMap[visualIndex]==logicalIndex</code>, where
7.2987 + * <code>indexMap</code> represents the returned array.
7.2988 + *
7.2989 + * @throws IllegalStateException if this call is not preceded by a successful
7.2990 + * call to <code>setPara</code> or <code>setLine</code>
7.2991 + *
7.2992 + * @see #getLogicalMap
7.2993 + * @see #getLogicalIndex
7.2994 + * @see #getResultLength
7.2995 + * @see #MAP_NOWHERE
7.2996 + * @see #OPTION_INSERT_MARKS
7.2997 + * @see #writeReordered
7.2998 + * @stable ICU 3.8
7.2999 + */
7.3000 + private int[] getVisualMap()
7.3001 + {
7.3002 + /* countRuns() checks successful call to setPara/setLine */
7.3003 + countRuns();
7.3004 + if (resultLength <= 0) {
7.3005 + return new int[0];
7.3006 + }
7.3007 + return BidiLine.getVisualMap(this);
7.3008 + }
7.3009 +
7.3010 + /**
7.3011 + * This is a convenience method that does not use a <code>Bidi</code> object.
7.3012 + * It is intended to be used for when an application has determined the levels
7.3013 + * of objects (character sequences) and just needs to have them reordered (L2).
7.3014 + * This is equivalent to using <code>getVisualMap()</code> on a
7.3015 + * <code>Bidi</code> object.
7.3016 + *
7.3017 + * @param levels is an array of levels that have been determined by
7.3018 + * the application.
7.3019 + *
7.3020 + * @return an array of <code>levels.length</code>
7.3021 + * indexes which will reflect the reordering of the characters.<p>
7.3022 + * The index map will result in
7.3023 + * <code>indexMap[visualIndex]==logicalIndex</code>, where
7.3024 + * <code>indexMap</code> represents the returned array.
7.3025 + *
7.3026 + * @stable ICU 3.8
7.3027 + */
7.3028 + private static int[] reorderVisual(byte[] levels)
7.3029 + {
7.3030 + return BidiLine.reorderVisual(levels);
7.3031 + }
7.3032 +
7.3033 + /**
7.3034 + * Constant indicating that the base direction depends on the first strong
7.3035 + * directional character in the text according to the Unicode Bidirectional
7.3036 + * Algorithm. If no strong directional character is present, the base
7.3037 + * direction is left-to-right.
7.3038 + * @stable ICU 3.8
7.3039 + */
7.3040 + private static final int INTERNAL_DIRECTION_DEFAULT_LEFT_TO_RIGHT = 0x7e;
7.3041 +
7.3042 + /**
7.3043 + * Constant indicating that the base direction depends on the first strong
7.3044 + * directional character in the text according to the Unicode Bidirectional
7.3045 + * Algorithm. If no strong directional character is present, the base
7.3046 + * direction is right-to-left.
7.3047 + * @stable ICU 3.8
7.3048 + */
7.3049 + private static final int INTERMAL_DIRECTION_DEFAULT_RIGHT_TO_LEFT = 0x7f;
7.3050 +
7.3051 + /**
7.3052 + * Create Bidi from the given text, embedding, and direction information.
7.3053 + * The embeddings array may be null. If present, the values represent
7.3054 + * embedding level information. Negative values from -1 to -61 indicate
7.3055 + * overrides at the absolute value of the level. Positive values from 1 to
7.3056 + * 61 indicate embeddings. Where values are zero, the base embedding level
7.3057 + * as determined by the base direction is assumed.<p>
7.3058 + *
7.3059 + * Note: this constructor calls setPara() internally.
7.3060 + *
7.3061 + * @param text an array containing the paragraph of text to process.
7.3062 + * @param textStart the index into the text array of the start of the
7.3063 + * paragraph.
7.3064 + * @param embeddings an array containing embedding values for each character
7.3065 + * in the paragraph. This can be null, in which case it is assumed
7.3066 + * that there is no external embedding information.
7.3067 + * @param embStart the index into the embedding array of the start of the
7.3068 + * paragraph.
7.3069 + * @param paragraphLength the length of the paragraph in the text and
7.3070 + * embeddings arrays.
7.3071 + * @param flags a collection of flags that control the algorithm. The
7.3072 + * algorithm understands the flags DIRECTION_LEFT_TO_RIGHT,
7.3073 + * DIRECTION_RIGHT_TO_LEFT, DIRECTION_DEFAULT_LEFT_TO_RIGHT, and
7.3074 + * DIRECTION_DEFAULT_RIGHT_TO_LEFT. Other values are reserved.
7.3075 + *
7.3076 + * @throws IllegalArgumentException if the values in embeddings are
7.3077 + * not within the allowed range
7.3078 + *
7.3079 + * @see #DIRECTION_LEFT_TO_RIGHT
7.3080 + * @see #DIRECTION_RIGHT_TO_LEFT
7.3081 + * @see #DIRECTION_DEFAULT_LEFT_TO_RIGHT
7.3082 + * @see #DIRECTION_DEFAULT_RIGHT_TO_LEFT
7.3083 + * @stable ICU 3.8
7.3084 + */
7.3085 + public BidiBase(char[] text,
7.3086 + int textStart,
7.3087 + byte[] embeddings,
7.3088 + int embStart,
7.3089 + int paragraphLength,
7.3090 + int flags)
7.3091 + {
7.3092 + this(0, 0);
7.3093 + byte paraLvl;
7.3094 + switch (flags) {
7.3095 + case Bidi.DIRECTION_LEFT_TO_RIGHT:
7.3096 + default:
7.3097 + paraLvl = Bidi.DIRECTION_LEFT_TO_RIGHT;
7.3098 + break;
7.3099 + case Bidi.DIRECTION_RIGHT_TO_LEFT:
7.3100 + paraLvl = Bidi.DIRECTION_RIGHT_TO_LEFT;
7.3101 + break;
7.3102 + case Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT:
7.3103 + paraLvl = INTERNAL_LEVEL_DEFAULT_LTR;
7.3104 + break;
7.3105 + case Bidi.DIRECTION_DEFAULT_RIGHT_TO_LEFT:
7.3106 + paraLvl = INTERNAL_LEVEL_DEFAULT_RTL;
7.3107 + break;
7.3108 + }
7.3109 + byte[] paraEmbeddings;
7.3110 + if (embeddings == null) {
7.3111 + paraEmbeddings = null;
7.3112 + } else {
7.3113 + paraEmbeddings = new byte[paragraphLength];
7.3114 + byte lev;
7.3115 + for (int i = 0; i < paragraphLength; i++) {
7.3116 + lev = embeddings[i + embStart];
7.3117 + if (lev < 0) {
7.3118 + lev = (byte)((- lev) | INTERNAL_LEVEL_OVERRIDE);
7.3119 + } else if (lev == 0) {
7.3120 + lev = paraLvl;
7.3121 + if (paraLvl > MAX_EXPLICIT_LEVEL) {
7.3122 + lev &= 1;
7.3123 + }
7.3124 + }
7.3125 + paraEmbeddings[i] = lev;
7.3126 + }
7.3127 + }
7.3128 + if (textStart == 0 && embStart == 0 && paragraphLength == text.length) {
7.3129 + setPara(text, paraLvl, paraEmbeddings);
7.3130 + } else {
7.3131 + char[] paraText = new char[paragraphLength];
7.3132 + System.arraycopy(text, textStart, paraText, 0, paragraphLength);
7.3133 + setPara(paraText, paraLvl, paraEmbeddings);
7.3134 + }
7.3135 + }
7.3136 +
7.3137 + /**
7.3138 + * Return true if the line is not left-to-right or right-to-left. This means
7.3139 + * it either has mixed runs of left-to-right and right-to-left text, or the
7.3140 + * base direction differs from the direction of the only run of text.
7.3141 + *
7.3142 + * @return true if the line is not left-to-right or right-to-left.
7.3143 + *
7.3144 + * @throws IllegalStateException if this call is not preceded by a successful
7.3145 + * call to <code>setPara</code>
7.3146 + * @stable ICU 3.8
7.3147 + */
7.3148 + public boolean isMixed()
7.3149 + {
7.3150 + return (!isLeftToRight() && !isRightToLeft());
7.3151 + }
7.3152 +
7.3153 + /**
7.3154 + * Return true if the line is all left-to-right text and the base direction
7.3155 + * is left-to-right.
7.3156 + *
7.3157 + * @return true if the line is all left-to-right text and the base direction
7.3158 + * is left-to-right.
7.3159 + *
7.3160 + * @throws IllegalStateException if this call is not preceded by a successful
7.3161 + * call to <code>setPara</code>
7.3162 + * @stable ICU 3.8
7.3163 + */
7.3164 + public boolean isLeftToRight()
7.3165 + {
7.3166 + return (getDirection() == Bidi.DIRECTION_LEFT_TO_RIGHT && (paraLevel & 1) == 0);
7.3167 + }
7.3168 +
7.3169 + /**
7.3170 + * Return true if the line is all right-to-left text, and the base direction
7.3171 + * is right-to-left
7.3172 + *
7.3173 + * @return true if the line is all right-to-left text, and the base
7.3174 + * direction is right-to-left
7.3175 + *
7.3176 + * @throws IllegalStateException if this call is not preceded by a successful
7.3177 + * call to <code>setPara</code>
7.3178 + * @stable ICU 3.8
7.3179 + */
7.3180 + public boolean isRightToLeft()
7.3181 + {
7.3182 + return (getDirection() == Bidi.DIRECTION_RIGHT_TO_LEFT && (paraLevel & 1) == 1);
7.3183 + }
7.3184 +
7.3185 + /**
7.3186 + * Return true if the base direction is left-to-right
7.3187 + *
7.3188 + * @return true if the base direction is left-to-right
7.3189 + *
7.3190 + * @throws IllegalStateException if this call is not preceded by a successful
7.3191 + * call to <code>setPara</code> or <code>setLine</code>
7.3192 + *
7.3193 + * @stable ICU 3.8
7.3194 + */
7.3195 + public boolean baseIsLeftToRight()
7.3196 + {
7.3197 + return (getParaLevel() == Bidi.DIRECTION_LEFT_TO_RIGHT);
7.3198 + }
7.3199 +
7.3200 + /**
7.3201 + * Return the base level (0 if left-to-right, 1 if right-to-left).
7.3202 + *
7.3203 + * @return the base level
7.3204 + *
7.3205 + * @throws IllegalStateException if this call is not preceded by a successful
7.3206 + * call to <code>setPara</code> or <code>setLine</code>
7.3207 + *
7.3208 + * @stable ICU 3.8
7.3209 + */
7.3210 + public int getBaseLevel()
7.3211 + {
7.3212 + return getParaLevel();
7.3213 + }
7.3214 +
7.3215 + /**
7.3216 + * Compute the logical to visual run mapping
7.3217 + */
7.3218 + private void getLogicalToVisualRunsMap()
7.3219 + {
7.3220 + if (isGoodLogicalToVisualRunsMap) {
7.3221 + return;
7.3222 + }
7.3223 + int count = countRuns();
7.3224 + if ((logicalToVisualRunsMap == null) ||
7.3225 + (logicalToVisualRunsMap.length < count)) {
7.3226 + logicalToVisualRunsMap = new int[count];
7.3227 + }
7.3228 + int i;
7.3229 + long[] keys = new long[count];
7.3230 + for (i = 0; i < count; i++) {
7.3231 + keys[i] = ((long)(runs[i].start)<<32) + i;
7.3232 + }
7.3233 + Arrays.sort(keys);
7.3234 + for (i = 0; i < count; i++) {
7.3235 + logicalToVisualRunsMap[i] = (int)(keys[i] & 0x00000000FFFFFFFF);
7.3236 + }
7.3237 + keys = null;
7.3238 + isGoodLogicalToVisualRunsMap = true;
7.3239 + }
7.3240 +
7.3241 + /**
7.3242 + * Return the level of the nth logical run in this line.
7.3243 + *
7.3244 + * @param run the index of the run, between 0 and <code>countRuns()-1</code>
7.3245 + *
7.3246 + * @return the level of the run
7.3247 + *
7.3248 + * @throws IllegalStateException if this call is not preceded by a successful
7.3249 + * call to <code>setPara</code> or <code>setLine</code>
7.3250 + * @throws IllegalArgumentException if <code>run</code> is not in
7.3251 + * the range <code>0<=run<countRuns()</code>
7.3252 + * @stable ICU 3.8
7.3253 + */
7.3254 + public int getRunLevel(int run)
7.3255 + {
7.3256 + verifyValidParaOrLine();
7.3257 + BidiLine.getRuns(this);
7.3258 + if (runCount == 1) {
7.3259 + return getParaLevel();
7.3260 + }
7.3261 + verifyIndex(run, 0, runCount);
7.3262 + getLogicalToVisualRunsMap();
7.3263 + return runs[logicalToVisualRunsMap[run]].level;
7.3264 + }
7.3265 +
7.3266 + /**
7.3267 + * Return the index of the character at the start of the nth logical run in
7.3268 + * this line, as an offset from the start of the line.
7.3269 + *
7.3270 + * @param run the index of the run, between 0 and <code>countRuns()</code>
7.3271 + *
7.3272 + * @return the start of the run
7.3273 + *
7.3274 + * @throws IllegalStateException if this call is not preceded by a successful
7.3275 + * call to <code>setPara</code> or <code>setLine</code>
7.3276 + * @throws IllegalArgumentException if <code>run</code> is not in
7.3277 + * the range <code>0<=run<countRuns()</code>
7.3278 + * @stable ICU 3.8
7.3279 + */
7.3280 + public int getRunStart(int run)
7.3281 + {
7.3282 + verifyValidParaOrLine();
7.3283 + BidiLine.getRuns(this);
7.3284 + if (runCount == 1) {
7.3285 + return 0;
7.3286 + } else if (run == runCount) {
7.3287 + return length;
7.3288 + }
7.3289 + verifyIndex(run, 0, runCount);
7.3290 + getLogicalToVisualRunsMap();
7.3291 + return runs[logicalToVisualRunsMap[run]].start;
7.3292 + }
7.3293 +
7.3294 + /**
7.3295 + * Return the index of the character past the end of the nth logical run in
7.3296 + * this line, as an offset from the start of the line. For example, this
7.3297 + * will return the length of the line for the last run on the line.
7.3298 + *
7.3299 + * @param run the index of the run, between 0 and <code>countRuns()</code>
7.3300 + *
7.3301 + * @return the limit of the run
7.3302 + *
7.3303 + * @throws IllegalStateException if this call is not preceded by a successful
7.3304 + * call to <code>setPara</code> or <code>setLine</code>
7.3305 + * @throws IllegalArgumentException if <code>run</code> is not in
7.3306 + * the range <code>0<=run<countRuns()</code>
7.3307 + * @stable ICU 3.8
7.3308 + */
7.3309 + public int getRunLimit(int run)
7.3310 + {
7.3311 + verifyValidParaOrLine();
7.3312 + BidiLine.getRuns(this);
7.3313 + if (runCount == 1) {
7.3314 + return length;
7.3315 + }
7.3316 + verifyIndex(run, 0, runCount);
7.3317 + getLogicalToVisualRunsMap();
7.3318 + int idx = logicalToVisualRunsMap[run];
7.3319 + int len = idx == 0 ? runs[idx].limit :
7.3320 + runs[idx].limit - runs[idx-1].limit;
7.3321 + return runs[idx].start + len;
7.3322 + }
7.3323 +
7.3324 + /**
7.3325 + * Return true if the specified text requires bidi analysis. If this returns
7.3326 + * false, the text will display left-to-right. Clients can then avoid
7.3327 + * constructing a Bidi object. Text in the Arabic Presentation Forms area of
7.3328 + * Unicode is presumed to already be shaped and ordered for display, and so
7.3329 + * will not cause this method to return true.
7.3330 + *
7.3331 + * @param text the text containing the characters to test
7.3332 + * @param start the start of the range of characters to test
7.3333 + * @param limit the limit of the range of characters to test
7.3334 + *
7.3335 + * @return true if the range of characters requires bidi analysis
7.3336 + *
7.3337 + * @stable ICU 3.8
7.3338 + */
7.3339 + public static boolean requiresBidi(char[] text,
7.3340 + int start,
7.3341 + int limit)
7.3342 + {
7.3343 + final int RTLMask = (1 << Bidi.DIRECTION_RIGHT_TO_LEFT |
7.3344 + 1 << AL |
7.3345 + 1 << RLE |
7.3346 + 1 << RLO |
7.3347 + 1 << AN);
7.3348 +
7.3349 + if (0 > start || start > limit || limit > text.length) {
7.3350 + throw new IllegalArgumentException("Value start " + start +
7.3351 + " is out of range 0 to " + limit);
7.3352 + }
7.3353 + for (int i = start; i < limit; ++i) {
7.3354 + if (Character.isHighSurrogate(text[i]) && i < (limit-1) &&
7.3355 + Character.isLowSurrogate(text[i+1])) {
7.3356 + if (((1 << UCharacter.getDirection(Character.codePointAt(text, i))) & RTLMask) != 0) {
7.3357 + return true;
7.3358 + }
7.3359 + } else if (((1 << UCharacter.getDirection(text[i])) & RTLMask) != 0) {
7.3360 + return true;
7.3361 + }
7.3362 + }
7.3363 + return false;
7.3364 + }
7.3365 +
7.3366 + /**
7.3367 + * Reorder the objects in the array into visual order based on their levels.
7.3368 + * This is a utility method to use when you have a collection of objects
7.3369 + * representing runs of text in logical order, each run containing text at a
7.3370 + * single level. The elements at <code>index</code> from
7.3371 + * <code>objectStart</code> up to <code>objectStart + count</code> in the
7.3372 + * objects array will be reordered into visual order assuming
7.3373 + * each run of text has the level indicated by the corresponding element in
7.3374 + * the levels array (at <code>index - objectStart + levelStart</code>).
7.3375 + *
7.3376 + * @param levels an array representing the bidi level of each object
7.3377 + * @param levelStart the start position in the levels array
7.3378 + * @param objects the array of objects to be reordered into visual order
7.3379 + * @param objectStart the start position in the objects array
7.3380 + * @param count the number of objects to reorder
7.3381 + * @stable ICU 3.8
7.3382 + */
7.3383 + public static void reorderVisually(byte[] levels,
7.3384 + int levelStart,
7.3385 + Object[] objects,
7.3386 + int objectStart,
7.3387 + int count)
7.3388 + {
7.3389 + if (0 > levelStart || levels.length <= levelStart) {
7.3390 + throw new IllegalArgumentException("Value levelStart " +
7.3391 + levelStart + " is out of range 0 to " +
7.3392 + (levels.length-1));
7.3393 + }
7.3394 + if (0 > objectStart || objects.length <= objectStart) {
7.3395 + throw new IllegalArgumentException("Value objectStart " +
7.3396 + levelStart + " is out of range 0 to " +
7.3397 + (objects.length-1));
7.3398 + }
7.3399 + if (0 > count || objects.length < (objectStart+count)) {
7.3400 + throw new IllegalArgumentException("Value count " +
7.3401 + levelStart + " is out of range 0 to " +
7.3402 + (objects.length - objectStart));
7.3403 + }
7.3404 + byte[] reorderLevels = new byte[count];
7.3405 + System.arraycopy(levels, levelStart, reorderLevels, 0, count);
7.3406 + int[] indexMap = reorderVisual(reorderLevels);
7.3407 + Object[] temp = new Object[count];
7.3408 + System.arraycopy(objects, objectStart, temp, 0, count);
7.3409 + for (int i = 0; i < count; ++i) {
7.3410 + objects[objectStart + i] = temp[indexMap[i]];
7.3411 + }
7.3412 + }
7.3413 +
7.3414 + /**
7.3415 + * Display the bidi internal state, used in debugging.
7.3416 + */
7.3417 + public String toString() {
7.3418 + StringBuffer buf = new StringBuffer(super.toString());
7.3419 +
7.3420 + buf.append("[dir: " + direction);
7.3421 + buf.append(" baselevel: " + paraLevel);
7.3422 + buf.append(" length: " + length);
7.3423 + buf.append(" runs: ");
7.3424 + if (levels == null) {
7.3425 + buf.append("null");
7.3426 + } else {
7.3427 + buf.append('[');
7.3428 + buf.append(levels[0]);
7.3429 + for (int i = 0; i < levels.length; i++) {
7.3430 + buf.append(' ');
7.3431 + buf.append(levels[i]);
7.3432 + }
7.3433 + buf.append(']');
7.3434 + }
7.3435 + buf.append(" text: [0x");
7.3436 + buf.append(Integer.toHexString(text[0]));
7.3437 + for (int i = 0; i < text.length; i++) {
7.3438 + buf.append(" 0x");
7.3439 + buf.append(Integer.toHexString(text[i]));
7.3440 + }
7.3441 + buf.append(']');
7.3442 + buf.append(']');
7.3443 +
7.3444 + return buf.toString();
7.3445 + }
7.3446 +
7.3447 +}
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
8.2 +++ b/src/share/classes/sun/text/bidi/BidiLine.java Tue Jun 23 23:09:49 2009 -0700
8.3 @@ -0,0 +1,849 @@
8.4 +/*
8.5 + * Portions Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
8.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
8.7 + *
8.8 + * This code is free software; you can redistribute it and/or modify it
8.9 + * under the terms of the GNU General Public License version 2 only, as
8.10 + * published by the Free Software Foundation. Sun designates this
8.11 + * particular file as subject to the "Classpath" exception as provided
8.12 + * by Sun in the LICENSE file that accompanied this code.
8.13 + *
8.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
8.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
8.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
8.17 + * version 2 for more details (a copy is included in the LICENSE file that
8.18 + * accompanied this code).
8.19 + *
8.20 + * You should have received a copy of the GNU General Public License version
8.21 + * 2 along with this work; if not, write to the Free Software Foundation,
8.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
8.23 + *
8.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
8.25 + * CA 95054 USA or visit www.sun.com if you need additional information or
8.26 + * have any questions.
8.27 + */
8.28 +/*
8.29 + *******************************************************************************
8.30 + * (C) Copyright IBM Corp. and others, 1996-2009 - All Rights Reserved *
8.31 + * *
8.32 + * The original version of this source code and documentation is copyrighted *
8.33 + * and owned by IBM, These materials are provided under terms of a License *
8.34 + * Agreement between IBM and Sun. This technology is protected by multiple *
8.35 + * US and International patents. This notice and attribution to IBM may not *
8.36 + * to removed. *
8.37 + *******************************************************************************
8.38 + */
8.39 +/* Written by Simon Montagu, Matitiahu Allouche
8.40 + * (ported from C code written by Markus W. Scherer)
8.41 + */
8.42 +
8.43 +package sun.text.bidi;
8.44 +
8.45 +import java.text.Bidi;
8.46 +import java.util.Arrays;
8.47 +
8.48 +public final class BidiLine {
8.49 +
8.50 + /*
8.51 + * General remarks about the functions in this file:
8.52 + *
8.53 + * These functions deal with the aspects of potentially mixed-directional
8.54 + * text in a single paragraph or in a line of a single paragraph
8.55 + * which has already been processed according to
8.56 + * the Unicode 3.0 Bidi algorithm as defined in
8.57 + * http://www.unicode.org/unicode/reports/tr9/ , version 13,
8.58 + * also described in The Unicode Standard, Version 4.0.1 .
8.59 + *
8.60 + * This means that there is a Bidi object with a levels
8.61 + * and a dirProps array.
8.62 + * paraLevel and direction are also set.
8.63 + * Only if the length of the text is zero, then levels==dirProps==NULL.
8.64 + *
8.65 + * The overall directionality of the paragraph
8.66 + * or line is used to bypass the reordering steps if possible.
8.67 + * Even purely RTL text does not need reordering there because
8.68 + * the getLogical/VisualIndex() methods can compute the
8.69 + * index on the fly in such a case.
8.70 + *
8.71 + * The implementation of the access to same-level-runs and of the reordering
8.72 + * do attempt to provide better performance and less memory usage compared to
8.73 + * a direct implementation of especially rule (L2) with an array of
8.74 + * one (32-bit) integer per text character.
8.75 + *
8.76 + * Here, the levels array is scanned as soon as necessary, and a vector of
8.77 + * same-level-runs is created. Reordering then is done on this vector.
8.78 + * For each run of text positions that were resolved to the same level,
8.79 + * only 8 bytes are stored: the first text position of the run and the visual
8.80 + * position behind the run after reordering.
8.81 + * One sign bit is used to hold the directionality of the run.
8.82 + * This is inefficient if there are many very short runs. If the average run
8.83 + * length is <2, then this uses more memory.
8.84 + *
8.85 + * In a further attempt to save memory, the levels array is never changed
8.86 + * after all the resolution rules (Xn, Wn, Nn, In).
8.87 + * Many methods have to consider the field trailingWSStart:
8.88 + * if it is less than length, then there is an implicit trailing run
8.89 + * at the paraLevel,
8.90 + * which is not reflected in the levels array.
8.91 + * This allows a line Bidi object to use the same levels array as
8.92 + * its paragraph parent object.
8.93 + *
8.94 + * When a Bidi object is created for a line of a paragraph, then the
8.95 + * paragraph's levels and dirProps arrays are reused by way of setting
8.96 + * a pointer into them, not by copying. This again saves memory and forbids to
8.97 + * change the now shared levels for (L1).
8.98 + */
8.99 +
8.100 + /* handle trailing WS (L1) -------------------------------------------------- */
8.101 +
8.102 + /*
8.103 + * setTrailingWSStart() sets the start index for a trailing
8.104 + * run of WS in the line. This is necessary because we do not modify
8.105 + * the paragraph's levels array that we just point into.
8.106 + * Using trailingWSStart is another form of performing (L1).
8.107 + *
8.108 + * To make subsequent operations easier, we also include the run
8.109 + * before the WS if it is at the paraLevel - we merge the two here.
8.110 + *
8.111 + * This method is called only from setLine(), so paraLevel is
8.112 + * set correctly for the line even when contextual multiple paragraphs.
8.113 + */
8.114 +
8.115 + static void setTrailingWSStart(BidiBase bidiBase)
8.116 + {
8.117 + byte[] dirProps = bidiBase.dirProps;
8.118 + byte[] levels = bidiBase.levels;
8.119 + int start = bidiBase.length;
8.120 + byte paraLevel = bidiBase.paraLevel;
8.121 +
8.122 + /* If the line is terminated by a block separator, all preceding WS etc...
8.123 + are already set to paragraph level.
8.124 + Setting trailingWSStart to pBidi->length will avoid changing the
8.125 + level of B chars from 0 to paraLevel in getLevels when
8.126 + orderParagraphsLTR==TRUE
8.127 + */
8.128 + if (BidiBase.NoContextRTL(dirProps[start - 1]) == BidiBase.B) {
8.129 + bidiBase.trailingWSStart = start; /* currently == bidiBase.length */
8.130 + return;
8.131 + }
8.132 + /* go backwards across all WS, BN, explicit codes */
8.133 + while (start > 0 &&
8.134 + (BidiBase.DirPropFlagNC(dirProps[start - 1]) & BidiBase.MASK_WS) != 0) {
8.135 + --start;
8.136 + }
8.137 +
8.138 + /* if the WS run can be merged with the previous run then do so here */
8.139 + while (start > 0 && levels[start - 1] == paraLevel) {
8.140 + --start;
8.141 + }
8.142 +
8.143 + bidiBase.trailingWSStart=start;
8.144 + }
8.145 +
8.146 + public static Bidi setLine(Bidi bidi, BidiBase paraBidi,
8.147 + Bidi newBidi, BidiBase newBidiBase,
8.148 + int start, int limit) {
8.149 + int length;
8.150 +
8.151 + BidiBase lineBidi = newBidiBase;
8.152 +
8.153 + /* set the values in lineBidi from its paraBidi parent */
8.154 + /* class members are already initialized to 0 */
8.155 + // lineBidi.paraBidi = null; /* mark unfinished setLine */
8.156 + // lineBidi.flags = 0;
8.157 + // lineBidi.controlCount = 0;
8.158 +
8.159 + length = lineBidi.length = lineBidi.originalLength =
8.160 + lineBidi.resultLength = limit - start;
8.161 +
8.162 + lineBidi.text = new char[length];
8.163 + System.arraycopy(paraBidi.text, start, lineBidi.text, 0, length);
8.164 + lineBidi.paraLevel = paraBidi.GetParaLevelAt(start);
8.165 + lineBidi.paraCount = paraBidi.paraCount;
8.166 + lineBidi.runs = new BidiRun[0];
8.167 + if (paraBidi.controlCount > 0) {
8.168 + int j;
8.169 + for (j = start; j < limit; j++) {
8.170 + if (BidiBase.IsBidiControlChar(paraBidi.text[j])) {
8.171 + lineBidi.controlCount++;
8.172 + }
8.173 + }
8.174 + lineBidi.resultLength -= lineBidi.controlCount;
8.175 + }
8.176 + /* copy proper subset of DirProps */
8.177 + lineBidi.getDirPropsMemory(length);
8.178 + lineBidi.dirProps = lineBidi.dirPropsMemory;
8.179 + System.arraycopy(paraBidi.dirProps, start, lineBidi.dirProps, 0,
8.180 + length);
8.181 + /* copy proper subset of Levels */
8.182 + lineBidi.getLevelsMemory(length);
8.183 + lineBidi.levels = lineBidi.levelsMemory;
8.184 + System.arraycopy(paraBidi.levels, start, lineBidi.levels, 0,
8.185 + length);
8.186 + lineBidi.runCount = -1;
8.187 +
8.188 + if (paraBidi.direction != BidiBase.MIXED) {
8.189 + /* the parent is already trivial */
8.190 + lineBidi.direction = paraBidi.direction;
8.191 +
8.192 + /*
8.193 + * The parent's levels are all either
8.194 + * implicitly or explicitly ==paraLevel;
8.195 + * do the same here.
8.196 + */
8.197 + if (paraBidi.trailingWSStart <= start) {
8.198 + lineBidi.trailingWSStart = 0;
8.199 + } else if (paraBidi.trailingWSStart < limit) {
8.200 + lineBidi.trailingWSStart = paraBidi.trailingWSStart - start;
8.201 + } else {
8.202 + lineBidi.trailingWSStart = length;
8.203 + }
8.204 + } else {
8.205 + byte[] levels = lineBidi.levels;
8.206 + int i, trailingWSStart;
8.207 + byte level;
8.208 +
8.209 + setTrailingWSStart(lineBidi);
8.210 + trailingWSStart = lineBidi.trailingWSStart;
8.211 +
8.212 + /* recalculate lineBidi.direction */
8.213 + if (trailingWSStart == 0) {
8.214 + /* all levels are at paraLevel */
8.215 + lineBidi.direction = (byte)(lineBidi.paraLevel & 1);
8.216 + } else {
8.217 + /* get the level of the first character */
8.218 + level = (byte)(levels[0] & 1);
8.219 +
8.220 + /* if there is anything of a different level, then the line
8.221 + is mixed */
8.222 + if (trailingWSStart < length &&
8.223 + (lineBidi.paraLevel & 1) != level) {
8.224 + /* the trailing WS is at paraLevel, which differs from
8.225 + levels[0] */
8.226 + lineBidi.direction = BidiBase.MIXED;
8.227 + } else {
8.228 + /* see if levels[1..trailingWSStart-1] have the same
8.229 + direction as levels[0] and paraLevel */
8.230 + for (i = 1; ; i++) {
8.231 + if (i == trailingWSStart) {
8.232 + /* the direction values match those in level */
8.233 + lineBidi.direction = level;
8.234 + break;
8.235 + } else if ((levels[i] & 1) != level) {
8.236 + lineBidi.direction = BidiBase.MIXED;
8.237 + break;
8.238 + }
8.239 + }
8.240 + }
8.241 + }
8.242 +
8.243 + switch(lineBidi.direction) {
8.244 + case Bidi.DIRECTION_LEFT_TO_RIGHT:
8.245 + /* make sure paraLevel is even */
8.246 + lineBidi.paraLevel = (byte)
8.247 + ((lineBidi.paraLevel + 1) & ~1);
8.248 +
8.249 + /* all levels are implicitly at paraLevel (important for
8.250 + getLevels()) */
8.251 + lineBidi.trailingWSStart = 0;
8.252 + break;
8.253 + case Bidi.DIRECTION_RIGHT_TO_LEFT:
8.254 + /* make sure paraLevel is odd */
8.255 + lineBidi.paraLevel |= 1;
8.256 +
8.257 + /* all levels are implicitly at paraLevel (important for
8.258 + getLevels()) */
8.259 + lineBidi.trailingWSStart = 0;
8.260 + break;
8.261 + default:
8.262 + break;
8.263 + }
8.264 + }
8.265 +
8.266 + newBidiBase.paraBidi = paraBidi; /* mark successful setLine */
8.267 + return newBidi;
8.268 + }
8.269 +
8.270 + static byte getLevelAt(BidiBase bidiBase, int charIndex)
8.271 + {
8.272 + /* return paraLevel if in the trailing WS run, otherwise the real level */
8.273 + if (bidiBase.direction != BidiBase.MIXED || charIndex >= bidiBase.trailingWSStart) {
8.274 + return bidiBase.GetParaLevelAt(charIndex);
8.275 + } else {
8.276 + return bidiBase.levels[charIndex];
8.277 + }
8.278 + }
8.279 +
8.280 + static byte[] getLevels(BidiBase bidiBase)
8.281 + {
8.282 + int start = bidiBase.trailingWSStart;
8.283 + int length = bidiBase.length;
8.284 +
8.285 + if (start != length) {
8.286 + /* the current levels array does not reflect the WS run */
8.287 + /*
8.288 + * After the previous if(), we know that the levels array
8.289 + * has an implicit trailing WS run and therefore does not fully
8.290 + * reflect itself all the levels.
8.291 + * This must be a Bidi object for a line, and
8.292 + * we need to create a new levels array.
8.293 + */
8.294 + /* bidiBase.paraLevel is ok even if contextual multiple paragraphs,
8.295 + since bidiBase is a line object */
8.296 + Arrays.fill(bidiBase.levels, start, length, bidiBase.paraLevel);
8.297 +
8.298 + /* this new levels array is set for the line and reflects the WS run */
8.299 + bidiBase.trailingWSStart = length;
8.300 + }
8.301 + if (length < bidiBase.levels.length) {
8.302 + byte[] levels = new byte[length];
8.303 + System.arraycopy(bidiBase.levels, 0, levels, 0, length);
8.304 + return levels;
8.305 + }
8.306 + return bidiBase.levels;
8.307 + }
8.308 +
8.309 + static BidiRun getLogicalRun(BidiBase bidiBase, int logicalPosition)
8.310 + {
8.311 + /* this is done based on runs rather than on levels since levels have
8.312 + a special interpretation when REORDER_RUNS_ONLY
8.313 + */
8.314 + BidiRun newRun = new BidiRun(), iRun;
8.315 + getRuns(bidiBase);
8.316 + int runCount = bidiBase.runCount;
8.317 + int visualStart = 0, logicalLimit = 0;
8.318 + iRun = bidiBase.runs[0];
8.319 +
8.320 + for (int i = 0; i < runCount; i++) {
8.321 + iRun = bidiBase.runs[i];
8.322 + logicalLimit = iRun.start + iRun.limit - visualStart;
8.323 + if ((logicalPosition >= iRun.start) &&
8.324 + (logicalPosition < logicalLimit)) {
8.325 + break;
8.326 + }
8.327 + visualStart = iRun.limit;
8.328 + }
8.329 + newRun.start = iRun.start;
8.330 + newRun.limit = logicalLimit;
8.331 + newRun.level = iRun.level;
8.332 + return newRun;
8.333 + }
8.334 +
8.335 + /* in trivial cases there is only one trivial run; called by getRuns() */
8.336 + private static void getSingleRun(BidiBase bidiBase, byte level) {
8.337 + /* simple, single-run case */
8.338 + bidiBase.runs = bidiBase.simpleRuns;
8.339 + bidiBase.runCount = 1;
8.340 +
8.341 + /* fill and reorder the single run */
8.342 + bidiBase.runs[0] = new BidiRun(0, bidiBase.length, level);
8.343 + }
8.344 +
8.345 + /* reorder the runs array (L2) ---------------------------------------------- */
8.346 +
8.347 + /*
8.348 + * Reorder the same-level runs in the runs array.
8.349 + * Here, runCount>1 and maxLevel>=minLevel>=paraLevel.
8.350 + * All the visualStart fields=logical start before reordering.
8.351 + * The "odd" bits are not set yet.
8.352 + *
8.353 + * Reordering with this data structure lends itself to some handy shortcuts:
8.354 + *
8.355 + * Since each run is moved but not modified, and since at the initial maxLevel
8.356 + * each sequence of same-level runs consists of only one run each, we
8.357 + * don't need to do anything there and can predecrement maxLevel.
8.358 + * In many simple cases, the reordering is thus done entirely in the
8.359 + * index mapping.
8.360 + * Also, reordering occurs only down to the lowest odd level that occurs,
8.361 + * which is minLevel|1. However, if the lowest level itself is odd, then
8.362 + * in the last reordering the sequence of the runs at this level or higher
8.363 + * will be all runs, and we don't need the elaborate loop to search for them.
8.364 + * This is covered by ++minLevel instead of minLevel|=1 followed
8.365 + * by an extra reorder-all after the reorder-some loop.
8.366 + * About a trailing WS run:
8.367 + * Such a run would need special treatment because its level is not
8.368 + * reflected in levels[] if this is not a paragraph object.
8.369 + * Instead, all characters from trailingWSStart on are implicitly at
8.370 + * paraLevel.
8.371 + * However, for all maxLevel>paraLevel, this run will never be reordered
8.372 + * and does not need to be taken into account. maxLevel==paraLevel is only reordered
8.373 + * if minLevel==paraLevel is odd, which is done in the extra segment.
8.374 + * This means that for the main reordering loop we don't need to consider
8.375 + * this run and can --runCount. If it is later part of the all-runs
8.376 + * reordering, then runCount is adjusted accordingly.
8.377 + */
8.378 + private static void reorderLine(BidiBase bidiBase, byte minLevel, byte maxLevel) {
8.379 +
8.380 + /* nothing to do? */
8.381 + if (maxLevel<=(minLevel|1)) {
8.382 + return;
8.383 + }
8.384 +
8.385 + BidiRun[] runs;
8.386 + BidiRun tempRun;
8.387 + byte[] levels;
8.388 + int firstRun, endRun, limitRun, runCount;
8.389 +
8.390 + /*
8.391 + * Reorder only down to the lowest odd level
8.392 + * and reorder at an odd minLevel in a separate, simpler loop.
8.393 + * See comments above for why minLevel is always incremented.
8.394 + */
8.395 + ++minLevel;
8.396 +
8.397 + runs = bidiBase.runs;
8.398 + levels = bidiBase.levels;
8.399 + runCount = bidiBase.runCount;
8.400 +
8.401 + /* do not include the WS run at paraLevel<=old minLevel except in the simple loop */
8.402 + if (bidiBase.trailingWSStart < bidiBase.length) {
8.403 + --runCount;
8.404 + }
8.405 +
8.406 + while (--maxLevel >= minLevel) {
8.407 + firstRun = 0;
8.408 +
8.409 + /* loop for all sequences of runs */
8.410 + for ( ; ; ) {
8.411 + /* look for a sequence of runs that are all at >=maxLevel */
8.412 + /* look for the first run of such a sequence */
8.413 + while (firstRun < runCount && levels[runs[firstRun].start] < maxLevel) {
8.414 + ++firstRun;
8.415 + }
8.416 + if (firstRun >= runCount) {
8.417 + break; /* no more such runs */
8.418 + }
8.419 +
8.420 + /* look for the limit run of such a sequence (the run behind it) */
8.421 + for (limitRun = firstRun; ++limitRun < runCount &&
8.422 + levels[runs[limitRun].start]>=maxLevel; ) {}
8.423 +
8.424 + /* Swap the entire sequence of runs from firstRun to limitRun-1. */
8.425 + endRun = limitRun - 1;
8.426 + while (firstRun < endRun) {
8.427 + tempRun = runs[firstRun];
8.428 + runs[firstRun] = runs[endRun];
8.429 + runs[endRun] = tempRun;
8.430 + ++firstRun;
8.431 + --endRun;
8.432 + }
8.433 +
8.434 + if (limitRun == runCount) {
8.435 + break; /* no more such runs */
8.436 + } else {
8.437 + firstRun = limitRun + 1;
8.438 + }
8.439 + }
8.440 + }
8.441 +
8.442 + /* now do maxLevel==old minLevel (==odd!), see above */
8.443 + if ((minLevel & 1) == 0) {
8.444 + firstRun = 0;
8.445 +
8.446 + /* include the trailing WS run in this complete reordering */
8.447 + if (bidiBase.trailingWSStart == bidiBase.length) {
8.448 + --runCount;
8.449 + }
8.450 +
8.451 + /* Swap the entire sequence of all runs. (endRun==runCount) */
8.452 + while (firstRun < runCount) {
8.453 + tempRun = runs[firstRun];
8.454 + runs[firstRun] = runs[runCount];
8.455 + runs[runCount] = tempRun;
8.456 + ++firstRun;
8.457 + --runCount;
8.458 + }
8.459 + }
8.460 + }
8.461 +
8.462 + /* compute the runs array --------------------------------------------------- */
8.463 +
8.464 + static int getRunFromLogicalIndex(BidiBase bidiBase, int logicalIndex) {
8.465 + BidiRun[] runs = bidiBase.runs;
8.466 + int runCount = bidiBase.runCount, visualStart = 0, i, length, logicalStart;
8.467 +
8.468 + for (i = 0; i < runCount; i++) {
8.469 + length = runs[i].limit - visualStart;
8.470 + logicalStart = runs[i].start;
8.471 + if ((logicalIndex >= logicalStart) && (logicalIndex < (logicalStart+length))) {
8.472 + return i;
8.473 + }
8.474 + visualStart += length;
8.475 + }
8.476 + /* we should never get here */
8.477 + throw new IllegalStateException("Internal ICU error in getRunFromLogicalIndex");
8.478 + }
8.479 +
8.480 + /*
8.481 + * Compute the runs array from the levels array.
8.482 + * After getRuns() returns true, runCount is guaranteed to be >0
8.483 + * and the runs are reordered.
8.484 + * Odd-level runs have visualStart on their visual right edge and
8.485 + * they progress visually to the left.
8.486 + * If option OPTION_INSERT_MARKS is set, insertRemove will contain the
8.487 + * sum of appropriate LRM/RLM_BEFORE/AFTER flags.
8.488 + * If option OPTION_REMOVE_CONTROLS is set, insertRemove will contain the
8.489 + * negative number of BiDi control characters within this run.
8.490 + */
8.491 + static void getRuns(BidiBase bidiBase) {
8.492 + /*
8.493 + * This method returns immediately if the runs are already set. This
8.494 + * includes the case of length==0 (handled in setPara)..
8.495 + */
8.496 + if (bidiBase.runCount >= 0) {
8.497 + return;
8.498 + }
8.499 + if (bidiBase.direction != BidiBase.MIXED) {
8.500 + /* simple, single-run case - this covers length==0 */
8.501 + /* bidiBase.paraLevel is ok even for contextual multiple paragraphs */
8.502 + getSingleRun(bidiBase, bidiBase.paraLevel);
8.503 + } else /* BidiBase.MIXED, length>0 */ {
8.504 + /* mixed directionality */
8.505 + int length = bidiBase.length, limit;
8.506 + byte[] levels = bidiBase.levels;
8.507 + int i, runCount;
8.508 + byte level = BidiBase.INTERNAL_LEVEL_DEFAULT_LTR; /* initialize with no valid level */
8.509 + /*
8.510 + * If there are WS characters at the end of the line
8.511 + * and the run preceding them has a level different from
8.512 + * paraLevel, then they will form their own run at paraLevel (L1).
8.513 + * Count them separately.
8.514 + * We need some special treatment for this in order to not
8.515 + * modify the levels array which a line Bidi object shares
8.516 + * with its paragraph parent and its other line siblings.
8.517 + * In other words, for the trailing WS, it may be
8.518 + * levels[]!=paraLevel but we have to treat it like it were so.
8.519 + */
8.520 + limit = bidiBase.trailingWSStart;
8.521 + /* count the runs, there is at least one non-WS run, and limit>0 */
8.522 + runCount = 0;
8.523 + for (i = 0; i < limit; ++i) {
8.524 + /* increment runCount at the start of each run */
8.525 + if (levels[i] != level) {
8.526 + ++runCount;
8.527 + level = levels[i];
8.528 + }
8.529 + }
8.530 +
8.531 + /*
8.532 + * We don't need to see if the last run can be merged with a trailing
8.533 + * WS run because setTrailingWSStart() would have done that.
8.534 + */
8.535 + if (runCount == 1 && limit == length) {
8.536 + /* There is only one non-WS run and no trailing WS-run. */
8.537 + getSingleRun(bidiBase, levels[0]);
8.538 + } else /* runCount>1 || limit<length */ {
8.539 + /* allocate and set the runs */
8.540 + BidiRun[] runs;
8.541 + int runIndex, start;
8.542 + byte minLevel = BidiBase.MAX_EXPLICIT_LEVEL + 1;
8.543 + byte maxLevel=0;
8.544 +
8.545 + /* now, count a (non-mergeable) WS run */
8.546 + if (limit < length) {
8.547 + ++runCount;
8.548 + }
8.549 +
8.550 + /* runCount > 1 */
8.551 + bidiBase.getRunsMemory(runCount);
8.552 + runs = bidiBase.runsMemory;
8.553 +
8.554 + /* set the runs */
8.555 + /* FOOD FOR THOUGHT: this could be optimized, e.g.:
8.556 + * 464->444, 484->444, 575->555, 595->555
8.557 + * However, that would take longer. Check also how it would
8.558 + * interact with BiDi control removal and inserting Marks.
8.559 + */
8.560 + runIndex = 0;
8.561 +
8.562 + /* search for the run limits and initialize visualLimit values with the run lengths */
8.563 + i = 0;
8.564 + do {
8.565 + /* prepare this run */
8.566 + start = i;
8.567 + level = levels[i];
8.568 + if (level < minLevel) {
8.569 + minLevel = level;
8.570 + }
8.571 + if (level > maxLevel) {
8.572 + maxLevel = level;
8.573 + }
8.574 +
8.575 + /* look for the run limit */
8.576 + while (++i < limit && levels[i] == level) {}
8.577 +
8.578 + /* i is another run limit */
8.579 + runs[runIndex] = new BidiRun(start, i - start, level);
8.580 + ++runIndex;
8.581 + } while (i < limit);
8.582 +
8.583 + if (limit < length) {
8.584 + /* there is a separate WS run */
8.585 + runs[runIndex] = new BidiRun(limit, length - limit, bidiBase.paraLevel);
8.586 + /* For the trailing WS run, bidiBase.paraLevel is ok even
8.587 + if contextual multiple paragraphs. */
8.588 + if (bidiBase.paraLevel < minLevel) {
8.589 + minLevel = bidiBase.paraLevel;
8.590 + }
8.591 + }
8.592 +
8.593 + /* set the object fields */
8.594 + bidiBase.runs = runs;
8.595 + bidiBase.runCount = runCount;
8.596 +
8.597 + reorderLine(bidiBase, minLevel, maxLevel);
8.598 +
8.599 + /* now add the direction flags and adjust the visualLimit's to be just that */
8.600 + /* this loop will also handle the trailing WS run */
8.601 + limit = 0;
8.602 + for (i = 0; i < runCount; ++i) {
8.603 + runs[i].level = levels[runs[i].start];
8.604 + limit = (runs[i].limit += limit);
8.605 + }
8.606 +
8.607 + /* Set the embedding level for the trailing WS run. */
8.608 + /* For a RTL paragraph, it will be the *first* run in visual order. */
8.609 + /* For the trailing WS run, bidiBase.paraLevel is ok even if
8.610 + contextual multiple paragraphs. */
8.611 + if (runIndex < runCount) {
8.612 + int trailingRun = ((bidiBase.paraLevel & 1) != 0)? 0 : runIndex;
8.613 + runs[trailingRun].level = bidiBase.paraLevel;
8.614 + }
8.615 + }
8.616 + }
8.617 +
8.618 + /* handle insert LRM/RLM BEFORE/AFTER run */
8.619 + if (bidiBase.insertPoints.size > 0) {
8.620 + BidiBase.Point point;
8.621 + int runIndex, ip;
8.622 + for (ip = 0; ip < bidiBase.insertPoints.size; ip++) {
8.623 + point = bidiBase.insertPoints.points[ip];
8.624 + runIndex = getRunFromLogicalIndex(bidiBase, point.pos);
8.625 + bidiBase.runs[runIndex].insertRemove |= point.flag;
8.626 + }
8.627 + }
8.628 +
8.629 + /* handle remove BiDi control characters */
8.630 + if (bidiBase.controlCount > 0) {
8.631 + int runIndex, ic;
8.632 + char c;
8.633 + for (ic = 0; ic < bidiBase.length; ic++) {
8.634 + c = bidiBase.text[ic];
8.635 + if (BidiBase.IsBidiControlChar(c)) {
8.636 + runIndex = getRunFromLogicalIndex(bidiBase, ic);
8.637 + bidiBase.runs[runIndex].insertRemove--;
8.638 + }
8.639 + }
8.640 + }
8.641 + }
8.642 +
8.643 + static int[] prepareReorder(byte[] levels, byte[] pMinLevel, byte[] pMaxLevel)
8.644 + {
8.645 + int start;
8.646 + byte level, minLevel, maxLevel;
8.647 +
8.648 + if (levels == null || levels.length <= 0) {
8.649 + return null;
8.650 + }
8.651 +
8.652 + /* determine minLevel and maxLevel */
8.653 + minLevel = BidiBase.MAX_EXPLICIT_LEVEL + 1;
8.654 + maxLevel = 0;
8.655 + for (start = levels.length; start>0; ) {
8.656 + level = levels[--start];
8.657 + if (level > BidiBase.MAX_EXPLICIT_LEVEL + 1) {
8.658 + return null;
8.659 + }
8.660 + if (level < minLevel) {
8.661 + minLevel = level;
8.662 + }
8.663 + if (level > maxLevel) {
8.664 + maxLevel = level;
8.665 + }
8.666 + }
8.667 + pMinLevel[0] = minLevel;
8.668 + pMaxLevel[0] = maxLevel;
8.669 +
8.670 + /* initialize the index map */
8.671 + int[] indexMap = new int[levels.length];
8.672 + for (start = levels.length; start > 0; ) {
8.673 + --start;
8.674 + indexMap[start] = start;
8.675 + }
8.676 +
8.677 + return indexMap;
8.678 + }
8.679 +
8.680 + static int[] reorderVisual(byte[] levels)
8.681 + {
8.682 + byte[] aMinLevel = new byte[1];
8.683 + byte[] aMaxLevel = new byte[1];
8.684 + int start, end, limit, temp;
8.685 + byte minLevel, maxLevel;
8.686 +
8.687 + int[] indexMap = prepareReorder(levels, aMinLevel, aMaxLevel);
8.688 + if (indexMap == null) {
8.689 + return null;
8.690 + }
8.691 +
8.692 + minLevel = aMinLevel[0];
8.693 + maxLevel = aMaxLevel[0];
8.694 +
8.695 + /* nothing to do? */
8.696 + if (minLevel == maxLevel && (minLevel & 1) == 0) {
8.697 + return indexMap;
8.698 + }
8.699 +
8.700 + /* reorder only down to the lowest odd level */
8.701 + minLevel |= 1;
8.702 +
8.703 + /* loop maxLevel..minLevel */
8.704 + do {
8.705 + start = 0;
8.706 +
8.707 + /* loop for all sequences of levels to reorder at the current maxLevel */
8.708 + for ( ; ; ) {
8.709 + /* look for a sequence of levels that are all at >=maxLevel */
8.710 + /* look for the first index of such a sequence */
8.711 + while (start < levels.length && levels[start] < maxLevel) {
8.712 + ++start;
8.713 + }
8.714 + if (start >= levels.length) {
8.715 + break; /* no more such runs */
8.716 + }
8.717 +
8.718 + /* look for the limit of such a sequence (the index behind it) */
8.719 + for (limit = start; ++limit < levels.length && levels[limit] >= maxLevel; ) {}
8.720 +
8.721 + /*
8.722 + * Swap the entire interval of indexes from start to limit-1.
8.723 + * We don't need to swap the levels for the purpose of this
8.724 + * algorithm: the sequence of levels that we look at does not
8.725 + * move anyway.
8.726 + */
8.727 + end = limit - 1;
8.728 + while (start < end) {
8.729 + temp = indexMap[start];
8.730 + indexMap[start] = indexMap[end];
8.731 + indexMap[end] = temp;
8.732 +
8.733 + ++start;
8.734 + --end;
8.735 + }
8.736 +
8.737 + if (limit == levels.length) {
8.738 + break; /* no more such sequences */
8.739 + } else {
8.740 + start = limit + 1;
8.741 + }
8.742 + }
8.743 + } while (--maxLevel >= minLevel);
8.744 +
8.745 + return indexMap;
8.746 + }
8.747 +
8.748 + static int[] getVisualMap(BidiBase bidiBase)
8.749 + {
8.750 + /* fill a visual-to-logical index map using the runs[] */
8.751 + BidiRun[] runs = bidiBase.runs;
8.752 + int logicalStart, visualStart, visualLimit;
8.753 + int allocLength = bidiBase.length > bidiBase.resultLength ? bidiBase.length
8.754 + : bidiBase.resultLength;
8.755 + int[] indexMap = new int[allocLength];
8.756 +
8.757 + visualStart = 0;
8.758 + int idx = 0;
8.759 + for (int j = 0; j < bidiBase.runCount; ++j) {
8.760 + logicalStart = runs[j].start;
8.761 + visualLimit = runs[j].limit;
8.762 + if (runs[j].isEvenRun()) {
8.763 + do { /* LTR */
8.764 + indexMap[idx++] = logicalStart++;
8.765 + } while (++visualStart < visualLimit);
8.766 + } else {
8.767 + logicalStart += visualLimit - visualStart; /* logicalLimit */
8.768 + do { /* RTL */
8.769 + indexMap[idx++] = --logicalStart;
8.770 + } while (++visualStart < visualLimit);
8.771 + }
8.772 + /* visualStart==visualLimit; */
8.773 + }
8.774 +
8.775 + if (bidiBase.insertPoints.size > 0) {
8.776 + int markFound = 0, runCount = bidiBase.runCount;
8.777 + int insertRemove, i, j, k;
8.778 + runs = bidiBase.runs;
8.779 + /* count all inserted marks */
8.780 + for (i = 0; i < runCount; i++) {
8.781 + insertRemove = runs[i].insertRemove;
8.782 + if ((insertRemove & (BidiBase.LRM_BEFORE|BidiBase.RLM_BEFORE)) > 0) {
8.783 + markFound++;
8.784 + }
8.785 + if ((insertRemove & (BidiBase.LRM_AFTER|BidiBase.RLM_AFTER)) > 0) {
8.786 + markFound++;
8.787 + }
8.788 + }
8.789 + /* move back indexes by number of preceding marks */
8.790 + k = bidiBase.resultLength;
8.791 + for (i = runCount - 1; i >= 0 && markFound > 0; i--) {
8.792 + insertRemove = runs[i].insertRemove;
8.793 + if ((insertRemove & (BidiBase.LRM_AFTER|BidiBase.RLM_AFTER)) > 0) {
8.794 + indexMap[--k] = BidiBase.MAP_NOWHERE;
8.795 + markFound--;
8.796 + }
8.797 + visualStart = i > 0 ? runs[i-1].limit : 0;
8.798 + for (j = runs[i].limit - 1; j >= visualStart && markFound > 0; j--) {
8.799 + indexMap[--k] = indexMap[j];
8.800 + }
8.801 + if ((insertRemove & (BidiBase.LRM_BEFORE|BidiBase.RLM_BEFORE)) > 0) {
8.802 + indexMap[--k] = BidiBase.MAP_NOWHERE;
8.803 + markFound--;
8.804 + }
8.805 + }
8.806 + }
8.807 + else if (bidiBase.controlCount > 0) {
8.808 + int runCount = bidiBase.runCount, logicalEnd;
8.809 + int insertRemove, length, i, j, k, m;
8.810 + char uchar;
8.811 + boolean evenRun;
8.812 + runs = bidiBase.runs;
8.813 + visualStart = 0;
8.814 + /* move forward indexes by number of preceding controls */
8.815 + k = 0;
8.816 + for (i = 0; i < runCount; i++, visualStart += length) {
8.817 + length = runs[i].limit - visualStart;
8.818 + insertRemove = runs[i].insertRemove;
8.819 + /* if no control found yet, nothing to do in this run */
8.820 + if ((insertRemove == 0) && (k == visualStart)) {
8.821 + k += length;
8.822 + continue;
8.823 + }
8.824 + /* if no control in this run */
8.825 + if (insertRemove == 0) {
8.826 + visualLimit = runs[i].limit;
8.827 + for (j = visualStart; j < visualLimit; j++) {
8.828 + indexMap[k++] = indexMap[j];
8.829 + }
8.830 + continue;
8.831 + }
8.832 + logicalStart = runs[i].start;
8.833 + evenRun = runs[i].isEvenRun();
8.834 + logicalEnd = logicalStart + length - 1;
8.835 + for (j = 0; j < length; j++) {
8.836 + m = evenRun ? logicalStart + j : logicalEnd - j;
8.837 + uchar = bidiBase.text[m];
8.838 + if (!BidiBase.IsBidiControlChar(uchar)) {
8.839 + indexMap[k++] = m;
8.840 + }
8.841 + }
8.842 + }
8.843 + }
8.844 + if (allocLength == bidiBase.resultLength) {
8.845 + return indexMap;
8.846 + }
8.847 + int[] newMap = new int[bidiBase.resultLength];
8.848 + System.arraycopy(indexMap, 0, newMap, 0, bidiBase.resultLength);
8.849 + return newMap;
8.850 + }
8.851 +
8.852 +}
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
9.2 +++ b/src/share/classes/sun/text/bidi/BidiRun.java Tue Jun 23 23:09:49 2009 -0700
9.3 @@ -0,0 +1,124 @@
9.4 +/*
9.5 + * Portions Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
9.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
9.7 + *
9.8 + * This code is free software; you can redistribute it and/or modify it
9.9 + * under the terms of the GNU General Public License version 2 only, as
9.10 + * published by the Free Software Foundation. Sun designates this
9.11 + * particular file as subject to the "Classpath" exception as provided
9.12 + * by Sun in the LICENSE file that accompanied this code.
9.13 + *
9.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
9.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
9.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
9.17 + * version 2 for more details (a copy is included in the LICENSE file that
9.18 + * accompanied this code).
9.19 + *
9.20 + * You should have received a copy of the GNU General Public License version
9.21 + * 2 along with this work; if not, write to the Free Software Foundation,
9.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
9.23 + *
9.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
9.25 + * CA 95054 USA or visit www.sun.com if you need additional information or
9.26 + * have any questions.
9.27 + */
9.28 +/*
9.29 + *******************************************************************************
9.30 + * (C) Copyright IBM Corp. and others, 1996-2009 - All Rights Reserved *
9.31 + * *
9.32 + * The original version of this source code and documentation is copyrighted *
9.33 + * and owned by IBM, These materials are provided under terms of a License *
9.34 + * Agreement between IBM and Sun. This technology is protected by multiple *
9.35 + * US and International patents. This notice and attribution to IBM may not *
9.36 + * to removed. *
9.37 + *******************************************************************************
9.38 + */
9.39 +/* Written by Simon Montagu, Matitiahu Allouche
9.40 + * (ported from C code written by Markus W. Scherer)
9.41 + */
9.42 +
9.43 +package sun.text.bidi;
9.44 +
9.45 +/**
9.46 + * A BidiRun represents a sequence of characters at the same embedding level.
9.47 + * The Bidi algorithm decomposes a piece of text into sequences of characters
9.48 + * at the same embedding level, each such sequence is called a <quote>run</quote>.
9.49 + *
9.50 + * <p>A BidiRun represents such a run by storing its essential properties,
9.51 + * but does not duplicate the characters which form the run.
9.52 + *
9.53 + * <p>The "limit" of the run is the position just after the
9.54 + * last character, i.e., one more than that position.
9.55 + *
9.56 + * <p>This class has no public constructor, and its members cannot be
9.57 + * modified by users.
9.58 + *
9.59 + * @see com.ibm.icu.text.Bidi
9.60 + */
9.61 +public class BidiRun {
9.62 +
9.63 + int start; /* first logical position of the run */
9.64 + int limit; /* last visual position of the run +1 */
9.65 + int insertRemove; /* if >0, flags for inserting LRM/RLM before/after run,
9.66 + if <0, count of bidi controls within run */
9.67 + byte level;
9.68 +
9.69 + /*
9.70 + * Default constructor
9.71 + *
9.72 + * Note that members start and limit of a run instance have different
9.73 + * meanings depending whether the run is part of the runs array of a Bidi
9.74 + * object, or if it is a reference returned by getVisualRun() or
9.75 + * getLogicalRun().
9.76 + * For a member of the runs array of a Bidi object,
9.77 + * - start is the first logical position of the run in the source text.
9.78 + * - limit is one after the last visual position of the run.
9.79 + * For a reference returned by getLogicalRun() or getVisualRun(),
9.80 + * - start is the first logical position of the run in the source text.
9.81 + * - limit is one after the last logical position of the run.
9.82 + */
9.83 + BidiRun()
9.84 + {
9.85 + this(0, 0, (byte)0);
9.86 + }
9.87 +
9.88 + /*
9.89 + * Constructor
9.90 + */
9.91 + BidiRun(int start, int limit, byte embeddingLevel)
9.92 + {
9.93 + this.start = start;
9.94 + this.limit = limit;
9.95 + this.level = embeddingLevel;
9.96 + }
9.97 +
9.98 + /*
9.99 + * Copy the content of a BidiRun instance
9.100 + */
9.101 + void copyFrom(BidiRun run)
9.102 + {
9.103 + this.start = run.start;
9.104 + this.limit = run.limit;
9.105 + this.level = run.level;
9.106 + this.insertRemove = run.insertRemove;
9.107 + }
9.108 +
9.109 + /**
9.110 + * Get level of run
9.111 + */
9.112 + public byte getEmbeddingLevel()
9.113 + {
9.114 + return level;
9.115 + }
9.116 +
9.117 + /**
9.118 + * Check if run level is even
9.119 + * @return true if the embedding level of this run is even, i.e. it is a
9.120 + * left-to-right run.
9.121 + */
9.122 + boolean isEvenRun()
9.123 + {
9.124 + return (level & 1) == 0;
9.125 + }
9.126 +
9.127 +}
10.1 --- a/src/share/classes/sun/text/normalizer/UCharacter.java Sun Jun 21 23:52:58 2009 -0700
10.2 +++ b/src/share/classes/sun/text/normalizer/UCharacter.java Tue Jun 23 23:09:49 2009 -0700
10.3 @@ -1,5 +1,5 @@
10.4 /*
10.5 - * Portions Copyright 2005-2009 Sun Microsystems, Inc. All Rights Reserved.
10.6 + * Portions Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
10.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
10.8 *
10.9 * This code is free software; you can redistribute it and/or modify it
10.10 @@ -355,7 +355,7 @@
10.11 private static int getEuropeanDigit(int ch) {
10.12 if ((ch > 0x7a && ch < 0xff21)
10.13 || ch < 0x41 || (ch > 0x5a && ch < 0x61)
10.14 - || ch > 0xff5a || (ch > 0xff31 && ch < 0xff41)) {
10.15 + || ch > 0xff5a || (ch > 0xff3a && ch < 0xff41)) {
10.16 return -1;
10.17 }
10.18 if (ch <= 0x7a) {
11.1 --- a/src/share/native/sun/font/bidi/cmemory.h Sun Jun 21 23:52:58 2009 -0700
11.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
11.3 @@ -1,66 +0,0 @@
11.4 -/*
11.5 - * Portions Copyright 2000 Sun Microsystems, Inc. All Rights Reserved.
11.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
11.7 - *
11.8 - * This code is free software; you can redistribute it and/or modify it
11.9 - * under the terms of the GNU General Public License version 2 only, as
11.10 - * published by the Free Software Foundation. Sun designates this
11.11 - * particular file as subject to the "Classpath" exception as provided
11.12 - * by Sun in the LICENSE file that accompanied this code.
11.13 - *
11.14 - * This code is distributed in the hope that it will be useful, but WITHOUT
11.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11.16 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11.17 - * version 2 for more details (a copy is included in the LICENSE file that
11.18 - * accompanied this code).
11.19 - *
11.20 - * You should have received a copy of the GNU General Public License version
11.21 - * 2 along with this work; if not, write to the Free Software Foundation,
11.22 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
11.23 - *
11.24 - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
11.25 - * CA 95054 USA or visit www.sun.com if you need additional information or
11.26 - * have any questions.
11.27 - */
11.28 -
11.29 -/*
11.30 - * (C) Copyright IBM Corp. 1998, 1999 - All Rights Reserved
11.31 - *
11.32 - * The original version of this source code and documentation is
11.33 - * copyrighted and owned by IBM. These materials are provided
11.34 - * under terms of a License Agreement between IBM and Sun.
11.35 - * This technology is protected by multiple US and International
11.36 - * patents. This notice and attribution to IBM may not be removed.
11.37 - */
11.38 -
11.39 -/*
11.40 -* File CMEMORY.H
11.41 -*
11.42 -* Contains stdlib.h/string.h memory functions
11.43 -*
11.44 -* @author Bertrand A. Damiba
11.45 -*
11.46 -* Modification History:
11.47 -*
11.48 -* Date Name Description
11.49 -* 6/20/98 Bertrand Created.
11.50 -* 05/03/99 stephen Changed from functions to macros.
11.51 -*
11.52 -*******************************************************************************
11.53 -*/
11.54 -
11.55 -#ifndef CMEMORY_H
11.56 -#define CMEMORY_H
11.57 -
11.58 -#include <stdlib.h>
11.59 -#include <string.h>
11.60 -
11.61 -#define icu_malloc(size) malloc(size)
11.62 -#define icu_realloc(buffer, size) realloc(buffer, size)
11.63 -#define icu_free(buffer) free(buffer)
11.64 -#define icu_memcpy(dst, src, size) memcpy(dst, src, size)
11.65 -#define icu_memmove(dst, src, size) memmove(dst, src, size)
11.66 -#define icu_memset(buffer, mark, size) memset(buffer, mark, size)
11.67 -#define icu_memcmp(buffer1, buffer2, size) memcmp(buffer1, buffer2,size)
11.68 -
11.69 -#endif
12.1 --- a/src/share/native/sun/font/bidi/jbidi.c Sun Jun 21 23:52:58 2009 -0700
12.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
12.3 @@ -1,167 +0,0 @@
12.4 -/*
12.5 - * Portions Copyright 2000-2003 Sun Microsystems, Inc. All Rights Reserved.
12.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
12.7 - *
12.8 - * This code is free software; you can redistribute it and/or modify it
12.9 - * under the terms of the GNU General Public License version 2 only, as
12.10 - * published by the Free Software Foundation. Sun designates this
12.11 - * particular file as subject to the "Classpath" exception as provided
12.12 - * by Sun in the LICENSE file that accompanied this code.
12.13 - *
12.14 - * This code is distributed in the hope that it will be useful, but WITHOUT
12.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12.16 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12.17 - * version 2 for more details (a copy is included in the LICENSE file that
12.18 - * accompanied this code).
12.19 - *
12.20 - * You should have received a copy of the GNU General Public License version
12.21 - * 2 along with this work; if not, write to the Free Software Foundation,
12.22 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
12.23 - *
12.24 - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
12.25 - * CA 95054 USA or visit www.sun.com if you need additional information or
12.26 - * have any questions.
12.27 - */
12.28 -
12.29 -/*
12.30 - * (C) Copyright IBM Corp. 2000 - 2003 - All Rights Reserved
12.31 - *
12.32 - * The original version of this source code and documentation is
12.33 - * copyrighted and owned by IBM. These materials are provided
12.34 - * under terms of a License Agreement between IBM and Sun.
12.35 - * This technology is protected by multiple US and International
12.36 - * patents. This notice and attribution to IBM may not be removed.
12.37 - */
12.38 -
12.39 -// jni interface to native bidi from java
12.40 -
12.41 -#include <stdlib.h>
12.42 -#include "jbidi.h"
12.43 -
12.44 -#define U_COMMON_IMPLEMENTATION
12.45 -#include "ubidi.h"
12.46 -#include "ubidiimp.h"
12.47 -#include "uchardir.h"
12.48 -
12.49 -static jclass g_bidi_class = 0;
12.50 -static jmethodID g_bidi_reset = 0;
12.51 -
12.52 -static void resetBidi(JNIEnv *env, jclass cls, jobject bidi, jint dir, jint level, jint len, jintArray runs, jintArray cws) {
12.53 - if (!g_bidi_class) {
12.54 - g_bidi_class = (*env)->NewGlobalRef(env, cls);
12.55 - g_bidi_reset = (*env)->GetMethodID(env, g_bidi_class, "reset", "(III[I[I)V");
12.56 - }
12.57 -
12.58 - (*env)->CallVoidMethod(env, bidi, g_bidi_reset, dir, level, len, runs, cws);
12.59 -}
12.60 -
12.61 -JNIEXPORT jint JNICALL Java_java_text_Bidi_nativeGetDirectionCode
12.62 - (JNIEnv *env, jclass cls, jint cp)
12.63 -{
12.64 - return (jint)u_getDirection((uint32_t)cp);
12.65 -}
12.66 -
12.67 -JNIEXPORT void JNICALL Java_java_text_Bidi_nativeBidiChars
12.68 - (JNIEnv *env, jclass cls, jobject jbidi, jcharArray text, jint tStart, jbyteArray embs, jint eStart, jint length, jint dir)
12.69 -{
12.70 - UErrorCode err = U_ZERO_ERROR;
12.71 - UBiDi* bidi = ubidi_openSized(length, length, &err);
12.72 - if (!U_FAILURE(err)) {
12.73 - jchar *cText = (jchar*)(*env)->GetPrimitiveArrayCritical(env, text, NULL);
12.74 - if (cText) {
12.75 - UBiDiLevel baseLevel = (UBiDiLevel)dir;
12.76 - jbyte *cEmbs = 0;
12.77 - uint8_t *cEmbsAdj = 0;
12.78 - if (embs != NULL) {
12.79 - cEmbs = (jbyte*)(*env)->GetPrimitiveArrayCritical(env, embs, NULL);
12.80 - if (cEmbs) {
12.81 - cEmbsAdj = (uint8_t*)(cEmbs + eStart);
12.82 - }
12.83 - }
12.84 - ubidi_setPara(bidi, cText + tStart, length, baseLevel, cEmbsAdj, &err);
12.85 - if (cEmbs) {
12.86 - (*env)->ReleasePrimitiveArrayCritical(env, embs, cEmbs, JNI_ABORT);
12.87 - }
12.88 -
12.89 - (*env)->ReleasePrimitiveArrayCritical(env, text, cText, JNI_ABORT);
12.90 -
12.91 - if (!U_FAILURE(err)) {
12.92 - jint resDir = (jint)ubidi_getDirection(bidi);
12.93 - jint resLevel = (jint)ubidi_getParaLevel(bidi);
12.94 - jint resRunCount = 0;
12.95 - jintArray resRuns = 0;
12.96 - jintArray resCWS = 0;
12.97 - if (resDir == UBIDI_MIXED) {
12.98 - resRunCount = (jint)ubidi_countRuns(bidi, &err);
12.99 - if (!U_FAILURE(err)) {
12.100 - if (resRunCount) {
12.101 - jint* cResRuns = (jint*)calloc(resRunCount * 2, sizeof(jint));
12.102 - if (cResRuns) {
12.103 - int32_t limit = 0;
12.104 - UBiDiLevel level;
12.105 - jint *p = cResRuns;
12.106 - while (limit < length) {
12.107 - ubidi_getLogicalRun(bidi, limit, &limit, &level);
12.108 - *p++ = (jint)limit;
12.109 - *p++ = (jint)level;
12.110 - }
12.111 -
12.112 - {
12.113 - const DirProp *dp = bidi->dirProps;
12.114 - jint ccws = 0;
12.115 - jint n = 0;
12.116 - p = cResRuns;
12.117 - do {
12.118 - if ((*(p+1) ^ resLevel) & 0x1) {
12.119 - while (n < *p) {
12.120 - if (dp[n++] == WS) {
12.121 - ++ccws;
12.122 - }
12.123 - }
12.124 - } else {
12.125 - n = *p;
12.126 - }
12.127 - p += 2;
12.128 - } while (n < length);
12.129 -
12.130 - resCWS = (*env)->NewIntArray(env, ccws);
12.131 - if (resCWS) {
12.132 - jint* cResCWS = (jint*)(*env)->GetPrimitiveArrayCritical(env, resCWS, NULL);
12.133 - if (cResCWS) {
12.134 - jint ccws = 0;
12.135 - jint n = 0;
12.136 - p = cResRuns;
12.137 - do {
12.138 - if ((*(p+1) ^ resLevel) & 0x1) {
12.139 - while (n < *p) {
12.140 - if (dp[n] == WS) {
12.141 - cResCWS[ccws++] = n;
12.142 - }
12.143 - ++n;
12.144 - }
12.145 - } else {
12.146 - n = *p;
12.147 - }
12.148 - p += 2;
12.149 - } while (n < length);
12.150 - (*env)->ReleasePrimitiveArrayCritical(env, resCWS, cResCWS, 0);
12.151 - }
12.152 - }
12.153 - }
12.154 -
12.155 - resRuns = (*env)->NewIntArray(env, resRunCount * 2);
12.156 - if (resRuns) {
12.157 - (*env)->SetIntArrayRegion(env, resRuns, 0, resRunCount * 2, cResRuns);
12.158 - }
12.159 - free(cResRuns);
12.160 - }
12.161 - }
12.162 - }
12.163 - }
12.164 -
12.165 - resetBidi(env, cls, jbidi, resDir, resLevel, length, resRuns, resCWS);
12.166 - }
12.167 - }
12.168 - ubidi_close(bidi);
12.169 - }
12.170 -}
13.1 --- a/src/share/native/sun/font/bidi/jbidi.h Sun Jun 21 23:52:58 2009 -0700
13.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
13.3 @@ -1,69 +0,0 @@
13.4 -/*
13.5 - * Portions Copyright 2000-2003 Sun Microsystems, Inc. All Rights Reserved.
13.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
13.7 - *
13.8 - * This code is free software; you can redistribute it and/or modify it
13.9 - * under the terms of the GNU General Public License version 2 only, as
13.10 - * published by the Free Software Foundation. Sun designates this
13.11 - * particular file as subject to the "Classpath" exception as provided
13.12 - * by Sun in the LICENSE file that accompanied this code.
13.13 - *
13.14 - * This code is distributed in the hope that it will be useful, but WITHOUT
13.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13.16 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13.17 - * version 2 for more details (a copy is included in the LICENSE file that
13.18 - * accompanied this code).
13.19 - *
13.20 - * You should have received a copy of the GNU General Public License version
13.21 - * 2 along with this work; if not, write to the Free Software Foundation,
13.22 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
13.23 - *
13.24 - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
13.25 - * CA 95054 USA or visit www.sun.com if you need additional information or
13.26 - * have any questions.
13.27 - */
13.28 -
13.29 -/*
13.30 - * (C) Copyright IBM Corp. 2000 - 2003 - All Rights Reserved
13.31 - *
13.32 - * The original version of this source code and documentation is
13.33 - * copyrighted and owned by IBM. These materials are provided
13.34 - * under terms of a License Agreement between IBM and Sun.
13.35 - * This technology is protected by multiple US and International
13.36 - * patents. This notice and attribution to IBM may not be removed.
13.37 - */
13.38 -
13.39 -/* DO NOT EDIT THIS FILE - it is machine generated */
13.40 -#include <jni.h>
13.41 -/* Header for class Bidi */
13.42 -
13.43 -#ifndef _Included_Bidi
13.44 -#define _Included_Bidi
13.45 -#ifdef __cplusplus
13.46 -extern "C" {
13.47 -#endif
13.48 -#undef Bidi_DIR_LTR
13.49 -#define Bidi_DIR_LTR 0L
13.50 -#undef Bidi_DIR_RTL
13.51 -#define Bidi_DIR_RTL 1L
13.52 -#undef Bidi_DIR_DEFAULT_LTR
13.53 -#define Bidi_DIR_DEFAULT_LTR -2L
13.54 -#undef Bidi_DIR_DEFAULT_RTL
13.55 -#define Bidi_DIR_DEFAULT_RTL -1L
13.56 -#undef Bidi_DIR_MIXED
13.57 -#define Bidi_DIR_MIXED -1L
13.58 -#undef Bidi_DIR_MIN
13.59 -#define Bidi_DIR_MIN -2L
13.60 -#undef Bidi_DIR_MAX
13.61 -#define Bidi_DIR_MAX 1L
13.62 -
13.63 -JNIEXPORT jint JNICALL Java_java_text_Bidi_nativeGetDirectionCode
13.64 - (JNIEnv *, jclass, jint);
13.65 -
13.66 -JNIEXPORT void JNICALL Java_java_text_Bidi_nativeBidiChars
13.67 - (JNIEnv *, jclass, jobject, jcharArray, jint, jbyteArray, jint, jint, jint);
13.68 -
13.69 -#ifdef __cplusplus
13.70 -}
13.71 -#endif
13.72 -#endif
14.1 --- a/src/share/native/sun/font/bidi/ubidi.c Sun Jun 21 23:52:58 2009 -0700
14.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
14.3 @@ -1,1433 +0,0 @@
14.4 -/*
14.5 - * Portions Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
14.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
14.7 - *
14.8 - * This code is free software; you can redistribute it and/or modify it
14.9 - * under the terms of the GNU General Public License version 2 only, as
14.10 - * published by the Free Software Foundation. Sun designates this
14.11 - * particular file as subject to the "Classpath" exception as provided
14.12 - * by Sun in the LICENSE file that accompanied this code.
14.13 - *
14.14 - * This code is distributed in the hope that it will be useful, but WITHOUT
14.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14.16 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14.17 - * version 2 for more details (a copy is included in the LICENSE file that
14.18 - * accompanied this code).
14.19 - *
14.20 - * You should have received a copy of the GNU General Public License version
14.21 - * 2 along with this work; if not, write to the Free Software Foundation,
14.22 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
14.23 - *
14.24 - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
14.25 - * CA 95054 USA or visit www.sun.com if you need additional information or
14.26 - * have any questions.
14.27 - */
14.28 -
14.29 -/*
14.30 - * (C) Copyright IBM Corp. 1999-2003 - All Rights Reserved
14.31 - *
14.32 - * The original version of this source code and documentation is
14.33 - * copyrighted and owned by IBM. These materials are provided
14.34 - * under terms of a License Agreement between IBM and Sun.
14.35 - * This technology is protected by multiple US and International
14.36 - * patents. This notice and attribution to IBM may not be removed.
14.37 - */
14.38 -
14.39 -/*
14.40 -*
14.41 -******************************************************************************
14.42 -* file name: ubidi.c
14.43 -* encoding: US-ASCII
14.44 -* tab size: 8 (not used)
14.45 -* indentation:4
14.46 -*
14.47 -* created on: 1999jul27
14.48 -* created by: Markus W. Scherer
14.49 -*/
14.50 -
14.51 -/* set import/export definitions */
14.52 -#ifndef U_COMMON_IMPLEMENTATION
14.53 -# define U_COMMON_IMPLEMENTATION
14.54 -#endif
14.55 -
14.56 -#include "cmemory.h"
14.57 -#include "utypes.h"
14.58 -#include "uchardir.h"
14.59 -#include "ubidi.h"
14.60 -#include "ubidiimp.h"
14.61 -
14.62 -/*
14.63 - * General implementation notes:
14.64 - *
14.65 - * Throughout the implementation, there are comments like (W2) that refer to
14.66 - * rules of the BiDi algorithm in its version 5, in this example to the second
14.67 - * rule of the resolution of weak types.
14.68 - *
14.69 - * For handling surrogate pairs, where two UChar's form one "abstract" (or UTF-32)
14.70 - * character according to UTF-16, the second UChar gets the directional property of
14.71 - * the entire character assigned, while the first one gets a BN, a boundary
14.72 - * neutral, type, which is ignored by most of the algorithm according to
14.73 - * rule (X9) and the implementation suggestions of the BiDi algorithm.
14.74 - *
14.75 - * Later, adjustWSLevels() will set the level for each BN to that of the
14.76 - * following character (UChar), which results in surrogate pairs getting the
14.77 - * same level on each of their surrogates.
14.78 - *
14.79 - * In a UTF-8 implementation, the same thing could be done: the last byte of
14.80 - * a multi-byte sequence would get the "real" property, while all previous
14.81 - * bytes of that sequence would get BN.
14.82 - *
14.83 - * It is not possible to assign all those parts of a character the same real
14.84 - * property because this would fail in the resolution of weak types with rules
14.85 - * that look at immediately surrounding types.
14.86 - *
14.87 - * As a related topic, this implementation does not remove Boundary Neutral
14.88 - * types from the input, but ignores them whereever this is relevant.
14.89 - * For example, the loop for the resolution of the weak types reads
14.90 - * types until it finds a non-BN.
14.91 - * Also, explicit embedding codes are neither changed into BN nor removed.
14.92 - * They are only treated the same way real BNs are.
14.93 - * As stated before, adjustWSLevels() takes care of them at the end.
14.94 - * For the purpose of conformance, the levels of all these codes
14.95 - * do not matter.
14.96 - *
14.97 - * Note that this implementation never modifies the dirProps
14.98 - * after the initial setup.
14.99 - *
14.100 - *
14.101 - * In this implementation, the resolution of weak types (Wn),
14.102 - * neutrals (Nn), and the assignment of the resolved level (In)
14.103 - * are all done in one single loop, in resolveImplicitLevels().
14.104 - * Changes of dirProp values are done on the fly, without writing
14.105 - * them back to the dirProps array.
14.106 - *
14.107 - *
14.108 - * This implementation contains code that allows to bypass steps of the
14.109 - * algorithm that are not needed on the specific paragraph
14.110 - * in order to speed up the most common cases considerably,
14.111 - * like text that is entirely LTR, or RTL text without numbers.
14.112 - *
14.113 - * Most of this is done by setting a bit for each directional property
14.114 - * in a flags variable and later checking for whether there are
14.115 - * any LTR characters or any RTL characters, or both, whether
14.116 - * there are any explicit embedding codes, etc.
14.117 - *
14.118 - * If the (Xn) steps are performed, then the flags are re-evaluated,
14.119 - * because they will then not contain the embedding codes any more
14.120 - * and will be adjusted for override codes, so that subsequently
14.121 - * more bypassing may be possible than what the initial flags suggested.
14.122 - *
14.123 - * If the text is not mixed-directional, then the
14.124 - * algorithm steps for the weak type resolution are not performed,
14.125 - * and all levels are set to the paragraph level.
14.126 - *
14.127 - * If there are no explicit embedding codes, then the (Xn) steps
14.128 - * are not performed.
14.129 - *
14.130 - * If embedding levels are supplied as a parameter, then all
14.131 - * explicit embedding codes are ignored, and the (Xn) steps
14.132 - * are not performed.
14.133 - *
14.134 - * White Space types could get the level of the run they belong to,
14.135 - * and are checked with a test of (flags&MASK_EMBEDDING) to
14.136 - * consider if the paragraph direction should be considered in
14.137 - * the flags variable.
14.138 - *
14.139 - * If there are no White Space types in the paragraph, then
14.140 - * (L1) is not necessary in adjustWSLevels().
14.141 - */
14.142 -
14.143 -/* prototypes --------------------------------------------------------------- */
14.144 -
14.145 -static void
14.146 -getDirProps(UBiDi *pBiDi, const UChar *text);
14.147 -
14.148 -static UBiDiDirection
14.149 -resolveExplicitLevels(UBiDi *pBiDi);
14.150 -
14.151 -static UBiDiDirection
14.152 -checkExplicitLevels(UBiDi *pBiDi, UErrorCode *pErrorCode);
14.153 -
14.154 -static UBiDiDirection
14.155 -directionFromFlags(Flags flags);
14.156 -
14.157 -static void
14.158 -resolveImplicitLevels(UBiDi *pBiDi,
14.159 - int32_t start, int32_t limit,
14.160 - DirProp sor, DirProp eor);
14.161 -
14.162 -static void
14.163 -adjustWSLevels(UBiDi *pBiDi);
14.164 -
14.165 -/* to avoid some conditional statements, use tiny constant arrays */
14.166 -static const Flags flagLR[2]={ DIRPROP_FLAG(L), DIRPROP_FLAG(R) };
14.167 -static const Flags flagE[2]={ DIRPROP_FLAG(LRE), DIRPROP_FLAG(RLE) };
14.168 -static const Flags flagO[2]={ DIRPROP_FLAG(LRO), DIRPROP_FLAG(RLO) };
14.169 -
14.170 -#define DIRPROP_FLAG_LR(level) flagLR[(level)&1]
14.171 -#define DIRPROP_FLAG_E(level) flagE[(level)&1]
14.172 -#define DIRPROP_FLAG_O(level) flagO[(level)&1]
14.173 -
14.174 -/* UBiDi object management -------------------------------------------------- */
14.175 -
14.176 -U_CAPI UBiDi * U_EXPORT2
14.177 -ubidi_open(void)
14.178 -{
14.179 - UErrorCode errorCode=U_ZERO_ERROR;
14.180 - return ubidi_openSized(0, 0, &errorCode);
14.181 -}
14.182 -
14.183 -U_CAPI UBiDi * U_EXPORT2
14.184 -ubidi_openSized(int32_t maxLength, int32_t maxRunCount, UErrorCode *pErrorCode) {
14.185 - UBiDi *pBiDi;
14.186 -
14.187 - /* check the argument values */
14.188 - if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
14.189 - return NULL;
14.190 - } else if(maxLength<0 || maxRunCount<0) {
14.191 - *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
14.192 - return NULL; /* invalid arguments */
14.193 - }
14.194 -
14.195 - /* allocate memory for the object */
14.196 - pBiDi=(UBiDi *)icu_malloc(sizeof(UBiDi));
14.197 - if(pBiDi==NULL) {
14.198 - *pErrorCode=U_MEMORY_ALLOCATION_ERROR;
14.199 - return NULL;
14.200 - }
14.201 -
14.202 - /* reset the object, all pointers NULL, all flags FALSE, all sizes 0 */
14.203 - icu_memset(pBiDi, 0, sizeof(UBiDi));
14.204 -
14.205 - /* allocate memory for arrays as requested */
14.206 - if(maxLength>0) {
14.207 - if( !getInitialDirPropsMemory(pBiDi, maxLength) ||
14.208 - !getInitialLevelsMemory(pBiDi, maxLength)
14.209 - ) {
14.210 - *pErrorCode=U_MEMORY_ALLOCATION_ERROR;
14.211 - }
14.212 - } else {
14.213 - pBiDi->mayAllocateText=TRUE;
14.214 - }
14.215 -
14.216 - if(maxRunCount>0) {
14.217 - if(maxRunCount==1) {
14.218 - /* use simpleRuns[] */
14.219 - pBiDi->runsSize=sizeof(Run);
14.220 - } else if(!getInitialRunsMemory(pBiDi, maxRunCount)) {
14.221 - *pErrorCode=U_MEMORY_ALLOCATION_ERROR;
14.222 - }
14.223 - } else {
14.224 - pBiDi->mayAllocateRuns=TRUE;
14.225 - }
14.226 -
14.227 - if(U_SUCCESS(*pErrorCode)) {
14.228 - return pBiDi;
14.229 - } else {
14.230 - ubidi_close(pBiDi);
14.231 - return NULL;
14.232 - }
14.233 -}
14.234 -
14.235 -/*
14.236 - * We are allowed to allocate memory if memory==NULL or
14.237 - * mayAllocate==TRUE for each array that we need.
14.238 - * We also try to grow and shrink memory as needed if we
14.239 - * allocate it.
14.240 - *
14.241 - * Assume sizeNeeded>0.
14.242 - * If *pMemory!=NULL, then assume *pSize>0.
14.243 - *
14.244 - * ### this realloc() may unnecessarily copy the old data,
14.245 - * which we know we don't need any more;
14.246 - * is this the best way to do this??
14.247 - */
14.248 -extern bool_t
14.249 -ubidi_getMemory(void **pMemory, int32_t *pSize, bool_t mayAllocate, int32_t sizeNeeded) {
14.250 - /* check for existing memory */
14.251 - if(*pMemory==NULL) {
14.252 - /* we need to allocate memory */
14.253 - if(mayAllocate && (*pMemory=icu_malloc(sizeNeeded))!=NULL) {
14.254 - *pSize=sizeNeeded;
14.255 - return TRUE;
14.256 - } else {
14.257 - return FALSE;
14.258 - }
14.259 - } else {
14.260 - /* there is some memory, is it enough or too much? */
14.261 - if(sizeNeeded>*pSize && !mayAllocate) {
14.262 - /* not enough memory, and we must not allocate */
14.263 - return FALSE;
14.264 - } else if(sizeNeeded!=*pSize && mayAllocate) {
14.265 - /* we may try to grow or shrink */
14.266 - void *memory;
14.267 -
14.268 - if((memory=icu_realloc(*pMemory, sizeNeeded))!=NULL) {
14.269 - *pMemory=memory;
14.270 - *pSize=sizeNeeded;
14.271 - return TRUE;
14.272 - } else {
14.273 - /* we failed to grow */
14.274 - return FALSE;
14.275 - }
14.276 - } else {
14.277 - /* we have at least enough memory and must not allocate */
14.278 - return TRUE;
14.279 - }
14.280 - }
14.281 -}
14.282 -
14.283 -U_CAPI void U_EXPORT2
14.284 -ubidi_close(UBiDi *pBiDi) {
14.285 - if(pBiDi!=NULL) {
14.286 - if(pBiDi->dirPropsMemory!=NULL) {
14.287 - icu_free(pBiDi->dirPropsMemory);
14.288 - }
14.289 - if(pBiDi->levelsMemory!=NULL) {
14.290 - icu_free(pBiDi->levelsMemory);
14.291 - }
14.292 - if(pBiDi->runsMemory!=NULL) {
14.293 - icu_free(pBiDi->runsMemory);
14.294 - }
14.295 - icu_free(pBiDi);
14.296 - }
14.297 -}
14.298 -
14.299 -/* set to approximate "inverse BiDi" ---------------------------------------- */
14.300 -
14.301 -U_CAPI void U_EXPORT2
14.302 -ubidi_setInverse(UBiDi *pBiDi, bool_t isInverse) {
14.303 - if(pBiDi!=NULL) {
14.304 - pBiDi->isInverse=isInverse;
14.305 - }
14.306 -}
14.307 -
14.308 -U_CAPI bool_t U_EXPORT2
14.309 -ubidi_isInverse(UBiDi *pBiDi) {
14.310 - if(pBiDi!=NULL) {
14.311 - return pBiDi->isInverse;
14.312 - } else {
14.313 - return FALSE;
14.314 - }
14.315 -}
14.316 -
14.317 -/* ubidi_setPara ------------------------------------------------------------ */
14.318 -
14.319 -U_CAPI void U_EXPORT2
14.320 -ubidi_setPara(UBiDi *pBiDi, const UChar *text, int32_t length,
14.321 - UBiDiLevel paraLevel, UBiDiLevel *embeddingLevels,
14.322 - UErrorCode *pErrorCode) {
14.323 - UBiDiDirection direction;
14.324 -
14.325 - /* check the argument values */
14.326 - if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
14.327 - return;
14.328 - } else if(pBiDi==NULL || text==NULL ||
14.329 - ((UBIDI_MAX_EXPLICIT_LEVEL<paraLevel) && !IS_DEFAULT_LEVEL(paraLevel)) ||
14.330 - length<-1
14.331 - ) {
14.332 - *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
14.333 - return;
14.334 - }
14.335 -
14.336 - if(length==-1) {
14.337 - // length=u_strlen(text);
14.338 - const UChar *p = text - 1;
14.339 - while(*++p);
14.340 - length = p - text;
14.341 - }
14.342 -
14.343 - /* initialize the UBiDi structure */
14.344 - pBiDi->text=text;
14.345 - pBiDi->length=length;
14.346 - pBiDi->paraLevel=paraLevel;
14.347 - pBiDi->direction=UBIDI_LTR;
14.348 - pBiDi->trailingWSStart=length; /* the levels[] will reflect the WS run */
14.349 -
14.350 - pBiDi->dirProps=NULL;
14.351 - pBiDi->levels=NULL;
14.352 - pBiDi->runs=NULL;
14.353 -
14.354 - if(length==0) {
14.355 - /*
14.356 - * For an empty paragraph, create a UBiDi object with the paraLevel and
14.357 - * the flags and the direction set but without allocating zero-length arrays.
14.358 - * There is nothing more to do.
14.359 - */
14.360 - if(IS_DEFAULT_LEVEL(paraLevel)) {
14.361 - pBiDi->paraLevel&=1;
14.362 - }
14.363 - if(paraLevel&1) {
14.364 - pBiDi->flags=DIRPROP_FLAG(R);
14.365 - pBiDi->direction=UBIDI_RTL;
14.366 - } else {
14.367 - pBiDi->flags=DIRPROP_FLAG(L);
14.368 - pBiDi->direction=UBIDI_LTR;
14.369 - }
14.370 -
14.371 - pBiDi->runCount=0;
14.372 - return;
14.373 - }
14.374 -
14.375 - pBiDi->runCount=-1;
14.376 -
14.377 - /*
14.378 - * Get the directional properties,
14.379 - * the flags bit-set, and
14.380 - * determine the partagraph level if necessary.
14.381 - */
14.382 - if(getDirPropsMemory(pBiDi, length)) {
14.383 - pBiDi->dirProps=pBiDi->dirPropsMemory;
14.384 - getDirProps(pBiDi, text);
14.385 - } else {
14.386 - *pErrorCode=U_MEMORY_ALLOCATION_ERROR;
14.387 - return;
14.388 - }
14.389 -
14.390 - if (getLevelsMemory(pBiDi, length)) {
14.391 - pBiDi->levels=pBiDi->levelsMemory;
14.392 - /* are explicit levels specified? */
14.393 - if(embeddingLevels==NULL) {
14.394 - /* no: determine explicit levels according to the (Xn) rules */
14.395 - direction=resolveExplicitLevels(pBiDi);
14.396 - } else {
14.397 - /* set BN for all explicit codes, check that all levels are paraLevel..UBIDI_MAX_EXPLICIT_LEVEL */
14.398 - icu_memcpy(pBiDi->levels, embeddingLevels, length);
14.399 - direction=checkExplicitLevels(pBiDi, pErrorCode);
14.400 - if(U_FAILURE(*pErrorCode)) {
14.401 - return;
14.402 - }
14.403 - }
14.404 - } else {
14.405 - *pErrorCode=U_MEMORY_ALLOCATION_ERROR;
14.406 - return;
14.407 - }
14.408 -
14.409 - /*
14.410 - * The steps after (X9) in the UBiDi algorithm are performed only if
14.411 - * the paragraph text has mixed directionality!
14.412 - */
14.413 - pBiDi->direction=direction;
14.414 - switch(direction) {
14.415 - case UBIDI_LTR:
14.416 - /* make sure paraLevel is even */
14.417 - pBiDi->paraLevel=(UBiDiLevel)((pBiDi->paraLevel+1)&~1);
14.418 -
14.419 - /* all levels are implicitly at paraLevel (important for ubidi_getLevels()) */
14.420 - pBiDi->trailingWSStart=0;
14.421 - break;
14.422 - case UBIDI_RTL:
14.423 - /* make sure paraLevel is odd */
14.424 - pBiDi->paraLevel|=1;
14.425 -
14.426 - /* all levels are implicitly at paraLevel (important for ubidi_getLevels()) */
14.427 - pBiDi->trailingWSStart=0;
14.428 - break;
14.429 - default:
14.430 - /*
14.431 - * If there are no external levels specified and there
14.432 - * are no significant explicit level codes in the text,
14.433 - * then we can treat the entire paragraph as one run.
14.434 - * Otherwise, we need to perform the following rules on runs of
14.435 - * the text with the same embedding levels. (X10)
14.436 - * "Significant" explicit level codes are ones that actually
14.437 - * affect non-BN characters.
14.438 - * Examples for "insignificant" ones are empty embeddings
14.439 - * LRE-PDF, LRE-RLE-PDF-PDF, etc.
14.440 - */
14.441 - if(embeddingLevels==NULL && !(pBiDi->flags&DIRPROP_FLAG_MULTI_RUNS)) {
14.442 - resolveImplicitLevels(pBiDi, 0, length,
14.443 - GET_LR_FROM_LEVEL(pBiDi->paraLevel),
14.444 - GET_LR_FROM_LEVEL(pBiDi->paraLevel));
14.445 - } else {
14.446 - /* sor, eor: start and end types of same-level-run */
14.447 - UBiDiLevel *levels=pBiDi->levels;
14.448 - int32_t start, limit=0;
14.449 - UBiDiLevel level, nextLevel;
14.450 - DirProp sor, eor;
14.451 -
14.452 - /* determine the first sor and set eor to it because of the loop body (sor=eor there) */
14.453 - level=pBiDi->paraLevel;
14.454 - nextLevel=levels[0];
14.455 - if(level<nextLevel) {
14.456 - eor=GET_LR_FROM_LEVEL(nextLevel);
14.457 - } else {
14.458 - eor=GET_LR_FROM_LEVEL(level);
14.459 - }
14.460 -
14.461 - do {
14.462 - /* determine start and limit of the run (end points just behind the run) */
14.463 -
14.464 - /* the values for this run's start are the same as for the previous run's end */
14.465 - sor=eor;
14.466 - start=limit;
14.467 - level=nextLevel;
14.468 -
14.469 - /* search for the limit of this run */
14.470 - while(++limit<length && levels[limit]==level) {}
14.471 -
14.472 - /* get the correct level of the next run */
14.473 - if(limit<length) {
14.474 - nextLevel=levels[limit];
14.475 - } else {
14.476 - nextLevel=pBiDi->paraLevel;
14.477 - }
14.478 -
14.479 - /* determine eor from max(level, nextLevel); sor is last run's eor */
14.480 - if((level&~UBIDI_LEVEL_OVERRIDE)<(nextLevel&~UBIDI_LEVEL_OVERRIDE)) {
14.481 - eor=GET_LR_FROM_LEVEL(nextLevel);
14.482 - } else {
14.483 - eor=GET_LR_FROM_LEVEL(level);
14.484 - }
14.485 -
14.486 - /* if the run consists of overridden directional types, then there
14.487 - are no implicit types to be resolved */
14.488 - if(!(level&UBIDI_LEVEL_OVERRIDE)) {
14.489 - resolveImplicitLevels(pBiDi, start, limit, sor, eor);
14.490 - } else {
14.491 - /* remove the UBIDI_LEVEL_OVERRIDE flags */
14.492 - do {
14.493 - levels[start++]&=~UBIDI_LEVEL_OVERRIDE;
14.494 - } while(start<limit);
14.495 - }
14.496 - } while(limit<length);
14.497 - }
14.498 -
14.499 - /* reset the embedding levels for some non-graphic characters (L1), (X9) */
14.500 - adjustWSLevels(pBiDi);
14.501 -
14.502 - /* for "inverse BiDi", ubidi_getRuns() modifies the levels of numeric runs following RTL runs */
14.503 - if(pBiDi->isInverse) {
14.504 - if(!ubidi_getRuns(pBiDi)) {
14.505 - *pErrorCode=U_MEMORY_ALLOCATION_ERROR;
14.506 - return;
14.507 - }
14.508 - }
14.509 - break;
14.510 - }
14.511 -}
14.512 -
14.513 -/* perform (P2)..(P3) ------------------------------------------------------- */
14.514 -
14.515 -/*
14.516 - * Get the directional properties for the text,
14.517 - * calculate the flags bit-set, and
14.518 - * determine the partagraph level if necessary.
14.519 - */
14.520 -static void
14.521 -getDirProps(UBiDi *pBiDi, const UChar *text) {
14.522 - DirProp *dirProps=pBiDi->dirPropsMemory; /* pBiDi->dirProps is const */
14.523 -
14.524 - int32_t i=0, i0, i1, length=pBiDi->length;
14.525 - Flags flags=0; /* collect all directionalities in the text */
14.526 - UChar uchar;
14.527 - DirProp dirProp;
14.528 -
14.529 - if(IS_DEFAULT_LEVEL(pBiDi->paraLevel)) {
14.530 - /* determine the paragraph level (P2..P3) */
14.531 - for(;;) {
14.532 - uchar=text[i];
14.533 - if(!IS_FIRST_SURROGATE(uchar) || i+1==length || !IS_SECOND_SURROGATE(text[i+1])) {
14.534 - /* not a surrogate pair */
14.535 - flags|=DIRPROP_FLAG(dirProps[i]=dirProp=u_charDirection(uchar));
14.536 - } else {
14.537 - /* a surrogate pair */
14.538 - dirProps[i++]=BN; /* first surrogate in the pair gets the BN type */
14.539 - flags|=DIRPROP_FLAG(dirProps[i]=dirProp=u_surrogatePairDirection(uchar, text[i]))|DIRPROP_FLAG(BN);
14.540 - }
14.541 - ++i;
14.542 - if(dirProp==L) {
14.543 - pBiDi->paraLevel=0;
14.544 - break;
14.545 - } else if(dirProp==R || dirProp==AL) {
14.546 - pBiDi->paraLevel=1;
14.547 - break;
14.548 - } else if(i>=length) {
14.549 - /*
14.550 - * see comment in ubidi.h:
14.551 - * the DEFAULT_XXX values are designed so that
14.552 - * their bit 0 alone yields the intended default
14.553 - */
14.554 - pBiDi->paraLevel&=1;
14.555 - break;
14.556 - }
14.557 - }
14.558 - } else {
14.559 - flags|=DIRPROP_FLAG_LR(pBiDi->paraLevel);
14.560 - }
14.561 -
14.562 - /* get the rest of the directional properties and the flags bits */
14.563 - while(i<length) {
14.564 - uchar=text[i];
14.565 - if(!IS_FIRST_SURROGATE(uchar) || i+1==length || !IS_SECOND_SURROGATE(text[i+1])) {
14.566 - /* not a surrogate pair */
14.567 - flags|=DIRPROP_FLAG(dirProps[i]=u_charDirection(uchar));
14.568 - } else {
14.569 - /* a surrogate pair */
14.570 - dirProps[i++]=BN; /* first surrogate in the pair gets the BN type */
14.571 - flags|=DIRPROP_FLAG(dirProps[i]=dirProp=u_surrogatePairDirection(uchar, text[i]))|DIRPROP_FLAG(BN);
14.572 - }
14.573 - ++i;
14.574 - }
14.575 - if(flags&MASK_EMBEDDING) {
14.576 - flags|=DIRPROP_FLAG_LR(pBiDi->paraLevel);
14.577 - }
14.578 -
14.579 - pBiDi->flags=flags;
14.580 -}
14.581 -
14.582 -/* perform (X1)..(X9) ------------------------------------------------------- */
14.583 -
14.584 -/*
14.585 - * Resolve the explicit levels as specified by explicit embedding codes.
14.586 - * Recalculate the flags to have them reflect the real properties
14.587 - * after taking the explicit embeddings into account.
14.588 - *
14.589 - * The BiDi algorithm is designed to result in the same behavior whether embedding
14.590 - * levels are externally specified (from "styled text", supposedly the preferred
14.591 - * method) or set by explicit embedding codes (LRx, RLx, PDF) in the plain text.
14.592 - * That is why (X9) instructs to remove all explicit codes (and BN).
14.593 - * However, in a real implementation, this removal of these codes and their index
14.594 - * positions in the plain text is undesirable since it would result in
14.595 - * reallocated, reindexed text.
14.596 - * Instead, this implementation leaves the codes in there and just ignores them
14.597 - * in the subsequent processing.
14.598 - * In order to get the same reordering behavior, positions with a BN or an
14.599 - * explicit embedding code just get the same level assigned as the last "real"
14.600 - * character.
14.601 - *
14.602 - * Some implementations, not this one, then overwrite some of these
14.603 - * directionality properties at "real" same-level-run boundaries by
14.604 - * L or R codes so that the resolution of weak types can be performed on the
14.605 - * entire paragraph at once instead of having to parse it once more and
14.606 - * perform that resolution on same-level-runs.
14.607 - * This limits the scope of the implicit rules in effectively
14.608 - * the same way as the run limits.
14.609 - *
14.610 - * Instead, this implementation does not modify these codes.
14.611 - * On one hand, the paragraph has to be scanned for same-level-runs, but
14.612 - * on the other hand, this saves another loop to reset these codes,
14.613 - * or saves making and modifying a copy of dirProps[].
14.614 - *
14.615 - *
14.616 - * Note that (Pn) and (Xn) changed significantly from version 4 of the BiDi algorithm.
14.617 - *
14.618 - *
14.619 - * Handling the stack of explicit levels (Xn):
14.620 - *
14.621 - * With the BiDi stack of explicit levels,
14.622 - * as pushed with each LRE, RLE, LRO, and RLO and popped with each PDF,
14.623 - * the explicit level must never exceed UBIDI_MAX_EXPLICIT_LEVEL==61.
14.624 - *
14.625 - * In order to have a correct push-pop semantics even in the case of overflows,
14.626 - * there are two overflow counters:
14.627 - * - countOver60 is incremented with each LRx at level 60
14.628 - * - from level 60, one RLx increases the level to 61
14.629 - * - countOver61 is incremented with each LRx and RLx at level 61
14.630 - *
14.631 - * Popping levels with PDF must work in the opposite order so that level 61
14.632 - * is correct at the correct point. Underflows (too many PDFs) must be checked.
14.633 - *
14.634 - * This implementation assumes that UBIDI_MAX_EXPLICIT_LEVEL is odd.
14.635 - */
14.636 -
14.637 -static UBiDiDirection
14.638 -resolveExplicitLevels(UBiDi *pBiDi) {
14.639 - const DirProp *dirProps=pBiDi->dirProps;
14.640 - UBiDiLevel *levels=pBiDi->levels;
14.641 -
14.642 - int32_t i=0, length=pBiDi->length;
14.643 - Flags flags=pBiDi->flags; /* collect all directionalities in the text */
14.644 - DirProp dirProp;
14.645 - UBiDiLevel level=pBiDi->paraLevel;
14.646 -
14.647 - UBiDiDirection direction;
14.648 -
14.649 - /* determine if the text is mixed-directional or single-directional */
14.650 - direction=directionFromFlags(flags);
14.651 -
14.652 - /* we may not need to resolve any explicit levels */
14.653 - if(direction!=UBIDI_MIXED) {
14.654 - /* not mixed directionality: levels don't matter - trailingWSStart will be 0 */
14.655 - } else if(!(flags&MASK_EXPLICIT) || pBiDi->isInverse) {
14.656 - /* mixed, but all characters are at the same embedding level */
14.657 - /* or we are in "inverse BiDi" */
14.658 - /* set all levels to the paragraph level */
14.659 - for(i=0; i<length; ++i) {
14.660 - levels[i]=level;
14.661 - }
14.662 - } else {
14.663 - /* continue to perform (Xn) */
14.664 -
14.665 - /* (X1) level is set for all codes, embeddingLevel keeps track of the push/pop operations */
14.666 - /* both variables may carry the UBIDI_LEVEL_OVERRIDE flag to indicate the override status */
14.667 - UBiDiLevel embeddingLevel=level, newLevel, stackTop=0;
14.668 -
14.669 - UBiDiLevel stack[UBIDI_MAX_EXPLICIT_LEVEL]; /* we never push anything >=UBIDI_MAX_EXPLICIT_LEVEL */
14.670 - uint32_t countOver60=0, countOver61=0; /* count overflows of explicit levels */
14.671 -
14.672 - /* recalculate the flags */
14.673 - flags=0;
14.674 -
14.675 - /* since we assume that this is a single paragraph, we ignore (X8) */
14.676 - for(i=0; i<length; ++i) {
14.677 - dirProp=dirProps[i];
14.678 - switch(dirProp) {
14.679 - case LRE:
14.680 - case LRO:
14.681 - /* (X3, X5) */
14.682 - newLevel=(UBiDiLevel)((embeddingLevel+2)&~(UBIDI_LEVEL_OVERRIDE|1)); /* least greater even level */
14.683 - if(newLevel<=UBIDI_MAX_EXPLICIT_LEVEL) {
14.684 - stack[stackTop]=embeddingLevel;
14.685 - ++stackTop;
14.686 - embeddingLevel=newLevel;
14.687 - if(dirProp==LRO) {
14.688 - embeddingLevel|=UBIDI_LEVEL_OVERRIDE;
14.689 - } else {
14.690 - embeddingLevel&=~UBIDI_LEVEL_OVERRIDE;
14.691 - }
14.692 - } else if((embeddingLevel&~UBIDI_LEVEL_OVERRIDE)==UBIDI_MAX_EXPLICIT_LEVEL) {
14.693 - ++countOver61;
14.694 - } else /* (embeddingLevel&~UBIDI_LEVEL_OVERRIDE)==UBIDI_MAX_EXPLICIT_LEVEL-1 */ {
14.695 - ++countOver60;
14.696 - }
14.697 - flags|=DIRPROP_FLAG(BN);
14.698 - break;
14.699 - case RLE:
14.700 - case RLO:
14.701 - /* (X2, X4) */
14.702 - newLevel=(UBiDiLevel)(((embeddingLevel&~UBIDI_LEVEL_OVERRIDE)+1)|1); /* least greater odd level */
14.703 - if(newLevel<=UBIDI_MAX_EXPLICIT_LEVEL) {
14.704 - stack[stackTop]=embeddingLevel;
14.705 - ++stackTop;
14.706 - embeddingLevel=newLevel;
14.707 - if(dirProp==RLO) {
14.708 - embeddingLevel|=UBIDI_LEVEL_OVERRIDE;
14.709 - } else {
14.710 - embeddingLevel&=~UBIDI_LEVEL_OVERRIDE;
14.711 - }
14.712 - } else {
14.713 - ++countOver61;
14.714 - }
14.715 - flags|=DIRPROP_FLAG(BN);
14.716 - break;
14.717 - case PDF:
14.718 - /* (X7) */
14.719 - /* handle all the overflow cases first */
14.720 - if(countOver61>0) {
14.721 - --countOver61;
14.722 - } else if(countOver60>0 && (embeddingLevel&~UBIDI_LEVEL_OVERRIDE)!=UBIDI_MAX_EXPLICIT_LEVEL) {
14.723 - /* handle LRx overflows from level 60 */
14.724 - --countOver60;
14.725 - } else if(stackTop>0) {
14.726 - /* this is the pop operation; it also pops level 61 while countOver60>0 */
14.727 - --stackTop;
14.728 - embeddingLevel=stack[stackTop];
14.729 - /* } else { (underflow) */
14.730 - }
14.731 - flags|=DIRPROP_FLAG(BN);
14.732 - break;
14.733 - case B:
14.734 - /*
14.735 - * We do not really expect to see a paragraph separator (B),
14.736 - * but we should do something reasonable with it,
14.737 - * especially at the end of the text.
14.738 - */
14.739 - stackTop=0;
14.740 - countOver60=countOver61=0;
14.741 - embeddingLevel=level=pBiDi->paraLevel;
14.742 - flags|=DIRPROP_FLAG(B);
14.743 - break;
14.744 - case BN:
14.745 - /* BN, LRE, RLE, and PDF are supposed to be removed (X9) */
14.746 - /* they will get their levels set correctly in adjustWSLevels() */
14.747 - flags|=DIRPROP_FLAG(BN);
14.748 - break;
14.749 - default:
14.750 - /* all other types get the "real" level */
14.751 - if(level!=embeddingLevel) {
14.752 - level=embeddingLevel;
14.753 - if(level&UBIDI_LEVEL_OVERRIDE) {
14.754 - flags|=DIRPROP_FLAG_O(level)|DIRPROP_FLAG_MULTI_RUNS;
14.755 - } else {
14.756 - flags|=DIRPROP_FLAG_E(level)|DIRPROP_FLAG_MULTI_RUNS;
14.757 - }
14.758 - }
14.759 - if(!(level&UBIDI_LEVEL_OVERRIDE)) {
14.760 - flags|=DIRPROP_FLAG(dirProp);
14.761 - }
14.762 - break;
14.763 - }
14.764 -
14.765 - /*
14.766 - * We need to set reasonable levels even on BN codes and
14.767 - * explicit codes because we will later look at same-level runs (X10).
14.768 - */
14.769 - levels[i]=level;
14.770 - }
14.771 - if(flags&MASK_EMBEDDING) {
14.772 - flags|=DIRPROP_FLAG_LR(pBiDi->paraLevel);
14.773 - }
14.774 -
14.775 - /* subsequently, ignore the explicit codes and BN (X9) */
14.776 -
14.777 - /* again, determine if the text is mixed-directional or single-directional */
14.778 - pBiDi->flags=flags;
14.779 - direction=directionFromFlags(flags);
14.780 - }
14.781 - return direction;
14.782 -}
14.783 -
14.784 -/*
14.785 - * Use a pre-specified embedding levels array:
14.786 - *
14.787 - * Adjust the directional properties for overrides (->LEVEL_OVERRIDE),
14.788 - * ignore all explicit codes (X9),
14.789 - * and check all the preset levels.
14.790 - *
14.791 - * Recalculate the flags to have them reflect the real properties
14.792 - * after taking the explicit embeddings into account.
14.793 - */
14.794 -static UBiDiDirection
14.795 -checkExplicitLevels(UBiDi *pBiDi, UErrorCode *pErrorCode) {
14.796 - const DirProp *dirProps=pBiDi->dirProps;
14.797 - UBiDiLevel *levels=pBiDi->levels;
14.798 -
14.799 - int32_t i, length=pBiDi->length;
14.800 - Flags flags=0; /* collect all directionalities in the text */
14.801 - UBiDiLevel level, paraLevel=pBiDi->paraLevel;
14.802 -
14.803 - for(i=0; i<length; ++i) {
14.804 - // dlf: we special case levels array for java, 0 means base level, not actually 0
14.805 - if (levels[i] == 0) {
14.806 - levels[i] = paraLevel;
14.807 - }
14.808 - level=levels[i];
14.809 - if(level&UBIDI_LEVEL_OVERRIDE) {
14.810 - /* keep the override flag in levels[i] but adjust the flags */
14.811 - level&=~UBIDI_LEVEL_OVERRIDE; /* make the range check below simpler */
14.812 - flags|=DIRPROP_FLAG_O(level);
14.813 - } else {
14.814 - /* set the flags */
14.815 - flags|=DIRPROP_FLAG_E(level)|DIRPROP_FLAG(dirProps[i]);
14.816 - }
14.817 - if(level<paraLevel || UBIDI_MAX_EXPLICIT_LEVEL<level) {
14.818 - /* level out of bounds */
14.819 - *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
14.820 - return UBIDI_LTR;
14.821 - }
14.822 - }
14.823 - if(flags&MASK_EMBEDDING) {
14.824 - flags|=DIRPROP_FLAG_LR(pBiDi->paraLevel);
14.825 - }
14.826 -
14.827 - /* determine if the text is mixed-directional or single-directional */
14.828 - pBiDi->flags=flags;
14.829 - return directionFromFlags(flags);
14.830 -}
14.831 -
14.832 -/* determine if the text is mixed-directional or single-directional */
14.833 -static UBiDiDirection
14.834 -directionFromFlags(Flags flags) {
14.835 - /* if the text contains AN and neutrals, then some neutrals may become RTL */
14.836 - if(!(flags&MASK_RTL || ((flags&DIRPROP_FLAG(AN)) && (flags&MASK_POSSIBLE_N)))) {
14.837 - return UBIDI_LTR;
14.838 - } else if(!(flags&MASK_LTR)) {
14.839 - return UBIDI_RTL;
14.840 - } else {
14.841 - return UBIDI_MIXED;
14.842 - }
14.843 -}
14.844 -
14.845 -/* perform rules (Wn), (Nn), and (In) on a run of the text ------------------ */
14.846 -
14.847 -/*
14.848 - * This implementation of the (Wn) rules applies all rules in one pass.
14.849 - * In order to do so, it needs a look-ahead of typically 1 character
14.850 - * (except for W5: sequences of ET) and keeps track of changes
14.851 - * in a rule Wp that affect a later Wq (p<q).
14.852 - *
14.853 - * historyOfEN is a variable-saver: it contains 4 boolean states;
14.854 - * a bit in it set to 1 means:
14.855 - * bit 0: the current code is an EN after W2
14.856 - * bit 1: the current code is an EN after W4
14.857 - * bit 2: the previous code was an EN after W2
14.858 - * bit 3: the previous code was an EN after W4
14.859 - * In other words, b0..1 have transitions of EN in the current iteration,
14.860 - * while b2..3 have the transitions of EN in the previous iteration.
14.861 - * A simple historyOfEN<<=2 suffices for the propagation.
14.862 - *
14.863 - * The (Nn) and (In) rules are also performed in that same single loop,
14.864 - * but effectively one iteration behind for white space.
14.865 - *
14.866 - * Since all implicit rules are performed in one step, it is not necessary
14.867 - * to actually store the intermediate directional properties in dirProps[].
14.868 - */
14.869 -
14.870 -#define EN_SHIFT 2
14.871 -#define EN_AFTER_W2 1
14.872 -#define EN_AFTER_W4 2
14.873 -#define EN_ALL 3
14.874 -#define PREV_EN_AFTER_W2 4
14.875 -#define PREV_EN_AFTER_W4 8
14.876 -
14.877 -static void
14.878 -resolveImplicitLevels(UBiDi *pBiDi,
14.879 - int32_t start, int32_t limit,
14.880 - DirProp sor, DirProp eor) {
14.881 - const DirProp *dirProps=pBiDi->dirProps;
14.882 - UBiDiLevel *levels=pBiDi->levels;
14.883 -
14.884 - int32_t i, next, neutralStart=-1;
14.885 - DirProp prevDirProp, dirProp, nextDirProp, lastStrong, beforeNeutral=L;
14.886 - UBiDiLevel numberLevel;
14.887 - uint8_t historyOfEN;
14.888 -
14.889 - /* initialize: current at sor, next at start (it is start<limit) */
14.890 - next=start;
14.891 - dirProp=lastStrong=sor;
14.892 - nextDirProp=dirProps[next];
14.893 - historyOfEN=0;
14.894 -
14.895 - if(pBiDi->isInverse) {
14.896 - /*
14.897 - * For "inverse BiDi", we set the levels of numbers just like for
14.898 - * regular L characters, plus a flag that ubidi_getRuns() will use
14.899 - * to set a similar flag on the corresponding output run.
14.900 - */
14.901 - numberLevel=levels[start];
14.902 - if(numberLevel&1) {
14.903 - ++numberLevel;
14.904 - }
14.905 - } else {
14.906 - /* normal BiDi: least greater even level */
14.907 - numberLevel=(UBiDiLevel)((levels[start]+2)&~1);
14.908 - }
14.909 -
14.910 - /*
14.911 - * In all steps of this implementation, BN and explicit embedding codes
14.912 - * must be treated as if they didn't exist (X9).
14.913 - * They will get levels set before a non-neutral character, and remain
14.914 - * undefined before a neutral one, but adjustWSLevels() will take care
14.915 - * of all of them.
14.916 - */
14.917 - while(DIRPROP_FLAG(nextDirProp)&MASK_BN_EXPLICIT) {
14.918 - if(++next<limit) {
14.919 - nextDirProp=dirProps[next];
14.920 - } else {
14.921 - nextDirProp=eor;
14.922 - break;
14.923 - }
14.924 - }
14.925 -
14.926 - /*
14.927 - * Note: at the end of this file, there is a prototype
14.928 - * of a version of this function that uses a statetable
14.929 - * at the core of this state machine.
14.930 - * If you make changes to this state machine,
14.931 - * please update that prototype as well.
14.932 - */
14.933 -
14.934 - /* loop for entire run */
14.935 - while(next<limit) {
14.936 - /* advance */
14.937 - prevDirProp=dirProp;
14.938 - dirProp=nextDirProp;
14.939 - i=next;
14.940 - do {
14.941 - if(++next<limit) {
14.942 - nextDirProp=dirProps[next];
14.943 - } else {
14.944 - nextDirProp=eor;
14.945 - break;
14.946 - }
14.947 - } while(DIRPROP_FLAG(nextDirProp)&MASK_BN_EXPLICIT);
14.948 - historyOfEN<<=EN_SHIFT;
14.949 -
14.950 - /* (W1..W7) */
14.951 - switch(dirProp) {
14.952 - case L:
14.953 - lastStrong=L;
14.954 - break;
14.955 - case R:
14.956 - lastStrong=R;
14.957 - break;
14.958 - case AL:
14.959 - /* (W3) */
14.960 - lastStrong=AL;
14.961 - dirProp=R;
14.962 - break;
14.963 - case EN:
14.964 - /* we have to set historyOfEN correctly */
14.965 - if(lastStrong==AL) {
14.966 - /* (W2) */
14.967 - dirProp=AN;
14.968 - } else {
14.969 - if(lastStrong==L) {
14.970 - /* (W7) */
14.971 - dirProp=L;
14.972 - }
14.973 - /* this EN stays after (W2) and (W4) - at least before (W7) */
14.974 - historyOfEN|=EN_ALL;
14.975 - }
14.976 - break;
14.977 - case ES:
14.978 - if( historyOfEN&PREV_EN_AFTER_W2 && /* previous was EN before (W4) */
14.979 - nextDirProp==EN && lastStrong!=AL /* next is EN and (W2) won't make it AN */
14.980 - ) {
14.981 - /* (W4) */
14.982 - if(lastStrong!=L) {
14.983 - dirProp=EN;
14.984 - } else {
14.985 - /* (W7) */
14.986 - dirProp=L;
14.987 - }
14.988 - historyOfEN|=EN_AFTER_W4;
14.989 - } else {
14.990 - /* (W6) */
14.991 - dirProp=ON;
14.992 - }
14.993 - break;
14.994 - case CS:
14.995 - if( historyOfEN&PREV_EN_AFTER_W2 && /* previous was EN before (W4) */
14.996 - nextDirProp==EN && lastStrong!=AL /* next is EN and (W2) won't make it AN */
14.997 - ) {
14.998 - /* (W4) */
14.999 - if(lastStrong!=L) {
14.1000 - dirProp=EN;
14.1001 - } else {
14.1002 - /* (W7) */
14.1003 - dirProp=L;
14.1004 - }
14.1005 - historyOfEN|=EN_AFTER_W4;
14.1006 - } else if(prevDirProp==AN && /* previous was AN */
14.1007 - (nextDirProp==AN || /* next is AN */
14.1008 - (nextDirProp==EN && lastStrong==AL)) /* or (W2) will make it one */
14.1009 - ) {
14.1010 - /* (W4) */
14.1011 - dirProp=AN;
14.1012 - } else {
14.1013 - /* (W6) */
14.1014 - dirProp=ON;
14.1015 - }
14.1016 - break;
14.1017 - case ET:
14.1018 - /* get sequence of ET; advance only next, not current, previous or historyOfEN */
14.1019 - if(next<limit) {
14.1020 - while(DIRPROP_FLAG(nextDirProp)&MASK_ET_NSM_BN /* (W1), (X9) */) {
14.1021 - if(++next<limit) {
14.1022 - nextDirProp=dirProps[next];
14.1023 - } else {
14.1024 - nextDirProp=eor;
14.1025 - break;
14.1026 - }
14.1027 - }
14.1028 - }
14.1029 -
14.1030 - /* now process the sequence of ET like a single ET */
14.1031 - if((historyOfEN&PREV_EN_AFTER_W4) || /* previous was EN before (W5) */
14.1032 - (nextDirProp==EN && lastStrong!=AL) /* next is EN and (W2) won't make it AN */
14.1033 - ) {
14.1034 - /* (W5) */
14.1035 - if(lastStrong!=L) {
14.1036 - dirProp=EN;
14.1037 - } else {
14.1038 - /* (W7) */
14.1039 - dirProp=L;
14.1040 - }
14.1041 - } else {
14.1042 - /* (W6) */
14.1043 - dirProp=ON;
14.1044 - }
14.1045 -
14.1046 - /* apply the result of (W1), (W5)..(W7) to the entire sequence of ET */
14.1047 - break;
14.1048 - case NSM:
14.1049 - /* (W1) */
14.1050 - dirProp=prevDirProp;
14.1051 - /* set historyOfEN back to prevDirProp's historyOfEN */
14.1052 - historyOfEN>>=EN_SHIFT;
14.1053 - /*
14.1054 - * Technically, this should be done before the switch() in the form
14.1055 - * if(nextDirProp==NSM) {
14.1056 - * dirProps[next]=nextDirProp=dirProp;
14.1057 - * }
14.1058 - *
14.1059 - * - effectively one iteration ahead.
14.1060 - * However, whether the next dirProp is NSM or is equal to the current dirProp
14.1061 - * does not change the outcome of any condition in (W2)..(W7).
14.1062 - */
14.1063 - break;
14.1064 - default:
14.1065 - break;
14.1066 - }
14.1067 -
14.1068 - /* here, it is always [prev,this,next]dirProp!=BN; it may be next>i+1 */
14.1069 -
14.1070 - /* perform (Nn) - here, only L, R, EN, AN, and neutrals are left */
14.1071 - /* for "inverse BiDi", treat neutrals like L */
14.1072 - /* this is one iteration late for the neutrals */
14.1073 - if(DIRPROP_FLAG(dirProp)&MASK_N) {
14.1074 - if(neutralStart<0) {
14.1075 - /* start of a sequence of neutrals */
14.1076 - neutralStart=i;
14.1077 - beforeNeutral=prevDirProp;
14.1078 - }
14.1079 - } else /* not a neutral, can be only one of { L, R, EN, AN } */ {
14.1080 - /*
14.1081 - * Note that all levels[] values are still the same at this
14.1082 - * point because this function is called for an entire
14.1083 - * same-level run.
14.1084 - * Therefore, we need to read only one actual level.
14.1085 - */
14.1086 - UBiDiLevel level=levels[i];
14.1087 -
14.1088 - if(neutralStart>=0) {
14.1089 - UBiDiLevel final;
14.1090 - /* end of a sequence of neutrals (dirProp is "afterNeutral") */
14.1091 - if(!(pBiDi->isInverse)) {
14.1092 - if(beforeNeutral==L) {
14.1093 - if(dirProp==L) {
14.1094 - final=0; /* make all neutrals L (N1) */
14.1095 - } else {
14.1096 - final=level; /* make all neutrals "e" (N2) */
14.1097 - }
14.1098 - } else /* beforeNeutral is one of { R, EN, AN } */ {
14.1099 - if(dirProp==L) {
14.1100 - final=level; /* make all neutrals "e" (N2) */
14.1101 - } else {
14.1102 - final=1; /* make all neutrals R (N1) */
14.1103 - }
14.1104 - }
14.1105 - } else {
14.1106 - /* "inverse BiDi": collapse [before]dirProps L, EN, AN into L */
14.1107 - if(beforeNeutral!=R) {
14.1108 - if(dirProp!=R) {
14.1109 - final=0; /* make all neutrals L (N1) */
14.1110 - } else {
14.1111 - final=level; /* make all neutrals "e" (N2) */
14.1112 - }
14.1113 - } else /* beforeNeutral is one of { R, EN, AN } */ {
14.1114 - if(dirProp!=R) {
14.1115 - final=level; /* make all neutrals "e" (N2) */
14.1116 - } else {
14.1117 - final=1; /* make all neutrals R (N1) */
14.1118 - }
14.1119 - }
14.1120 - }
14.1121 - /* perform (In) on the sequence of neutrals */
14.1122 - if((level^final)&1) {
14.1123 - /* do something only if we need to _change_ the level */
14.1124 - do {
14.1125 - ++levels[neutralStart];
14.1126 - } while(++neutralStart<i);
14.1127 - }
14.1128 - neutralStart=-1;
14.1129 - }
14.1130 -
14.1131 - /* perform (In) on the non-neutral character */
14.1132 - /*
14.1133 - * in the cases of (W5), processing a sequence of ET,
14.1134 - * and of (X9), skipping BN,
14.1135 - * there may be multiple characters from i to <next
14.1136 - * that all get (virtually) the same dirProp and (really) the same level
14.1137 - */
14.1138 - if(dirProp==L) {
14.1139 - if(level&1) {
14.1140 - ++level;
14.1141 - } else {
14.1142 - i=next; /* we keep the levels */
14.1143 - }
14.1144 - } else if(dirProp==R) {
14.1145 - if(!(level&1)) {
14.1146 - ++level;
14.1147 - } else {
14.1148 - i=next; /* we keep the levels */
14.1149 - }
14.1150 - } else /* EN or AN */ {
14.1151 - /* this level depends on whether we do "inverse BiDi" */
14.1152 - level=numberLevel;
14.1153 - }
14.1154 -
14.1155 - /* apply the new level to the sequence, if necessary */
14.1156 - while(i<next) {
14.1157 - levels[i++]=level;
14.1158 - }
14.1159 - }
14.1160 - }
14.1161 -
14.1162 - /* perform (Nn) - here,
14.1163 - the character after the the neutrals is eor, which is either L or R */
14.1164 - /* this is one iteration late for the neutrals */
14.1165 - if(neutralStart>=0) {
14.1166 - /*
14.1167 - * Note that all levels[] values are still the same at this
14.1168 - * point because this function is called for an entire
14.1169 - * same-level run.
14.1170 - * Therefore, we need to read only one actual level.
14.1171 - */
14.1172 - UBiDiLevel level=levels[neutralStart], final;
14.1173 -
14.1174 - /* end of a sequence of neutrals (eor is "afterNeutral") */
14.1175 - if(!(pBiDi->isInverse)) {
14.1176 - if(beforeNeutral==L) {
14.1177 - if(eor==L) {
14.1178 - final=0; /* make all neutrals L (N1) */
14.1179 - } else {
14.1180 - final=level; /* make all neutrals "e" (N2) */
14.1181 - }
14.1182 - } else /* beforeNeutral is one of { R, EN, AN } */ {
14.1183 - if(eor==L) {
14.1184 - final=level; /* make all neutrals "e" (N2) */
14.1185 - } else {
14.1186 - final=1; /* make all neutrals R (N1) */
14.1187 - }
14.1188 - }
14.1189 - } else {
14.1190 - /* "inverse BiDi": collapse [before]dirProps L, EN, AN into L */
14.1191 - if(beforeNeutral!=R) {
14.1192 - if(eor!=R) {
14.1193 - final=0; /* make all neutrals L (N1) */
14.1194 - } else {
14.1195 - final=level; /* make all neutrals "e" (N2) */
14.1196 - }
14.1197 - } else /* beforeNeutral is one of { R, EN, AN } */ {
14.1198 - if(eor!=R) {
14.1199 - final=level; /* make all neutrals "e" (N2) */
14.1200 - } else {
14.1201 - final=1; /* make all neutrals R (N1) */
14.1202 - }
14.1203 - }
14.1204 - }
14.1205 - /* perform (In) on the sequence of neutrals */
14.1206 - if((level^final)&1) {
14.1207 - /* do something only if we need to _change_ the level */
14.1208 - do {
14.1209 - ++levels[neutralStart];
14.1210 - } while(++neutralStart<limit);
14.1211 - }
14.1212 - }
14.1213 -}
14.1214 -
14.1215 -/* perform (L1) and (X9) ---------------------------------------------------- */
14.1216 -
14.1217 -/*
14.1218 - * Reset the embedding levels for some non-graphic characters (L1).
14.1219 - * This function also sets appropriate levels for BN, and
14.1220 - * explicit embedding types that are supposed to have been removed
14.1221 - * from the paragraph in (X9).
14.1222 - */
14.1223 -static void
14.1224 -adjustWSLevels(UBiDi *pBiDi) {
14.1225 - const DirProp *dirProps=pBiDi->dirProps;
14.1226 - UBiDiLevel *levels=pBiDi->levels;
14.1227 - int32_t i;
14.1228 -
14.1229 - if(pBiDi->flags&MASK_WS) {
14.1230 - UBiDiLevel paraLevel=pBiDi->paraLevel;
14.1231 - Flags flag;
14.1232 -
14.1233 - i=pBiDi->trailingWSStart;
14.1234 - while(i>0) {
14.1235 - /* reset a sequence of WS/BN before eop and B/S to the paragraph paraLevel */
14.1236 - while(i>0 && DIRPROP_FLAG(dirProps[--i])&MASK_WS) {
14.1237 - levels[i]=paraLevel;
14.1238 - }
14.1239 -
14.1240 - /* reset BN to the next character's paraLevel until B/S, which restarts above loop */
14.1241 - /* here, i+1 is guaranteed to be <length */
14.1242 - while(i>0) {
14.1243 - flag=DIRPROP_FLAG(dirProps[--i]);
14.1244 - if(flag&MASK_BN_EXPLICIT) {
14.1245 - levels[i]=levels[i+1];
14.1246 - } else if(flag&MASK_B_S) {
14.1247 - levels[i]=paraLevel;
14.1248 - break;
14.1249 - }
14.1250 - }
14.1251 - }
14.1252 - }
14.1253 -
14.1254 - /* now remove the UBIDI_LEVEL_OVERRIDE flags, if any */
14.1255 - /* (a separate loop can be optimized more easily by a compiler) */
14.1256 - if(pBiDi->flags&MASK_OVERRIDE) {
14.1257 - for(i=pBiDi->trailingWSStart; i>0;) {
14.1258 - levels[--i]&=~UBIDI_LEVEL_OVERRIDE;
14.1259 - }
14.1260 - }
14.1261 -}
14.1262 -
14.1263 -/* -------------------------------------------------------------------------- */
14.1264 -
14.1265 -U_CAPI UBiDiDirection U_EXPORT2
14.1266 -ubidi_getDirection(const UBiDi *pBiDi) {
14.1267 - if(pBiDi!=NULL) {
14.1268 - return pBiDi->direction;
14.1269 - } else {
14.1270 - return UBIDI_LTR;
14.1271 - }
14.1272 -}
14.1273 -
14.1274 -U_CAPI const UChar * U_EXPORT2
14.1275 -ubidi_getText(const UBiDi *pBiDi) {
14.1276 - if(pBiDi!=NULL) {
14.1277 - return pBiDi->text;
14.1278 - } else {
14.1279 - return NULL;
14.1280 - }
14.1281 -}
14.1282 -
14.1283 -U_CAPI int32_t U_EXPORT2
14.1284 -ubidi_getLength(const UBiDi *pBiDi) {
14.1285 - if(pBiDi!=NULL) {
14.1286 - return pBiDi->length;
14.1287 - } else {
14.1288 - return 0;
14.1289 - }
14.1290 -}
14.1291 -
14.1292 -U_CAPI UBiDiLevel U_EXPORT2
14.1293 -ubidi_getParaLevel(const UBiDi *pBiDi) {
14.1294 - if(pBiDi!=NULL) {
14.1295 - return pBiDi->paraLevel;
14.1296 - } else {
14.1297 - return 0;
14.1298 - }
14.1299 -}
14.1300 -
14.1301 -/* statetable prototype ----------------------------------------------------- */
14.1302 -
14.1303 -/*
14.1304 - * This is here for possible future
14.1305 - * performance work and is not compiled right now.
14.1306 - */
14.1307 -
14.1308 -#if 0
14.1309 -/*
14.1310 - * This is a piece of code that could be part of ubidi.c/resolveImplicitLevels().
14.1311 - * It replaces in the (Wn) state machine the switch()-if()-cascade with
14.1312 - * just a few if()s and a state table.
14.1313 - */
14.1314 -
14.1315 -/* use the state table only for the following dirProp's */
14.1316 -#define MASK_W_TABLE (FLAG(L)|FLAG(R)|FLAG(AL)|FLAG(EN)|FLAG(ES)|FLAG(CS)|FLAG(ET)|FLAG(AN))
14.1317 -
14.1318 -/*
14.1319 - * inputs:
14.1320 - *
14.1321 - * 0..1 historyOfEN - 2b
14.1322 - * 2 prevDirProp==AN - 1b
14.1323 - * 3..4 lastStrong, one of { L, R, AL, none } - 2b
14.1324 - * 5..7 dirProp, one of { L, R, AL, EN, ES, CS, ET, AN } - 3b
14.1325 - * 8..9 nextDirProp, one of { EN, AN, other }
14.1326 - *
14.1327 - * total: 10b=1024 states
14.1328 - */
14.1329 -enum { _L, _R, _AL, _EN, _ES, _CS, _ET, _AN, _OTHER }; /* lastStrong, dirProp */
14.1330 -enum { __EN, __AN, __OTHER }; /* nextDirProp */
14.1331 -
14.1332 -#define LAST_STRONG_SHIFT 3
14.1333 -#define DIR_PROP_SHIFT 5
14.1334 -#define NEXT_DIR_PROP_SHIFT 8
14.1335 -
14.1336 -/* masks after shifting */
14.1337 -#define LAST_STRONG_MASK 3
14.1338 -#define DIR_PROP_MASK 7
14.1339 -#define STATE_MASK 0x1f
14.1340 -
14.1341 -/* convert dirProp into _dirProp (above enum) */
14.1342 -static DirProp inputDirProp[dirPropCount]={ _X<<DIR_PROP_SHIFT, ... };
14.1343 -
14.1344 -/* convert dirProp into __dirProp (above enum) */
14.1345 -static DirProp inputNextDirProp[dirPropCount]={ __X<<NEXT_DIR_PROP_SHIFT, ... };
14.1346 -
14.1347 -/*
14.1348 - * outputs:
14.1349 - *
14.1350 - * dirProp, one of { L, R, EN, AN, ON } - 3b
14.1351 - *
14.1352 - * 0..1 historyOfEN - 2b
14.1353 - * 2 prevDirProp==AN - 1b
14.1354 - * 3..4 lastStrong, one of { L, R, AL, none } - 2b
14.1355 - * 5..7 new dirProp, one of { L, R, EN, AN, ON }
14.1356 - *
14.1357 - * total: 8 bits=1 byte per state
14.1358 - */
14.1359 -enum { ___L, ___R, ___EN, ___AN, ___ON, ___count };
14.1360 -
14.1361 -/* convert ___dirProp into dirProp (above enum) */
14.1362 -static DirProp outputDirProp[___count]={ X, ... };
14.1363 -
14.1364 -/* state table */
14.1365 -static uint8_t wnTable[1024]={ /* calculate with switch()-if()-cascade */ };
14.1366 -
14.1367 -static void
14.1368 -resolveImplicitLevels(BiDi *pBiDi,
14.1369 - Index start, Index end,
14.1370 - DirProp sor, DirProp eor) {
14.1371 - /* new variable */
14.1372 - uint8_t state;
14.1373 -
14.1374 - /* remove variable lastStrong */
14.1375 -
14.1376 - /* set initial state (set lastStrong, the rest is 0) */
14.1377 - state= sor==L ? 0 : _R<<LAST_STRONG_SHIFT;
14.1378 -
14.1379 - while(next<limit) {
14.1380 - /* advance */
14.1381 - prevDirProp=dirProp;
14.1382 - dirProp=nextDirProp;
14.1383 - i=next;
14.1384 - do {
14.1385 - if(++next<limit) {
14.1386 - nextDirProp=dirProps[next];
14.1387 - } else {
14.1388 - nextDirProp=eor;
14.1389 - break;
14.1390 - }
14.1391 - } while(FLAG(nextDirProp)&MASK_BN_EXPLICIT);
14.1392 -
14.1393 - /* (W1..W7) */
14.1394 - /* ### This may be more efficient with a switch(dirProp). */
14.1395 - if(FLAG(dirProp)&MASK_W_TABLE) {
14.1396 - state=wnTable[
14.1397 - ((int)state)|
14.1398 - inputDirProp[dirProp]|
14.1399 - inputNextDirProp[nextDirProp]
14.1400 - ];
14.1401 - dirProp=outputDirProp[state>>DIR_PROP_SHIFT];
14.1402 - state&=STATE_MASK;
14.1403 - } else if(dirProp==ET) {
14.1404 - /* get sequence of ET; advance only next, not current, previous or historyOfEN */
14.1405 - while(next<limit && FLAG(nextDirProp)&MASK_ET_NSM_BN /* (W1), (X9) */) {
14.1406 - if(++next<limit) {
14.1407 - nextDirProp=dirProps[next];
14.1408 - } else {
14.1409 - nextDirProp=eor;
14.1410 - break;
14.1411 - }
14.1412 - }
14.1413 -
14.1414 - state=wnTable[
14.1415 - ((int)state)|
14.1416 - _ET<<DIR_PROP_SHIFT|
14.1417 - inputNextDirProp[nextDirProp]
14.1418 - ];
14.1419 - dirProp=outputDirProp[state>>DIR_PROP_SHIFT];
14.1420 - state&=STATE_MASK;
14.1421 -
14.1422 - /* apply the result of (W1), (W5)..(W7) to the entire sequence of ET */
14.1423 - } else if(dirProp==NSM) {
14.1424 - /* (W1) */
14.1425 - dirProp=prevDirProp;
14.1426 - /* keep prevDirProp's EN and AN states! */
14.1427 - } else /* other */ {
14.1428 - /* set EN and AN states to 0 */
14.1429 - state&=LAST_STRONG_MASK<<LAST_STRONG_SHIFT;
14.1430 - }
14.1431 -
14.1432 - /* perform (Nn) and (In) as usual */
14.1433 - }
14.1434 - /* perform (Nn) and (In) as usual */
14.1435 -}
14.1436 -#endif
15.1 --- a/src/share/native/sun/font/bidi/ubidi.h Sun Jun 21 23:52:58 2009 -0700
15.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
15.3 @@ -1,913 +0,0 @@
15.4 -/*
15.5 - * Portions Copyright 2000-2003 Sun Microsystems, Inc. All Rights Reserved.
15.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
15.7 - *
15.8 - * This code is free software; you can redistribute it and/or modify it
15.9 - * under the terms of the GNU General Public License version 2 only, as
15.10 - * published by the Free Software Foundation. Sun designates this
15.11 - * particular file as subject to the "Classpath" exception as provided
15.12 - * by Sun in the LICENSE file that accompanied this code.
15.13 - *
15.14 - * This code is distributed in the hope that it will be useful, but WITHOUT
15.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15.16 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15.17 - * version 2 for more details (a copy is included in the LICENSE file that
15.18 - * accompanied this code).
15.19 - *
15.20 - * You should have received a copy of the GNU General Public License version
15.21 - * 2 along with this work; if not, write to the Free Software Foundation,
15.22 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
15.23 - *
15.24 - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
15.25 - * CA 95054 USA or visit www.sun.com if you need additional information or
15.26 - * have any questions.
15.27 - */
15.28 -
15.29 -/*
15.30 - * (C) Copyright IBM Corp. 1999-2003 - All Rights Reserved
15.31 - *
15.32 - * The original version of this source code and documentation is
15.33 - * copyrighted and owned by IBM. These materials are provided
15.34 - * under terms of a License Agreement between IBM and Sun.
15.35 - * This technology is protected by multiple US and International
15.36 - * patents. This notice and attribution to IBM may not be removed.
15.37 - */
15.38 -
15.39 -/*
15.40 -* file name: ubidi.h
15.41 -* encoding: US-ASCII
15.42 -* tab size: 8 (not used)
15.43 -* indentation:4
15.44 -*
15.45 -* created on: 1999jul27
15.46 -* created by: Markus W. Scherer
15.47 -*/
15.48 -
15.49 -#ifndef UBIDI_H
15.50 -#define UBIDI_H
15.51 -
15.52 -#include "utypes.h"
15.53 -#include "uchardir.h"
15.54 -
15.55 -/*
15.56 - * javadoc-style comments are intended to be transformed into HTML
15.57 - * using DOC++ - see
15.58 - * http://www.zib.de/Visual/software/doc++/index.html .
15.59 - *
15.60 - * The HTML documentation is created with
15.61 - * doc++ -H ubidi.h
15.62 - *
15.63 - * The following #define trick allows us to do it all in one file
15.64 - * and still be able to compile it.
15.65 - */
15.66 -#define DOCXX_TAG
15.67 -#define BIDI_SAMPLE_CODE
15.68 -
15.69 -/**
15.70 - * @name BiDi algorithm for ICU
15.71 - *
15.72 - * <h2>BiDi algorithm for ICU</h2>
15.73 - *
15.74 - * This is an implementation of the Unicode Bidirectional algorithm.
15.75 - * The algorithm is defined in the
15.76 - * <a href="http://www.unicode.org/unicode/reports/tr9/">Unicode Technical Report 9</a>,
15.77 - * version 5, also described in The Unicode Standard, Version 3.0 .<p>
15.78 - *
15.79 - * <h3>General remarks about the API:</h3>
15.80 - *
15.81 - * In functions with an error code parameter,
15.82 - * the <code>pErrorCode</code> pointer must be valid
15.83 - * and the value that it points to must not indicate a failure before
15.84 - * the function call. Otherwise, the function returns immediately.
15.85 - * After the function call, the value indicates success or failure.<p>
15.86 - *
15.87 - * The <quote>limit</quote> of a sequence of characters is the position just after their
15.88 - * last character, i.e., one more than that position.<p>
15.89 - *
15.90 - * Some of the API functions provide access to <quote>runs</quote>.
15.91 - * Such a <quote>run</quote> is defined as a sequence of characters
15.92 - * that are at the same embedding level
15.93 - * after performing the BiDi algorithm.<p>
15.94 - *
15.95 - * @author Markus W. Scherer
15.96 - */
15.97 -DOCXX_TAG
15.98 -/*@{*/
15.99 -
15.100 -/**
15.101 - * UBiDiLevel is the type of the level values in this
15.102 - * BiDi implementation.
15.103 - * It holds an embedding level and indicates the visual direction
15.104 - * by its bit 0 (even/odd value).<p>
15.105 - *
15.106 - * It can also hold non-level values for the
15.107 - * <code>paraLevel</code> and <code>embeddingLevels</code>
15.108 - * arguments of <code>ubidi_setPara()</code>; there:
15.109 - * <ul>
15.110 - * <li>bit 7 of an <code>embeddingLevels[]</code>
15.111 - * value indicates whether the using application is
15.112 - * specifying the level of a character to <i>override</i> whatever the
15.113 - * BiDi implementation would resolve it to.</li>
15.114 - * <li><code>paraLevel</code> can be set to the
15.115 - * pesudo-level values <code>UBIDI_DEFAULT_LTR</code>
15.116 - * and <code>UBIDI_DEFAULT_RTL</code>.</li>
15.117 - *
15.118 - * @see ubidi_setPara
15.119 - *
15.120 - * <p>The related constants are not real, valid level values.
15.121 - * <code>UBIDI_DEFAULT_XXX</code> can be used to specify
15.122 - * a default for the paragraph level for
15.123 - * when the <code>ubidi_setPara()</code> function
15.124 - * shall determine it but there is no
15.125 - * strongly typed character in the input.<p>
15.126 - *
15.127 - * Note that the value for <code>UBIDI_DEFAULT_LTR</code> is even
15.128 - * and the one for <code>UBIDI_DEFAULT_RTL</code> is odd,
15.129 - * just like with normal LTR and RTL level values -
15.130 - * these special values are designed that way. Also, the implementation
15.131 - * assumes that UBIDI_MAX_EXPLICIT_LEVEL is odd.
15.132 - *
15.133 - * @see UBIDI_DEFAULT_LTR
15.134 - * @see UBIDI_DEFAULT_RTL
15.135 - * @see UBIDI_LEVEL_OVERRIDE
15.136 - * @see UBIDI_MAX_EXPLICIT_LEVEL
15.137 - */
15.138 -typedef uint8_t UBiDiLevel;
15.139 -
15.140 -/** @memo If there is no strong character, then set the paragraph level to 0 (left-to-right). */
15.141 -#define UBIDI_DEFAULT_LTR 0xfe
15.142 -
15.143 -/** @memo If there is no strong character, then set the paragraph level to 1 (right-to-left). */
15.144 -#define UBIDI_DEFAULT_RTL 0xff
15.145 -
15.146 -/**
15.147 - * @memo Maximum explicit embedding level
15.148 - * (The maximum resolved level can be up to <code>UBIDI_MAX_EXPLICIT_LEVEL+1</code>).
15.149 - */
15.150 -#define UBIDI_MAX_EXPLICIT_LEVEL 61
15.151 -
15.152 -/** @memo Bit flag for level input: overrides directional properties. */
15.153 -#define UBIDI_LEVEL_OVERRIDE 0x80
15.154 -
15.155 -/**
15.156 - * @memo <code>UBiDiDirection</code> values indicate the text direction.
15.157 - */
15.158 -enum UBiDiDirection {
15.159 - /** @memo All left-to-right text. This is a 0 value. */
15.160 - UBIDI_LTR,
15.161 - /** @memo All right-to-left text. This is a 1 value. */
15.162 - UBIDI_RTL,
15.163 - /** @memo Mixed-directional text. */
15.164 - UBIDI_MIXED
15.165 -};
15.166 -
15.167 -typedef enum UBiDiDirection UBiDiDirection;
15.168 -
15.169 -/**
15.170 - * Forward declaration of the <code>UBiDi</code> structure for the declaration of
15.171 - * the API functions. Its fields are implementation-specific.<p>
15.172 - * This structure holds information about a paragraph of text
15.173 - * with BiDi-algorithm-related details, or about one line of
15.174 - * such a paragraph.<p>
15.175 - * Reordering can be done on a line, or on a paragraph which is
15.176 - * then interpreted as one single line.
15.177 - */
15.178 -struct UBiDi;
15.179 -
15.180 -typedef struct UBiDi UBiDi;
15.181 -
15.182 -/**
15.183 - * Allocate a <code>UBiDi</code> structure.
15.184 - * Such an object is initially empty. It is assigned
15.185 - * the BiDi properties of a paragraph by <code>ubidi_setPara()</code>
15.186 - * or the BiDi properties of a line of a paragraph by
15.187 - * <code>ubidi_getLine()</code>.<p>
15.188 - * This object can be reused for as long as it is not deallocated
15.189 - * by calling <code>ubidi_close()</code>.<p>
15.190 - * <code>ubidi_set()</code> will allocate additional memory for
15.191 - * internal structures as necessary.
15.192 - *
15.193 - * @return An empty <code>UBiDi</code> object.
15.194 - */
15.195 -U_CAPI UBiDi * U_EXPORT2
15.196 -ubidi_open();
15.197 -
15.198 -/**
15.199 - * Allocate a <code>UBiDi</code> structure with preallocated memory
15.200 - * for internal structures.
15.201 - * This function provides a <code>UBiDi</code> object like <code>ubidi_open()</code>
15.202 - * with no arguments, but it also preallocates memory for internal structures
15.203 - * according to the sizings supplied by the caller.<p>
15.204 - * Subsequent functions will not allocate any more memory, and are thus
15.205 - * guaranteed not to fail because of lack of memory.<p>
15.206 - * The preallocation can be limited to some of the internal memory
15.207 - * by setting some values to 0 here. That means that if, e.g.,
15.208 - * <code>maxRunCount</code> cannot be reasonably predetermined and should not
15.209 - * be set to <code>maxLength</code> (the only failproof value) to avoid
15.210 - * wasting memory, then <code>maxRunCount</code> could be set to 0 here
15.211 - * and the internal structures that are associated with it will be allocated
15.212 - * on demand, just like with <code>ubidi_open()</code>.
15.213 - *
15.214 - * @param maxLength is the maximum paragraph or line length that internal memory
15.215 - * will be preallocated for. An attempt to associate this object with a
15.216 - * longer text will fail, unless this value is 0, which leaves the allocation
15.217 - * up to the implementation.
15.218 - *
15.219 - * @param maxRunCount is the maximum anticipated number of same-level runs
15.220 - * that internal memory will be preallocated for. An attempt to access
15.221 - * visual runs on an object that was not preallocated for as many runs
15.222 - * as the text was actually resolved to will fail,
15.223 - * unless this value is 0, which leaves the allocation up to the implementation.<p>
15.224 - * The number of runs depends on the actual text and maybe anywhere between
15.225 - * 1 and <code>maxLength</code>. It is typically small.<p>
15.226 - *
15.227 - * @param pErrorCode must be a valid pointer to an error code value,
15.228 - * which must not indicate a failure before the function call.
15.229 - *
15.230 - * @return An empty <code>UBiDi</code> object with preallocated memory.
15.231 - */
15.232 -U_CAPI UBiDi * U_EXPORT2
15.233 -ubidi_openSized(int32_t maxLength, int32_t maxRunCount, UErrorCode *pErrorCode);
15.234 -
15.235 -/**
15.236 - * <code>ubidi_close()</code> must be called to free the memory
15.237 - * associated with a UBiDi object.<p>
15.238 - *
15.239 - * <strong>Important: </strong>
15.240 - * If a <code>UBiDi</code> object is the <quote>child</quote>
15.241 - * of another one (its <quote>parent</quote>), after calling
15.242 - * <code>ubidi_setLine()</code>, then the child object must
15.243 - * be destroyed (closed) or reused (by calling
15.244 - * <code>ubidi_setPara()</code> or <code>ubidi_setLine()</code>)
15.245 - * before the parent object.
15.246 - *
15.247 - * @param pBiDi is a <code>UBiDi</code> object.
15.248 - *
15.249 - * @see ubidi_setPara
15.250 - * @see ubidi_setLine
15.251 - */
15.252 -U_CAPI void U_EXPORT2
15.253 -ubidi_close(UBiDi *pBiDi);
15.254 -
15.255 -/**
15.256 - * Perform the Unicode BiDi algorithm. It is defined in the
15.257 - * <a href="http://www.unicode.org/unicode/reports/tr9/">Unicode Technical Report 9</a>,
15.258 - * version 5,
15.259 - * also described in The Unicode Standard, Version 3.0 .<p>
15.260 - *
15.261 - * This function takes a single plain text paragraph with or without
15.262 - * externally specified embedding levels from <quote>styled</quote> text
15.263 - * and computes the left-right-directionality of each character.<p>
15.264 - *
15.265 - * If the entire paragraph consists of text of only one direction, then
15.266 - * the function may not perform all the steps described by the algorithm,
15.267 - * i.e., some levels may not be the same as if all steps were performed.
15.268 - * This is not relevant for unidirectional text.<br>
15.269 - * For example, in pure LTR text with numbers the numbers would get
15.270 - * a resolved level of 2 higher than the surrounding text according to
15.271 - * the algorithm. This implementation may set all resolved levels to
15.272 - * the same value in such a case.<p>
15.273 - *
15.274 - * The text must be externally split into separate paragraphs (rule P1).
15.275 - * Paragraph separators (B) should appear at most at the very end.
15.276 - *
15.277 - * @param pBiDi A <code>UBiDi</code> object allocated with <code>ubidi_open()</code>
15.278 - * which will be set to contain the reordering information,
15.279 - * especially the resolved levels for all the characters in <code>text</code>.
15.280 - *
15.281 - * @param text is a pointer to the single-paragraph text that the
15.282 - * BiDi algorithm will be performed on
15.283 - * (step (P1) of the algorithm is performed externally).
15.284 - * <strong>The text must be (at least) <code>length</code> long.</strong>
15.285 - *
15.286 - * @param length is the length of the text; if <code>length==-1</code> then
15.287 - * the text must be zero-terminated.
15.288 - *
15.289 - * @param paraLevel specifies the default level for the paragraph;
15.290 - * it is typically 0 (LTR) or 1 (RTL).
15.291 - * If the function shall determine the paragraph level from the text,
15.292 - * then <code>paraLevel</code> can be set to
15.293 - * either <code>UBIDI_DEFAULT_LTR</code>
15.294 - * or <code>UBIDI_DEFAULT_RTL</code>;
15.295 - * if there is no strongly typed character, then
15.296 - * the desired default is used (0 for LTR or 1 for RTL).
15.297 - * Any other value between 0 and <code>UBIDI_MAX_EXPLICIT_LEVEL</code> is also valid,
15.298 - * with odd levels indicating RTL.
15.299 - *
15.300 - * @param embeddingLevels (in) may be used to preset the embedding and override levels,
15.301 - * ignoring characters like LRE and PDF in the text.
15.302 - * A level overrides the directional property of its corresponding
15.303 - * (same index) character if the level has the
15.304 - * <code>UBIDI_LEVEL_OVERRIDE</code> bit set.<p>
15.305 - * Except for that bit, it must be
15.306 - * <code>paraLevel<=embeddingLevels[]<=UBIDI_MAX_EXPLICIT_LEVEL</code>.<p>
15.307 - * <strong>Caution: </strong>A copy of this pointer, not of the levels,
15.308 - * will be stored in the <code>UBiDi</code> object;
15.309 - * the <code>embeddingLevels</code> array must not be
15.310 - * deallocated before the <code>UBiDi</code> structure is destroyed or reused,
15.311 - * and the <code>embeddingLevels</code>
15.312 - * should not be modified to avoid unexpected results on subsequent BiDi operations.
15.313 - * However, the <code>ubidi_setPara()</code> and
15.314 - * <code>ubidi_setLine()</code> functions may modify some or all of the levels.<p>
15.315 - * After the <code>UBiDi</code> object is reused or destroyed, the caller
15.316 - * must take care of the deallocation of the <code>embeddingLevels</code> array.<p>
15.317 - * <strong>The <code>embeddingLevels</code> array must be
15.318 - * at least <code>length</code> long.</strong>
15.319 - *
15.320 - * @param pErrorCode must be a valid pointer to an error code value,
15.321 - * which must not indicate a failure before the function call.
15.322 - */
15.323 -U_CAPI void U_EXPORT2
15.324 -ubidi_setPara(UBiDi *pBiDi, const UChar *text, int32_t length,
15.325 - UBiDiLevel paraLevel, UBiDiLevel *embeddingLevels,
15.326 - UErrorCode *pErrorCode);
15.327 -
15.328 -/**
15.329 - * <code>ubidi_getLine()</code> sets a <code>UBiDi</code> to
15.330 - * contain the reordering information, especially the resolved levels,
15.331 - * for all the characters in a line of text. This line of text is
15.332 - * specified by referring to a <code>UBiDi</code> object representing
15.333 - * this information for a paragraph of text, and by specifying
15.334 - * a range of indexes in this paragraph.<p>
15.335 - * In the new line object, the indexes will range from 0 to <code>limit-start</code>.<p>
15.336 - *
15.337 - * This is used after calling <code>ubidi_setPara()</code>
15.338 - * for a paragraph, and after line-breaking on that paragraph.
15.339 - * It is not necessary if the paragraph is treated as a single line.<p>
15.340 - *
15.341 - * After line-breaking, rules (L1) and (L2) for the treatment of
15.342 - * trailing WS and for reordering are performed on
15.343 - * a <code>UBiDi</code> object that represents a line.<p>
15.344 - *
15.345 - * <strong>Important: </strong><code>pLineBiDi</code> shares data with
15.346 - * <code>pParaBiDi</code>.
15.347 - * You must destroy or reuse <code>pLineBiDi</code> before <code>pParaBiDi</code>.
15.348 - * In other words, you must destroy or reuse the <code>UBiDi</code> object for a line
15.349 - * before the object for its parent paragraph.
15.350 - *
15.351 - * @param pParaBiDi is the parent paragraph object.
15.352 - *
15.353 - * @param start is the line's first index into the paragraph text.
15.354 - *
15.355 - * @param limit is just behind the line's last index into the paragraph text
15.356 - * (its last index +1).<br>
15.357 - * It must be <code>0<=start<=limit<=</code>paragraph length.
15.358 - *
15.359 - * @param pLineBiDi is the object that will now represent a line of the paragraph.
15.360 - *
15.361 - * @param pErrorCode must be a valid pointer to an error code value,
15.362 - * which must not indicate a failure before the function call.
15.363 - *
15.364 - * @see ubidi_setPara
15.365 - */
15.366 -U_CAPI void U_EXPORT2
15.367 -ubidi_setLine(const UBiDi *pParaBiDi,
15.368 - int32_t start, int32_t limit,
15.369 - UBiDi *pLineBiDi,
15.370 - UErrorCode *pErrorCode);
15.371 -
15.372 -/**
15.373 - * Get the directionality of the text.
15.374 - *
15.375 - * @param pBiDi is the paragraph or line <code>UBiDi</code> object.
15.376 - *
15.377 - * @return A <code>UBIDI_XXX</code> value that indicates if the entire text
15.378 - * represented by this object is unidirectional,
15.379 - * and which direction, or if it is mixed-directional.
15.380 - *
15.381 - * @see UBiDiDirection
15.382 - */
15.383 -U_CAPI UBiDiDirection U_EXPORT2
15.384 -ubidi_getDirection(const UBiDi *pBiDi);
15.385 -
15.386 -/**
15.387 - * Get the length of the text.
15.388 - *
15.389 - * @param pBiDi is the paragraph or line <code>UBiDi</code> object.
15.390 - *
15.391 - * @return The length of the text that the UBiDi object was created for.
15.392 - */
15.393 -U_CAPI int32_t U_EXPORT2
15.394 -ubidi_getLength(const UBiDi *pBiDi);
15.395 -
15.396 -/**
15.397 - * Get the paragraph level of the text.
15.398 - *
15.399 - * @param pBiDi is the paragraph or line <code>UBiDi</code> object.
15.400 - *
15.401 - * @return The paragraph level.
15.402 - *
15.403 - * @see UBiDiLevel
15.404 - */
15.405 -U_CAPI UBiDiLevel U_EXPORT2
15.406 -ubidi_getParaLevel(const UBiDi *pBiDi);
15.407 -
15.408 -/**
15.409 - * Get the level for one character.
15.410 - *
15.411 - * @param pBiDi is the paragraph or line <code>UBiDi</code> object.
15.412 - *
15.413 - * @param charIndex the index of a character.
15.414 - *
15.415 - * @return The level for the character at charIndex.
15.416 - *
15.417 - * @see UBiDiLevel
15.418 - */
15.419 -U_CAPI UBiDiLevel U_EXPORT2
15.420 -ubidi_getLevelAt(const UBiDi *pBiDi, int32_t charIndex);
15.421 -
15.422 -/**
15.423 - * Get an array of levels for each character.<p>
15.424 - *
15.425 - * Note that this function may allocate memory under some
15.426 - * circumstances, unlike <code>ubidi_getLevelAt()</code>.
15.427 - *
15.428 - * @param pBiDi is the paragraph or line <code>UBiDi</code> object.
15.429 - *
15.430 - * @param pErrorCode must be a valid pointer to an error code value,
15.431 - * which must not indicate a failure before the function call.
15.432 - *
15.433 - * @return The levels array for the text,
15.434 - * or <code>NULL</code> if an error occurs.
15.435 - *
15.436 - * @see UBiDiLevel
15.437 - */
15.438 -U_CAPI const UBiDiLevel * U_EXPORT2
15.439 -ubidi_getLevels(UBiDi *pBiDi, UErrorCode *pErrorCode);
15.440 -
15.441 -/**
15.442 - * Get a logical run.
15.443 - * This function returns information about a run and is used
15.444 - * to retrieve runs in logical order.<p>
15.445 - * This is especially useful for line-breaking on a paragraph.
15.446 - *
15.447 - * @param pBiDi is the paragraph or line <code>UBiDi</code> object.
15.448 - *
15.449 - * @param logicalStart is the first character of the run.
15.450 - *
15.451 - * @param pLogicalLimit will receive the limit of the run.
15.452 - * The l-value that you point to here may be the
15.453 - * same expression (variable) as the one for
15.454 - * <code>logicalStart</code>.
15.455 - * This pointer can be <code>NULL</code> if this
15.456 - * value is not necessary.
15.457 - *
15.458 - * @param pLevel will receive the level of the run.
15.459 - * This pointer can be <code>NULL</code> if this
15.460 - * value is not necessary.
15.461 - */
15.462 -U_CAPI void U_EXPORT2
15.463 -ubidi_getLogicalRun(const UBiDi *pBiDi, int32_t logicalStart,
15.464 - int32_t *pLogicalLimit, UBiDiLevel *pLevel);
15.465 -
15.466 -/**
15.467 - * Get the number of runs.
15.468 - * This function may invoke the actual reordering on the
15.469 - * <code>UBiDi</code> object, after <code>ubidi_setPara()</code>
15.470 - * may have resolved only the levels of the text. Therefore,
15.471 - * <code>ubidi_countRuns()</code> may have to allocate memory,
15.472 - * and may fail doing so.
15.473 - *
15.474 - * @param pBiDi is the paragraph or line <code>UBiDi</code> object.
15.475 - *
15.476 - * @param pErrorCode must be a valid pointer to an error code value,
15.477 - * which must not indicate a failure before the function call.
15.478 - *
15.479 - * @return The number of runs.
15.480 - */
15.481 -U_CAPI int32_t U_EXPORT2
15.482 -ubidi_countRuns(UBiDi *pBiDi, UErrorCode *pErrorCode);
15.483 -
15.484 -/**
15.485 - * Get one run's logical start, length, and directionality,
15.486 - * which can be 0 for LTR or 1 for RTL.
15.487 - * In an RTL run, the character at the logical start is
15.488 - * visually on the right of the displayed run.
15.489 - * The length is the number of characters in the run.<p>
15.490 - * <code>ubidi_countRuns()</code> should be called
15.491 - * before the runs are retrieved.
15.492 - *
15.493 - * @param pBiDi is the paragraph or line <code>UBiDi</code> object.
15.494 - *
15.495 - * @param runIndex is the number of the run in visual order, in the
15.496 - * range <code>[0..ubidi_countRuns(pBiDi)-1]</code>.
15.497 - *
15.498 - * @param pLogicalStart is the first logical character index in the text.
15.499 - * The pointer may be <code>NULL</code> if this index is not needed.
15.500 - *
15.501 - * @param pLength is the number of characters (at least one) in the run.
15.502 - * The pointer may be <code>NULL</code> if this is not needed.
15.503 - *
15.504 - * @return the directionality of the run,
15.505 - * <code>UBIDI_LTR==0</code> or <code>UBIDI_RTL==1</code>,
15.506 - * never <code>UBIDI_MIXED</code>.
15.507 - *
15.508 - * @see ubidi_countRuns
15.509 - *
15.510 - * Example:
15.511 - * <pre>
15.512 - * int32_t i, count=ubidi_countRuns(pBiDi),
15.513 - * logicalStart, visualIndex=0, length;
15.514 - * for(i=0; i<count; ++i) {
15.515 - * if(UBIDI_LTR==ubidi_getVisualRun(pBiDi, i, &logicalStart, &length)) {
15.516 - * do { // LTR
15.517 - * show_char(text[logicalStart++], visualIndex++);
15.518 - * } while(--length>0);
15.519 - * } else {
15.520 - * logicalStart+=length; // logicalLimit
15.521 - * do { // RTL
15.522 - * show_char(text[--logicalStart], visualIndex++);
15.523 - * } while(--length>0);
15.524 - * }
15.525 - * }
15.526 - * </pre>
15.527 - *
15.528 - * Note that in right-to-left runs, code like this places
15.529 - * modifier letters before base characters and second surrogates
15.530 - * before first ones.
15.531 - */
15.532 -U_CAPI UBiDiDirection U_EXPORT2
15.533 -ubidi_getVisualRun(UBiDi *pBiDi, int32_t runIndex,
15.534 - int32_t *pLogicalStart, int32_t *pLength);
15.535 -
15.536 -/**
15.537 - * Get the visual position from a logical text position.
15.538 - * If such a mapping is used many times on the same
15.539 - * <code>UBiDi</code> object, then calling
15.540 - * <code>ubidi_getLogicalMap()</code> is more efficient.<p>
15.541 - *
15.542 - * Note that in right-to-left runs, this mapping places
15.543 - * modifier letters before base characters and second surrogates
15.544 - * before first ones.
15.545 - *
15.546 - * @param pBiDi is the paragraph or line <code>UBiDi</code> object.
15.547 - *
15.548 - * @param logicalIndex is the index of a character in the text.
15.549 - *
15.550 - * @param pErrorCode must be a valid pointer to an error code value,
15.551 - * which must not indicate a failure before the function call.
15.552 - *
15.553 - * @return The visual position of this character.
15.554 - *
15.555 - * @see ubidi_getLogicalMap
15.556 - * @see ubidi_getLogicalIndex
15.557 - */
15.558 -U_CAPI int32_t U_EXPORT2
15.559 -ubidi_getVisualIndex(UBiDi *pBiDi, int32_t logicalIndex, UErrorCode *pErrorCode);
15.560 -
15.561 -/**
15.562 - * Get the logical text position from a visual position.
15.563 - * If such a mapping is used many times on the same
15.564 - * <code>UBiDi</code> object, then calling
15.565 - * <code>ubidi_getVisualMap()</code> is more efficient.<p>
15.566 - *
15.567 - * This is the inverse function to <code>ubidi_getVisualIndex()</code>.
15.568 - *
15.569 - * @param pBiDi is the paragraph or line <code>UBiDi</code> object.
15.570 - *
15.571 - * @param visualIndex is the visual position of a character.
15.572 - *
15.573 - * @param pErrorCode must be a valid pointer to an error code value,
15.574 - * which must not indicate a failure before the function call.
15.575 - *
15.576 - * @return The index of this character in the text.
15.577 - *
15.578 - * @see ubidi_getVisualMap
15.579 - * @see ubidi_getVisualIndex
15.580 - */
15.581 -U_CAPI int32_t U_EXPORT2
15.582 -ubidi_getLogicalIndex(UBiDi *pBiDi, int32_t visualIndex, UErrorCode *pErrorCode);
15.583 -
15.584 -/**
15.585 - * Get a logical-to-visual index map (array) for the characters in the UBiDi
15.586 - * (paragraph or line) object.
15.587 - *
15.588 - * @param pBiDi is the paragraph or line <code>UBiDi</code> object.
15.589 - *
15.590 - * @param indexMap is a pointer to an array of <code>ubidi_getLength()</code>
15.591 - * indexes which will reflect the reordering of the characters.
15.592 - * The array does not need to be initialized.<p>
15.593 - * The index map will result in <code>indexMap[logicalIndex]==visualIndex</code>.<p>
15.594 - *
15.595 - * @param pErrorCode must be a valid pointer to an error code value,
15.596 - * which must not indicate a failure before the function call.
15.597 - *
15.598 - * @see ubidi_getVisualMap
15.599 - * @see ubidi_getVisualIndex
15.600 - */
15.601 -U_CAPI void U_EXPORT2
15.602 -ubidi_getLogicalMap(UBiDi *pBiDi, int32_t *indexMap, UErrorCode *pErrorCode);
15.603 -
15.604 -/**
15.605 - * Get a visual-to-logical index map (array) for the characters in the UBiDi
15.606 - * (paragraph or line) object.
15.607 - *
15.608 - * @param pBiDi is the paragraph or line <code>UBiDi</code> object.
15.609 - *
15.610 - * @param indexMap is a pointer to an array of <code>ubidi_getLength()</code>
15.611 - * indexes which will reflect the reordering of the characters.
15.612 - * The array does not need to be initialized.<p>
15.613 - * The index map will result in <code>indexMap[visualIndex]==logicalIndex</code>.<p>
15.614 - *
15.615 - * @param pErrorCode must be a valid pointer to an error code value,
15.616 - * which must not indicate a failure before the function call.
15.617 - *
15.618 - * @see ubidi_getLogicalMap
15.619 - * @see ubidi_getLogicalIndex
15.620 - */
15.621 -U_CAPI void U_EXPORT2
15.622 -ubidi_getVisualMap(UBiDi *pBiDi, int32_t *indexMap, UErrorCode *pErrorCode);
15.623 -
15.624 -/**
15.625 - * This is a convenience function that does not use a UBiDi object.
15.626 - * It is intended to be used for when an application has determined the levels
15.627 - * of objects (character sequences) and just needs to have them reordered (L2).
15.628 - * This is equivalent to using <code>ubidi_getLogicalMap</code> on a
15.629 - * <code>UBiDi</code> object.
15.630 - *
15.631 - * @param levels is an array with <code>length</code> levels that have been determined by
15.632 - * the application.
15.633 - *
15.634 - * @param length is the number of levels in the array, or, semantically,
15.635 - * the number of objects to be reordered.
15.636 - * It must be <code>length>0</code>.
15.637 - *
15.638 - * @param indexMap is a pointer to an array of <code>length</code>
15.639 - * indexes which will reflect the reordering of the characters.
15.640 - * The array does not need to be initialized.<p>
15.641 - * The index map will result in <code>indexMap[logicalIndex]==visualIndex</code>.
15.642 - */
15.643 -U_CAPI void U_EXPORT2
15.644 -ubidi_reorderLogical(const UBiDiLevel *levels, int32_t length, int32_t *indexMap);
15.645 -
15.646 -/**
15.647 - * This is a convenience function that does not use a UBiDi object.
15.648 - * It is intended to be used for when an application has determined the levels
15.649 - * of objects (character sequences) and just needs to have them reordered (L2).
15.650 - * This is equivalent to using <code>ubidi_getVisualMap</code> on a
15.651 - * <code>UBiDi</code> object.
15.652 - *
15.653 - * @param levels is an array with <code>length</code> levels that have been determined by
15.654 - * the application.
15.655 - *
15.656 - * @param length is the number of levels in the array, or, semantically,
15.657 - * the number of objects to be reordered.
15.658 - * It must be <code>length>0</code>.
15.659 - *
15.660 - * @param indexMap is a pointer to an array of <code>length</code>
15.661 - * indexes which will reflect the reordering of the characters.
15.662 - * The array does not need to be initialized.<p>
15.663 - * The index map will result in <code>indexMap[visualIndex]==logicalIndex</code>.
15.664 - */
15.665 -U_CAPI void U_EXPORT2
15.666 -ubidi_reorderVisual(const UBiDiLevel *levels, int32_t length, int32_t *indexMap);
15.667 -
15.668 -/**
15.669 - * Invert an index map.
15.670 - * The one-to-one index mapping of the first map is inverted and written to
15.671 - * the second one.
15.672 - *
15.673 - * @param srcMap is an array with <code>length</code> indexes
15.674 - * which define the original mapping.
15.675 - *
15.676 - * @param destMap is an array with <code>length</code> indexes
15.677 - * which will be filled with the inverse mapping.
15.678 - *
15.679 - * @param length is the length of each array.
15.680 - */
15.681 -U_CAPI void U_EXPORT2
15.682 -ubidi_invertMap(const int32_t *srcMap, int32_t *destMap, int32_t length);
15.683 -
15.684 -/**
15.685 - * @name Sample code for the ICU BiDi API
15.686 - *
15.687 - * <h2>Rendering a paragraph with the ICU BiDi API</h2>
15.688 - *
15.689 - * This is (hypothetical) sample code that illustrates
15.690 - * how the ICU BiDi API could be used to render a paragraph of text.
15.691 - * Rendering code depends highly on the graphics system,
15.692 - * therefore this sample code must make a lot of assumptions,
15.693 - * which may or may not match any existing graphics system's properties.
15.694 - *
15.695 - * <p>The basic assumptions are:</p>
15.696 - * <ul>
15.697 - * <li>Rendering is done from left to right on a horizontal line.</li>
15.698 - * <li>A run of single-style, unidirectional text can be rendered at once.</li>
15.699 - * <li>Such a run of text is passed to the graphics system with
15.700 - * characters (code units) in logical order.</li>
15.701 - * <li>The line-breaking algorithm is very complicated
15.702 - * and Locale-dependent -
15.703 - * and therefore its implementation omitted from this sample code.</li>
15.704 - * </ul>
15.705 - *
15.706 - * <pre>
15.707 - * #include "ubidi.h"
15.708 - *
15.709 - * typedef enum {
15.710 - * styleNormal=0, styleSelected=1,
15.711 - * styleBold=2, styleItalics=4,
15.712 - * styleSuper=8, styleSub=16
15.713 - * } Style;
15.714 - *
15.715 - * typedef struct { int32_t limit; Style style; } StyleRun;
15.716 - *
15.717 - * int getTextWidth(const UChar *text, int32_t start, int32_t limit,
15.718 - * const StyleRun *styleRuns, int styleRunCount);
15.719 - *
15.720 - * // set *pLimit and *pStyleRunLimit for a line
15.721 - * // from text[start] and from styleRuns[styleRunStart]
15.722 - * // using ubidi_getLogicalRun(para, ...)
15.723 - * void getLineBreak(const UChar *text, int32_t start, int32_t *pLimit,
15.724 - * UBiDi *para,
15.725 - * const StyleRun *styleRuns, int styleRunStart, int *pStyleRunLimit,
15.726 - * int *pLineWidth);
15.727 - *
15.728 - * // render runs on a line sequentially, always from left to right
15.729 - *
15.730 - * // prepare rendering a new line
15.731 - * void startLine(UBiDiDirection textDirection, int lineWidth);
15.732 - *
15.733 - * // render a run of text and advance to the right by the run width
15.734 - * // the text[start..limit-1] is always in logical order
15.735 - * void renderRun(const UChar *text, int32_t start, int32_t limit,
15.736 - * UBiDiDirection textDirection, Style style);
15.737 - *
15.738 - * // We could compute a cross-product
15.739 - * // from the style runs with the directional runs
15.740 - * // and then reorder it.
15.741 - * // Instead, here we iterate over each run type
15.742 - * // and render the intersections -
15.743 - * // with shortcuts in simple (and common) cases.
15.744 - * // renderParagraph() is the main function.
15.745 - *
15.746 - * // render a directional run with
15.747 - * // (possibly) multiple style runs intersecting with it
15.748 - * void renderDirectionalRun(const UChar *text,
15.749 - * int32_t start, int32_t limit,
15.750 - * UBiDiDirection direction,
15.751 - * const StyleRun *styleRuns, int styleRunCount) {
15.752 - * int i;
15.753 - *
15.754 - * // iterate over style runs
15.755 - * if(direction==UBIDI_LTR) {
15.756 - * int styleLimit;
15.757 - *
15.758 - * for(i=0; i<styleRunCount; ++i) {
15.759 - * styleLimit=styleRun[i].limit;
15.760 - * if(start<styleLimit) {
15.761 - * if(styleLimit>limit) { styleLimit=limit; }
15.762 - * renderRun(text, start, styleLimit,
15.763 - * direction, styleRun[i].style);
15.764 - * if(styleLimit==limit) { break; }
15.765 - * start=styleLimit;
15.766 - * }
15.767 - * }
15.768 - * } else {
15.769 - * int styleStart;
15.770 - *
15.771 - * for(i=styleRunCount-1; i>=0; --i) {
15.772 - * if(i>0) {
15.773 - * styleStart=styleRun[i-1].limit;
15.774 - * } else {
15.775 - * styleStart=0;
15.776 - * }
15.777 - * if(limit>=styleStart) {
15.778 - * if(styleStart<start) { styleStart=start; }
15.779 - * renderRun(text, styleStart, limit,
15.780 - * direction, styleRun[i].style);
15.781 - * if(styleStart==start) { break; }
15.782 - * limit=styleStart;
15.783 - * }
15.784 - * }
15.785 - * }
15.786 - * }
15.787 - *
15.788 - * // the line object represents text[start..limit-1]
15.789 - * void renderLine(UBiDi *line, const UChar *text,
15.790 - * int32_t start, int32_t limit,
15.791 - * const StyleRun *styleRuns, int styleRunCount) {
15.792 - * UBiDiDirection direction=ubidi_getDirection(line);
15.793 - * if(direction!=UBIDI_MIXED) {
15.794 - * // unidirectional
15.795 - * if(styleRunCount<=1) {
15.796 - * renderRun(text, start, limit, direction, styleRuns[0].style);
15.797 - * } else {
15.798 - * renderDirectionalRun(text, start, limit,
15.799 - * direction, styleRuns, styleRunCount);
15.800 - * }
15.801 - * } else {
15.802 - * // mixed-directional
15.803 - * int32_t count, i, length;
15.804 - * UBiDiLevel level;
15.805 - *
15.806 - * count=ubidi_countRuns(para, pErrorCode);
15.807 - * if(U_SUCCESS(*pErrorCode)) {
15.808 - * if(styleRunCount<=1) {
15.809 - * Style style=styleRuns[0].style;
15.810 - *
15.811 - * // iterate over directional runs
15.812 - * for(i=0; i<count; ++i) {
15.813 - * direction=ubidi_getVisualRun(para, i, &start, &length);
15.814 - * renderRun(text, start, start+length, direction, style);
15.815 - * }
15.816 - * } else {
15.817 - * int32_t j;
15.818 - *
15.819 - * // iterate over both directional and style runs
15.820 - * for(i=0; i<count; ++i) {
15.821 - * direction=ubidi_getVisualRun(line, i, &start, &length);
15.822 - * renderDirectionalRun(text, start, start+length,
15.823 - * direction, styleRuns, styleRunCount);
15.824 - * }
15.825 - * }
15.826 - * }
15.827 - * }
15.828 - * }
15.829 - *
15.830 - * void renderParagraph(const UChar *text, int32_t length,
15.831 - * UBiDiDirection textDirection,
15.832 - * const StyleRun *styleRuns, int styleRunCount,
15.833 - * int lineWidth,
15.834 - * UErrorCode *pErrorCode) {
15.835 - * UBiDi *para;
15.836 - *
15.837 - * if(pErrorCode==NULL || U_FAILURE(*pErrorCode) || length<=0) {
15.838 - * return;
15.839 - * }
15.840 - *
15.841 - * para=ubidi_openSized(length, 0, pErrorCode);
15.842 - * if(para==NULL) { return; }
15.843 - *
15.844 - * ubidi_setPara(para, text, length,
15.845 - * textDirection ? UBIDI_DEFAULT_RTL : UBIDI_DEFAULT_LTR,
15.846 - * NULL, pErrorCode);
15.847 - * if(U_SUCCESS(*pErrorCode)) {
15.848 - * UBiDiLevel paraLevel=1&ubidi_getParaLevel(para);
15.849 - * StyleRun styleRun={ length, styleNormal };
15.850 - * int width;
15.851 - *
15.852 - * if(styleRuns==NULL || styleRunCount<=0) {
15.853 - * styleRunCount=1;
15.854 - * styleRuns=&styleRun;
15.855 - * }
15.856 - *
15.857 - * // assume styleRuns[styleRunCount-1].limit>=length
15.858 - *
15.859 - * width=getTextWidth(text, 0, length, styleRuns, styleRunCount);
15.860 - * if(width<=lineWidth) {
15.861 - * // everything fits onto one line
15.862 - *
15.863 - * // prepare rendering a new line from either left or right
15.864 - * startLine(paraLevel, width);
15.865 - *
15.866 - * renderLine(para, text, 0, length,
15.867 - * styleRuns, styleRunCount);
15.868 - * } else {
15.869 - * UBiDi *line;
15.870 - *
15.871 - * // we need to render several lines
15.872 - * line=ubidi_openSized(length, 0, pErrorCode);
15.873 - * if(line!=NULL) {
15.874 - * int32_t start=0, limit;
15.875 - * int styleRunStart=0, styleRunLimit;
15.876 - *
15.877 - * for(;;) {
15.878 - * limit=length;
15.879 - * styleRunLimit=styleRunCount;
15.880 - * getLineBreak(text, start, &limit, para,
15.881 - * styleRuns, styleRunStart, &styleRunLimit,
15.882 - * &width);
15.883 - * ubidi_setLine(para, start, limit, line, pErrorCode);
15.884 - * if(U_SUCCESS(*pErrorCode)) {
15.885 - * // prepare rendering a new line
15.886 - * // from either left or right
15.887 - * startLine(paraLevel, width);
15.888 - *
15.889 - * renderLine(line, text, start, limit,
15.890 - * styleRuns+styleRunStart,
15.891 - * styleRunLimit-styleRunStart);
15.892 - * }
15.893 - * if(limit==length) { break; }
15.894 - * start=limit;
15.895 - * styleRunStart=styleRunLimit-1;
15.896 - * if(start>=styleRuns[styleRunStart].limit) {
15.897 - * ++styleRunStart;
15.898 - * }
15.899 - * }
15.900 - *
15.901 - * ubidi_close(line);
15.902 - * }
15.903 - * }
15.904 - * }
15.905 - *
15.906 - * ubidi_close(para);
15.907 - * }
15.908 - * </pre>
15.909 - */
15.910 -BIDI_SAMPLE_CODE
15.911 -/*@{*/
15.912 -/*@}*/
15.913 -
15.914 -/*@}*/
15.915 -
15.916 -#endif
16.1 --- a/src/share/native/sun/font/bidi/ubidiimp.h Sun Jun 21 23:52:58 2009 -0700
16.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
16.3 @@ -1,246 +0,0 @@
16.4 -/*
16.5 - * Portions Copyright 2000-2003 Sun Microsystems, Inc. All Rights Reserved.
16.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
16.7 - *
16.8 - * This code is free software; you can redistribute it and/or modify it
16.9 - * under the terms of the GNU General Public License version 2 only, as
16.10 - * published by the Free Software Foundation. Sun designates this
16.11 - * particular file as subject to the "Classpath" exception as provided
16.12 - * by Sun in the LICENSE file that accompanied this code.
16.13 - *
16.14 - * This code is distributed in the hope that it will be useful, but WITHOUT
16.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16.16 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16.17 - * version 2 for more details (a copy is included in the LICENSE file that
16.18 - * accompanied this code).
16.19 - *
16.20 - * You should have received a copy of the GNU General Public License version
16.21 - * 2 along with this work; if not, write to the Free Software Foundation,
16.22 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
16.23 - *
16.24 - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
16.25 - * CA 95054 USA or visit www.sun.com if you need additional information or
16.26 - * have any questions.
16.27 - */
16.28 -
16.29 -/*
16.30 - * (C) Copyright IBM Corp. 1999-2003 - All Rights Reserved
16.31 - *
16.32 - * The original version of this source code and documentation is
16.33 - * copyrighted and owned by IBM. These materials are provided
16.34 - * under terms of a License Agreement between IBM and Sun.
16.35 - * This technology is protected by multiple US and International
16.36 - * patents. This notice and attribution to IBM may not be removed.
16.37 - */
16.38 -
16.39 -/*
16.40 -* file name: ubidiimp.h
16.41 -* encoding: US-ASCII
16.42 -* tab size: 8 (not used)
16.43 -* indentation:4
16.44 -*
16.45 -* created on: 1999aug06
16.46 -* created by: Markus W. Scherer
16.47 -*/
16.48 -
16.49 -#ifndef UBIDIIMP_H
16.50 -#define UBIDIIMP_H
16.51 -
16.52 -/* set import/export definitions */
16.53 -#ifdef U_COMMON_IMPLEMENTATION
16.54 -
16.55 -#include "utypes.h"
16.56 -#include "uchardir.h"
16.57 -
16.58 -/* miscellaneous definitions ---------------------------------------------- */
16.59 -
16.60 -typedef uint8_t DirProp;
16.61 -typedef uint32_t Flags;
16.62 -
16.63 -/* Comparing the description of the BiDi algorithm with this implementation
16.64 - is easier with the same names for the BiDi types in the code as there.
16.65 - See UCharDirection in uchar.h .
16.66 -*/
16.67 -enum {
16.68 - L= U_LEFT_TO_RIGHT,
16.69 - R= U_RIGHT_TO_LEFT,
16.70 - EN= U_EUROPEAN_NUMBER,
16.71 - ES= U_EUROPEAN_NUMBER_SEPARATOR,
16.72 - ET= U_EUROPEAN_NUMBER_TERMINATOR,
16.73 - AN= U_ARABIC_NUMBER,
16.74 - CS= U_COMMON_NUMBER_SEPARATOR,
16.75 - B= U_BLOCK_SEPARATOR,
16.76 - S= U_SEGMENT_SEPARATOR,
16.77 - WS= U_WHITE_SPACE_NEUTRAL,
16.78 - ON= U_OTHER_NEUTRAL,
16.79 - LRE=U_LEFT_TO_RIGHT_EMBEDDING,
16.80 - LRO=U_LEFT_TO_RIGHT_OVERRIDE,
16.81 - AL= U_RIGHT_TO_LEFT_ARABIC,
16.82 - RLE=U_RIGHT_TO_LEFT_EMBEDDING,
16.83 - RLO=U_RIGHT_TO_LEFT_OVERRIDE,
16.84 - PDF=U_POP_DIRECTIONAL_FORMAT,
16.85 - NSM=U_DIR_NON_SPACING_MARK,
16.86 - BN= U_BOUNDARY_NEUTRAL,
16.87 - dirPropCount
16.88 -};
16.89 -
16.90 -/*
16.91 - * Sometimes, bit values are more appropriate
16.92 - * to deal with directionality properties.
16.93 - * Abbreviations in these macro names refer to names
16.94 - * used in the BiDi algorithm.
16.95 - */
16.96 -#define DIRPROP_FLAG(dir) (1UL<<(dir))
16.97 -
16.98 -/* special flag for multiple runs from explicit embedding codes */
16.99 -#define DIRPROP_FLAG_MULTI_RUNS (1UL<<31)
16.100 -
16.101 -/* are there any characters that are LTR or RTL? */
16.102 -#define MASK_LTR (DIRPROP_FLAG(L)|DIRPROP_FLAG(EN)|DIRPROP_FLAG(AN)|DIRPROP_FLAG(LRE)|DIRPROP_FLAG(LRO))
16.103 -#define MASK_RTL (DIRPROP_FLAG(R)|DIRPROP_FLAG(AL)|DIRPROP_FLAG(RLE)|DIRPROP_FLAG(RLO))
16.104 -
16.105 -/* explicit embedding codes */
16.106 -#define MASK_LRX (DIRPROP_FLAG(LRE)|DIRPROP_FLAG(LRO))
16.107 -#define MASK_RLX (DIRPROP_FLAG(RLE)|DIRPROP_FLAG(RLO))
16.108 -#define MASK_OVERRIDE (DIRPROP_FLAG(LRO)|DIRPROP_FLAG(RLO))
16.109 -
16.110 -#define MASK_EXPLICIT (MASK_LRX|MASK_RLX|DIRPROP_FLAG(PDF))
16.111 -#define MASK_BN_EXPLICIT (DIRPROP_FLAG(BN)|MASK_EXPLICIT)
16.112 -
16.113 -/* paragraph and segment separators */
16.114 -#define MASK_B_S (DIRPROP_FLAG(B)|DIRPROP_FLAG(S))
16.115 -
16.116 -/* all types that are counted as White Space or Neutral in some steps */
16.117 -#define MASK_WS (MASK_B_S|DIRPROP_FLAG(WS)|MASK_BN_EXPLICIT)
16.118 -#define MASK_N (DIRPROP_FLAG(ON)|MASK_WS)
16.119 -
16.120 -/* all types that are included in a sequence of European Terminators for (W5) */
16.121 -#define MASK_ET_NSM_BN (DIRPROP_FLAG(ET)|DIRPROP_FLAG(NSM)|MASK_BN_EXPLICIT)
16.122 -
16.123 -/* types that are neutrals or could becomes neutrals in (Wn) */
16.124 -#define MASK_POSSIBLE_N (DIRPROP_FLAG(CS)|DIRPROP_FLAG(ES)|DIRPROP_FLAG(ET)|MASK_N)
16.125 -
16.126 -/*
16.127 - * These types may be changed to "e",
16.128 - * the embedding type (L or R) of the run,
16.129 - * in the BiDi algorithm (N2)
16.130 - */
16.131 -#define MASK_EMBEDDING (DIRPROP_FLAG(NSM)|MASK_POSSIBLE_N)
16.132 -
16.133 -/* the dirProp's L and R are defined to 0 and 1 values in UCharDirection */
16.134 -#define GET_LR_FROM_LEVEL(level) ((DirProp)((level)&1))
16.135 -
16.136 -#define IS_DEFAULT_LEVEL(level) (((level)&0xfe)==0xfe)
16.137 -
16.138 -/* handle surrogate pairs --------------------------------------------------- */
16.139 -/* Note: dlf added for java */
16.140 -#define IS_FIRST_SURROGATE(uchar) (((uchar)&0xfc00)==0xd800)
16.141 -#define IS_SECOND_SURROGATE(uchar) (((uchar)&0xfc00)==0xdc00)
16.142 -
16.143 -/* get the UTF-32 value directly from the surrogate pseudo-characters */
16.144 -#define SURROGATE_OFFSET ((0xd800<<10UL)+0xdc00-0x10000)
16.145 -#define GET_UTF_32(first, second) (((first)<<10UL)+(second)-SURROGATE_OFFSET)
16.146 -
16.147 -/* Run structure for reordering --------------------------------------------- */
16.148 -
16.149 -typedef struct Run {
16.150 - int32_t logicalStart, /* first character of the run; b31 indicates even/odd level */
16.151 - visualLimit; /* last visual position of the run +1 */
16.152 -} Run;
16.153 -
16.154 -/* in a Run, logicalStart will get this bit set if the run level is odd */
16.155 -#define INDEX_ODD_BIT (1UL<<31)
16.156 -
16.157 -#define MAKE_INDEX_ODD_PAIR(index, level) (index|((uint32_t)level<<31))
16.158 -#define ADD_ODD_BIT_FROM_LEVEL(x, level) ((x)|=((uint32_t)level<<31))
16.159 -#define REMOVE_ODD_BIT(x) ((x)&=~INDEX_ODD_BIT)
16.160 -
16.161 -#define GET_INDEX(x) (x&~INDEX_ODD_BIT)
16.162 -#define GET_ODD_BIT(x) ((uint32_t)x>>31)
16.163 -#define IS_ODD_RUN(x) ((x&INDEX_ODD_BIT)!=0)
16.164 -#define IS_EVEN_RUN(x) ((x&INDEX_ODD_BIT)==0)
16.165 -
16.166 -U_CFUNC bool_t
16.167 -ubidi_getRuns(UBiDi *pBiDi);
16.168 -
16.169 -/* UBiDi structure ----------------------------------------------------------- */
16.170 -
16.171 -struct UBiDi {
16.172 - /* alias pointer to the current text */
16.173 - const UChar *text;
16.174 -
16.175 - /* length of the current text */
16.176 - int32_t length;
16.177 -
16.178 - /* memory sizes in bytes */
16.179 - int32_t dirPropsSize, levelsSize, runsSize;
16.180 -
16.181 - /* allocated memory */
16.182 - DirProp *dirPropsMemory;
16.183 - UBiDiLevel *levelsMemory;
16.184 - Run *runsMemory;
16.185 -
16.186 - /* indicators for whether memory may be allocated after ubidi_open() */
16.187 - bool_t mayAllocateText, mayAllocateRuns;
16.188 -
16.189 - /* arrays with one value per text-character */
16.190 - const DirProp *dirProps;
16.191 - UBiDiLevel *levels;
16.192 -
16.193 - /* are we performing an approximation of the "inverse BiDi" algorithm? */
16.194 - bool_t isInverse;
16.195 -
16.196 - /* the paragraph level */
16.197 - UBiDiLevel paraLevel;
16.198 -
16.199 - /* the overall paragraph or line directionality - see UBiDiDirection */
16.200 - UBiDiDirection direction;
16.201 -
16.202 - /* flags is a bit set for which directional properties are in the text */
16.203 - Flags flags;
16.204 -
16.205 - /* characters after trailingWSStart are WS and are */
16.206 - /* implicitly at the paraLevel (rule (L1)) - levels may not reflect that */
16.207 - int32_t trailingWSStart;
16.208 -
16.209 - /* fields for line reordering */
16.210 - int32_t runCount; /* ==-1: runs not set up yet */
16.211 - Run *runs;
16.212 -
16.213 - /* for non-mixed text, we only need a tiny array of runs (no malloc()) */
16.214 - Run simpleRuns[1];
16.215 -};
16.216 -
16.217 -/* helper function to (re)allocate memory if allowed */
16.218 -extern bool_t
16.219 -ubidi_getMemory(void **pMemory, int32_t *pSize, bool_t mayAllocate, int32_t sizeNeeded);
16.220 -
16.221 -/* helper macros for each allocated array in UBiDi */
16.222 -#define getDirPropsMemory(pBiDi, length) \
16.223 - ubidi_getMemory((void **)&(pBiDi)->dirPropsMemory, &(pBiDi)->dirPropsSize, \
16.224 - (pBiDi)->mayAllocateText, (length))
16.225 -
16.226 -#define getLevelsMemory(pBiDi, length) \
16.227 - ubidi_getMemory((void **)&(pBiDi)->levelsMemory, &(pBiDi)->levelsSize, \
16.228 - (pBiDi)->mayAllocateText, (length))
16.229 -
16.230 -#define getRunsMemory(pBiDi, length) \
16.231 - ubidi_getMemory((void **)&(pBiDi)->runsMemory, &(pBiDi)->runsSize, \
16.232 - (pBiDi)->mayAllocateRuns, (length)*sizeof(Run))
16.233 -
16.234 -/* additional macros used by ubidi_open() - always allow allocation */
16.235 -#define getInitialDirPropsMemory(pBiDi, length) \
16.236 - ubidi_getMemory((void **)&(pBiDi)->dirPropsMemory, &(pBiDi)->dirPropsSize, \
16.237 - TRUE, (length))
16.238 -
16.239 -#define getInitialLevelsMemory(pBiDi, length) \
16.240 - ubidi_getMemory((void **)&(pBiDi)->levelsMemory, &(pBiDi)->levelsSize, \
16.241 - TRUE, (length))
16.242 -
16.243 -#define getInitialRunsMemory(pBiDi, length) \
16.244 - ubidi_getMemory((void **)&(pBiDi)->runsMemory, &(pBiDi)->runsSize, \
16.245 - TRUE, (length)*sizeof(Run))
16.246 -
16.247 -#endif
16.248 -
16.249 -#endif
17.1 --- a/src/share/native/sun/font/bidi/ubidiln.c Sun Jun 21 23:52:58 2009 -0700
17.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
17.3 @@ -1,996 +0,0 @@
17.4 -/*
17.5 - * Portions Copyright 2000-2003 Sun Microsystems, Inc. All Rights Reserved.
17.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
17.7 - *
17.8 - * This code is free software; you can redistribute it and/or modify it
17.9 - * under the terms of the GNU General Public License version 2 only, as
17.10 - * published by the Free Software Foundation. Sun designates this
17.11 - * particular file as subject to the "Classpath" exception as provided
17.12 - * by Sun in the LICENSE file that accompanied this code.
17.13 - *
17.14 - * This code is distributed in the hope that it will be useful, but WITHOUT
17.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17.16 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17.17 - * version 2 for more details (a copy is included in the LICENSE file that
17.18 - * accompanied this code).
17.19 - *
17.20 - * You should have received a copy of the GNU General Public License version
17.21 - * 2 along with this work; if not, write to the Free Software Foundation,
17.22 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17.23 - *
17.24 - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
17.25 - * CA 95054 USA or visit www.sun.com if you need additional information or
17.26 - * have any questions.
17.27 - */
17.28 -
17.29 -/*
17.30 - * (C) Copyright IBM Corp. 1999-2003 - All Rights Reserved
17.31 - *
17.32 - * The original version of this source code and documentation is
17.33 - * copyrighted and owned by IBM. These materials are provided
17.34 - * under terms of a License Agreement between IBM and Sun.
17.35 - * This technology is protected by multiple US and International
17.36 - * patents. This notice and attribution to IBM may not be removed.
17.37 - */
17.38 -
17.39 -/*
17.40 -* file name: ubidiln.c
17.41 -* encoding: US-ASCII
17.42 -* tab size: 8 (not used)
17.43 -* indentation:4
17.44 -*
17.45 -* created on: 1999aug06
17.46 -* created by: Markus W. Scherer
17.47 -*/
17.48 -
17.49 -/* set import/export definitions */
17.50 -#ifndef U_COMMON_IMPLEMENTATION
17.51 -# define U_COMMON_IMPLEMENTATION
17.52 -#endif
17.53 -
17.54 -#include "cmemory.h"
17.55 -#include "utypes.h"
17.56 -#include "uchardir.h"
17.57 -#include "ubidi.h"
17.58 -#include "ubidiimp.h"
17.59 -
17.60 -/*
17.61 - * General remarks about the functions in this file:
17.62 - *
17.63 - * These functions deal with the aspects of potentially mixed-directional
17.64 - * text in a single paragraph or in a line of a single paragraph
17.65 - * which has already been processed according to
17.66 - * the Unicode 3.0 BiDi algorithm as defined in
17.67 - * http://www.unicode.org/unicode/reports/tr9/ , version 5,
17.68 - * also described in The Unicode Standard, Version 3.0 .
17.69 - *
17.70 - * This means that there is a UBiDi object with a levels
17.71 - * and a dirProps array.
17.72 - * paraLevel and direction are also set.
17.73 - * Only if the length of the text is zero, then levels==dirProps==NULL.
17.74 - *
17.75 - * The overall directionality of the paragraph
17.76 - * or line is used to bypass the reordering steps if possible.
17.77 - * Even purely RTL text does not need reordering there because
17.78 - * the ubidi_getLogical/VisualIndex() functions can compute the
17.79 - * index on the fly in such a case.
17.80 - *
17.81 - * The implementation of the access to same-level-runs and of the reordering
17.82 - * do attempt to provide better performance and less memory usage compared to
17.83 - * a direct implementation of especially rule (L2) with an array of
17.84 - * one (32-bit) integer per text character.
17.85 - *
17.86 - * Here, the levels array is scanned as soon as necessary, and a vector of
17.87 - * same-level-runs is created. Reordering then is done on this vector.
17.88 - * For each run of text positions that were resolved to the same level,
17.89 - * only 8 bytes are stored: the first text position of the run and the visual
17.90 - * position behind the run after reordering.
17.91 - * One sign bit is used to hold the directionality of the run.
17.92 - * This is inefficient if there are many very short runs. If the average run
17.93 - * length is <2, then this uses more memory.
17.94 - *
17.95 - * In a further attempt to save memory, the levels array is never changed
17.96 - * after all the resolution rules (Xn, Wn, Nn, In).
17.97 - * Many functions have to consider the field trailingWSStart:
17.98 - * if it is less than length, then there is an implicit trailing run
17.99 - * at the paraLevel,
17.100 - * which is not reflected in the levels array.
17.101 - * This allows a line UBiDi object to use the same levels array as
17.102 - * its paragraph parent object.
17.103 - *
17.104 - * When a UBiDi object is created for a line of a paragraph, then the
17.105 - * paragraph's levels and dirProps arrays are reused by way of setting
17.106 - * a pointer into them, not by copying. This again saves memory and forbids to
17.107 - * change the now shared levels for (L1).
17.108 - */
17.109 -
17.110 -/* prototypes --------------------------------------------------------------- */
17.111 -
17.112 -static void
17.113 -setTrailingWSStart(UBiDi *pBiDi);
17.114 -
17.115 -static void
17.116 -getSingleRun(UBiDi *pBiDi, UBiDiLevel level);
17.117 -
17.118 -static void
17.119 -reorderLine(UBiDi *pBiDi, UBiDiLevel minLevel, UBiDiLevel maxLevel);
17.120 -
17.121 -static bool_t
17.122 -prepareReorder(const UBiDiLevel *levels, int32_t length,
17.123 - int32_t *indexMap,
17.124 - UBiDiLevel *pMinLevel, UBiDiLevel *pMaxLevel);
17.125 -
17.126 -/* ubidi_setLine ------------------------------------------------------------ */
17.127 -
17.128 -U_CAPI void U_EXPORT2
17.129 -ubidi_setLine(const UBiDi *pParaBiDi,
17.130 - int32_t start, int32_t limit,
17.131 - UBiDi *pLineBiDi,
17.132 - UErrorCode *pErrorCode) {
17.133 - int32_t length;
17.134 -
17.135 - /* check the argument values */
17.136 - if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
17.137 - return;
17.138 - } else if(pParaBiDi==NULL || pLineBiDi==NULL) {
17.139 - *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
17.140 - return;
17.141 - } else if(start<0 || start>limit || limit>pParaBiDi->length) {
17.142 - *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
17.143 - return;
17.144 - }
17.145 -
17.146 - /* set the values in pLineBiDi from its pParaBiDi parent */
17.147 - pLineBiDi->text=pParaBiDi->text+start;
17.148 - length=pLineBiDi->length=limit-start;
17.149 - pLineBiDi->paraLevel=pParaBiDi->paraLevel;
17.150 -
17.151 - pLineBiDi->runs=NULL;
17.152 - pLineBiDi->flags=0;
17.153 -
17.154 - if(length>0) {
17.155 - pLineBiDi->dirProps=pParaBiDi->dirProps+start;
17.156 - pLineBiDi->levels=pParaBiDi->levels+start;
17.157 - pLineBiDi->runCount=-1;
17.158 -
17.159 - if(pParaBiDi->direction!=UBIDI_MIXED) {
17.160 - /* the parent is already trivial */
17.161 - pLineBiDi->direction=pParaBiDi->direction;
17.162 -
17.163 - /*
17.164 - * The parent's levels are all either
17.165 - * implicitly or explicitly ==paraLevel;
17.166 - * do the same here.
17.167 - */
17.168 - if(pParaBiDi->trailingWSStart<=start) {
17.169 - pLineBiDi->trailingWSStart=0;
17.170 - } else if(pParaBiDi->trailingWSStart<limit) {
17.171 - pLineBiDi->trailingWSStart=pParaBiDi->trailingWSStart-start;
17.172 - } else {
17.173 - pLineBiDi->trailingWSStart=length;
17.174 - }
17.175 - } else {
17.176 - const UBiDiLevel *levels=pLineBiDi->levels;
17.177 - int32_t i, trailingWSStart;
17.178 - UBiDiLevel level;
17.179 -
17.180 - setTrailingWSStart(pLineBiDi);
17.181 - trailingWSStart=pLineBiDi->trailingWSStart;
17.182 -
17.183 - /* recalculate pLineBiDi->direction */
17.184 - if(trailingWSStart==0) {
17.185 - /* all levels are at paraLevel */
17.186 - pLineBiDi->direction=(UBiDiDirection)(pLineBiDi->paraLevel&1);
17.187 - } else {
17.188 - /* get the level of the first character */
17.189 - level=(UBiDiLevel)(levels[0]&1);
17.190 -
17.191 - /* if there is anything of a different level, then the line is mixed */
17.192 - if(trailingWSStart<length && (pLineBiDi->paraLevel&1)!=level) {
17.193 - /* the trailing WS is at paraLevel, which differs from levels[0] */
17.194 - pLineBiDi->direction=UBIDI_MIXED;
17.195 - } else {
17.196 - /* see if levels[1..trailingWSStart-1] have the same direction as levels[0] and paraLevel */
17.197 - i=1;
17.198 - for(;;) {
17.199 - if(i==trailingWSStart) {
17.200 - /* the direction values match those in level */
17.201 - pLineBiDi->direction=(UBiDiDirection)level;
17.202 - break;
17.203 - } else if((levels[i]&1)!=level) {
17.204 - pLineBiDi->direction=UBIDI_MIXED;
17.205 - break;
17.206 - }
17.207 - ++i;
17.208 - }
17.209 - }
17.210 - }
17.211 -
17.212 - switch(pLineBiDi->direction) {
17.213 - case UBIDI_LTR:
17.214 - /* make sure paraLevel is even */
17.215 - pLineBiDi->paraLevel=(UBiDiLevel)((pLineBiDi->paraLevel+1)&~1);
17.216 -
17.217 - /* all levels are implicitly at paraLevel (important for ubidi_getLevels()) */
17.218 - pLineBiDi->trailingWSStart=0;
17.219 - break;
17.220 - case UBIDI_RTL:
17.221 - /* make sure paraLevel is odd */
17.222 - pLineBiDi->paraLevel|=1;
17.223 -
17.224 - /* all levels are implicitly at paraLevel (important for ubidi_getLevels()) */
17.225 - pLineBiDi->trailingWSStart=0;
17.226 - break;
17.227 - default:
17.228 - break;
17.229 - }
17.230 - }
17.231 - } else {
17.232 - /* create an object for a zero-length line */
17.233 - pLineBiDi->direction=pLineBiDi->paraLevel&1 ? UBIDI_RTL : UBIDI_LTR;
17.234 - pLineBiDi->trailingWSStart=pLineBiDi->runCount=0;
17.235 -
17.236 - pLineBiDi->dirProps=NULL;
17.237 - pLineBiDi->levels=NULL;
17.238 - }
17.239 - return;
17.240 -}
17.241 -
17.242 -U_CAPI UBiDiLevel U_EXPORT2
17.243 -ubidi_getLevelAt(const UBiDi *pBiDi, int32_t charIndex) {
17.244 - /* return paraLevel if in the trailing WS run, otherwise the real level */
17.245 - if(pBiDi==NULL || charIndex<0 || pBiDi->length<=charIndex) {
17.246 - return 0;
17.247 - } else if(pBiDi->direction!=UBIDI_MIXED || charIndex>=pBiDi->trailingWSStart) {
17.248 - return pBiDi->paraLevel;
17.249 - } else {
17.250 - return pBiDi->levels[charIndex];
17.251 - }
17.252 -}
17.253 -
17.254 -U_CAPI const UBiDiLevel * U_EXPORT2
17.255 -ubidi_getLevels(UBiDi *pBiDi, UErrorCode *pErrorCode) {
17.256 - int32_t start, length;
17.257 -
17.258 - if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
17.259 - return NULL;
17.260 - } else if(pBiDi==NULL || (length=pBiDi->length)<=0) {
17.261 - *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
17.262 - return NULL;
17.263 - }
17.264 -
17.265 - if((start=pBiDi->trailingWSStart)==length) {
17.266 - /* the current levels array reflects the WS run */
17.267 - return pBiDi->levels;
17.268 - }
17.269 -
17.270 - /*
17.271 - * After the previous if(), we know that the levels array
17.272 - * has an implicit trailing WS run and therefore does not fully
17.273 - * reflect itself all the levels.
17.274 - * This must be a UBiDi object for a line, and
17.275 - * we need to create a new levels array.
17.276 - */
17.277 -
17.278 - if(getLevelsMemory(pBiDi, length)) {
17.279 - UBiDiLevel *levels=pBiDi->levelsMemory;
17.280 -
17.281 - if(start>0 && levels!=pBiDi->levels) {
17.282 - icu_memcpy(levels, pBiDi->levels, start);
17.283 - }
17.284 - icu_memset(levels+start, pBiDi->paraLevel, length-start);
17.285 -
17.286 - /* this new levels array is set for the line and reflects the WS run */
17.287 - pBiDi->trailingWSStart=length;
17.288 - return pBiDi->levels=levels;
17.289 - } else {
17.290 - /* out of memory */
17.291 - *pErrorCode=U_MEMORY_ALLOCATION_ERROR;
17.292 - return NULL;
17.293 - }
17.294 -}
17.295 -
17.296 -U_CAPI void U_EXPORT2
17.297 -ubidi_getLogicalRun(const UBiDi *pBiDi, int32_t logicalStart,
17.298 - int32_t *pLogicalLimit, UBiDiLevel *pLevel) {
17.299 - int32_t length;
17.300 -
17.301 - if(pBiDi==NULL || logicalStart<0 || (length=pBiDi->length)<=logicalStart) {
17.302 - return;
17.303 - }
17.304 -
17.305 - if(pBiDi->direction!=UBIDI_MIXED || logicalStart>=pBiDi->trailingWSStart) {
17.306 - if(pLogicalLimit!=NULL) {
17.307 - *pLogicalLimit=length;
17.308 - }
17.309 - if(pLevel!=NULL) {
17.310 - *pLevel=pBiDi->paraLevel;
17.311 - }
17.312 - } else {
17.313 - UBiDiLevel *levels=pBiDi->levels;
17.314 - UBiDiLevel level=levels[logicalStart];
17.315 -
17.316 - /* search for the end of the run */
17.317 - length=pBiDi->trailingWSStart;
17.318 - while(++logicalStart<length && level==levels[logicalStart]) {}
17.319 -
17.320 - if(pLogicalLimit!=NULL) {
17.321 - *pLogicalLimit=logicalStart;
17.322 - }
17.323 - if(pLevel!=NULL) {
17.324 - *pLevel=level;
17.325 - }
17.326 - }
17.327 -}
17.328 -
17.329 -/* handle trailing WS (L1) -------------------------------------------------- */
17.330 -
17.331 -/*
17.332 - * setTrailingWSStart() sets the start index for a trailing
17.333 - * run of WS in the line. This is necessary because we do not modify
17.334 - * the paragraph's levels array that we just point into.
17.335 - * Using trailingWSStart is another form of performing (L1).
17.336 - *
17.337 - * To make subsequent operations easier, we also include the run
17.338 - * before the WS if it is at the paraLevel - we merge the two here.
17.339 - */
17.340 -static void
17.341 -setTrailingWSStart(UBiDi *pBiDi) {
17.342 - /* pBiDi->direction!=UBIDI_MIXED */
17.343 -
17.344 - const DirProp *dirProps=pBiDi->dirProps;
17.345 - UBiDiLevel *levels=pBiDi->levels;
17.346 - int32_t start=pBiDi->length;
17.347 - UBiDiLevel paraLevel=pBiDi->paraLevel;
17.348 -
17.349 - /* go backwards across all WS, BN, explicit codes */
17.350 - while(start>0 && DIRPROP_FLAG(dirProps[start-1])&MASK_WS) {
17.351 - --start;
17.352 - }
17.353 -
17.354 - /* if the WS run can be merged with the previous run then do so here */
17.355 - while(start>0 && levels[start-1]==paraLevel) {
17.356 - --start;
17.357 - }
17.358 -
17.359 - pBiDi->trailingWSStart=start;
17.360 -}
17.361 -
17.362 -/* runs API functions ------------------------------------------------------- */
17.363 -
17.364 -U_CAPI int32_t U_EXPORT2
17.365 -ubidi_countRuns(UBiDi *pBiDi, UErrorCode *pErrorCode) {
17.366 - if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
17.367 - return -1;
17.368 - } else if(pBiDi==NULL || (pBiDi->runCount<0 && !ubidi_getRuns(pBiDi))) {
17.369 - *pErrorCode=U_MEMORY_ALLOCATION_ERROR;
17.370 - return -1;
17.371 - } else {
17.372 - return pBiDi->runCount;
17.373 - }
17.374 -}
17.375 -
17.376 -U_CAPI UBiDiDirection U_EXPORT2
17.377 -ubidi_getVisualRun(UBiDi *pBiDi, int32_t runIndex,
17.378 - int32_t *pLogicalStart, int32_t *pLength) {
17.379 - if( pBiDi==NULL || runIndex<0 ||
17.380 - (pBiDi->runCount==-1 && !ubidi_getRuns(pBiDi)) ||
17.381 - runIndex>=pBiDi->runCount
17.382 - ) {
17.383 - return UBIDI_LTR;
17.384 - } else {
17.385 - int32_t start=pBiDi->runs[runIndex].logicalStart;
17.386 - if(pLogicalStart!=NULL) {
17.387 - *pLogicalStart=GET_INDEX(start);
17.388 - }
17.389 - if(pLength!=NULL) {
17.390 - if(runIndex>0) {
17.391 - *pLength=pBiDi->runs[runIndex].visualLimit-
17.392 - pBiDi->runs[runIndex-1].visualLimit;
17.393 - } else {
17.394 - *pLength=pBiDi->runs[0].visualLimit;
17.395 - }
17.396 - }
17.397 - return (UBiDiDirection)GET_ODD_BIT(start);
17.398 - }
17.399 -}
17.400 -
17.401 -/* compute the runs array --------------------------------------------------- */
17.402 -
17.403 -/*
17.404 - * Compute the runs array from the levels array.
17.405 - * After ubidi_getRuns() returns TRUE, runCount is guaranteed to be >0
17.406 - * and the runs are reordered.
17.407 - * Odd-level runs have visualStart on their visual right edge and
17.408 - * they progress visually to the left.
17.409 - */
17.410 -U_CFUNC bool_t
17.411 -ubidi_getRuns(UBiDi *pBiDi) {
17.412 - if(pBiDi->direction!=UBIDI_MIXED) {
17.413 - /* simple, single-run case - this covers length==0 */
17.414 - getSingleRun(pBiDi, pBiDi->paraLevel);
17.415 - } else /* UBIDI_MIXED, length>0 */ {
17.416 - /* mixed directionality */
17.417 - int32_t length=pBiDi->length, limit;
17.418 -
17.419 - /*
17.420 - * If there are WS characters at the end of the line
17.421 - * and the run preceding them has a level different from
17.422 - * paraLevel, then they will form their own run at paraLevel (L1).
17.423 - * Count them separately.
17.424 - * We need some special treatment for this in order to not
17.425 - * modify the levels array which a line UBiDi object shares
17.426 - * with its paragraph parent and its other line siblings.
17.427 - * In other words, for the trailing WS, it may be
17.428 - * levels[]!=paraLevel but we have to treat it like it were so.
17.429 - */
17.430 - limit=pBiDi->trailingWSStart;
17.431 - if(limit==0) {
17.432 - /* there is only WS on this line */
17.433 - getSingleRun(pBiDi, pBiDi->paraLevel);
17.434 - } else {
17.435 - UBiDiLevel *levels=pBiDi->levels;
17.436 - int32_t i, runCount;
17.437 - UBiDiLevel level=UBIDI_DEFAULT_LTR; /* initialize with no valid level */
17.438 -
17.439 - /* count the runs, there is at least one non-WS run, and limit>0 */
17.440 - runCount=0;
17.441 - for(i=0; i<limit; ++i) {
17.442 - /* increment runCount at the start of each run */
17.443 - if(levels[i]!=level) {
17.444 - ++runCount;
17.445 - level=levels[i];
17.446 - }
17.447 - }
17.448 -
17.449 - /*
17.450 - * We don't need to see if the last run can be merged with a trailing
17.451 - * WS run because setTrailingWSStart() would have done that.
17.452 - */
17.453 - if(runCount==1 && limit==length) {
17.454 - /* There is only one non-WS run and no trailing WS-run. */
17.455 - getSingleRun(pBiDi, levels[0]);
17.456 - } else /* runCount>1 || limit<length */ {
17.457 - /* allocate and set the runs */
17.458 - Run *runs;
17.459 - int32_t runIndex, start;
17.460 - UBiDiLevel minLevel=UBIDI_MAX_EXPLICIT_LEVEL+1, maxLevel=0;
17.461 -
17.462 - /* now, count a (non-mergable) WS run */
17.463 - if(limit<length) {
17.464 - ++runCount;
17.465 - }
17.466 -
17.467 - /* runCount>1 */
17.468 - if(getRunsMemory(pBiDi, runCount)) {
17.469 - runs=pBiDi->runsMemory;
17.470 - } else {
17.471 - return FALSE;
17.472 - }
17.473 -
17.474 - /* set the runs */
17.475 - /* this could be optimized, e.g.: 464->444, 484->444, 575->555, 595->555 */
17.476 - /* however, that would take longer and make other functions more complicated */
17.477 - runIndex=0;
17.478 -
17.479 - /* search for the run limits and initialize visualLimit values with the run lengths */
17.480 - i=0;
17.481 - do {
17.482 - /* prepare this run */
17.483 - start=i;
17.484 - level=levels[i];
17.485 - if(level<minLevel) {
17.486 - minLevel=level;
17.487 - }
17.488 - if(level>maxLevel) {
17.489 - maxLevel=level;
17.490 - }
17.491 -
17.492 - /* look for the run limit */
17.493 - while(++i<limit && levels[i]==level) {}
17.494 -
17.495 - /* i is another run limit */
17.496 - runs[runIndex].logicalStart=start;
17.497 - runs[runIndex].visualLimit=i-start;
17.498 - ++runIndex;
17.499 - } while(i<limit);
17.500 -
17.501 - if(limit<length) {
17.502 - /* there is a separate WS run */
17.503 - runs[runIndex].logicalStart=limit;
17.504 - runs[runIndex].visualLimit=length-limit;
17.505 - if(pBiDi->paraLevel<minLevel) {
17.506 - minLevel=pBiDi->paraLevel;
17.507 - }
17.508 - }
17.509 -
17.510 - /* set the object fields */
17.511 - pBiDi->runs=runs;
17.512 - pBiDi->runCount=runCount;
17.513 -
17.514 - reorderLine(pBiDi, minLevel, maxLevel);
17.515 -
17.516 - /* now add the direction flags and adjust the visualLimit's to be just that */
17.517 - ADD_ODD_BIT_FROM_LEVEL(runs[0].logicalStart, levels[runs[0].logicalStart]);
17.518 - limit=runs[0].visualLimit;
17.519 - for(i=1; i<runIndex; ++i) {
17.520 - ADD_ODD_BIT_FROM_LEVEL(runs[i].logicalStart, levels[runs[i].logicalStart]);
17.521 - limit=runs[i].visualLimit+=limit;
17.522 - }
17.523 -
17.524 - /* same for the trailing WS run */
17.525 - if(runIndex<runCount) {
17.526 - ADD_ODD_BIT_FROM_LEVEL(runs[i].logicalStart, pBiDi->paraLevel);
17.527 - runs[runIndex].visualLimit+=limit;
17.528 - }
17.529 - }
17.530 - }
17.531 - }
17.532 - return TRUE;
17.533 -}
17.534 -
17.535 -/* in trivial cases there is only one trivial run; called by ubidi_getRuns() */
17.536 -static void
17.537 -getSingleRun(UBiDi *pBiDi, UBiDiLevel level) {
17.538 - /* simple, single-run case */
17.539 - pBiDi->runs=pBiDi->simpleRuns;
17.540 - pBiDi->runCount=1;
17.541 -
17.542 - /* fill and reorder the single run */
17.543 - pBiDi->runs[0].logicalStart=MAKE_INDEX_ODD_PAIR(0, level);
17.544 - pBiDi->runs[0].visualLimit=pBiDi->length;
17.545 -}
17.546 -
17.547 -/* reorder the runs array (L2) ---------------------------------------------- */
17.548 -
17.549 -/*
17.550 - * Reorder the same-level runs in the runs array.
17.551 - * Here, runCount>1 and maxLevel>=minLevel>=paraLevel.
17.552 - * All the visualStart fields=logical start before reordering.
17.553 - * The "odd" bits are not set yet.
17.554 - *
17.555 - * Reordering with this data structure lends itself to some handy shortcuts:
17.556 - *
17.557 - * Since each run is moved but not modified, and since at the initial maxLevel
17.558 - * each sequence of same-level runs consists of only one run each, we
17.559 - * don't need to do anything there and can predecrement maxLevel.
17.560 - * In many simple cases, the reordering is thus done entirely in the
17.561 - * index mapping.
17.562 - * Also, reordering occurs only down to the lowest odd level that occurs,
17.563 - * which is minLevel|1. However, if the lowest level itself is odd, then
17.564 - * in the last reordering the sequence of the runs at this level or higher
17.565 - * will be all runs, and we don't need the elaborate loop to search for them.
17.566 - * This is covered by ++minLevel instead of minLevel|=1 followed
17.567 - * by an extra reorder-all after the reorder-some loop.
17.568 - * About a trailing WS run:
17.569 - * Such a run would need special treatment because its level is not
17.570 - * reflected in levels[] if this is not a paragraph object.
17.571 - * Instead, all characters from trailingWSStart on are implicitly at
17.572 - * paraLevel.
17.573 - * However, for all maxLevel>paraLevel, this run will never be reordered
17.574 - * and does not need to be taken into account. maxLevel==paraLevel is only reordered
17.575 - * if minLevel==paraLevel is odd, which is done in the extra segment.
17.576 - * This means that for the main reordering loop we don't need to consider
17.577 - * this run and can --runCount. If it is later part of the all-runs
17.578 - * reordering, then runCount is adjusted accordingly.
17.579 - */
17.580 -static void
17.581 -reorderLine(UBiDi *pBiDi, UBiDiLevel minLevel, UBiDiLevel maxLevel) {
17.582 - Run *runs;
17.583 - UBiDiLevel *levels;
17.584 - int32_t firstRun, endRun, limitRun, runCount,
17.585 - temp;
17.586 -
17.587 - /* nothing to do? */
17.588 - if(maxLevel<=(minLevel|1)) {
17.589 - return;
17.590 - }
17.591 -
17.592 - /*
17.593 - * Reorder only down to the lowest odd level
17.594 - * and reorder at an odd minLevel in a separate, simpler loop.
17.595 - * See comments above for why minLevel is always incremented.
17.596 - */
17.597 - ++minLevel;
17.598 -
17.599 - runs=pBiDi->runs;
17.600 - levels=pBiDi->levels;
17.601 - runCount=pBiDi->runCount;
17.602 -
17.603 - /* do not include the WS run at paraLevel<=old minLevel except in the simple loop */
17.604 - if(pBiDi->trailingWSStart<pBiDi->length) {
17.605 - --runCount;
17.606 - }
17.607 -
17.608 - while(--maxLevel>=minLevel) {
17.609 - firstRun=0;
17.610 -
17.611 - /* loop for all sequences of runs */
17.612 - for(;;) {
17.613 - /* look for a sequence of runs that are all at >=maxLevel */
17.614 - /* look for the first run of such a sequence */
17.615 - while(firstRun<runCount && levels[runs[firstRun].logicalStart]<maxLevel) {
17.616 - ++firstRun;
17.617 - }
17.618 - if(firstRun>=runCount) {
17.619 - break; /* no more such runs */
17.620 - }
17.621 -
17.622 - /* look for the limit run of such a sequence (the run behind it) */
17.623 - for(limitRun=firstRun; ++limitRun<runCount && levels[runs[limitRun].logicalStart]>=maxLevel;) {}
17.624 -
17.625 - /* Swap the entire sequence of runs from firstRun to limitRun-1. */
17.626 - endRun=limitRun-1;
17.627 - while(firstRun<endRun) {
17.628 - temp=runs[firstRun].logicalStart;
17.629 - runs[firstRun].logicalStart=runs[endRun].logicalStart;
17.630 - runs[endRun].logicalStart=temp;
17.631 -
17.632 - temp=runs[firstRun].visualLimit;
17.633 - runs[firstRun].visualLimit=runs[endRun].visualLimit;
17.634 - runs[endRun].visualLimit=temp;
17.635 -
17.636 - ++firstRun;
17.637 - --endRun;
17.638 - }
17.639 -
17.640 - if(limitRun==runCount) {
17.641 - break; /* no more such runs */
17.642 - } else {
17.643 - firstRun=limitRun+1;
17.644 - }
17.645 - }
17.646 - }
17.647 -
17.648 - /* now do maxLevel==old minLevel (==odd!), see above */
17.649 - if(!(minLevel&1)) {
17.650 - firstRun=0;
17.651 -
17.652 - /* include the trailing WS run in this complete reordering */
17.653 - if(pBiDi->trailingWSStart==pBiDi->length) {
17.654 - --runCount;
17.655 - }
17.656 -
17.657 - /* Swap the entire sequence of all runs. (endRun==runCount) */
17.658 - while(firstRun<runCount) {
17.659 - temp=runs[firstRun].logicalStart;
17.660 - runs[firstRun].logicalStart=runs[runCount].logicalStart;
17.661 - runs[runCount].logicalStart=temp;
17.662 -
17.663 - temp=runs[firstRun].visualLimit;
17.664 - runs[firstRun].visualLimit=runs[runCount].visualLimit;
17.665 - runs[runCount].visualLimit=temp;
17.666 -
17.667 - ++firstRun;
17.668 - --runCount;
17.669 - }
17.670 - }
17.671 -}
17.672 -
17.673 -/* reorder a line based on a levels array (L2) ------------------------------ */
17.674 -
17.675 -U_CAPI void U_EXPORT2
17.676 -ubidi_reorderLogical(const UBiDiLevel *levels, int32_t length, int32_t *indexMap) {
17.677 - int32_t start, limit, sumOfSosEos;
17.678 - UBiDiLevel minLevel, maxLevel;
17.679 -
17.680 - if(indexMap==NULL || !prepareReorder(levels, length, indexMap, &minLevel, &maxLevel)) {
17.681 - return;
17.682 - }
17.683 -
17.684 - /* nothing to do? */
17.685 - if(minLevel==maxLevel && (minLevel&1)==0) {
17.686 - return;
17.687 - }
17.688 -
17.689 - /* reorder only down to the lowest odd level */
17.690 - minLevel|=1;
17.691 -
17.692 - /* loop maxLevel..minLevel */
17.693 - do {
17.694 - start=0;
17.695 -
17.696 - /* loop for all sequences of levels to reorder at the current maxLevel */
17.697 - for(;;) {
17.698 - /* look for a sequence of levels that are all at >=maxLevel */
17.699 - /* look for the first index of such a sequence */
17.700 - while(start<length && levels[start]<maxLevel) {
17.701 - ++start;
17.702 - }
17.703 - if(start>=length) {
17.704 - break; /* no more such sequences */
17.705 - }
17.706 -
17.707 - /* look for the limit of such a sequence (the index behind it) */
17.708 - for(limit=start; ++limit<length && levels[limit]>=maxLevel;) {}
17.709 -
17.710 - /*
17.711 - * sos=start of sequence, eos=end of sequence
17.712 - *
17.713 - * The closed (inclusive) interval from sos to eos includes all the logical
17.714 - * and visual indexes within this sequence. They are logically and
17.715 - * visually contiguous and in the same range.
17.716 - *
17.717 - * For each run, the new visual index=sos+eos-old visual index;
17.718 - * we pre-add sos+eos into sumOfSosEos ->
17.719 - * new visual index=sumOfSosEos-old visual index;
17.720 - */
17.721 - sumOfSosEos=start+limit-1;
17.722 -
17.723 - /* reorder each index in the sequence */
17.724 - do {
17.725 - indexMap[start]=sumOfSosEos-indexMap[start];
17.726 - } while(++start<limit);
17.727 -
17.728 - /* start==limit */
17.729 - if(limit==length) {
17.730 - break; /* no more such sequences */
17.731 - } else {
17.732 - start=limit+1;
17.733 - }
17.734 - }
17.735 - } while(--maxLevel>=minLevel);
17.736 -}
17.737 -
17.738 -U_CAPI void U_EXPORT2
17.739 -ubidi_reorderVisual(const UBiDiLevel *levels, int32_t length, int32_t *indexMap) {
17.740 - int32_t start, end, limit, temp;
17.741 - UBiDiLevel minLevel, maxLevel;
17.742 -
17.743 - if(indexMap==NULL || !prepareReorder(levels, length, indexMap, &minLevel, &maxLevel)) {
17.744 - return;
17.745 - }
17.746 -
17.747 - /* nothing to do? */
17.748 - if(minLevel==maxLevel && (minLevel&1)==0) {
17.749 - return;
17.750 - }
17.751 -
17.752 - /* reorder only down to the lowest odd level */
17.753 - minLevel|=1;
17.754 -
17.755 - /* loop maxLevel..minLevel */
17.756 - do {
17.757 - start=0;
17.758 -
17.759 - /* loop for all sequences of levels to reorder at the current maxLevel */
17.760 - for(;;) {
17.761 - /* look for a sequence of levels that are all at >=maxLevel */
17.762 - /* look for the first index of such a sequence */
17.763 - while(start<length && levels[start]<maxLevel) {
17.764 - ++start;
17.765 - }
17.766 - if(start>=length) {
17.767 - break; /* no more such runs */
17.768 - }
17.769 -
17.770 - /* look for the limit of such a sequence (the index behind it) */
17.771 - for(limit=start; ++limit<length && levels[limit]>=maxLevel;) {}
17.772 -
17.773 - /*
17.774 - * Swap the entire interval of indexes from start to limit-1.
17.775 - * We don't need to swap the levels for the purpose of this
17.776 - * algorithm: the sequence of levels that we look at does not
17.777 - * move anyway.
17.778 - */
17.779 - end=limit-1;
17.780 - while(start<end) {
17.781 - temp=indexMap[start];
17.782 - indexMap[start]=indexMap[end];
17.783 - indexMap[end]=temp;
17.784 -
17.785 - ++start;
17.786 - --end;
17.787 - }
17.788 -
17.789 - if(limit==length) {
17.790 - break; /* no more such sequences */
17.791 - } else {
17.792 - start=limit+1;
17.793 - }
17.794 - }
17.795 - } while(--maxLevel>=minLevel);
17.796 -}
17.797 -
17.798 -static bool_t
17.799 -prepareReorder(const UBiDiLevel *levels, int32_t length,
17.800 - int32_t *indexMap,
17.801 - UBiDiLevel *pMinLevel, UBiDiLevel *pMaxLevel) {
17.802 - int32_t start;
17.803 - UBiDiLevel level, minLevel, maxLevel;
17.804 -
17.805 - if(levels==NULL || length<=0) {
17.806 - return FALSE;
17.807 - }
17.808 -
17.809 - /* determine minLevel and maxLevel */
17.810 - minLevel=UBIDI_MAX_EXPLICIT_LEVEL+1;
17.811 - maxLevel=0;
17.812 - for(start=length; start>0;) {
17.813 - level=levels[--start];
17.814 - if(level>UBIDI_MAX_EXPLICIT_LEVEL+1) {
17.815 - return FALSE;
17.816 - }
17.817 - if(level<minLevel) {
17.818 - minLevel=level;
17.819 - }
17.820 - if(level>maxLevel) {
17.821 - maxLevel=level;
17.822 - }
17.823 - }
17.824 - *pMinLevel=minLevel;
17.825 - *pMaxLevel=maxLevel;
17.826 -
17.827 - /* initialize the index map */
17.828 - for(start=length; start>0;) {
17.829 - --start;
17.830 - indexMap[start]=start;
17.831 - }
17.832 -
17.833 - return TRUE;
17.834 -}
17.835 -
17.836 -/* API functions for logical<->visual mapping ------------------------------- */
17.837 -
17.838 -U_CAPI int32_t U_EXPORT2
17.839 -ubidi_getVisualIndex(UBiDi *pBiDi, int32_t logicalIndex, UErrorCode *pErrorCode) {
17.840 - if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
17.841 - return 0;
17.842 - } else if(pBiDi==NULL) {
17.843 - *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
17.844 - return 0;
17.845 - } else if(logicalIndex<0 || pBiDi->length<=logicalIndex) {
17.846 - *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
17.847 - return 0;
17.848 - } else {
17.849 - /* we can do the trivial cases without the runs array */
17.850 - switch(pBiDi->direction) {
17.851 - case UBIDI_LTR:
17.852 - return logicalIndex;
17.853 - case UBIDI_RTL:
17.854 - return pBiDi->length-logicalIndex-1;
17.855 - default:
17.856 - if(pBiDi->runCount<0 && !ubidi_getRuns(pBiDi)) {
17.857 - *pErrorCode=U_MEMORY_ALLOCATION_ERROR;
17.858 - return 0;
17.859 - } else {
17.860 - Run *runs=pBiDi->runs;
17.861 - int32_t i, visualStart=0, offset, length;
17.862 -
17.863 - /* linear search for the run, search on the visual runs */
17.864 - for(i=0;; ++i) {
17.865 - length=runs[i].visualLimit-visualStart;
17.866 - offset=logicalIndex-GET_INDEX(runs[i].logicalStart);
17.867 - if(offset>=0 && offset<length) {
17.868 - if(IS_EVEN_RUN(runs[i].logicalStart)) {
17.869 - /* LTR */
17.870 - return visualStart+offset;
17.871 - } else {
17.872 - /* RTL */
17.873 - return visualStart+length-offset-1;
17.874 - }
17.875 - }
17.876 - visualStart+=length;
17.877 - }
17.878 - }
17.879 - }
17.880 - }
17.881 -}
17.882 -
17.883 -U_CAPI int32_t U_EXPORT2
17.884 -ubidi_getLogicalIndex(UBiDi *pBiDi, int32_t visualIndex, UErrorCode *pErrorCode) {
17.885 - if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
17.886 - return 0;
17.887 - } else if(pBiDi==NULL) {
17.888 - *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
17.889 - return 0;
17.890 - } else if(visualIndex<0 || pBiDi->length<=visualIndex) {
17.891 - *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
17.892 - return 0;
17.893 - } else {
17.894 - /* we can do the trivial cases without the runs array */
17.895 - switch(pBiDi->direction) {
17.896 - case UBIDI_LTR:
17.897 - return visualIndex;
17.898 - case UBIDI_RTL:
17.899 - return pBiDi->length-visualIndex-1;
17.900 - default:
17.901 - if(pBiDi->runCount<0 && !ubidi_getRuns(pBiDi)) {
17.902 - *pErrorCode=U_MEMORY_ALLOCATION_ERROR;
17.903 - return 0;
17.904 - } else {
17.905 - Run *runs=pBiDi->runs;
17.906 - int32_t i, runCount=pBiDi->runCount, start;
17.907 -
17.908 - if(runCount<=10) {
17.909 - /* linear search for the run */
17.910 - for(i=0; visualIndex>=runs[i].visualLimit; ++i) {}
17.911 - } else {
17.912 - /* binary search for the run */
17.913 - int32_t begin=0, limit=runCount;
17.914 -
17.915 - /* the middle if() will guaranteed find the run, we don't need a loop limit */
17.916 - for(;;) {
17.917 - i=(begin+limit)/2;
17.918 - if(visualIndex>=runs[i].visualLimit) {
17.919 - begin=i+1;
17.920 - } else if(i==0 || visualIndex>=runs[i-1].visualLimit) {
17.921 - break;
17.922 - } else {
17.923 - limit=i;
17.924 - }
17.925 - }
17.926 - }
17.927 -
17.928 - start=runs[i].logicalStart;
17.929 - if(IS_EVEN_RUN(start)) {
17.930 - /* LTR */
17.931 - /* the offset in runs[i] is visualIndex-runs[i-1].visualLimit */
17.932 - if(i>0) {
17.933 - visualIndex-=runs[i-1].visualLimit;
17.934 - }
17.935 - return GET_INDEX(start)+visualIndex;
17.936 - } else {
17.937 - /* RTL */
17.938 - return GET_INDEX(start)+runs[i].visualLimit-visualIndex-1;
17.939 - }
17.940 - }
17.941 - }
17.942 - }
17.943 -}
17.944 -
17.945 -U_CAPI void U_EXPORT2
17.946 -ubidi_getLogicalMap(UBiDi *pBiDi, int32_t *indexMap, UErrorCode *pErrorCode) {
17.947 - UBiDiLevel *levels;
17.948 -
17.949 - /* ubidi_getLevels() checks all of its and our arguments */
17.950 - if((levels=(UBiDiLevel *)ubidi_getLevels(pBiDi, pErrorCode))==NULL) {
17.951 - /* no op */
17.952 - } else if(indexMap==NULL) {
17.953 - *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
17.954 - } else {
17.955 - ubidi_reorderLogical(levels, pBiDi->length, indexMap);
17.956 - }
17.957 -}
17.958 -
17.959 -U_CAPI void U_EXPORT2
17.960 -ubidi_getVisualMap(UBiDi *pBiDi, int32_t *indexMap, UErrorCode *pErrorCode) {
17.961 - /* ubidi_countRuns() checks all of its and our arguments */
17.962 - if(ubidi_countRuns(pBiDi, pErrorCode)<=0) {
17.963 - /* no op */
17.964 - } else if(indexMap==NULL) {
17.965 - *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
17.966 - } else {
17.967 - /* fill a visual-to-logical index map using the runs[] */
17.968 - Run *runs=pBiDi->runs, *runsLimit=runs+pBiDi->runCount;
17.969 - int32_t logicalStart, visualStart, visualLimit;
17.970 -
17.971 - visualStart=0;
17.972 - for(; runs<runsLimit; ++runs) {
17.973 - logicalStart=runs->logicalStart;
17.974 - visualLimit=runs->visualLimit;
17.975 - if(IS_EVEN_RUN(logicalStart)) {
17.976 - do { /* LTR */
17.977 - *indexMap++ = logicalStart++;
17.978 - } while(++visualStart<visualLimit);
17.979 - } else {
17.980 - REMOVE_ODD_BIT(logicalStart);
17.981 - logicalStart+=visualLimit-visualStart; /* logicalLimit */
17.982 - do { /* RTL */
17.983 - *indexMap++ = --logicalStart;
17.984 - } while(++visualStart<visualLimit);
17.985 - }
17.986 - /* visualStart==visualLimit; */
17.987 - }
17.988 - }
17.989 -}
17.990 -
17.991 -U_CAPI void U_EXPORT2
17.992 -ubidi_invertMap(const int32_t *srcMap, int32_t *destMap, int32_t length) {
17.993 - if(srcMap!=NULL && destMap!=NULL) {
17.994 - srcMap+=length;
17.995 - while(length>0) {
17.996 - destMap[*--srcMap]=--length;
17.997 - }
17.998 - }
17.999 -}
18.1 --- a/src/share/native/sun/font/bidi/uchardir.c Sun Jun 21 23:52:58 2009 -0700
18.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
18.3 @@ -1,652 +0,0 @@
18.4 -/*
18.5 - * Portions Copyright 2000-2005 Sun Microsystems, Inc. All Rights Reserved.
18.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
18.7 - *
18.8 - * This code is free software; you can redistribute it and/or modify it
18.9 - * under the terms of the GNU General Public License version 2 only, as
18.10 - * published by the Free Software Foundation. Sun designates this
18.11 - * particular file as subject to the "Classpath" exception as provided
18.12 - * by Sun in the LICENSE file that accompanied this code.
18.13 - *
18.14 - * This code is distributed in the hope that it will be useful, but WITHOUT
18.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18.16 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18.17 - * version 2 for more details (a copy is included in the LICENSE file that
18.18 - * accompanied this code).
18.19 - *
18.20 - * You should have received a copy of the GNU General Public License version
18.21 - * 2 along with this work; if not, write to the Free Software Foundation,
18.22 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18.23 - *
18.24 - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
18.25 - * CA 95054 USA or visit www.sun.com if you need additional information or
18.26 - * have any questions.
18.27 - */
18.28 -
18.29 -/*
18.30 - * (C) Copyright IBM Corp. 1999-2003 - All Rights Reserved
18.31 - *
18.32 - * The original version of this source code and documentation is
18.33 - * copyrighted and owned by IBM. These materials are provided
18.34 - * under terms of a License Agreement between IBM and Sun.
18.35 - * This technology is protected by multiple US and International
18.36 - * patents. This notice and attribution to IBM may not be removed.
18.37 - */
18.38 -
18.39 -/*
18.40 -*
18.41 -* File UCHAR.CPP
18.42 -*
18.43 -* Modification History:
18.44 -*
18.45 -* Date Name Description
18.46 -* 11/30/1999 dfelt Creation. Extract from uchar.c, reduce to data
18.47 -* query only.
18.48 -********************************************************************************
18.49 -*/
18.50 -
18.51 -#include "uchardir.h"
18.52 -
18.53 -/* new 4.0 surrogate data */
18.54 -static uint32_t ASCII_START = 0x0;
18.55 -static uint32_t ASCII_LIMIT = 0x80;
18.56 -static uint8_t ASCII[] = {
18.57 - (uint8_t)0x12, (uint8_t)0x12, (uint8_t)0x12, (uint8_t)0x12, (uint8_t)0x12, (uint8_t)0x12, (uint8_t)0x12, (uint8_t)0x12,
18.58 - (uint8_t)0x12, (uint8_t)0x08, (uint8_t)0x07, (uint8_t)0x08, (uint8_t)0x09, (uint8_t)0x07, (uint8_t)0x12, (uint8_t)0x12,
18.59 - (uint8_t)0x12, (uint8_t)0x12, (uint8_t)0x12, (uint8_t)0x12, (uint8_t)0x12, (uint8_t)0x12, (uint8_t)0x12, (uint8_t)0x12,
18.60 - (uint8_t)0x12, (uint8_t)0x12, (uint8_t)0x12, (uint8_t)0x12, (uint8_t)0x07, (uint8_t)0x07, (uint8_t)0x07, (uint8_t)0x08,
18.61 - (uint8_t)0x09, (uint8_t)0x0a, (uint8_t)0x0a, (uint8_t)0x04, (uint8_t)0x04, (uint8_t)0x04, (uint8_t)0x0a, (uint8_t)0x0a,
18.62 - (uint8_t)0x0a, (uint8_t)0x0a, (uint8_t)0x0a, (uint8_t)0x04, (uint8_t)0x06, (uint8_t)0x04, (uint8_t)0x06, (uint8_t)0x03,
18.63 - (uint8_t)0x02, (uint8_t)0x02, (uint8_t)0x02, (uint8_t)0x02, (uint8_t)0x02, (uint8_t)0x02, (uint8_t)0x02, (uint8_t)0x02,
18.64 - (uint8_t)0x02, (uint8_t)0x02, (uint8_t)0x06, (uint8_t)0x0a, (uint8_t)0x0a, (uint8_t)0x0a, (uint8_t)0x0a, (uint8_t)0x0a,
18.65 - (uint8_t)0x0a, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00,
18.66 - (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00,
18.67 - (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00,
18.68 - (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x0a, (uint8_t)0x0a, (uint8_t)0x0a, (uint8_t)0x0a, (uint8_t)0x0a,
18.69 - (uint8_t)0x0a, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00,
18.70 - (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00,
18.71 - (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00,
18.72 - (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x0a, (uint8_t)0x0a, (uint8_t)0x0a, (uint8_t)0x0a, (uint8_t)0x12,
18.73 -};
18.74 -static uint32_t RTL_START = 0x591;
18.75 -static uint32_t RTL_LIMIT = 0x671;
18.76 -static uint8_t RTL[] = {
18.77 - (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11,
18.78 - (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11,
18.79 - (uint8_t)0x11, (uint8_t)0x01, (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11,
18.80 - (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11,
18.81 - (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11,
18.82 - (uint8_t)0x11, (uint8_t)0x01, (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x01, (uint8_t)0x11, (uint8_t)0x01,
18.83 - (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x01, (uint8_t)0x11, (uint8_t)0x01, (uint8_t)0x01, (uint8_t)0x01, (uint8_t)0x01,
18.84 - (uint8_t)0x01, (uint8_t)0x01, (uint8_t)0x01, (uint8_t)0x01, (uint8_t)0x01, (uint8_t)0x01, (uint8_t)0x01, (uint8_t)0x01,
18.85 - (uint8_t)0x01, (uint8_t)0x01, (uint8_t)0x01, (uint8_t)0x01, (uint8_t)0x01, (uint8_t)0x01, (uint8_t)0x01, (uint8_t)0x01,
18.86 - (uint8_t)0x01, (uint8_t)0x01, (uint8_t)0x01, (uint8_t)0x01, (uint8_t)0x01, (uint8_t)0x01, (uint8_t)0x01, (uint8_t)0x01,
18.87 - (uint8_t)0x01, (uint8_t)0x01, (uint8_t)0x01, (uint8_t)0x01, (uint8_t)0x01, (uint8_t)0x01, (uint8_t)0x01, (uint8_t)0x01,
18.88 - (uint8_t)0x01, (uint8_t)0x01, (uint8_t)0x01, (uint8_t)0x01, (uint8_t)0x01, (uint8_t)0x01, (uint8_t)0x01, (uint8_t)0x01,
18.89 - (uint8_t)0x01, (uint8_t)0x01, (uint8_t)0x01, (uint8_t)0x01, (uint8_t)0x01, (uint8_t)0x01, (uint8_t)0x01, (uint8_t)0x01,
18.90 - (uint8_t)0x01, (uint8_t)0x01, (uint8_t)0x01, (uint8_t)0x01, (uint8_t)0x01, (uint8_t)0x01, (uint8_t)0x01, (uint8_t)0x0d,
18.91 - (uint8_t)0x0d, (uint8_t)0x0d, (uint8_t)0x0d, (uint8_t)0x0d, (uint8_t)0x0d, (uint8_t)0x0d, (uint8_t)0x0d, (uint8_t)0x0d,
18.92 - (uint8_t)0x0d, (uint8_t)0x0d, (uint8_t)0x0d, (uint8_t)0x06, (uint8_t)0x0d, (uint8_t)0x0a, (uint8_t)0x0a, (uint8_t)0x11,
18.93 - (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x0d, (uint8_t)0x0d, (uint8_t)0x0d,
18.94 - (uint8_t)0x0d, (uint8_t)0x0d, (uint8_t)0x0d, (uint8_t)0x0d, (uint8_t)0x0d, (uint8_t)0x0d, (uint8_t)0x0d, (uint8_t)0x0d,
18.95 - (uint8_t)0x0d, (uint8_t)0x0d, (uint8_t)0x0d, (uint8_t)0x0d, (uint8_t)0x0d, (uint8_t)0x0d, (uint8_t)0x0d, (uint8_t)0x0d,
18.96 - (uint8_t)0x0d, (uint8_t)0x0d, (uint8_t)0x0d, (uint8_t)0x0d, (uint8_t)0x0d, (uint8_t)0x0d, (uint8_t)0x0d, (uint8_t)0x0d,
18.97 - (uint8_t)0x0d, (uint8_t)0x0d, (uint8_t)0x0d, (uint8_t)0x0d, (uint8_t)0x0d, (uint8_t)0x0d, (uint8_t)0x0d, (uint8_t)0x0d,
18.98 - (uint8_t)0x0d, (uint8_t)0x0d, (uint8_t)0x0d, (uint8_t)0x0d, (uint8_t)0x0d, (uint8_t)0x0d, (uint8_t)0x0d, (uint8_t)0x0d,
18.99 - (uint8_t)0x0d, (uint8_t)0x0d, (uint8_t)0x0d, (uint8_t)0x0d, (uint8_t)0x0d, (uint8_t)0x0d, (uint8_t)0x0d, (uint8_t)0x0d,
18.100 - (uint8_t)0x0d, (uint8_t)0x0d, (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11,
18.101 - (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11,
18.102 - (uint8_t)0x0d, (uint8_t)0x0d, (uint8_t)0x0d, (uint8_t)0x0d, (uint8_t)0x0d, (uint8_t)0x0d, (uint8_t)0x0d, (uint8_t)0x05,
18.103 - (uint8_t)0x05, (uint8_t)0x05, (uint8_t)0x05, (uint8_t)0x05, (uint8_t)0x05, (uint8_t)0x05, (uint8_t)0x05, (uint8_t)0x05,
18.104 - (uint8_t)0x05, (uint8_t)0x04, (uint8_t)0x05, (uint8_t)0x05, (uint8_t)0x0d, (uint8_t)0x0d, (uint8_t)0x0d, (uint8_t)0x11,
18.105 -};
18.106 -static uint8_t t0[] = {
18.107 - (uint8_t)0x99, (uint8_t)0x99, (uint8_t)0x99, (uint8_t)0x99, (uint8_t)0x9b, (uint8_t)0xab, (uint8_t)0xca, (uint8_t)0x99,
18.108 - (uint8_t)0x99, (uint8_t)0x99, (uint8_t)0x99, (uint8_t)0x99, (uint8_t)0x99, (uint8_t)0x99, (uint8_t)0xaa, (uint8_t)0xab,
18.109 - (uint8_t)0xcd, (uint8_t)0xd5, (uint8_t)0x55, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xd5, (uint8_t)0x75, (uint8_t)0x74,
18.110 - (uint8_t)0x33, (uint8_t)0x33, (uint8_t)0x33, (uint8_t)0x33, (uint8_t)0x33, (uint8_t)0x7d, (uint8_t)0xdd, (uint8_t)0xdd,
18.111 - (uint8_t)0xd0, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00,
18.112 - (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x0d, (uint8_t)0xdd, (uint8_t)0xdd,
18.113 - (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x0d, (uint8_t)0xdd, (uint8_t)0xd9,
18.114 - (uint8_t)0x99, (uint8_t)0x99, (uint8_t)0x9a, (uint8_t)0x99, (uint8_t)0x99, (uint8_t)0x99, (uint8_t)0x99, (uint8_t)0x99,
18.115 - (uint8_t)0x99, (uint8_t)0x99, (uint8_t)0x99, (uint8_t)0x99, (uint8_t)0x99, (uint8_t)0x99, (uint8_t)0x99, (uint8_t)0x99,
18.116 - (uint8_t)0x7d, (uint8_t)0x55, (uint8_t)0x55, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0x0d, (uint8_t)0xdd, (uint8_t)0xdd,
18.117 - (uint8_t)0x55, (uint8_t)0x33, (uint8_t)0xd0, (uint8_t)0xdd, (uint8_t)0xd3, (uint8_t)0x0d, (uint8_t)0xdd, (uint8_t)0xdd,
18.118 - (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00,
18.119 - (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x0d, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00,
18.120 - (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x0d, (uint8_t)0xd0, (uint8_t)0x00, (uint8_t)0x00,
18.121 - (uint8_t)0x00, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd,
18.122 - (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x0d, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0x0d,
18.123 - (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd,
18.124 - (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x88,
18.125 - (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x08, (uint8_t)0x88,
18.126 - (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0xdd, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0xd0,
18.127 - (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0xdd, (uint8_t)0x0d, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00,
18.128 - (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0xd0, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00,
18.129 - (uint8_t)0x00, (uint8_t)0x08, (uint8_t)0x88, (uint8_t)0x80, (uint8_t)0x88, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00,
18.130 - (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0xd0, (uint8_t)0x00, (uint8_t)0x00,
18.131 - (uint8_t)0x18, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x88,
18.132 - (uint8_t)0x88, (uint8_t)0x18, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x88,
18.133 - (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x18, (uint8_t)0x88, (uint8_t)0x18,
18.134 - (uint8_t)0x18, (uint8_t)0x81, (uint8_t)0x81, (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11,
18.135 - (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11,
18.136 - (uint8_t)0x22, (uint8_t)0x22, (uint8_t)0x22, (uint8_t)0x22, (uint8_t)0x22, (uint8_t)0x22, (uint8_t)0x72, (uint8_t)0xdd,
18.137 - (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x22, (uint8_t)0x22, (uint8_t)0x22, (uint8_t)0x22, (uint8_t)0x22,
18.138 - (uint8_t)0x22, (uint8_t)0x22, (uint8_t)0x22, (uint8_t)0x22, (uint8_t)0x22, (uint8_t)0x22, (uint8_t)0x22, (uint8_t)0x22,
18.139 - (uint8_t)0x22, (uint8_t)0x22, (uint8_t)0x22, (uint8_t)0x22, (uint8_t)0x22, (uint8_t)0x28, (uint8_t)0x88, (uint8_t)0x88,
18.140 - (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x82, (uint8_t)0x22, (uint8_t)0x22, (uint8_t)0x22,
18.141 - (uint8_t)0x66, (uint8_t)0x66, (uint8_t)0x66, (uint8_t)0x66, (uint8_t)0x66, (uint8_t)0x56, (uint8_t)0x62, (uint8_t)0x22,
18.142 - (uint8_t)0x82, (uint8_t)0x22, (uint8_t)0x22, (uint8_t)0x22, (uint8_t)0x22, (uint8_t)0x22, (uint8_t)0x22, (uint8_t)0x22,
18.143 - (uint8_t)0x22, (uint8_t)0x22, (uint8_t)0x22, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x82, (uint8_t)0x88,
18.144 - (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x82, (uint8_t)0x28, (uint8_t)0x8d, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x22,
18.145 - (uint8_t)0x33, (uint8_t)0x33, (uint8_t)0x33, (uint8_t)0x33, (uint8_t)0x33, (uint8_t)0x22, (uint8_t)0x22, (uint8_t)0x22,
18.146 - (uint8_t)0x22, (uint8_t)0x22, (uint8_t)0x22, (uint8_t)0x22, (uint8_t)0x22, (uint8_t)0x22, (uint8_t)0x22, (uint8_t)0x29,
18.147 - (uint8_t)0x28, (uint8_t)0x22, (uint8_t)0x22, (uint8_t)0x22, (uint8_t)0x22, (uint8_t)0x22, (uint8_t)0x22, (uint8_t)0x22,
18.148 - (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x82, (uint8_t)0x22, (uint8_t)0x22,
18.149 - (uint8_t)0x22, (uint8_t)0x22, (uint8_t)0x22, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x88,
18.150 - (uint8_t)0x08, (uint8_t)0x80, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00,
18.151 - (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x80, (uint8_t)0x00,
18.152 - (uint8_t)0x08, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x80, (uint8_t)0x00, (uint8_t)0x08, (uint8_t)0x00,
18.153 - (uint8_t)0x08, (uint8_t)0x88, (uint8_t)0x80, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00,
18.154 - (uint8_t)0x00, (uint8_t)0x88, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00,
18.155 - (uint8_t)0x08, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00,
18.156 - (uint8_t)0x08, (uint8_t)0x88, (uint8_t)0x80, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x08, (uint8_t)0x00,
18.157 - (uint8_t)0x00, (uint8_t)0x55, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00,
18.158 - (uint8_t)0x08, (uint8_t)0x80, (uint8_t)0x00, (uint8_t)0x08, (uint8_t)0x80, (uint8_t)0x08, (uint8_t)0x88, (uint8_t)0x00,
18.159 - (uint8_t)0x88, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00,
18.160 - (uint8_t)0x08, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x08, (uint8_t)0x80, (uint8_t)0x00, (uint8_t)0x08, (uint8_t)0x00,
18.161 - (uint8_t)0x05, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00,
18.162 - (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x80, (uint8_t)0x08,
18.163 - (uint8_t)0x08, (uint8_t)0x88, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x08, (uint8_t)0x00,
18.164 - (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x80, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00,
18.165 - (uint8_t)0x00, (uint8_t)0x80, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00,
18.166 - (uint8_t)0x80, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x08, (uint8_t)0x00,
18.167 - (uint8_t)0x00, (uint8_t)0x0d, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xd5, (uint8_t)0xd0, (uint8_t)0x00, (uint8_t)0x00,
18.168 - (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x88,
18.169 - (uint8_t)0x80, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x88, (uint8_t)0x80, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x00,
18.170 - (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x08, (uint8_t)0x80, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00,
18.171 - (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x88, (uint8_t)0x00,
18.172 - (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x80, (uint8_t)0x00, (uint8_t)0x00,
18.173 - (uint8_t)0x00, (uint8_t)0x88, (uint8_t)0x80, (uint8_t)0x80, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00,
18.174 - (uint8_t)0x08, (uint8_t)0x00, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x80, (uint8_t)0x00, (uint8_t)0x05,
18.175 - (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x08, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x80,
18.176 - (uint8_t)0x08, (uint8_t)0x00, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x08, (uint8_t)0x80, (uint8_t)0x00,
18.177 - (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x00,
18.178 - (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x88, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00,
18.179 - (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x08, (uint8_t)0x08, (uint8_t)0x08, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0x00,
18.180 - (uint8_t)0x08, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x80,
18.181 - (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x80, (uint8_t)0x88, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00,
18.182 - (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x08, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x88,
18.183 - (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x80, (uint8_t)0x00,
18.184 - (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x08, (uint8_t)0x88,
18.185 - (uint8_t)0x80, (uint8_t)0x80, (uint8_t)0x00, (uint8_t)0x88, (uint8_t)0x08, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00,
18.186 - (uint8_t)0xc0, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00,
18.187 - (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x0d, (uint8_t)0xd0, (uint8_t)0x00,
18.188 - (uint8_t)0x00, (uint8_t)0x88, (uint8_t)0x80, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00,
18.189 - (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x08, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x00,
18.190 - (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x80, (uint8_t)0x08, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x88,
18.191 - (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x05, (uint8_t)0x08, (uint8_t)0x00,
18.192 - (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00,
18.193 - (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xd8, (uint8_t)0x88, (uint8_t)0xc0,
18.194 - (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x08, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00,
18.195 - (uint8_t)0x88, (uint8_t)0x80, (uint8_t)0x00, (uint8_t)0x08, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x00, (uint8_t)0x00,
18.196 - (uint8_t)0x00, (uint8_t)0x80, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x08, (uint8_t)0x88, (uint8_t)0x00, (uint8_t)0x00,
18.197 - (uint8_t)0xd0, (uint8_t)0x00, (uint8_t)0xdd, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00,
18.198 - (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x0d, (uint8_t)0x0d,
18.199 - (uint8_t)0xdd, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x0d, (uint8_t)0xdd,
18.200 - (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x0d, (uint8_t)0xdd,
18.201 - (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x0d, (uint8_t)0xd0,
18.202 - (uint8_t)0xcc, (uint8_t)0xcc, (uint8_t)0xcc, (uint8_t)0xcc, (uint8_t)0xcc, (uint8_t)0xc9, (uint8_t)0x99, (uint8_t)0x01,
18.203 - (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xca, (uint8_t)0xee, (uint8_t)0xee, (uint8_t)0xec,
18.204 - (uint8_t)0x55, (uint8_t)0x55, (uint8_t)0x5d, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd,
18.205 - (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xd0, (uint8_t)0x0d, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x0c,
18.206 - (uint8_t)0x99, (uint8_t)0x99, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x99, (uint8_t)0x99, (uint8_t)0x99,
18.207 - (uint8_t)0x30, (uint8_t)0x00, (uint8_t)0x33, (uint8_t)0x33, (uint8_t)0x33, (uint8_t)0x55, (uint8_t)0xdd, (uint8_t)0xd0,
18.208 - (uint8_t)0x33, (uint8_t)0x33, (uint8_t)0x33, (uint8_t)0x33, (uint8_t)0x33, (uint8_t)0x55, (uint8_t)0xdd, (uint8_t)0xd0,
18.209 - (uint8_t)0x55, (uint8_t)0x55, (uint8_t)0x55, (uint8_t)0x55, (uint8_t)0x55, (uint8_t)0x55, (uint8_t)0x55, (uint8_t)0x55,
18.210 - (uint8_t)0x55, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00,
18.211 - (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x80, (uint8_t)0x00, (uint8_t)0x00,
18.212 - (uint8_t)0xdd, (uint8_t)0x0d, (uint8_t)0xdd, (uint8_t)0xd0, (uint8_t)0xdd, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00,
18.213 - (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0xd0, (uint8_t)0xdd, (uint8_t)0xd0, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0xdd,
18.214 - (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0x0d, (uint8_t)0x0d, (uint8_t)0x0d, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x50,
18.215 - (uint8_t)0x00, (uint8_t)0xd0, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0xdd, (uint8_t)0x00, (uint8_t)0x00,
18.216 - (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xd0, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0xdd, (uint8_t)0x00, (uint8_t)0x00,
18.217 - (uint8_t)0x00, (uint8_t)0x0d, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd,
18.218 - (uint8_t)0xdd, (uint8_t)0x55, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd,
18.219 - (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00,
18.220 - (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xd0, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd,
18.221 - (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xd0, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00,
18.222 - (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xd0, (uint8_t)0x00, (uint8_t)0x00,
18.223 - (uint8_t)0x33, (uint8_t)0x33, (uint8_t)0x33, (uint8_t)0x33, (uint8_t)0x33, (uint8_t)0x33, (uint8_t)0x33, (uint8_t)0x33,
18.224 - (uint8_t)0x33, (uint8_t)0x33, (uint8_t)0x33, (uint8_t)0x33, (uint8_t)0x33, (uint8_t)0x33, (uint8_t)0x00, (uint8_t)0x00,
18.225 - (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x3d, (uint8_t)0xdd, (uint8_t)0xdd,
18.226 - (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0x0d, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd,
18.227 - (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0x00,
18.228 - (uint8_t)0xdd, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00,
18.229 - (uint8_t)0x0d, (uint8_t)0xdd, (uint8_t)0xd0, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0x00, (uint8_t)0xdd, (uint8_t)0xdd,
18.230 - (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0x0d, (uint8_t)0x0d,
18.231 - (uint8_t)0xdd, (uint8_t)0xd0, (uint8_t)0x00, (uint8_t)0xd0, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xd0,
18.232 - (uint8_t)0x0d, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd,
18.233 - (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xd0, (uint8_t)0x00, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd,
18.234 - (uint8_t)0x0d, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xd0,
18.235 - (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0x00, (uint8_t)0x00,
18.236 - (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0x0d, (uint8_t)0xdd, (uint8_t)0xdd,
18.237 - (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00,
18.238 - (uint8_t)0xcd, (uint8_t)0xdd, (uint8_t)0xd0, (uint8_t)0x00, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd,
18.239 - (uint8_t)0xd0, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x88,
18.240 - (uint8_t)0xd0, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0xdd, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x0d, (uint8_t)0xdd,
18.241 - (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x08, (uint8_t)0x8d, (uint8_t)0xd0, (uint8_t)0x00,
18.242 - (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x0d, (uint8_t)0x00, (uint8_t)0x00,
18.243 - (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0xdd, (uint8_t)0x00,
18.244 - (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0xdd, (uint8_t)0xdd,
18.245 - (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x0d, (uint8_t)0xdd, (uint8_t)0xd0, (uint8_t)0x00, (uint8_t)0x00,
18.246 - (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0xdd,
18.247 - (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x0d,
18.248 - (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x01, (uint8_t)0x81,
18.249 - (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x15, (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11,
18.250 - (uint8_t)0x22, (uint8_t)0x22, (uint8_t)0x22, (uint8_t)0x22, (uint8_t)0x22, (uint8_t)0x22, (uint8_t)0x22, (uint8_t)0xdd,
18.251 - (uint8_t)0x22, (uint8_t)0x22, (uint8_t)0x22, (uint8_t)0x22, (uint8_t)0x22, (uint8_t)0x22, (uint8_t)0x2d, (uint8_t)0x22,
18.252 - (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00,
18.253 - (uint8_t)0x7d, (uint8_t)0x70, (uint8_t)0xd7, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xd5,
18.254 - (uint8_t)0xdd, (uint8_t)0x55, (uint8_t)0xdd, (uint8_t)0xd0, (uint8_t)0xd5, (uint8_t)0x5d, (uint8_t)0x00, (uint8_t)0x00,
18.255 - (uint8_t)0x0d, (uint8_t)0xd5, (uint8_t)0x55, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xd5, (uint8_t)0x75, (uint8_t)0x74,
18.256 - (uint8_t)0x55, (uint8_t)0xdd, (uint8_t)0xd5, (uint8_t)0x50, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xdd, (uint8_t)0xd0,
18.257 - (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x09, (uint8_t)0x99, (uint8_t)0xdd, (uint8_t)0x00,
18.258 - (uint8_t)0x0d, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00,
18.259 - (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x08, (uint8_t)0x88, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00,
18.260 - (uint8_t)0x00, (uint8_t)0x09, (uint8_t)0x99, (uint8_t)0x99, (uint8_t)0x99, (uint8_t)0x98, (uint8_t)0x88, (uint8_t)0x88,
18.261 - (uint8_t)0x88, (uint8_t)0x80, (uint8_t)0x08, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x00, (uint8_t)0x00,
18.262 - (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x88, (uint8_t)0x88, (uint8_t)0x00,
18.263 - (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x33,
18.264 - (uint8_t)0x09, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00, (uint8_t)0x00,
18.265 -};
18.266 -
18.267 -static uint8_t t1[] = {
18.268 - (uint8_t)0x00, (uint8_t)0x01, (uint8_t)0x02, (uint8_t)0x03, (uint8_t)0x04, (uint8_t)0x05, (uint8_t)0x04, (uint8_t)0x06,
18.269 - (uint8_t)0x07, (uint8_t)0x08, (uint8_t)0x09, (uint8_t)0x0a, (uint8_t)0x0b, (uint8_t)0x0c, (uint8_t)0x0b, (uint8_t)0x0c,
18.270 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.271 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.272 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.273 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0d, (uint8_t)0x0e, (uint8_t)0x0e, (uint8_t)0x0f, (uint8_t)0x10,
18.274 - (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x12, (uint8_t)0x11, (uint8_t)0x13,
18.275 - (uint8_t)0x14, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x15,
18.276 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.277 - (uint8_t)0x16, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.278 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.279 - (uint8_t)0x17, (uint8_t)0x18, (uint8_t)0x19, (uint8_t)0x1a, (uint8_t)0x1b, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c,
18.280 - (uint8_t)0x1d, (uint8_t)0x1e, (uint8_t)0x1f, (uint8_t)0x1f, (uint8_t)0x20, (uint8_t)0x21, (uint8_t)0x22, (uint8_t)0x23,
18.281 - (uint8_t)0x1f, (uint8_t)0x1f, (uint8_t)0x1f, (uint8_t)0x1f, (uint8_t)0x1f, (uint8_t)0x24, (uint8_t)0x25, (uint8_t)0x26,
18.282 - (uint8_t)0x27, (uint8_t)0x28, (uint8_t)0x1f, (uint8_t)0x11, (uint8_t)0x29, (uint8_t)0x1f, (uint8_t)0x1f, (uint8_t)0x1f,
18.283 - (uint8_t)0x1f, (uint8_t)0x1f, (uint8_t)0x2a, (uint8_t)0x23, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c,
18.284 - (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c,
18.285 - (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c,
18.286 - (uint8_t)0x2b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x2c, (uint8_t)0x2d, (uint8_t)0x2e, (uint8_t)0x2f, (uint8_t)0x0b,
18.287 - (uint8_t)0x30, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x2c, (uint8_t)0x31, (uint8_t)0x0b, (uint8_t)0x2f, (uint8_t)0x32,
18.288 - (uint8_t)0x2b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x2c, (uint8_t)0x33, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x34,
18.289 - (uint8_t)0x2b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x2c, (uint8_t)0x35, (uint8_t)0x0b, (uint8_t)0x2f, (uint8_t)0x36,
18.290 - (uint8_t)0x30, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x37, (uint8_t)0x38, (uint8_t)0x39, (uint8_t)0x0b, (uint8_t)0x0b,
18.291 - (uint8_t)0x3a, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x3b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x3c,
18.292 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x3d, (uint8_t)0x3e, (uint8_t)0x3f, (uint8_t)0x0b, (uint8_t)0x0b,
18.293 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x2c, (uint8_t)0x40, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.294 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x38, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.295 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x41, (uint8_t)0x42, (uint8_t)0x0b, (uint8_t)0x0b,
18.296 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x43, (uint8_t)0x44, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.297 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x45, (uint8_t)0x46, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.298 - (uint8_t)0x0b, (uint8_t)0x47, (uint8_t)0x0b, (uint8_t)0x48, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x49,
18.299 - (uint8_t)0x4a, (uint8_t)0x4b, (uint8_t)0x11, (uint8_t)0x4c, (uint8_t)0x39, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.300 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x4d, (uint8_t)0x4e, (uint8_t)0x0b, (uint8_t)0x47, (uint8_t)0x0b, (uint8_t)0x0b,
18.301 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.302 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.303 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.304 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.305 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.306 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.307 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.308 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.309 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.310 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.311 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.312 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.313 - (uint8_t)0x4f, (uint8_t)0x50, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.314 - (uint8_t)0x0b, (uint8_t)0x51, (uint8_t)0x0b, (uint8_t)0x51, (uint8_t)0x0b, (uint8_t)0x2f, (uint8_t)0x0b, (uint8_t)0x2f,
18.315 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x52, (uint8_t)0x53, (uint8_t)0x54, (uint8_t)0x0b, (uint8_t)0x55,
18.316 - (uint8_t)0x56, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.317 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x57, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.318 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x58, (uint8_t)0x59, (uint8_t)0x5a, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.319 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x10, (uint8_t)0x10,
18.320 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.321 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.322 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.323 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.324 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.325 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.326 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.327 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.328 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.329 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.330 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.331 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x5b, (uint8_t)0x5c, (uint8_t)0x5d, (uint8_t)0x5d, (uint8_t)0x5e,
18.332 - (uint8_t)0x5f, (uint8_t)0x10, (uint8_t)0x60, (uint8_t)0x61, (uint8_t)0x10, (uint8_t)0x62, (uint8_t)0x63, (uint8_t)0x64,
18.333 - (uint8_t)0x65, (uint8_t)0x0b, (uint8_t)0x66, (uint8_t)0x67, (uint8_t)0x0b, (uint8_t)0x11, (uint8_t)0x68, (uint8_t)0x0b,
18.334 - (uint8_t)0x69, (uint8_t)0x6a, (uint8_t)0x6b, (uint8_t)0x6c, (uint8_t)0x6d, (uint8_t)0x6e, (uint8_t)0x0b, (uint8_t)0x0b,
18.335 - (uint8_t)0x0b, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10,
18.336 - (uint8_t)0x10, (uint8_t)0x6f, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10,
18.337 - (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10,
18.338 - (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x70, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x05,
18.339 - (uint8_t)0x10, (uint8_t)0x71, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x04, (uint8_t)0x0b, (uint8_t)0x0b,
18.340 - (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x72, (uint8_t)0x0b, (uint8_t)0x73, (uint8_t)0x0b, (uint8_t)0x74, (uint8_t)0x74,
18.341 - (uint8_t)0x74, (uint8_t)0x75, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x76, (uint8_t)0x10,
18.342 - (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10,
18.343 - (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10,
18.344 - (uint8_t)0x10, (uint8_t)0x77, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x78,
18.345 - (uint8_t)0x10, (uint8_t)0x79, (uint8_t)0x79, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.346 - (uint8_t)0x7a, (uint8_t)0x10, (uint8_t)0x77, (uint8_t)0x10, (uint8_t)0x7b, (uint8_t)0x7c, (uint8_t)0x7d, (uint8_t)0x10,
18.347 - (uint8_t)0x10, (uint8_t)0x7e, (uint8_t)0x10, (uint8_t)0x7f, (uint8_t)0x0b, (uint8_t)0x10, (uint8_t)0x80, (uint8_t)0x10,
18.348 - (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10,
18.349 - (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10,
18.350 - (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10,
18.351 - (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10,
18.352 - (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10,
18.353 - (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10,
18.354 - (uint8_t)0x78, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.355 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.356 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.357 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.358 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.359 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.360 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.361 - (uint8_t)0x10, (uint8_t)0x81, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x82,
18.362 - (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10,
18.363 - (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x70, (uint8_t)0x0b, (uint8_t)0x80,
18.364 - (uint8_t)0x83, (uint8_t)0x10, (uint8_t)0x84, (uint8_t)0x85, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.365 - (uint8_t)0x0b, (uint8_t)0x86, (uint8_t)0x04, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x87,
18.366 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.367 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.368 - (uint8_t)0x0b, (uint8_t)0x5e, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x10, (uint8_t)0x0b, (uint8_t)0x88,
18.369 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x7d, (uint8_t)0x89, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.370 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x8a,
18.371 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x8b, (uint8_t)0x0b, (uint8_t)0x8c,
18.372 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.373 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.374 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.375 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.376 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.377 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.378 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.379 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.380 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.381 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.382 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.383 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.384 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.385 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.386 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.387 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.388 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.389 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.390 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.391 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.392 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.393 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.394 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.395 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.396 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.397 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.398 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.399 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.400 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.401 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.402 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.403 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.404 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.405 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.406 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.407 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10,
18.408 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.409 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.410 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.411 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.412 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.413 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.414 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.415 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.416 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.417 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.418 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.419 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.420 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.421 - (uint8_t)0x0b, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x72, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.422 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.423 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.424 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.425 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.426 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.427 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.428 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.429 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.430 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.431 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.432 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.433 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.434 - (uint8_t)0x0b, (uint8_t)0x8d, (uint8_t)0x8e, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1f, (uint8_t)0x1f, (uint8_t)0x1f,
18.435 - (uint8_t)0x1f, (uint8_t)0x1f, (uint8_t)0x1f, (uint8_t)0x1f, (uint8_t)0x1f, (uint8_t)0x1f, (uint8_t)0x1f, (uint8_t)0x1f,
18.436 - (uint8_t)0x1f, (uint8_t)0x1f, (uint8_t)0x1f, (uint8_t)0x1f, (uint8_t)0x1f, (uint8_t)0x1f, (uint8_t)0x1f, (uint8_t)0x1f,
18.437 - (uint8_t)0x1f, (uint8_t)0x1f, (uint8_t)0x1f, (uint8_t)0x1f, (uint8_t)0x1f, (uint8_t)0x1f, (uint8_t)0x1f, (uint8_t)0x1f,
18.438 - (uint8_t)0x1f, (uint8_t)0x1f, (uint8_t)0x1f, (uint8_t)0x8f, (uint8_t)0x1f, (uint8_t)0x1f, (uint8_t)0x1f, (uint8_t)0x1f,
18.439 - (uint8_t)0x1f, (uint8_t)0x1f, (uint8_t)0x1f, (uint8_t)0x1f, (uint8_t)0x1f, (uint8_t)0x1f, (uint8_t)0x1f, (uint8_t)0x90,
18.440 - (uint8_t)0x11, (uint8_t)0x0b, (uint8_t)0x91, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x92, (uint8_t)0x93, (uint8_t)0x1f,
18.441 - (uint8_t)0x1f, (uint8_t)0x1f, (uint8_t)0x1f, (uint8_t)0x1f, (uint8_t)0x1f, (uint8_t)0x1f, (uint8_t)0x1f, (uint8_t)0x27,
18.442 - (uint8_t)0x94, (uint8_t)0x03, (uint8_t)0x04, (uint8_t)0x05, (uint8_t)0x04, (uint8_t)0x05, (uint8_t)0x70, (uint8_t)0x0b,
18.443 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x95, (uint8_t)0x96,
18.444 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.445 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.446 - (uint8_t)0x97, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.447 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.448 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.449 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.450 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.451 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.452 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.453 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.454 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.455 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.456 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.457 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.458 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.459 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.460 - (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c,
18.461 - (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c,
18.462 - (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c,
18.463 - (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c,
18.464 - (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c,
18.465 - (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c,
18.466 - (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c,
18.467 - (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c,
18.468 - (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c,
18.469 - (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c,
18.470 - (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c,
18.471 - (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c,
18.472 - (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c,
18.473 - (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c,
18.474 - (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c,
18.475 - (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c, (uint8_t)0x1c,
18.476 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.477 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.478 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x98, (uint8_t)0x99,
18.479 - (uint8_t)0x9a, (uint8_t)0x0b, (uint8_t)0x9b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.480 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.481 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.482 - (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x10, (uint8_t)0x72, (uint8_t)0x0b, (uint8_t)0x0b,
18.483 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.484 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.485 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.486 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.487 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.488 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.489 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.490 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.491 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x9c, (uint8_t)0x74, (uint8_t)0x74, (uint8_t)0x74,
18.492 - (uint8_t)0x9d, (uint8_t)0x0b, (uint8_t)0x08, (uint8_t)0x08, (uint8_t)0x08, (uint8_t)0x08, (uint8_t)0x08, (uint8_t)0x08,
18.493 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.494 - (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11,
18.495 - (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x0b,
18.496 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.497 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.498 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.499 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.500 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.501 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.502 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.503 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.504 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.505 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.506 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.507 - (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b, (uint8_t)0x0b,
18.508 -};
18.509 -
18.510 -static uint8_t ix[] = {
18.511 - (uint8_t)0x01, (uint8_t)0x23, (uint8_t)0x45, (uint8_t)0x67, (uint8_t)0x78, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77,
18.512 - (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x97, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x7a,
18.513 - (uint8_t)0xbc, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77,
18.514 - (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0xd7, (uint8_t)0x77, (uint8_t)0x77,
18.515 - (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77,
18.516 - (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77,
18.517 - (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77,
18.518 - (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77,
18.519 - (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77,
18.520 - (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77,
18.521 - (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77,
18.522 - (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77,
18.523 - (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77,
18.524 - (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77,
18.525 - (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77,
18.526 - (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77,
18.527 - (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77,
18.528 - (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77,
18.529 - (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77,
18.530 - (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77,
18.531 - (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77,
18.532 - (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77,
18.533 - (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77,
18.534 - (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77,
18.535 - (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77,
18.536 - (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77,
18.537 - (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77,
18.538 - (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77,
18.539 - (uint8_t)0xe7, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77,
18.540 - (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77,
18.541 - (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77,
18.542 - (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77,
18.543 - (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77,
18.544 - (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77,
18.545 - (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77,
18.546 - (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77,
18.547 - (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77,
18.548 - (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77,
18.549 - (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77,
18.550 - (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77,
18.551 - (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77,
18.552 - (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77,
18.553 - (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77,
18.554 - (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77,
18.555 - (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77,
18.556 - (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77,
18.557 - (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77,
18.558 - (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77,
18.559 - (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77,
18.560 - (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77,
18.561 - (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77,
18.562 - (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77,
18.563 - (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77,
18.564 - (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77,
18.565 - (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77,
18.566 - (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77,
18.567 - (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77,
18.568 - (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77,
18.569 - (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77,
18.570 - (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77,
18.571 - (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77,
18.572 - (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77,
18.573 - (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77,
18.574 - (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77, (uint8_t)0x77,
18.575 -};
18.576 -
18.577 -#define LOWBITS 4
18.578 -#define MEDBITS 7
18.579 -#define HIGHBITS (21 - MEDBITS - LOWBITS)
18.580 -
18.581 -#define HIGHSHIFT (LOWBITS + MEDBITS)
18.582 -
18.583 -#define BLOCKSIZE (1 << LOWBITS)
18.584 -#define IBLOCKSIZE (1 << MEDBITS)
18.585 -#define ISIZE (1 << HIGHBITS)
18.586 -
18.587 -#define BLOCKMASK (BLOCKSIZE - 1)
18.588 -#define IBLOCKMASK (IBLOCKSIZE - 1)
18.589 -#define IMASK (ISIZE - 1)
18.590 -
18.591 -static uint8_t jx2i[] = {
18.592 - 0, 1, 13, 2, 3, 4, 5, 6, 17, 18, 7, 8, 9, 10
18.593 -};
18.594 -
18.595 -static uint8_t x2i[] = {
18.596 - /* LRE RLE PDF LRO RLO */
18.597 - 11, 14, 16, 12, 15
18.598 -};
18.599 -
18.600 -static UCharDirection u_getDirectionInternal(uint32_t cp) {
18.601 - int dc;
18.602 - int n;
18.603 - int bi = cp & BLOCKMASK;
18.604 - int ibi = (cp >> LOWBITS) & IBLOCKMASK;
18.605 - int i = (cp >> HIGHSHIFT) & IMASK;
18.606 -
18.607 - n = ix[i >> 1];
18.608 - if ((i & 1) == 0) {
18.609 - n >>= 4;
18.610 - }
18.611 - n &= 0x0f;
18.612 - n = t1[n * IBLOCKSIZE + ibi];
18.613 - n = n * BLOCKSIZE + bi;
18.614 - dc = t0[n >> 1];
18.615 - if ((n & 1) == 0) {
18.616 - dc >>= 4;
18.617 - }
18.618 - dc &= 0x0f;
18.619 - if (dc > 13) {
18.620 - dc = x2i[cp - 0x202a];
18.621 - } else {
18.622 - dc = jx2i[dc];
18.623 - }
18.624 - return dc;
18.625 -}
18.626 -
18.627 -UCharDirection u_getDirection(uint32_t cp) {
18.628 - if (cp < ASCII_LIMIT) {
18.629 - return ASCII[cp];
18.630 - }
18.631 - if (cp < RTL_START) {
18.632 - return u_getDirectionInternal(cp);
18.633 - }
18.634 - if (cp < RTL_LIMIT) {
18.635 - return RTL[cp - RTL_START];
18.636 - }
18.637 - if (cp < 0x110000) {
18.638 - return u_getDirectionInternal(cp);
18.639 - }
18.640 - return 0;
18.641 -}
18.642 -
18.643 -UCharDirection
18.644 -u_charDirection(UChar ch) {
18.645 - return u_getDirection(ch);
18.646 -}
18.647 -
18.648 -#define LEAD_SURROGATE_SHIFT 10
18.649 -#define SURROGATE_OFFSET (0x010000 - (0xd800 << 10) - 0xdc00)
18.650 -
18.651 -UCharDirection
18.652 -u_surrogatePairDirection(UChar lead, UChar trail) {
18.653 - uint32_t cp = ((uint32_t)lead << LEAD_SURROGATE_SHIFT) + trail + SURROGATE_OFFSET;
18.654 - return u_getDirection(cp);
18.655 -}
19.1 --- a/src/share/native/sun/font/bidi/uchardir.h Sun Jun 21 23:52:58 2009 -0700
19.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
19.3 @@ -1,100 +0,0 @@
19.4 -/*
19.5 - * Portions Copyright 2000-2003 Sun Microsystems, Inc. All Rights Reserved.
19.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
19.7 - *
19.8 - * This code is free software; you can redistribute it and/or modify it
19.9 - * under the terms of the GNU General Public License version 2 only, as
19.10 - * published by the Free Software Foundation. Sun designates this
19.11 - * particular file as subject to the "Classpath" exception as provided
19.12 - * by Sun in the LICENSE file that accompanied this code.
19.13 - *
19.14 - * This code is distributed in the hope that it will be useful, but WITHOUT
19.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19.16 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19.17 - * version 2 for more details (a copy is included in the LICENSE file that
19.18 - * accompanied this code).
19.19 - *
19.20 - * You should have received a copy of the GNU General Public License version
19.21 - * 2 along with this work; if not, write to the Free Software Foundation,
19.22 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19.23 - *
19.24 - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
19.25 - * CA 95054 USA or visit www.sun.com if you need additional information or
19.26 - * have any questions.
19.27 - */
19.28 -
19.29 -/*
19.30 - * (C) Copyright IBM Corp. 1999-2003 - All Rights Reserved
19.31 - *
19.32 - * The original version of this source code and documentation is
19.33 - * copyrighted and owned by IBM. These materials are provided
19.34 - * under terms of a License Agreement between IBM and Sun.
19.35 - * This technology is protected by multiple US and International
19.36 - * patents. This notice and attribution to IBM may not be removed.
19.37 - */
19.38 -
19.39 -/*
19.40 -*
19.41 -* File UCHARDIR.H
19.42 -*
19.43 -* Modification History:
19.44 -*
19.45 -* Date Name Description
19.46 -* 11/30/1999 dfelt Creation. Copied UCharDirection from uchar.h
19.47 -********************************************************************************
19.48 -*/
19.49 -
19.50 -#ifndef UCHARDIR_H
19.51 -#define UCHARDIR_H
19.52 -
19.53 -#include "utypes.h"
19.54 -
19.55 -/*===========================================================================*/
19.56 -/* Unicode version number */
19.57 -/*===========================================================================*/
19.58 -#define UNICODE_VERSION "3.0.0.beta"
19.59 -
19.60 -enum UCharDirection {
19.61 - U_LEFT_TO_RIGHT = 0,
19.62 - U_RIGHT_TO_LEFT = 1,
19.63 - U_EUROPEAN_NUMBER = 2,
19.64 - U_EUROPEAN_NUMBER_SEPARATOR = 3,
19.65 - U_EUROPEAN_NUMBER_TERMINATOR = 4,
19.66 - U_ARABIC_NUMBER = 5,
19.67 - U_COMMON_NUMBER_SEPARATOR = 6,
19.68 - U_BLOCK_SEPARATOR = 7,
19.69 - U_SEGMENT_SEPARATOR = 8,
19.70 - U_WHITE_SPACE_NEUTRAL = 9,
19.71 - U_OTHER_NEUTRAL = 10,
19.72 - U_LEFT_TO_RIGHT_EMBEDDING = 11,
19.73 - U_LEFT_TO_RIGHT_OVERRIDE = 12,
19.74 - U_RIGHT_TO_LEFT_ARABIC = 13,
19.75 - U_RIGHT_TO_LEFT_EMBEDDING = 14,
19.76 - U_RIGHT_TO_LEFT_OVERRIDE = 15,
19.77 - U_POP_DIRECTIONAL_FORMAT = 16,
19.78 - U_DIR_NON_SPACING_MARK = 17,
19.79 - U_BOUNDARY_NEUTRAL = 18,
19.80 - U_CHAR_DIRECTION_COUNT
19.81 -};
19.82 -
19.83 -typedef enum UCharDirection UCharDirection;
19.84 -
19.85 -/**
19.86 - * Returns the linguistic direction property of a character.
19.87 - * <P>
19.88 - * Returns the linguistic direction property of a character.
19.89 - * For example, 0x0041 (letter A) has the LEFT_TO_RIGHT directional
19.90 - * property.
19.91 - * @see UCharDirection
19.92 - */
19.93 -U_CAPI UCharDirection U_EXPORT2
19.94 -u_charDirection(UChar c);
19.95 -
19.96 -U_CAPI UCharDirection U_EXPORT2
19.97 -u_getDirection(uint32_t cp);
19.98 -
19.99 -U_CAPI UCharDirection U_EXPORT2
19.100 -u_surrogatePairDirection(UChar lead, UChar trail);
19.101 -
19.102 -#endif /*_UCHAR*/
19.103 -/*eof*/
20.1 --- a/src/share/native/sun/font/bidi/utypes.h Sun Jun 21 23:52:58 2009 -0700
20.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
20.3 @@ -1,177 +0,0 @@
20.4 -/*
20.5 - * Portions Copyright 2000-2003 Sun Microsystems, Inc. All Rights Reserved.
20.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
20.7 - *
20.8 - * This code is free software; you can redistribute it and/or modify it
20.9 - * under the terms of the GNU General Public License version 2 only, as
20.10 - * published by the Free Software Foundation. Sun designates this
20.11 - * particular file as subject to the "Classpath" exception as provided
20.12 - * by Sun in the LICENSE file that accompanied this code.
20.13 - *
20.14 - * This code is distributed in the hope that it will be useful, but WITHOUT
20.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20.16 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20.17 - * version 2 for more details (a copy is included in the LICENSE file that
20.18 - * accompanied this code).
20.19 - *
20.20 - * You should have received a copy of the GNU General Public License version
20.21 - * 2 along with this work; if not, write to the Free Software Foundation,
20.22 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20.23 - *
20.24 - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20.25 - * CA 95054 USA or visit www.sun.com if you need additional information or
20.26 - * have any questions.
20.27 - */
20.28 -
20.29 -/*
20.30 - * (C) Copyright Taligent, Inc., 1996, 1997 *
20.31 - * (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
20.32 - *
20.33 - * The original version of this source code and documentation is
20.34 - * copyrighted and owned by IBM. These materials are provided
20.35 - * under terms of a License Agreement between IBM and Sun.
20.36 - * This technology is protected by multiple US and International
20.37 - * patents. This notice and attribution to IBM may not be removed.
20.38 - */
20.39 -
20.40 -/*
20.41 -*
20.42 -* FILE NAME : UTYPES.H (formerly ptypes.h)
20.43 -*
20.44 -* Date Name Description
20.45 -* 12/11/96 helena Creation.
20.46 -* 02/27/97 aliu Added typedefs for UClassID, int8, int16, int32,
20.47 -* uint8, uint16, and uint32.
20.48 -* 04/01/97 aliu Added XP_CPLUSPLUS and modified to work under C as
20.49 -* well as C++.
20.50 -* Modified to use memcpy() for icu_arrayCopy() fns.
20.51 -* 04/14/97 aliu Added TPlatformUtilities.
20.52 -* 05/07/97 aliu Added import/export specifiers (replacing the old
20.53 -* broken EXT_CLASS). Added version number for our
20.54 -* code. Cleaned up header.
20.55 -* 6/20/97 helena Java class name change.
20.56 -* 08/11/98 stephen UErrorCode changed from typedef to enum
20.57 -* 08/12/98 erm Changed T_ANALYTIC_PACKAGE_VERSION to 3
20.58 -* 08/14/98 stephen Added icu_arrayCopy() for int8_t, int16_t, int32_t
20.59 -* 12/09/98 jfitz Added BUFFER_OVERFLOW_ERROR (bug 1100066)
20.60 -* 04/20/99 stephen Cleaned up & reworked for autoconf.
20.61 -* Renamed to utypes.h.
20.62 -* 05/05/99 stephen Changed to use <inttypes.h>
20.63 -* 10/12/00 dfelt Adapted to use javavm types (plus juint from j2d)
20.64 -*******************************************************************************
20.65 -*/
20.66 -
20.67 -#ifndef UTYPES_H
20.68 -#define UTYPES_H
20.69 -
20.70 -// doesn't seem to be a way of getting around this
20.71 -
20.72 -//#if defined(WIN32) || defined(_WIN32)
20.73 -// not needed since we don't export to another dll
20.74 -
20.75 -#if 0
20.76 -
20.77 -#define U_EXPORT __declspec(dllexport)
20.78 -#define U_EXPORT2
20.79 -#define U_IMPORT __declspec(dllimport)
20.80 -
20.81 -#else
20.82 -
20.83 -#define U_EXPORT
20.84 -#define U_EXPORT2
20.85 -#define U_IMPORT
20.86 -
20.87 -#endif
20.88 -
20.89 -#ifdef XP_CPLUSPLUS
20.90 -# define U_CFUNC extern "C"
20.91 -# define U_CDECL_BEGIN extern "C" {
20.92 -# define U_CDECL_END }
20.93 -#else
20.94 -# define U_CFUNC
20.95 -# define U_CDECL_BEGIN
20.96 -# define U_CDECL_END
20.97 -#endif
20.98 -#define U_CAPI U_CFUNC U_EXPORT
20.99 -
20.100 -// defines jboolean, jchar, jshort, and jint via jni_md.h
20.101 -#include "jni.h"
20.102 -// defines jubyte, jushort, juint
20.103 -#include "j2d_md.h"
20.104 -
20.105 -typedef jboolean bool_t;
20.106 -
20.107 -/*
20.108 - * win32 does not have standard definitions for the following:
20.109 - */
20.110 -#ifdef WIN32
20.111 -
20.112 -#ifndef __int8_t_defined
20.113 -typedef jbyte int8_t;
20.114 -typedef jshort int16_t;
20.115 -typedef jint int32_t;
20.116 -#endif
20.117 -
20.118 -typedef jubyte uint8_t;
20.119 -typedef jushort uint16_t;
20.120 -typedef juint uint32_t;
20.121 -
20.122 -#endif /* WIN32 */
20.123 -
20.124 -/*===========================================================================*/
20.125 -/* Unicode character */
20.126 -/*===========================================================================*/
20.127 -typedef uint16_t UChar;
20.128 -
20.129 -
20.130 -/** Error code to replace exception handling */
20.131 -enum UErrorCode {
20.132 - U_ERROR_INFO_START = -128, /* Start of information results (semantically successful) */
20.133 - U_USING_FALLBACK_ERROR = -128,
20.134 - U_USING_DEFAULT_ERROR = -127,
20.135 - U_ERROR_INFO_LIMIT,
20.136 -
20.137 - U_ZERO_ERROR = 0, /* success */
20.138 -
20.139 - U_ILLEGAL_ARGUMENT_ERROR = 1, /* Start of codes indicating failure */
20.140 - U_MISSING_RESOURCE_ERROR = 2,
20.141 - U_INVALID_FORMAT_ERROR = 3,
20.142 - U_FILE_ACCESS_ERROR = 4,
20.143 - U_INTERNAL_PROGRAM_ERROR = 5, /* Indicates a bug in the library code */
20.144 - U_MESSAGE_PARSE_ERROR = 6,
20.145 - U_MEMORY_ALLOCATION_ERROR = 7, /* Memory allocation error */
20.146 - U_INDEX_OUTOFBOUNDS_ERROR = 8,
20.147 - U_PARSE_ERROR = 9, /* Equivalent to Java ParseException */
20.148 - U_INVALID_CHAR_FOUND = 10, /* In the Character conversion routines: Invalid character or sequence was encountered*/
20.149 - U_TRUNCATED_CHAR_FOUND = 11, /* In the Character conversion routines: More bytes are required to complete the conversion successfully*/
20.150 - U_ILLEGAL_CHAR_FOUND = 12, /* In codeset conversion: a sequence that does NOT belong in the codepage has been encountered*/
20.151 - U_INVALID_TABLE_FORMAT = 13, /* Conversion table file found, but corrupted*/
20.152 - U_INVALID_TABLE_FILE = 14, /* Conversion table file not found*/
20.153 - U_BUFFER_OVERFLOW_ERROR = 15, /* A result would not fit in the supplied buffer */
20.154 - U_UNSUPPORTED_ERROR = 16, /* Requested operation not supported in current context */
20.155 - U_ERROR_LIMIT
20.156 -};
20.157 -
20.158 -#ifndef XP_CPLUSPLUS
20.159 -typedef enum UErrorCode UErrorCode;
20.160 -#endif
20.161 -
20.162 -/* Use the following to determine if an UErrorCode represents */
20.163 -/* operational success or failure. */
20.164 -#ifdef XP_CPLUSPLUS
20.165 -inline bool_t U_SUCCESS(UErrorCode code) { return (bool_t)(code<=U_ZERO_ERROR); }
20.166 -inline bool_t U_FAILURE(UErrorCode code) { return (bool_t)(code>U_ZERO_ERROR); }
20.167 -#else
20.168 -#define U_SUCCESS(x) ((x)<=U_ZERO_ERROR)
20.169 -#define U_FAILURE(x) ((x)>U_ZERO_ERROR)
20.170 -#endif
20.171 -
20.172 -#ifndef TRUE
20.173 -# define TRUE 1
20.174 -#endif
20.175 -#ifndef FALSE
20.176 -# define FALSE 0
20.177 -#endif
20.178 -
20.179 -// UTYPES_H
20.180 -#endif
21.1 --- a/src/share/native/sun/font/layout/LETypes.h Sun Jun 21 23:52:58 2009 -0700
21.2 +++ b/src/share/native/sun/font/layout/LETypes.h Tue Jun 23 23:09:49 2009 -0700
21.3 @@ -36,7 +36,8 @@
21.4 #define LE_USE_CMEMORY
21.5
21.6 #ifdef LE_USE_CMEMORY
21.7 -#include "cmemory.h"
21.8 +#include <stdlib.h>
21.9 +#include <string.h>
21.10 #endif
21.11
21.12 #ifndef _LP64
22.1 --- a/src/solaris/native/sun/awt/awt_GraphicsEnv.c Sun Jun 21 23:52:58 2009 -0700
22.2 +++ b/src/solaris/native/sun/awt/awt_GraphicsEnv.c Tue Jun 23 23:09:49 2009 -0700
22.3 @@ -337,7 +337,7 @@
22.4 char errmsg[128];
22.5 int xinawareScreen;
22.6 void* xrenderLibHandle = NULL;
22.7 - XRenderFindVisualFormatFunc *XRenderFindVisualFormat = NULL;
22.8 + XRenderFindVisualFormatFunc* xrenderFindVisualFormat = NULL;
22.9 int major_opcode, first_event, first_error;
22.10
22.11 if (usingXinerama) {
22.12 @@ -435,7 +435,7 @@
22.13 #endif
22.14
22.15 if (xrenderLibHandle != NULL) {
22.16 - XRenderFindVisualFormat =
22.17 + xrenderFindVisualFormat =
22.18 (XRenderFindVisualFormatFunc*)dlsym(xrenderLibHandle,
22.19 "XRenderFindVisualFormat");
22.20 }
22.21 @@ -454,8 +454,8 @@
22.22 graphicsConfigs [ind]->awt_depth = pVITrue [i].depth;
22.23 memcpy (&graphicsConfigs [ind]->awt_visInfo, &pVITrue [i],
22.24 sizeof (XVisualInfo));
22.25 - if (XRenderFindVisualFormat != NULL) {
22.26 - XRenderPictFormat *format = XRenderFindVisualFormat (awt_display,
22.27 + if (xrenderFindVisualFormat != NULL) {
22.28 + XRenderPictFormat *format = xrenderFindVisualFormat (awt_display,
22.29 pVITrue [i].visual);
22.30 if (format &&
22.31 format->type == PictTypeDirect &&
23.1 --- a/src/solaris/native/sun/awt/awt_p.h Sun Jun 21 23:52:58 2009 -0700
23.2 +++ b/src/solaris/native/sun/awt/awt_p.h Tue Jun 23 23:09:49 2009 -0700
23.3 @@ -48,6 +48,7 @@
23.4 #include <X11/Xatom.h>
23.5 #include <X11/keysym.h>
23.6 #include <X11/keysymdef.h>
23.7 +#include <X11/extensions/Xrender.h>
23.8 #ifndef XAWT
23.9 #include <Xm/CascadeB.h>
23.10 #include <Xm/DrawingA.h>
23.11 @@ -120,48 +121,8 @@
23.12
23.13 #ifndef HEADLESS
23.14
23.15 -/* Note: until we include the <X11/extensions/Xrender.h> explicitly
23.16 - * we have to define a couple of things ourselves.
23.17 - */
23.18 -typedef unsigned long PictFormat;
23.19 -#define PictTypeIndexed 0
23.20 -#define PictTypeDirect 1
23.21 -
23.22 -typedef struct {
23.23 - short red;
23.24 - short redMask;
23.25 - short green;
23.26 - short greenMask;
23.27 - short blue;
23.28 - short blueMask;
23.29 - short alpha;
23.30 - short alphaMask;
23.31 -} XRenderDirectFormat;
23.32 -
23.33 -typedef struct {
23.34 - PictFormat id;
23.35 - int type;
23.36 - int depth;
23.37 - XRenderDirectFormat direct;
23.38 - Colormap colormap;
23.39 -} XRenderPictFormat;
23.40 -
23.41 -#define PictFormatID (1 << 0)
23.42 -#define PictFormatType (1 << 1)
23.43 -#define PictFormatDepth (1 << 2)
23.44 -#define PictFormatRed (1 << 3)
23.45 -#define PictFormatRedMask (1 << 4)
23.46 -#define PictFormatGreen (1 << 5)
23.47 -#define PictFormatGreenMask (1 << 6)
23.48 -#define PictFormatBlue (1 << 7)
23.49 -#define PictFormatBlueMask (1 << 8)
23.50 -#define PictFormatAlpha (1 << 9)
23.51 -#define PictFormatAlphaMask (1 << 10)
23.52 -#define PictFormatColormap (1 << 11)
23.53 -
23.54 typedef XRenderPictFormat *
23.55 XRenderFindVisualFormatFunc (Display *dpy, _Xconst Visual *visual);
23.56 -/* END OF Xrender.h chunk */
23.57
23.58 typedef struct _AwtGraphicsConfigData {
23.59 int awt_depth;
24.1 --- a/src/windows/native/sun/windows/awt_Component.cpp Sun Jun 21 23:52:58 2009 -0700
24.2 +++ b/src/windows/native/sun/windows/awt_Component.cpp Tue Jun 23 23:09:49 2009 -0700
24.3 @@ -1254,6 +1254,8 @@
24.4 WIN_MSG(WM_AWT_CREATECONTEXT)
24.5 WIN_MSG(WM_AWT_DESTROYCONTEXT)
24.6 WIN_MSG(WM_AWT_ASSOCIATECONTEXT)
24.7 + WIN_MSG(WM_AWT_GET_DEFAULT_IME_HANDLER)
24.8 + WIN_MSG(WM_AWT_HANDLE_NATIVE_IME_EVENT)
24.9 WIN_MSG(WM_AWT_PRE_KEYDOWN)
24.10 WIN_MSG(WM_AWT_PRE_KEYUP)
24.11 WIN_MSG(WM_AWT_PRE_SYSKEYDOWN)
24.12 @@ -3334,7 +3336,13 @@
24.13 // reset
24.14 resetKbdState( kbdState );
24.15 }else {
24.16 - printf ("++++Whats that? wkey 0x%x (%d)\n", i,i);
24.17 + // k > 1: this key does generate multiple characters. Ignore it.
24.18 + // An example: Arabic Lam and Alef ligature.
24.19 + // There will be no extended keycode and thus shortcuts for this key.
24.20 + // XXX shouldn't we reset the kbd state?
24.21 +#ifdef DEBUG
24.22 + DTRACE_PRINTLN2("wkey 0x%02X (%d)", i,i);
24.23 +#endif
24.24 }
24.25 kbdState[i] = 0; // "key unpressed"
24.26 }
25.1 --- a/src/windows/native/sun/windows/awt_InputMethod.cpp Sun Jun 21 23:52:58 2009 -0700
25.2 +++ b/src/windows/native/sun/windows/awt_InputMethod.cpp Tue Jun 23 23:09:49 2009 -0700
25.3 @@ -91,16 +91,19 @@
25.4 {
25.5 TRY;
25.6
25.7 - //get C++ Class of Focused Component
25.8 - if (peer == 0) return;
25.9 - AwtComponent* p = (AwtComponent*)JNI_GET_PDATA(peer);
25.10 - if (p == 0) return;
25.11 + jobject selfGlobalRef = env->NewGlobalRef(self);
25.12 + jobject peerGlobalRef = env->NewGlobalRef(peer);
25.13
25.14 - p->SetInputMethod(self, useNativeCompWindow);
25.15 + EnableNativeIMEStruct *enis = new EnableNativeIMEStruct;
25.16
25.17 - // use special message to call ImmAssociateContext() in main thread.
25.18 + enis->self = selfGlobalRef;
25.19 + enis->peer = peerGlobalRef;
25.20 + enis->context = context;
25.21 + enis->useNativeCompWindow = useNativeCompWindow;
25.22 +
25.23 AwtToolkit::GetInstance().SendMessage(WM_AWT_ASSOCIATECONTEXT,
25.24 - reinterpret_cast<WPARAM>(p->GetHWnd()), context);
25.25 + reinterpret_cast<WPARAM>(enis), (LPARAM)0);
25.26 + // global refs are deleted in message handler
25.27
25.28 CATCH_BAD_ALLOC;
25.29 }
25.30 @@ -116,16 +119,18 @@
25.31 {
25.32 TRY_NO_VERIFY;
25.33
25.34 - //get C++ Class of Focused Component
25.35 - if (peer == 0) return;
25.36 - AwtComponent* p = (AwtComponent*)JNI_GET_PDATA(peer);
25.37 - if (p == 0) return;
25.38 + jobject peerGlobalRef = env->NewGlobalRef(peer);
25.39 + // self reference is not used
25.40
25.41 - p->SetInputMethod(NULL, TRUE);
25.42 + EnableNativeIMEStruct *enis = new EnableNativeIMEStruct;
25.43 + enis->self = NULL;
25.44 + enis->peer = peerGlobalRef;
25.45 + enis->context = NULL;
25.46 + enis->useNativeCompWindow = JNI_TRUE;
25.47
25.48 - // use special message to call ImmAssociateContext() in main thread.
25.49 AwtToolkit::GetInstance().SendMessage(WM_AWT_ASSOCIATECONTEXT,
25.50 - reinterpret_cast<WPARAM>(p->GetHWnd()), NULL);
25.51 + reinterpret_cast<WPARAM>(enis), (LPARAM)0);
25.52 + // global refs are deleted in message handler
25.53
25.54 CATCH_BAD_ALLOC;
25.55 }
25.56 @@ -167,23 +172,14 @@
25.57 if (id >= java_awt_event_InputMethodEvent_INPUT_METHOD_FIRST &&
25.58 id <= java_awt_event_InputMethodEvent_INPUT_METHOD_LAST)
25.59 {
25.60 - long modifiers = p->GetJavaModifiers();
25.61 - if (msg.message==WM_CHAR || msg.message==WM_SYSCHAR) {
25.62 - WCHAR unicodeChar = L'\0';
25.63 - unicodeChar = (WCHAR)msg.wParam;
25.64 - p->SendKeyEvent(java_awt_event_KeyEvent_KEY_TYPED,
25.65 - 0, //to be fixed nowMillis(),
25.66 - java_awt_event_KeyEvent_CHAR_UNDEFINED,
25.67 - unicodeChar,
25.68 - modifiers,
25.69 - java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN, (jlong)0,
25.70 - &msg);
25.71 - } else {
25.72 - MSG* pCopiedMsg = new MSG;
25.73 - *pCopiedMsg = msg;
25.74 - p->SendMessage(WM_AWT_HANDLE_EVENT, (WPARAM) FALSE,
25.75 - (LPARAM) pCopiedMsg);
25.76 - }
25.77 + jobject peerGlobalRef = env->NewGlobalRef(peer);
25.78 +
25.79 + // use special message to access pData on the toolkit thread
25.80 + AwtToolkit::GetInstance().SendMessage(WM_AWT_HANDLE_NATIVE_IME_EVENT,
25.81 + reinterpret_cast<WPARAM>(peerGlobalRef),
25.82 + reinterpret_cast<LPARAM>(&msg));
25.83 + // global ref is deleted in message handler
25.84 +
25.85 (env)->SetBooleanField(event, AwtAWTEvent::consumedID, JNI_TRUE);
25.86 }
25.87
25.88 @@ -373,22 +369,27 @@
25.89 Windows system creates a default input method window for the
25.90 toolkit thread.
25.91 */
25.92 - HWND hwndIME = AwtToolkit::GetInstance().GetInputMethodWindow();
25.93 - if (hwndIME == NULL) {
25.94 - if (peer == NULL) {
25.95 - return;
25.96 +
25.97 + HWND defaultIMEHandler = AwtToolkit::GetInstance().GetInputMethodWindow();
25.98 +
25.99 + if (defaultIMEHandler == NULL)
25.100 + {
25.101 + jobject peerGlobalRef = env->NewGlobalRef(peer);
25.102 +
25.103 + // use special message to access pData on the toolkit thread
25.104 + LRESULT res = AwtToolkit::GetInstance().SendMessage(WM_AWT_GET_DEFAULT_IME_HANDLER,
25.105 + reinterpret_cast<WPARAM>(peerGlobalRef), 0);
25.106 + // global ref is deleted in message handler
25.107 +
25.108 + if (res == TRUE) {
25.109 + defaultIMEHandler = AwtToolkit::GetInstance().GetInputMethodWindow();
25.110 }
25.111 -
25.112 - AwtComponent* p = (AwtComponent*)JNI_GET_PDATA(peer);
25.113 - if (p == NULL || (hwndIME = ImmGetDefaultIMEWnd(p->GetHWnd())) == NULL) {
25.114 - return;
25.115 - }
25.116 -
25.117 - AwtToolkit::GetInstance().SetInputMethodWindow(hwndIME);
25.118 }
25.119
25.120 - ::SendMessage(hwndIME, WM_IME_CONTROL,
25.121 - visible ? IMC_OPENSTATUSWINDOW : IMC_CLOSESTATUSWINDOW, 0);
25.122 + if (defaultIMEHandler != NULL) {
25.123 + ::SendMessage(defaultIMEHandler, WM_IME_CONTROL,
25.124 + visible ? IMC_OPENSTATUSWINDOW : IMC_CLOSESTATUSWINDOW, 0);
25.125 + }
25.126 }
25.127
25.128 /*
25.129 @@ -417,6 +418,7 @@
25.130 // use special message to open candidate window in main thread.
25.131 AwtToolkit::GetInstance().SendMessage(WM_AWT_OPENCANDIDATEWINDOW,
25.132 (WPARAM)peerGlobalRef, MAKELONG(x, y));
25.133 + // global ref is deleted in message handler
25.134
25.135 CATCH_BAD_ALLOC;
25.136 }
26.1 --- a/src/windows/native/sun/windows/awt_Toolkit.cpp Sun Jun 21 23:52:58 2009 -0700
26.2 +++ b/src/windows/native/sun/windows/awt_Toolkit.cpp Tue Jun 23 23:09:49 2009 -0700
26.3 @@ -804,8 +804,73 @@
26.4 return 0;
26.5 }
26.6 case WM_AWT_ASSOCIATECONTEXT: {
26.7 - AwtComponent *p = AwtComponent::GetComponent((HWND)wParam);
26.8 - p->ImmAssociateContext((HIMC)lParam);
26.9 + EnableNativeIMEStruct *data = (EnableNativeIMEStruct*)wParam;
26.10 +
26.11 + jobject peer = data->peer;
26.12 + jobject self = data->self;
26.13 + jint context = data->context;
26.14 + jboolean useNativeCompWindow = data->useNativeCompWindow;
26.15 +
26.16 + AwtComponent* comp = (AwtComponent*)JNI_GET_PDATA(peer);
26.17 + if (comp != NULL)
26.18 + {
26.19 + comp->SetInputMethod(self, useNativeCompWindow);
26.20 + comp->ImmAssociateContext((HIMC)context);
26.21 + }
26.22 +
26.23 + if (peer != NULL) {
26.24 + env->DeleteGlobalRef(peer);
26.25 + }
26.26 + if (self != NULL) {
26.27 + env->DeleteGlobalRef(self);
26.28 + }
26.29 +
26.30 + delete data;
26.31 + return 0;
26.32 + }
26.33 + case WM_AWT_GET_DEFAULT_IME_HANDLER: {
26.34 + LRESULT ret = (LRESULT)FALSE;
26.35 + jobject peer = (jobject)wParam;
26.36 +
26.37 + AwtComponent* comp = (AwtComponent*)JNI_GET_PDATA(peer);
26.38 + if (comp != NULL) {
26.39 + HWND defaultIMEHandler = ImmGetDefaultIMEWnd(comp->GetHWnd());
26.40 + if (defaultIMEHandler != NULL) {
26.41 + AwtToolkit::GetInstance().SetInputMethodWindow(defaultIMEHandler);
26.42 + ret = (LRESULT)TRUE;
26.43 + }
26.44 + }
26.45 +
26.46 + if (peer != NULL) {
26.47 + env->DeleteGlobalRef(peer);
26.48 + }
26.49 + return ret;
26.50 + }
26.51 + case WM_AWT_HANDLE_NATIVE_IME_EVENT: {
26.52 + jobject peer = (jobject)wParam;
26.53 + AwtComponent* comp = (AwtComponent*)JNI_GET_PDATA(peer);
26.54 + MSG* msg = (MSG*)lParam;
26.55 +
26.56 + long modifiers = comp->GetJavaModifiers();
26.57 + if ((comp != NULL) && (msg->message==WM_CHAR || msg->message==WM_SYSCHAR)) {
26.58 + WCHAR unicodeChar = (WCHAR)msg->wParam;
26.59 + comp->SendKeyEvent(java_awt_event_KeyEvent_KEY_TYPED,
26.60 + 0, //to be fixed nowMillis(),
26.61 + java_awt_event_KeyEvent_CHAR_UNDEFINED,
26.62 + unicodeChar,
26.63 + modifiers,
26.64 + java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN, (jlong)0,
26.65 + msg);
26.66 + } else if (comp != NULL) {
26.67 + MSG* pCopiedMsg = new MSG;
26.68 + *pCopiedMsg = *msg;
26.69 + comp->SendMessage(WM_AWT_HANDLE_EVENT, (WPARAM) FALSE,
26.70 + (LPARAM) pCopiedMsg);
26.71 + }
26.72 +
26.73 + if (peer != NULL) {
26.74 + env->DeleteGlobalRef(peer);
26.75 + }
26.76 return 0;
26.77 }
26.78 case WM_AWT_ENDCOMPOSITION: {
27.1 --- a/src/windows/native/sun/windows/awt_Toolkit.h Sun Jun 21 23:52:58 2009 -0700
27.2 +++ b/src/windows/native/sun/windows/awt_Toolkit.h Tue Jun 23 23:09:49 2009 -0700
27.3 @@ -61,6 +61,14 @@
27.4 typedef VOID (CALLBACK* IDLEPROC)(VOID);
27.5 typedef BOOL (CALLBACK* PEEKMESSAGEPROC)(MSG&);
27.6
27.7 +// Struct for _WInputMethod_enable|disableNativeIME method
27.8 +struct EnableNativeIMEStruct {
27.9 + jobject self;
27.10 + jobject peer;
27.11 + jint context;
27.12 + jboolean useNativeCompWindow;
27.13 +};
27.14 +
27.15 /*
27.16 * class JNILocalFrame
27.17 * Push/PopLocalFrame helper
28.1 --- a/src/windows/native/sun/windows/awtmsg.h Sun Jun 21 23:52:58 2009 -0700
28.2 +++ b/src/windows/native/sun/windows/awtmsg.h Tue Jun 23 23:09:49 2009 -0700
28.3 @@ -208,6 +208,8 @@
28.4 WM_AWT_CREATECONTEXT,
28.5 WM_AWT_DESTROYCONTEXT,
28.6 WM_AWT_ASSOCIATECONTEXT,
28.7 + WM_AWT_GET_DEFAULT_IME_HANDLER,
28.8 + WM_AWT_HANDLE_NATIVE_IME_EVENT,
28.9 WM_AWT_PRE_KEYDOWN,
28.10 WM_AWT_PRE_KEYUP,
28.11 WM_AWT_PRE_SYSKEYDOWN,
29.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
29.2 +++ b/test/java/awt/EventDispatchThread/LoopRobustness/LoopRobustness.html Tue Jun 23 23:09:49 2009 -0700
29.3 @@ -0,0 +1,22 @@
29.4 +<HTML>
29.5 + <!-- @test
29.6 + @bug 4023283
29.7 + @summary Checks that an Error which propogate up to the EventDispatch
29.8 + loop does not crash AWT.
29.9 + @author Andrei Dmitriev: area=awt.event
29.10 + @library ../../regtesthelpers
29.11 + @build Util
29.12 + @run main LoopRobustness
29.13 + -->
29.14 + <HEAD>
29.15 + <TITLE>LoopRobustness</TITLE>
29.16 + </HEAD>
29.17 + <BODY>
29.18 + This is automatic test.
29.19 +
29.20 + <APPLET CODE="LoopRobustness.class"
29.21 + CODEBASE = "."
29.22 + WIDTH=350 HEIGHT=100>
29.23 + </APPLET>
29.24 + </BODY>
29.25 + </HTML>
30.1 --- a/test/java/awt/EventDispatchThread/LoopRobustness/LoopRobustness.java Sun Jun 21 23:52:58 2009 -0700
30.2 +++ b/test/java/awt/EventDispatchThread/LoopRobustness/LoopRobustness.java Tue Jun 23 23:09:49 2009 -0700
30.3 @@ -1,5 +1,5 @@
30.4 /*
30.5 - * Copyright 1998-2006 Sun Microsystems, Inc. All Rights Reserved.
30.6 + * Copyright 1998-2009 Sun Microsystems, Inc. All Rights Reserved.
30.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
30.8 *
30.9 * This code is free software; you can redistribute it and/or modify it
30.10 @@ -26,7 +26,10 @@
30.11 * @bug 4023283
30.12 * @summary Checks that an Error which propogate up to the EventDispatch
30.13 * loop does not crash AWT.
30.14 - * @author Andrei Dmitriev Oleg Sukhodolsky
30.15 + * @author Andrei Dmitriev: area=awt.event
30.16 + * @library ../../regtesthelpers
30.17 + * @build Util
30.18 + * @run main LoopRobustness
30.19 */
30.20
30.21 import java.awt.*;
31.1 --- a/test/java/awt/Graphics/DrawImageBG/SystemBgColorTest.java Sun Jun 21 23:52:58 2009 -0700
31.2 +++ b/test/java/awt/Graphics/DrawImageBG/SystemBgColorTest.java Tue Jun 23 23:09:49 2009 -0700
31.3 @@ -59,7 +59,6 @@
31.4 if (errcount > 0) {
31.5 throw new RuntimeException(errcount+" errors");
31.6 }
31.7 - System.exit(0); // For 1.3 and earlier VMs...
31.8 }
31.9
31.10 static int cmap[] = {
32.1 --- a/test/java/text/Bidi/BidiBug.java Sun Jun 21 23:52:58 2009 -0700
32.2 +++ b/test/java/text/Bidi/BidiBug.java Tue Jun 23 23:09:49 2009 -0700
32.3 @@ -23,7 +23,7 @@
32.4
32.5 /*
32.6 * @test
32.7 - * @bug 4827312
32.8 + * @bug 4827312 6850113
32.9 * @summary verify that argument validity check is not fooled by overflow
32.10 */
32.11 public class BidiBug {
32.12 @@ -33,9 +33,9 @@
32.13 java.text.Bidi bidi = new java.text.Bidi(new char[20],10,buff,Integer.MAX_VALUE-3,4,1);
32.14 }
32.15 catch (IllegalArgumentException e) {
32.16 - System.out.println(e);
32.17 + System.out.println("Passed: " + e);
32.18 return; // success
32.19 }
32.20 - throw new RuntimeException("didn't throw error, though we didn't crash either");
32.21 + throw new RuntimeException("Failed: Bidi didn't throw error, though we didn't crash either");
32.22 }
32.23 }
33.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
33.2 +++ b/test/java/text/Bidi/BidiConformance.java Tue Jun 23 23:09:49 2009 -0700
33.3 @@ -0,0 +1,2334 @@
33.4 +/*
33.5 + * Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved.
33.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
33.7 + *
33.8 + * This code is free software; you can redistribute it and/or modify it
33.9 + * under the terms of the GNU General Public License version 2 only, as
33.10 + * published by the Free Software Foundation.
33.11 + *
33.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
33.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
33.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
33.15 + * version 2 for more details (a copy is included in the LICENSE file that
33.16 + * accompanied this code).
33.17 + *
33.18 + * You should have received a copy of the GNU General Public License version
33.19 + * 2 along with this work; if not, write to the Free Software Foundation,
33.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
33.21 + *
33.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
33.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
33.24 + * have any questions.
33.25 + */
33.26 +
33.27 +/*
33.28 + * @test
33.29 + * @bug 6850113
33.30 + * @summary confirm the behavior of new Bidi implementation. (Backward compatibility)
33.31 + */
33.32 +
33.33 +import java.awt.font.NumericShaper;
33.34 +import java.awt.font.TextAttribute;
33.35 +import java.text.AttributedString;
33.36 +import java.text.Bidi;
33.37 +import java.util.Arrays;
33.38 +
33.39 +public class BidiConformance {
33.40 +
33.41 + /* internal flags */
33.42 + private static boolean error = false;
33.43 + private static boolean verbose = false;
33.44 + private static boolean abort = false;
33.45 +
33.46 + public static void main(String[] args) {
33.47 + for (int i = 0; i < args.length; i++) {
33.48 + String arg = args[i];
33.49 + if (arg.equals("-verbose")) {
33.50 + verbose = true;
33.51 + } else if (arg.equals("-abort")) {
33.52 + abort = true;
33.53 + }
33.54 + }
33.55 +
33.56 + BidiConformance bc = new BidiConformance();
33.57 + bc.test();
33.58 +
33.59 + if (error) {
33.60 + throw new RuntimeException("Failed.");
33.61 + } else {
33.62 + System.out.println("Passed.");
33.63 + }
33.64 + }
33.65 +
33.66 + private void test() {
33.67 + testConstants();
33.68 + testConstructors();
33.69 + testMethods();
33.70 +
33.71 + testMethods4Constructor1(); // Bidi(AttributedCharacterIterator)
33.72 + testMethods4Constructor2(); // Bidi(String, int)
33.73 + testMethods4Constructor3(); // Bidi(char[], ...)
33.74 + }
33.75 +
33.76 + private void testConstants() {
33.77 + System.out.println("*** Test constants");
33.78 +
33.79 + checkResult("Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT",
33.80 + -2, Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT);
33.81 + checkResult("Bidi.DIRECTION_DEFAULT_RIGHT_TO_LEFT",
33.82 + -1, Bidi.DIRECTION_DEFAULT_RIGHT_TO_LEFT);
33.83 + checkResult("Bidi.DIRECTION_LEFT_TO_RIGHT",
33.84 + 0, Bidi.DIRECTION_LEFT_TO_RIGHT);
33.85 + checkResult("Bidi.DIRECTION_RIGHT_TO_LEFT",
33.86 + 1, Bidi.DIRECTION_RIGHT_TO_LEFT);
33.87 + }
33.88 +
33.89 + private void testConstructors() {
33.90 + System.out.println("*** Test constructors");
33.91 +
33.92 + testConstructor1(); // Bidi(AttributedCharacterIterator)
33.93 + testConstructor2(); // Bidi(String, int)
33.94 + testConstructor3(); // Bidi(char[], ...)
33.95 + }
33.96 +
33.97 + private void testMethods() {
33.98 + System.out.println("*** Test methods");
33.99 +
33.100 + testMethod_createLineBidi1();
33.101 + testMethod_createLineBidi2();
33.102 + testMethod_getLevelAt();
33.103 + testMethod_getRunLevel();
33.104 + testMethod_getRunLimit();
33.105 + testMethod_getRunStart();
33.106 + testMethod_reorderVisually1();
33.107 + testMethod_reorderVisually2();
33.108 + testMethod_requiresBidi();
33.109 + }
33.110 +
33.111 + private void testMethods4Constructor1() {
33.112 + System.out.println("*** Test methods for constructor 1");
33.113 +
33.114 + String paragraph;
33.115 + Bidi bidi;
33.116 + NumericShaper ns = NumericShaper.getShaper(NumericShaper.ARABIC);
33.117 +
33.118 + for (int textNo = 0; textNo < data4Constructor1.length; textNo++) {
33.119 + paragraph = data4Constructor1[textNo][0];
33.120 + int start = paragraph.indexOf('<')+1;
33.121 + int limit = paragraph.indexOf('>');
33.122 + int testNo;
33.123 +
33.124 + System.out.println("*** Test textNo=" + textNo +
33.125 + ": Bidi(AttributedCharacterIterator\"" +
33.126 + toReadableString(paragraph) + "\") " +
33.127 + " start=" + start + ", limit=" + limit);
33.128 +
33.129 + // Test 0
33.130 + testNo = 0;
33.131 + System.out.println(" Test#" + testNo +": RUN_DIRECTION_LTR");
33.132 + AttributedString astr = new AttributedString(paragraph);
33.133 + astr.addAttribute(TextAttribute.RUN_DIRECTION,
33.134 + TextAttribute.RUN_DIRECTION_LTR);
33.135 + bidi = new Bidi(astr.getIterator());
33.136 +
33.137 + callTestEachMethod4Constructor1(textNo, testNo, bidi);
33.138 +
33.139 + // Test 1
33.140 + ++testNo;
33.141 + System.out.println(" Test#" + testNo +
33.142 + ": RUN_DIRECTION_LTR, BIDI_EMBEDDING(1)");
33.143 + astr = new AttributedString(paragraph);
33.144 + astr.addAttribute(TextAttribute.RUN_DIRECTION,
33.145 + TextAttribute.RUN_DIRECTION_LTR);
33.146 + astr.addAttribute(TextAttribute.BIDI_EMBEDDING, new Integer(1),
33.147 + start, limit);
33.148 + bidi = new Bidi(astr.getIterator());
33.149 + callTestEachMethod4Constructor1(textNo, testNo, bidi);
33.150 +
33.151 + // Test 2
33.152 + ++testNo;
33.153 + System.out.println(" Test#" + testNo +
33.154 + ": RUN_DIERCTION_LTR, BIDI_EMBEDDING(2)");
33.155 + astr = new AttributedString(paragraph);
33.156 + astr.addAttribute(TextAttribute.RUN_DIRECTION,
33.157 + TextAttribute.RUN_DIRECTION_LTR);
33.158 + astr.addAttribute(TextAttribute.BIDI_EMBEDDING, new Integer(2),
33.159 + start, limit);
33.160 + bidi = new Bidi(astr.getIterator());
33.161 + callTestEachMethod4Constructor1(textNo, testNo, bidi);
33.162 +
33.163 + // Test 3
33.164 + ++testNo;
33.165 + System.out.println(" Test#" + testNo +
33.166 + ": RUN_DIRECTIOIN_LTR, BIDI_EMBEDDING(-3)");
33.167 + astr = new AttributedString(paragraph);
33.168 + astr.addAttribute(TextAttribute.RUN_DIRECTION,
33.169 + TextAttribute.RUN_DIRECTION_LTR);
33.170 + astr.addAttribute(TextAttribute.BIDI_EMBEDDING, new Integer(-3),
33.171 + start, limit);
33.172 + bidi = new Bidi(astr.getIterator());
33.173 + callTestEachMethod4Constructor1(textNo, testNo, bidi);
33.174 +
33.175 + // Test 4
33.176 + ++testNo;
33.177 + System.out.println(" Test#" + testNo +
33.178 + ": RUN_DIRECTION_LTR, BIDI_EMBEDDING(-4)");
33.179 + astr = new AttributedString(paragraph);
33.180 + astr.addAttribute(TextAttribute.RUN_DIRECTION,
33.181 + TextAttribute.RUN_DIRECTION_LTR);
33.182 + astr.addAttribute(TextAttribute.BIDI_EMBEDDING, new Integer(-4),
33.183 + start, limit);
33.184 + bidi = new Bidi(astr.getIterator());
33.185 + callTestEachMethod4Constructor1(textNo, testNo, bidi);
33.186 +
33.187 + // Test 5
33.188 + ++testNo;
33.189 + System.out.println(" Test#" + testNo + ": RUN_DIRECTION_RTL");
33.190 + astr = new AttributedString(paragraph);
33.191 + astr.addAttribute(TextAttribute.RUN_DIRECTION,
33.192 + TextAttribute.RUN_DIRECTION_RTL);
33.193 + bidi = new Bidi(astr.getIterator());
33.194 + callTestEachMethod4Constructor1(textNo, testNo, bidi);
33.195 +
33.196 + // Test 6
33.197 + ++testNo;
33.198 + System.out.println(" Test#" + testNo +
33.199 + ": RUN_DIRECTION_RTL, BIDI_EMBEDDING(1)");
33.200 + astr = new AttributedString(paragraph);
33.201 + astr.addAttribute(TextAttribute.RUN_DIRECTION,
33.202 + TextAttribute.RUN_DIRECTION_RTL);
33.203 + astr.addAttribute(TextAttribute.BIDI_EMBEDDING, new Integer(1),
33.204 + start, limit);
33.205 + try {
33.206 + bidi = new Bidi(astr.getIterator());
33.207 + callTestEachMethod4Constructor1(textNo, testNo, bidi);
33.208 + }
33.209 + catch (IllegalArgumentException e) {
33.210 + errorHandling(" Unexpected exception: " + e);
33.211 + }
33.212 +
33.213 + // Test 7
33.214 + ++testNo;
33.215 + System.out.println(" Test#" + testNo +
33.216 + ": RUN_DIRECTION_RTL, BIDI_EMBEDDING(2)");
33.217 + astr = new AttributedString(paragraph);
33.218 + astr.addAttribute(TextAttribute.RUN_DIRECTION,
33.219 + TextAttribute.RUN_DIRECTION_RTL);
33.220 + astr.addAttribute(TextAttribute.BIDI_EMBEDDING, new Integer(2),
33.221 + start, limit);
33.222 + try {
33.223 + bidi = new Bidi(astr.getIterator());
33.224 + callTestEachMethod4Constructor1(textNo, testNo, bidi);
33.225 + }
33.226 + catch (IllegalArgumentException e) {
33.227 + errorHandling(" Unexpected exception: " + e);
33.228 + }
33.229 +
33.230 + // Test 8
33.231 + ++testNo;
33.232 + System.out.println(" Test#" + testNo +
33.233 + ": RUN_DIRECTION_RTL, BIDI_EMBEDDING(-3)");
33.234 + astr = new AttributedString(paragraph);
33.235 + astr.addAttribute(TextAttribute.RUN_DIRECTION,
33.236 + TextAttribute.RUN_DIRECTION_RTL);
33.237 + astr.addAttribute(TextAttribute.BIDI_EMBEDDING, new Integer(-3),
33.238 + start, limit);
33.239 + try {
33.240 + bidi = new Bidi(astr.getIterator());
33.241 + callTestEachMethod4Constructor1(textNo, testNo, bidi);
33.242 + }
33.243 + catch (IllegalArgumentException e) {
33.244 + errorHandling(" Unexpected exception: " + e);
33.245 + }
33.246 +
33.247 + // Test 9
33.248 + ++testNo;
33.249 + System.out.println(" Test#" + testNo +
33.250 + ": RUN_DIRECTION_RTL, BIDI_EMBEDDING(-4)");
33.251 + astr = new AttributedString(paragraph);
33.252 + astr.addAttribute(TextAttribute.RUN_DIRECTION,
33.253 + TextAttribute.RUN_DIRECTION_RTL);
33.254 + astr.addAttribute(TextAttribute.BIDI_EMBEDDING, new Integer(-4),
33.255 + start, limit);
33.256 + try {
33.257 + bidi = new Bidi(astr.getIterator());
33.258 + callTestEachMethod4Constructor1(textNo, testNo, bidi);
33.259 + }
33.260 + catch (IllegalArgumentException e) {
33.261 + errorHandling(" Unexpected exception: " + e);
33.262 + }
33.263 +
33.264 + // Test 10
33.265 + ++testNo;
33.266 + System.out.println(" Test#" + testNo +
33.267 + ": TextAttribute not specified");
33.268 + astr = new AttributedString(paragraph);
33.269 + bidi = new Bidi(astr.getIterator());
33.270 + callTestEachMethod4Constructor1(textNo, testNo, bidi);
33.271 +
33.272 + // Test 11
33.273 + ++testNo;
33.274 + System.out.println(" Test#" + testNo +
33.275 + ": RUN_DIRECTION_LTR, NUMERIC_SHAPING(ARABIC)");
33.276 + astr = new AttributedString(paragraph);
33.277 + astr.addAttribute(TextAttribute.RUN_DIRECTION,
33.278 + TextAttribute.RUN_DIRECTION_LTR);
33.279 + astr.addAttribute(TextAttribute.NUMERIC_SHAPING, ns);
33.280 + bidi = new Bidi(astr.getIterator());
33.281 + callTestEachMethod4Constructor1(textNo, testNo, bidi);
33.282 +
33.283 + // Test 12
33.284 + ++testNo;
33.285 + System.out.println(" Test#" + testNo +
33.286 + ": RUN_DIRECTION_RTL, NUMERIC_SHAPING(ARABIC)");
33.287 + astr = new AttributedString(paragraph);
33.288 + astr.addAttribute(TextAttribute.RUN_DIRECTION,
33.289 + TextAttribute.RUN_DIRECTION_RTL);
33.290 + astr.addAttribute(TextAttribute.NUMERIC_SHAPING, ns);
33.291 + bidi = new Bidi(astr.getIterator());
33.292 + callTestEachMethod4Constructor1(textNo, testNo, bidi);
33.293 + }
33.294 + }
33.295 +
33.296 + private void testMethods4Constructor2() {
33.297 + System.out.println("*** Test methods for constructor 2");
33.298 +
33.299 + String paragraph;
33.300 + Bidi bidi;
33.301 +
33.302 + for (int textNo = 0; textNo < data4Constructor2.length; textNo++) {
33.303 + paragraph = data4Constructor2[textNo][0];
33.304 + for (int flagNo = 0; flagNo < FLAGS.length; flagNo++) {
33.305 + int flag = FLAGS[flagNo];
33.306 +
33.307 + System.out.println("*** Test textNo=" + textNo +
33.308 + ": Bidi(\"" + toReadableString(paragraph) +
33.309 + "\", " + getFlagName(flag) + ")");
33.310 +
33.311 + bidi = new Bidi(paragraph, flag);
33.312 + callTestEachMethod4Constructor2(textNo, flagNo, bidi);
33.313 + }
33.314 + }
33.315 + }
33.316 +
33.317 + private void testMethods4Constructor3() {
33.318 + System.out.println("*** Test methods for constructor 3");
33.319 +
33.320 + String paragraph;
33.321 + Bidi bidi;
33.322 +
33.323 + for (int textNo = 0; textNo < data4Constructor3.length; textNo++) {
33.324 + paragraph = data4Constructor3[textNo][0];
33.325 + char[] c = paragraph.toCharArray();
33.326 + int start = paragraph.indexOf('<')+1;
33.327 + byte[][] embeddings = (c.length < emb4Constructor3[1][0].length) ?
33.328 + emb4Constructor3[0] : emb4Constructor3[1];
33.329 + for (int flagNo = 0; flagNo < FLAGS.length; flagNo++) {
33.330 + int flag = FLAGS[flagNo];
33.331 + for (int embNo = 0; embNo < embeddings.length; embNo++) {
33.332 + int dataNo = flagNo * FLAGS.length + embNo;
33.333 +
33.334 + System.out.println("*** Test textNo=" + textNo +
33.335 + ": Bidi(char[]\"" + toReadableString(paragraph) +
33.336 + "\", 0, embeddings={" + toString(embeddings[embNo]) +
33.337 + "}, " + c.length + ", " +
33.338 + getFlagName(flag) + ")" + " dataNo=" + dataNo);
33.339 +
33.340 + try {
33.341 + bidi = new Bidi(c, 0, embeddings[embNo], 0,
33.342 + c.length, flag);
33.343 + callTestEachMethod4Constructor3(textNo, dataNo, bidi);
33.344 + }
33.345 + catch (Exception e) {
33.346 + errorHandling(" Unexpected exception: " + e);
33.347 + }
33.348 + }
33.349 + }
33.350 + }
33.351 + }
33.352 +
33.353 + private void testConstructor1() {
33.354 + Bidi bidi;
33.355 +
33.356 + try {
33.357 + bidi = new Bidi(null);
33.358 + errorHandling("Bidi((AttributedCharacterIterator)null) " +
33.359 + "should throw an IAE.");
33.360 + }
33.361 + catch (IllegalArgumentException e) {
33.362 + }
33.363 + catch (NullPointerException e) {
33.364 + errorHandling("Bidi((AttributedCharacterIterator)null) " +
33.365 + "should not throw an NPE but an IAE.");
33.366 + }
33.367 +
33.368 + String paragraph = data4Constructor1[1][0];
33.369 + int start = paragraph.indexOf('<')+1;
33.370 + int limit = paragraph.indexOf('>');
33.371 + AttributedString astr = new AttributedString(paragraph);
33.372 + astr.addAttribute(TextAttribute.RUN_DIRECTION,
33.373 + TextAttribute.RUN_DIRECTION_RTL);
33.374 + astr.addAttribute(TextAttribute.BIDI_EMBEDDING, new Integer(-61),
33.375 + start, limit);
33.376 + try {
33.377 + bidi = new Bidi(astr.getIterator());
33.378 + for (int i = start; i < limit; i++) {
33.379 + if (bidi.getLevelAt(i) != 61) {
33.380 + errorHandling("Bidi(AttributedCharacterIterator).getLevelAt(" +
33.381 + i + ") should not be " + bidi.getLevelAt(i) +
33.382 + " but 60 when BIDI_EMBEDDING is -61.");
33.383 + }
33.384 + }
33.385 + }
33.386 + catch (Exception e) {
33.387 + errorHandling(" Unexpected exception: " + e);
33.388 + }
33.389 +
33.390 + astr = new AttributedString(paragraph);
33.391 + astr.addAttribute(TextAttribute.RUN_DIRECTION,
33.392 + TextAttribute.RUN_DIRECTION_RTL);
33.393 + astr.addAttribute(TextAttribute.BIDI_EMBEDDING, new Integer(-62),
33.394 + start, limit);
33.395 + try {
33.396 + bidi = new Bidi(astr.getIterator());
33.397 + for (int i = start; i < limit; i++) {
33.398 + if (bidi.getLevelAt(i) != 1) {
33.399 + errorHandling("Bidi(AttributedCharacterIterator).getLevelAt() " +
33.400 + "should be 1 when BIDI_EMBEDDING is -62.");
33.401 + }
33.402 + }
33.403 + }
33.404 + catch (Exception e) {
33.405 + errorHandling(" Unexpected exception: " + e);
33.406 + }
33.407 +
33.408 + astr = new AttributedString(paragraph);
33.409 + astr.addAttribute(TextAttribute.RUN_DIRECTION,
33.410 + TextAttribute.RUN_DIRECTION_RTL);
33.411 + astr.addAttribute(TextAttribute.BIDI_EMBEDDING, new Integer(60),
33.412 + start, limit);
33.413 + try {
33.414 + bidi = new Bidi(astr.getIterator());
33.415 + for (int i = start; i < limit; i++) {
33.416 + if (bidi.getLevelAt(i) != 61) {
33.417 + errorHandling("Bidi(AttributedCharacterIterator).getLevelAt() " +
33.418 + "should be 61 when BIDI_EMBEDDING is 60.");
33.419 + }
33.420 + }
33.421 + }
33.422 + catch (Exception e) {
33.423 + errorHandling(" Unexpected exception: " + e);
33.424 + }
33.425 +
33.426 + astr = new AttributedString(paragraph);
33.427 + astr.addAttribute(TextAttribute.RUN_DIRECTION,
33.428 + TextAttribute.RUN_DIRECTION_RTL);
33.429 + astr.addAttribute(TextAttribute.BIDI_EMBEDDING, new Integer(61),
33.430 + start, limit);
33.431 + try {
33.432 + bidi = new Bidi(astr.getIterator());
33.433 + for (int i = start; i < limit; i++) {
33.434 + if (bidi.getLevelAt(i) != 61) {
33.435 + errorHandling("Bidi(AttributedCharacterIterator).getLevelAt(" +
33.436 + i + ") should not be " + bidi.getLevelAt(i) +
33.437 + " but 61 when BIDI_EMBEDDING is 61.");
33.438 + }
33.439 + }
33.440 + }
33.441 + catch (Exception e) {
33.442 + errorHandling(" Unexpected exception: " + e);
33.443 + }
33.444 +
33.445 + astr = new AttributedString(paragraph);
33.446 + astr.addAttribute(TextAttribute.RUN_DIRECTION,
33.447 + TextAttribute.RUN_DIRECTION_RTL);
33.448 + astr.addAttribute(TextAttribute.BIDI_EMBEDDING, new Integer(62),
33.449 + start, limit);
33.450 + try {
33.451 + bidi = new Bidi(astr.getIterator());
33.452 + for (int i = start; i < limit; i++) {
33.453 + if (bidi.getLevelAt(i) != 1) {
33.454 + errorHandling("Bidi(AttributedCharacterIterator).getLevelAt()" +
33.455 + " should not be " + bidi.getLevelAt(i) +
33.456 + " but 1 when BIDI_EMBEDDING is 62.");
33.457 + }
33.458 + }
33.459 + }
33.460 + catch (Exception e) {
33.461 + errorHandling(" Unexpected exception: " + e);
33.462 + }
33.463 + }
33.464 +
33.465 + private void testConstructor2() {
33.466 + Bidi bidi;
33.467 +
33.468 + try {
33.469 + bidi = new Bidi(null, Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT);
33.470 + errorHandling("Bidi((String)null, DIRECTION_DEFAULT_LEFT_TO_RIGHT)" +
33.471 + " should throw an IAE.");
33.472 + }
33.473 + catch (IllegalArgumentException e) {
33.474 + }
33.475 + catch (NullPointerException e) {
33.476 + errorHandling("Bidi((String)null, DIRECTION_DEFAULT_LEFT_TO_RIGHT) " +
33.477 + "should not throw an NPE but an IAE.");
33.478 + }
33.479 +
33.480 + try {
33.481 + bidi = new Bidi("abc", -3);
33.482 + }
33.483 + catch (Exception e) {
33.484 + errorHandling("Bidi(\"abc\", -3) should not throw an exception: " +
33.485 + e);
33.486 + }
33.487 +
33.488 + try {
33.489 + bidi = new Bidi("abc", 2);
33.490 + }
33.491 + catch (Exception e) {
33.492 + errorHandling("Bidi(\"abc\", 2) should not throw an exception: " +
33.493 + e);
33.494 + }
33.495 + }
33.496 +
33.497 + private void testConstructor3() {
33.498 + char[] text = {'a', 'b', 'c', 'd', 'e'};
33.499 + byte[] embeddings = {0, 0, 0, 0, 0};
33.500 + Bidi bidi;
33.501 +
33.502 + try {
33.503 + bidi = new Bidi(null, 0, embeddings, 0, 5,
33.504 + Bidi.DIRECTION_LEFT_TO_RIGHT);
33.505 + errorHandling("Bidi(char[], ...) should throw an IAE " +
33.506 + "when text=null.");
33.507 + }
33.508 + catch (IllegalArgumentException e) {
33.509 + }
33.510 + catch (NullPointerException e) {
33.511 + errorHandling("Bidi(char[], ...) should not throw an NPE " +
33.512 + "but an IAE when text=null.");
33.513 + }
33.514 +
33.515 + try {
33.516 + bidi = new Bidi(text, -1, embeddings, 0, 5,
33.517 + Bidi.DIRECTION_LEFT_TO_RIGHT);
33.518 + errorHandling("Bidi(char[], ...) should throw an IAE " +
33.519 + "when textStart is incorrect(-1: too small).");
33.520 + }
33.521 + catch (IllegalArgumentException e) {
33.522 + }
33.523 + catch (ArrayIndexOutOfBoundsException e) {
33.524 + errorHandling("Bidi(char[], ...) should not throw an NPE " +
33.525 + "but an IAE when textStart is incorrect(-1: too small).");
33.526 + }
33.527 +
33.528 + try {
33.529 + bidi = new Bidi(text, 4, embeddings, 0, 2,
33.530 + Bidi.DIRECTION_LEFT_TO_RIGHT);
33.531 + errorHandling("Bidi(char[], ...) should throw an IAE " +
33.532 + "when textStart is incorrect(4: too large).");
33.533 + }
33.534 + catch (IllegalArgumentException e) {
33.535 + }
33.536 + catch (ArrayIndexOutOfBoundsException e) {
33.537 + errorHandling("Bidi(char[], ...) should not throw an NPE " +
33.538 + "but an IAE when textStart is incorrect(4: too large).");
33.539 + }
33.540 +
33.541 + byte[] actualLevels = new byte[text.length];
33.542 + byte[] validEmbeddings1 = {0, -61, -60, -2, -1};
33.543 + byte[] expectedLevels1 = {0, 61, 60, 2, 1};
33.544 + try {
33.545 + bidi = new Bidi(text, 0, validEmbeddings1, 0, 5,
33.546 + Bidi.DIRECTION_LEFT_TO_RIGHT);
33.547 + for (int i = 0; i < text.length; i++) {
33.548 + actualLevels[i] = (byte)bidi.getLevelAt(i);
33.549 + }
33.550 + if (!Arrays.equals(expectedLevels1, actualLevels)) {
33.551 + errorHandling("Bidi(char[], ...).getLevelAt()" +
33.552 + " should be {" + toString(actualLevels) +
33.553 + "} when embeddings are {" +
33.554 + toString(expectedLevels1) + "}.");
33.555 + }
33.556 + }
33.557 + catch (Exception e) {
33.558 + errorHandling("Bidi(char[], ...) should not throw an exception " +
33.559 + "when embeddings is valid(-61).");
33.560 + }
33.561 +
33.562 + byte[] validEmbeddings2 = {0, 61, 60, 2, 1};
33.563 + byte[] expectedLevels2 = {0, 62, 60, 2, 2};
33.564 + try {
33.565 + bidi = new Bidi(text, 0, validEmbeddings2, 0, 5,
33.566 + Bidi.DIRECTION_LEFT_TO_RIGHT);
33.567 + for (int i = 0; i < text.length; i++) {
33.568 + actualLevels[i] = (byte)bidi.getLevelAt(i);
33.569 + }
33.570 + if (!Arrays.equals(expectedLevels2, actualLevels)) {
33.571 + errorHandling("Bidi(char[], ...).getLevelAt()" +
33.572 + " should be {" + toString(actualLevels) +
33.573 + "} when embeddings are {" +
33.574 + toString(expectedLevels2) + "}.");
33.575 + }
33.576 + }
33.577 + catch (Exception e) {
33.578 + errorHandling("Bidi(char[], ...) should not throw an exception " +
33.579 + "when embeddings is valid(61).");
33.580 + }
33.581 +
33.582 + byte[] invalidEmbeddings1 = {0, -62, 0, 0, 0};
33.583 + try {
33.584 + bidi = new Bidi(text, 0, invalidEmbeddings1, 0, 5,
33.585 + Bidi.DIRECTION_LEFT_TO_RIGHT);
33.586 + if (bidi.getLevelAt(1) != 0) {
33.587 + errorHandling("Bidi(char[], ...).getLevelAt(1) should be 0 " +
33.588 + "when embeddings[1] is -62.");
33.589 + }
33.590 + }
33.591 + catch (Exception e) {
33.592 + errorHandling("Bidi(char[], ...) should not throw an exception " +
33.593 + "even when embeddings includes -62.");
33.594 + }
33.595 +
33.596 + byte[] invalidEmbeddings2 = {0, 62, 0, 0, 0};
33.597 + try {
33.598 + bidi = new Bidi(text, 0, invalidEmbeddings2, 0, 5,
33.599 + Bidi.DIRECTION_LEFT_TO_RIGHT);
33.600 + if (bidi.getLevelAt(1) != 0) {
33.601 + errorHandling("Bidi(char[], ...).getLevelAt(1) should be 0 " +
33.602 + "when embeddings[1] is 62.");
33.603 + }
33.604 + }
33.605 + catch (Exception e) {
33.606 + errorHandling("Bidi(char[], ...) should not throw an exception " +
33.607 + "even when embeddings includes 62.");
33.608 + }
33.609 +
33.610 + try {
33.611 + bidi = new Bidi(text, 0, embeddings, 0, -1,
33.612 + Bidi.DIRECTION_LEFT_TO_RIGHT);
33.613 + errorHandling("Bidi(char[], ...) should throw an IAE " +
33.614 + "when paragraphLength=-1(too small).");
33.615 + }
33.616 + catch (IllegalArgumentException e) {
33.617 + }
33.618 + catch (NegativeArraySizeException e) {
33.619 + errorHandling("Bidi(char[], ...) should not throw an NASE " +
33.620 + "but an IAE when paragraphLength=-1(too small).");
33.621 + }
33.622 +
33.623 + try {
33.624 + bidi = new Bidi(text, 0, embeddings, 0, 6,
33.625 + Bidi.DIRECTION_LEFT_TO_RIGHT);
33.626 + errorHandling("Bidi(char[], ...) should throw an IAE " +
33.627 + "when paragraphLength=6(too large).");
33.628 + }
33.629 + catch (IllegalArgumentException e) {
33.630 + }
33.631 + catch (ArrayIndexOutOfBoundsException e) {
33.632 + errorHandling("Bidi(char[], ...) should not throw an AIOoBE " +
33.633 + "but an IAE when paragraphLength=6(too large).");
33.634 + }
33.635 +
33.636 + try {
33.637 + bidi = new Bidi(text, 0, embeddings, 0, 4, -3);
33.638 + }
33.639 + catch (Exception e) {
33.640 + errorHandling("Bidi(char[], ...) should not throw an exception " +
33.641 + "even when flag=-3(too small).");
33.642 + }
33.643 +
33.644 + try {
33.645 + bidi = new Bidi(text, 0, embeddings, 0, 5, 2);
33.646 + }
33.647 + catch (Exception e) {
33.648 + errorHandling("Bidi(char[], ...) should not throw an exception " +
33.649 + "even when flag=2(too large).");
33.650 + }
33.651 + }
33.652 +
33.653 + private void callTestEachMethod4Constructor1(int textNo,
33.654 + int testNo,
33.655 + Bidi bidi) {
33.656 + testEachMethod(bidi,
33.657 + data4Constructor1[textNo][0],
33.658 + data4Constructor1[textNo][testNo+1],
33.659 + baseIsLTR4Constructor1[textNo][testNo],
33.660 + isLTR_isRTL4Constructor1[textNo][0][testNo],
33.661 + isLTR_isRTL4Constructor1[textNo][1][testNo]);
33.662 +System.out.println(bidi.toString());
33.663 + }
33.664 +
33.665 + private void callTestEachMethod4Constructor2(int textNo,
33.666 + int flagNo,
33.667 + Bidi bidi) {
33.668 + testEachMethod(bidi,
33.669 + data4Constructor2[textNo][0],
33.670 + data4Constructor2[textNo][flagNo+1],
33.671 + baseIsLTR4Constructor2[textNo][flagNo],
33.672 + isLTR_isRTL4Constructor2[textNo][0][flagNo],
33.673 + isLTR_isRTL4Constructor2[textNo][1][flagNo]);
33.674 +System.out.println(bidi.toString());
33.675 + }
33.676 +
33.677 + private void callTestEachMethod4Constructor3(int textNo,
33.678 + int dataNo,
33.679 + Bidi bidi) {
33.680 + testEachMethod(bidi,
33.681 + data4Constructor3[textNo][0],
33.682 + data4Constructor3[textNo][dataNo+1],
33.683 + baseIsLTR4Constructor3[textNo][dataNo],
33.684 + isLTR_isRTL4Constructor3[textNo][0][dataNo],
33.685 + isLTR_isRTL4Constructor3[textNo][1][dataNo]);
33.686 +System.out.println(bidi.toString());
33.687 + }
33.688 +
33.689 + private StringBuilder sb = new StringBuilder();
33.690 + private void testEachMethod(Bidi bidi,
33.691 + String text,
33.692 + String expectedLevels,
33.693 + boolean expectedBaseIsLTR,
33.694 + boolean expectedIsLTR,
33.695 + boolean expectedIsRTL
33.696 + ) {
33.697 + /* Test baseIsLeftToRight() */
33.698 + boolean actualBoolean = bidi.baseIsLeftToRight();
33.699 + checkResult("baseIsLeftToRight()", expectedBaseIsLTR, actualBoolean);
33.700 +
33.701 + /* Test getBaseLevel() */
33.702 + int expectedInt = (expectedBaseIsLTR) ? 0 : 1;
33.703 + int actualInt = bidi.getBaseLevel();
33.704 + checkResult("getBaseLevel()", expectedInt, actualInt);
33.705 +
33.706 + /* Test getLength() */
33.707 + expectedInt = text.length();
33.708 + actualInt = bidi.getLength();
33.709 + checkResult("getLength()", expectedInt, actualInt);
33.710 +
33.711 + /* Test getLevelAt() */
33.712 + sb.setLength(0);
33.713 + for (int i = 0; i < text.length(); i++) {
33.714 + sb.append(bidi.getLevelAt(i));
33.715 + }
33.716 + checkResult("getLevelAt()", expectedLevels, sb.toString());
33.717 +
33.718 + /* Test getRunCount() */
33.719 + expectedInt = getRunCount(expectedLevels);
33.720 + actualInt = bidi.getRunCount();
33.721 + checkResult("getRunCount()", expectedInt, actualInt);
33.722 +
33.723 + /* Test getRunLevel(), getRunLimit() and getRunStart() */
33.724 + if (expectedInt == actualInt) {
33.725 + int runCount = expectedInt;
33.726 + int[] expectedRunLevels = getRunLevels_int(runCount, expectedLevels);
33.727 + int[] expectedRunLimits = getRunLimits(runCount, expectedLevels);
33.728 + int[] expectedRunStarts = getRunStarts(runCount, expectedLevels);
33.729 + int[] actualRunLevels = new int[runCount];
33.730 + int[] actualRunLimits = new int[runCount];
33.731 + int[] actualRunStarts = new int[runCount];
33.732 +
33.733 + for (int k = 0; k < runCount; k++) {
33.734 + actualRunLevels[k] = bidi.getRunLevel(k);
33.735 + actualRunLimits[k] = bidi.getRunLimit(k);
33.736 + actualRunStarts[k] = bidi.getRunStart(k);
33.737 + }
33.738 +
33.739 + checkResult("getRunLevel()", expectedRunLevels, actualRunLevels);
33.740 + checkResult("getRunStart()", expectedRunStarts, actualRunStarts);
33.741 + checkResult("getRunLimit()", expectedRunLimits, actualRunLimits);
33.742 + }
33.743 +
33.744 + /* Test isLeftToRight() */
33.745 + boolean expectedBoolean = expectedIsLTR;
33.746 + actualBoolean = bidi.isLeftToRight();
33.747 + checkResult("isLeftToRight()", expectedBoolean, actualBoolean);
33.748 +
33.749 + /* Test isMixed() */
33.750 + expectedBoolean = !(expectedIsLTR || expectedIsRTL);
33.751 + actualBoolean = bidi.isMixed();
33.752 + checkResult("isMixed()", expectedBoolean, actualBoolean);
33.753 +
33.754 + /* Test isRightToLeft() */
33.755 + expectedBoolean = expectedIsRTL;
33.756 + actualBoolean = bidi.isRightToLeft();
33.757 + checkResult("isRightToLeft()", expectedBoolean, actualBoolean);
33.758 + }
33.759 +
33.760 + private int getRunCount(String levels) {
33.761 + int len = levels.length();
33.762 + char c = levels.charAt(0);
33.763 + int runCount = 1;
33.764 +
33.765 + for (int index = 1; index < len; index++) {
33.766 + if (levels.charAt(index) != c) {
33.767 + runCount++;
33.768 + c = levels.charAt(index);
33.769 + }
33.770 + }
33.771 +
33.772 + return runCount;
33.773 + }
33.774 +
33.775 + private int[] getRunLevels_int(int runCount, String levels) {
33.776 + int[] array = new int[runCount];
33.777 + int len = levels.length();
33.778 + char c = levels.charAt(0);
33.779 + int i = 0;
33.780 + array[i++] = c - '0';
33.781 +
33.782 + for (int index = 1; index < len; index++) {
33.783 + if (levels.charAt(index) != c) {
33.784 + c = levels.charAt(index);
33.785 + array[i++] = c - '0';
33.786 + }
33.787 + }
33.788 +
33.789 + return array;
33.790 + }
33.791 +
33.792 + private byte[] getRunLevels_byte(int runCount, String levels) {
33.793 + byte[] array = new byte[runCount];
33.794 + int len = levels.length();
33.795 + char c = levels.charAt(0);
33.796 + int i = 0;
33.797 + array[i++] = (byte)(c - '0');
33.798 +
33.799 + for (int index = 1; index < len; index++) {
33.800 + if (levels.charAt(index) != c) {
33.801 + c = levels.charAt(index);
33.802 + array[i++] = (byte)(c - '0');
33.803 + }
33.804 + }
33.805 +
33.806 + return array;
33.807 + }
33.808 +
33.809 + private int[] getRunLimits(int runCount, String levels) {
33.810 + int[] array = new int[runCount];
33.811 + int len = levels.length();
33.812 + char c = levels.charAt(0);
33.813 + int i = 0;
33.814 +
33.815 + for (int index = 1; index < len; index++) {
33.816 + if (levels.charAt(index) != c) {
33.817 + c = levels.charAt(index);
33.818 + array[i++] = index;
33.819 + }
33.820 + }
33.821 + array[i] = len;
33.822 +
33.823 + return array;
33.824 + }
33.825 +
33.826 + private int[] getRunStarts(int runCount, String levels) {
33.827 + int[] array = new int[runCount];
33.828 + int len = levels.length();
33.829 + char c = levels.charAt(0);
33.830 + int i = 1;
33.831 +
33.832 + for (int index = 1; index < len; index++) {
33.833 + if (levels.charAt(index) != c) {
33.834 + c = levels.charAt(index);
33.835 + array[i++] = index;
33.836 + }
33.837 + }
33.838 +
33.839 + return array;
33.840 + }
33.841 +
33.842 + private String[] getObjects(int runCount, String text, String levels) {
33.843 + String[] array = new String[runCount];
33.844 + int[] runLimits = getRunLimits(runCount, levels);
33.845 + int runStart = 0;
33.846 +
33.847 + for (int i = 0; i < runCount; i++) {
33.848 + array[i] = text.substring(runStart, runLimits[i]);
33.849 + runStart = runLimits[i];
33.850 + }
33.851 +
33.852 + return array;
33.853 + }
33.854 +
33.855 + private void testMethod_createLineBidi1() {
33.856 + System.out.println("*** Test createLineBidi() 1");
33.857 +
33.858 + String str = " ABC 123. " + HebrewABC + " " + NKo123 + ". ABC 123";
33.859 +
33.860 + int lineStart = str.indexOf('.') + 2;
33.861 + int lineLimit = str.lastIndexOf('.') + 2;
33.862 + Bidi bidi = new Bidi(str, FLAGS[0]);
33.863 + Bidi lineBidi = bidi.createLineBidi(lineStart, lineLimit);
33.864 +
33.865 + checkResult("getBaseLevel()",
33.866 + bidi.getBaseLevel(), lineBidi.getBaseLevel());
33.867 + checkResult("getLevelAt(5)",
33.868 + bidi.getLevelAt(lineStart+5), lineBidi.getLevelAt(5));
33.869 + }
33.870 +
33.871 + private void testMethod_createLineBidi2() {
33.872 + System.out.println("*** Test createLineBidi() 2");
33.873 +
33.874 + Bidi bidi = new Bidi(data4Constructor1[0][0], FLAGS[0]);
33.875 + int len = data4Constructor1[0][0].length();
33.876 +
33.877 + try {
33.878 + Bidi lineBidi = bidi.createLineBidi(0, len);
33.879 + }
33.880 + catch (Exception e) {
33.881 + errorHandling("createLineBidi(0, textLength)" +
33.882 + " should not throw an exception.");
33.883 + }
33.884 +
33.885 + try {
33.886 + Bidi lineBidi = bidi.createLineBidi(-1, len);
33.887 + errorHandling("createLineBidi(-1, textLength)" +
33.888 + " should throw an IAE.");
33.889 + }
33.890 + catch (IllegalArgumentException e) {
33.891 + }
33.892 +
33.893 + try {
33.894 + Bidi lineBidi = bidi.createLineBidi(0, len+1);
33.895 + errorHandling("createLineBidi(0, textLength+1)" +
33.896 + " should throw an IAE.");
33.897 + }
33.898 + catch (IllegalArgumentException e) {
33.899 + }
33.900 + }
33.901 +
33.902 + /*
33.903 + * Confirm that getLevelAt() doesn't throw an exception for invalid offset
33.904 + * unlike ICU4J.
33.905 + */
33.906 + private void testMethod_getLevelAt() {
33.907 + System.out.println("*** Test getLevelAt()");
33.908 +
33.909 + Bidi bidi = new Bidi(data4Constructor1[1][0], FLAGS[0]);
33.910 + int len = data4Constructor1[1][0].length();
33.911 +
33.912 + try {
33.913 + int level = bidi.getLevelAt(-1);
33.914 + if (level != bidi.getBaseLevel()) {
33.915 + errorHandling("getLevelAt(-1) returned a wrong level." +
33.916 + " Expected=" + bidi.getBaseLevel() + ", got=" + level);
33.917 + }
33.918 + }
33.919 + catch (Exception e) {
33.920 + errorHandling("getLevelAt(-1) should not throw an exception.");
33.921 + }
33.922 +
33.923 + try {
33.924 + int level = bidi.getLevelAt(len+1);
33.925 + if (level != bidi.getBaseLevel()) {
33.926 + errorHandling("getLevelAt(textLength+1)" +
33.927 + " returned a wrong level." +
33.928 + " Expected=" + bidi.getBaseLevel() + ", got=" + level);
33.929 + }
33.930 + }
33.931 + catch (Exception e) {
33.932 + errorHandling("getLevelAt(-1) should not throw an exception.");
33.933 + }
33.934 + }
33.935 +
33.936 + private void testMethod_getRunLevel() {
33.937 + System.out.println("*** Test getRunLevel()");
33.938 +
33.939 + String str = "ABC 123";
33.940 + int length = str.length();
33.941 + Bidi bidi = new Bidi(str, Bidi.DIRECTION_LEFT_TO_RIGHT);
33.942 +
33.943 + try {
33.944 + if (bidi.getRunLevel(-1) != 0 || // runCount - 2
33.945 + bidi.getRunLevel(0) != 0 || // runCount - 1
33.946 + bidi.getRunLevel(1) != 0 || // runCount
33.947 + bidi.getRunLevel(2) != 0) { // runCount + 1
33.948 + errorHandling("getRunLevel() should return 0" +
33.949 + " when getRunCount() is 1.");
33.950 + }
33.951 + }
33.952 + catch (Exception e) {
33.953 + errorHandling("getRunLevel() should not throw an exception " +
33.954 + "when getRunCount() is 1.");
33.955 + }
33.956 +
33.957 + str = "ABC " + HebrewABC + " 123";
33.958 + length = str.length();
33.959 + bidi = new Bidi(str, Bidi.DIRECTION_LEFT_TO_RIGHT);
33.960 +
33.961 + try {
33.962 + bidi.getRunLevel(-1);
33.963 + errorHandling("getRunLevel() should throw an AIOoBE " +
33.964 + "when run is -1(too small).");
33.965 + }
33.966 + catch (ArrayIndexOutOfBoundsException e) {
33.967 + }
33.968 + catch (IllegalArgumentException e) {
33.969 + errorHandling("getRunLevel() should not throw an IAE " +
33.970 + "but an AIOoBE when run is -1(too small).");
33.971 + }
33.972 +
33.973 + try {
33.974 + bidi.getRunLevel(0);
33.975 + bidi.getRunLevel(1);
33.976 + bidi.getRunLevel(2);
33.977 + }
33.978 + catch (Exception e) {
33.979 + errorHandling("getRunLevel() should not throw an exception" +
33.980 + " when run is from 0 to 2(runCount-1).");
33.981 + }
33.982 +
33.983 + try {
33.984 + bidi.getRunLevel(3);
33.985 + errorHandling("getRunLevel() should throw an AIOoBE" +
33.986 + " when run is 3(same as runCount).");
33.987 + }
33.988 + catch (ArrayIndexOutOfBoundsException e) {
33.989 + }
33.990 + catch (IllegalArgumentException e) {
33.991 + errorHandling("getRunLevel() should not throw an IAE " +
33.992 + "but an AIOoBE when run is 3(same as runCount).");
33.993 + }
33.994 + }
33.995 +
33.996 + private void testMethod_getRunLimit() {
33.997 + System.out.println("*** Test getRunLimit()");
33.998 +
33.999 + String str = "ABC 123";
33.1000 + int length = str.length();
33.1001 + Bidi bidi = new Bidi(str, Bidi.DIRECTION_LEFT_TO_RIGHT);
33.1002 +
33.1003 + try {
33.1004 + if (bidi.getRunLimit(-1) != length || // runCount - 2
33.1005 + bidi.getRunLimit(0) != length || // runCount - 1
33.1006 + bidi.getRunLimit(1) != length || // runCount
33.1007 + bidi.getRunLimit(2) != length) { // runCount + 1
33.1008 + errorHandling("getRunLimit() should return " + length +
33.1009 + " when getRunCount() is 1.");
33.1010 + }
33.1011 + }
33.1012 + catch (Exception e) {
33.1013 + errorHandling("getRunLimit() should not throw an exception " +
33.1014 + "when getRunCount() is 1.");
33.1015 + }
33.1016 +
33.1017 + str = "ABC " + ArabicABC + " 123";
33.1018 + length = str.length();
33.1019 + bidi = new Bidi(str, Bidi.DIRECTION_LEFT_TO_RIGHT);
33.1020 +
33.1021 + try {
33.1022 + bidi.getRunLimit(-1);
33.1023 + errorHandling("getRunLimit() should throw an AIOoBE " +
33.1024 + "when run is -1(too small).");
33.1025 + }
33.1026 + catch (ArrayIndexOutOfBoundsException e) {
33.1027 + }
33.1028 + catch (IllegalArgumentException e) {
33.1029 + errorHandling("getRunLimit() should not throw an IAE " +
33.1030 + "but an AIOoBE when run is -1(too small).");
33.1031 + }
33.1032 +
33.1033 + try {
33.1034 + bidi.getRunLimit(0);
33.1035 + bidi.getRunLimit(1);
33.1036 + bidi.getRunLimit(2);
33.1037 + }
33.1038 + catch (ArrayIndexOutOfBoundsException e) {
33.1039 + errorHandling("getRunLimit() should not throw an AIOOBE " +
33.1040 + "when run is from 0 to 2(runCount-1).");
33.1041 + }
33.1042 +
33.1043 + try {
33.1044 + bidi.getRunLimit(3);
33.1045 + errorHandling("getRunLimit() should throw an AIOoBE " +
33.1046 + "when run is 3(same as runCount).");
33.1047 + }
33.1048 + catch (ArrayIndexOutOfBoundsException e) {
33.1049 + }
33.1050 + catch (IllegalArgumentException e) {
33.1051 + errorHandling("getRunLimit() should not throw an IAE " +
33.1052 + "but an AIOoBE when run is 3(same as runCount).");
33.1053 + }
33.1054 + }
33.1055 +
33.1056 + private void testMethod_getRunStart() {
33.1057 + System.out.println("*** Test getRunStart()");
33.1058 +
33.1059 + String str = "ABC 123";
33.1060 + int length = str.length();
33.1061 + Bidi bidi = new Bidi(str, Bidi.DIRECTION_LEFT_TO_RIGHT);
33.1062 +
33.1063 + try {
33.1064 + if (bidi.getRunStart(-1) != 0 || // runCount - 2
33.1065 + bidi.getRunStart(0) != 0 || // runCount - 1
33.1066 + bidi.getRunStart(1) != 0 || // runCount
33.1067 + bidi.getRunStart(2) != 0) { // runCount + 1
33.1068 + errorHandling("getRunStart() should return 0" +
33.1069 + " when getRunCount() is 1.");
33.1070 + }
33.1071 + }
33.1072 + catch (Exception e) {
33.1073 + errorHandling("getRunLimit() should not throw an exception" +
33.1074 + " when getRunCount() is 1.");
33.1075 + }
33.1076 +
33.1077 + str = "ABC " + NKoABC + " 123";
33.1078 + length = str.length();
33.1079 + bidi = new Bidi(str, Bidi.DIRECTION_LEFT_TO_RIGHT);
33.1080 +
33.1081 + try {
33.1082 + bidi.getRunStart(-1);
33.1083 + errorHandling("getRunStart() should throw an AIOoBE" +
33.1084 + " when run is -1(too small).");
33.1085 + }
33.1086 + catch (ArrayIndexOutOfBoundsException e) {
33.1087 + }
33.1088 + catch (IllegalArgumentException e) {
33.1089 + errorHandling("getRunStart() should not throw an IAE " +
33.1090 + "but an AIOoBE when run is -1(too small).");
33.1091 + }
33.1092 +
33.1093 + try {
33.1094 + bidi.getRunStart(0);
33.1095 + bidi.getRunStart(1);
33.1096 + bidi.getRunStart(2);
33.1097 + }
33.1098 + catch (ArrayIndexOutOfBoundsException e) {
33.1099 + errorHandling("getRunStart() should not throw an AIOOBE " +
33.1100 + "when run is from 0 to 2(runCount-1).");
33.1101 + }
33.1102 +
33.1103 + try {
33.1104 + if (bidi.getRunStart(3) != length) {
33.1105 + errorHandling("getRunStart() should return " + length +
33.1106 + " when run is 3(same as runCount).");
33.1107 + }
33.1108 + }
33.1109 + catch (Exception e) {
33.1110 + errorHandling("getRunStart() should not throw an exception " +
33.1111 + "when run is 3(same as runCount).");
33.1112 + }
33.1113 +
33.1114 + try {
33.1115 + bidi.getRunStart(4);
33.1116 + errorHandling("getRunStart() should throw an AIOoBE " +
33.1117 + "when run is runCount+1(too large).");
33.1118 + }
33.1119 + catch (ArrayIndexOutOfBoundsException e) {
33.1120 + }
33.1121 + catch (IllegalArgumentException e) {
33.1122 + errorHandling("getRunStart() should not throw an IAE " +
33.1123 + "but an AIOoBE when run is runCount+1(too large).");
33.1124 + }
33.1125 + }
33.1126 +
33.1127 + private void testMethod_reorderVisually1() {
33.1128 + System.out.println("*** Test reorderVisually() 1");
33.1129 +
33.1130 + for (int textNo = 0; textNo < data4reorderVisually.length; textNo++) {
33.1131 + Object[] objects = data4reorderVisually[textNo][0];
33.1132 + byte[] levels = getLevels(data4reorderVisually[textNo]);
33.1133 + Object[] expectedObjects = data4reorderVisually[textNo][2];
33.1134 +
33.1135 + Bidi.reorderVisually(levels, 0, objects, 0, objects.length);
33.1136 +
33.1137 + checkResult("textNo=" + textNo + ": reorderVisually(levels=[" +
33.1138 + toString(levels) + "], objects=[" + toString(objects) + "])",
33.1139 + expectedObjects, objects);
33.1140 + }
33.1141 + }
33.1142 +
33.1143 + private void testMethod_reorderVisually2() {
33.1144 + System.out.println("*** Test reorderVisually() 2");
33.1145 +
33.1146 + Object[] objects = data4reorderVisually[0][0];
33.1147 + byte[] levels = getLevels(data4reorderVisually[0]);
33.1148 + int count = objects.length;
33.1149 + int llen = levels.length;
33.1150 + int olen = objects.length;
33.1151 +
33.1152 + try {
33.1153 + Bidi.reorderVisually(null, 0, objects, 0, count);
33.1154 + errorHandling("reorderVisually() should throw a NPE " +
33.1155 + "when levels is null.");
33.1156 + }
33.1157 + catch (NullPointerException e) {
33.1158 + }
33.1159 +
33.1160 + try {
33.1161 + Bidi.reorderVisually(levels, -1, objects, 0, count);
33.1162 + errorHandling("reorderVisually() should throw an IAE " +
33.1163 + "when levelStart is -1.");
33.1164 + }
33.1165 + catch (IllegalArgumentException e) {
33.1166 + }
33.1167 + catch (ArrayIndexOutOfBoundsException e) {
33.1168 + errorHandling("reorderVisually() should not throw an AIOoBE " +
33.1169 + "but an IAE when levelStart is -1.");
33.1170 + }
33.1171 +
33.1172 + try {
33.1173 + Bidi.reorderVisually(levels, llen, objects, 0, count);
33.1174 + errorHandling("reorderVisually() should throw an IAE " +
33.1175 + "when levelStart is 6(levels.length).");
33.1176 + }
33.1177 + catch (IllegalArgumentException e) {
33.1178 + }
33.1179 + catch (ArrayIndexOutOfBoundsException e) {
33.1180 + errorHandling("reorderVisually() should not throw an AIOoBE " +
33.1181 + "but an IAE when levelStart is 6(levels.length).");
33.1182 + }
33.1183 +
33.1184 + try {
33.1185 + Bidi.reorderVisually(levels, 0, null, 0, count);
33.1186 + errorHandling("reorderVisually() should throw a NPE" +
33.1187 + " when objects is null.");
33.1188 + }
33.1189 + catch (NullPointerException e) {
33.1190 + }
33.1191 +
33.1192 + try {
33.1193 + Bidi.reorderVisually(levels, 0, objects, -1, count);
33.1194 + errorHandling("reorderVisually() should throw an IAE" +
33.1195 + " when objectStart is -1.");
33.1196 + }
33.1197 + catch (IllegalArgumentException e) {
33.1198 + }
33.1199 + catch (ArrayIndexOutOfBoundsException e) {
33.1200 + errorHandling("reorderVisually() should not throw an AIOoBE " +
33.1201 + "but an IAE when objectStart is -1.");
33.1202 + }
33.1203 +
33.1204 + try {
33.1205 + Bidi.reorderVisually(levels, 0, objects, 6, objects.length);
33.1206 + errorHandling("reorderVisually() should throw an IAE " +
33.1207 + "when objectStart is 6(objects.length).");
33.1208 + }
33.1209 + catch (IllegalArgumentException e) {
33.1210 + }
33.1211 +
33.1212 + try {
33.1213 + Bidi.reorderVisually(levels, 0, objects, 0, -1);
33.1214 + errorHandling("reorderVisually() should throw an IAE " +
33.1215 + "when count is -1.");
33.1216 + }
33.1217 + catch (IllegalArgumentException e) {
33.1218 + }
33.1219 + catch (NegativeArraySizeException e) {
33.1220 + errorHandling("reorderVisually() should not throw an NASE " +
33.1221 + "but an IAE when count is -1.");
33.1222 + }
33.1223 +
33.1224 + try {
33.1225 + Bidi.reorderVisually(levels, 0, objects, 0, count+1);
33.1226 + errorHandling("reorderVisually() should throw an IAE " +
33.1227 + "when count is 7(objects.length+1).");
33.1228 + }
33.1229 + catch (IllegalArgumentException e) {
33.1230 + }
33.1231 + catch (ArrayIndexOutOfBoundsException e) {
33.1232 + errorHandling("reorderVisually() should not throw an AIOoBE " +
33.1233 + "but an IAE when count is 7(objects.length+1).");
33.1234 + }
33.1235 +
33.1236 + try {
33.1237 + Bidi.reorderVisually(levels, 0, objects, 0, 0);
33.1238 + checkResult("reorderVisually(count=0)",
33.1239 + data4reorderVisually[0][0], objects);
33.1240 + }
33.1241 + catch (Exception e) {
33.1242 + errorHandling("reorderVisually() should not throw an exception" +
33.1243 + " when count is 0.");
33.1244 + }
33.1245 + }
33.1246 +
33.1247 + private void testMethod_requiresBidi() {
33.1248 + System.out.println("*** Test requiresBidi()");
33.1249 +
33.1250 + String paragraph;
33.1251 + char[] text;
33.1252 + Bidi bidi;
33.1253 +
33.1254 + for (int textNo = 0; textNo < data4Constructor2.length; textNo++) {
33.1255 + paragraph = data4Constructor2[textNo][0];
33.1256 + text = paragraph.toCharArray();
33.1257 + boolean rBidi = Bidi.requiresBidi(text, 0, text.length);
33.1258 + if (rBidi != requiresBidi4Constructor2[textNo]) {
33.1259 + error = true;
33.1260 + System.err.println("Unexpected requiresBidi() value" +
33.1261 + " for requiresBidi(\"" + paragraph + "\", " + 0 + ", " +
33.1262 + text.length + ")." +
33.1263 + "\n Expected: " + requiresBidi4Constructor2[textNo] +
33.1264 + "\n Got : " + rBidi);
33.1265 + } else if (verbose) {
33.1266 + System.out.println(" Okay : requiresBidi() for" +
33.1267 + " requiresBidi(\"" + paragraph + "\", " + 0 + ", " +
33.1268 + text.length + ") Got: " + rBidi);
33.1269 + }
33.1270 + }
33.1271 +
33.1272 + char[] txt = {'A', 'B', 'C', 'D', 'E'};
33.1273 + int textLength = txt.length;
33.1274 +
33.1275 + try {
33.1276 + Bidi.requiresBidi(txt, -1, textLength);
33.1277 + errorHandling("requiresBidi() should throw an IAE" +
33.1278 + " when start is -1(too small).");
33.1279 + }
33.1280 + catch (IllegalArgumentException e) {
33.1281 + }
33.1282 + catch (ArrayIndexOutOfBoundsException e) {
33.1283 + errorHandling("requiresBidi() should not throw an AIOoBE " +
33.1284 + "but an IAE when start is -1(too small).");
33.1285 + }
33.1286 +
33.1287 + try {
33.1288 + Bidi.requiresBidi(txt, textLength, textLength);
33.1289 + }
33.1290 + catch (Exception e) {
33.1291 + errorHandling("requiresBidi() should not throw an exception " +
33.1292 + "when start is textLength.");
33.1293 + }
33.1294 +
33.1295 + try {
33.1296 + Bidi.requiresBidi(txt, textLength+1, textLength);
33.1297 + errorHandling("requiresBidi() should throw an IAE" +
33.1298 + " when start is textLength+1(too large).");
33.1299 + }
33.1300 + catch (IllegalArgumentException e) {
33.1301 + }
33.1302 +
33.1303 + try {
33.1304 + Bidi.requiresBidi(txt, 0, -1);
33.1305 + errorHandling("requiresBidi() should throw an IAE" +
33.1306 + " when limit is -1(too small).");
33.1307 + }
33.1308 + catch (IllegalArgumentException e) {
33.1309 + }
33.1310 +
33.1311 + try {
33.1312 + Bidi.requiresBidi(txt, 0, textLength+1);
33.1313 + errorHandling("requiresBidi() should throw an IAE" +
33.1314 + " when limit is textLength+1(too large).");
33.1315 + }
33.1316 + catch (IllegalArgumentException e) {
33.1317 + }
33.1318 + catch (ArrayIndexOutOfBoundsException e) {
33.1319 + errorHandling("requiresBidi() should not throw an AIOoBE " +
33.1320 + "but an IAE when limit is textLength+1(too large).");
33.1321 + }
33.1322 + }
33.1323 +
33.1324 + private void checkResult(String name,
33.1325 + int expectedValue,
33.1326 + int actualValue) {
33.1327 + if (expectedValue != actualValue) {
33.1328 + errorHandling("Unexpected " + name + " value." +
33.1329 + " Expected: " + expectedValue + " Got: " + actualValue);
33.1330 + } else if (verbose) {
33.1331 + System.out.println(" Okay : " + name + " = " + actualValue);
33.1332 + }
33.1333 + }
33.1334 +
33.1335 + private void checkResult(String name,
33.1336 + boolean expectedValue,
33.1337 + boolean actualValue) {
33.1338 + if (expectedValue != actualValue) {
33.1339 + errorHandling("Unexpected " + name + " value." +
33.1340 + " Expected: " + expectedValue + " Got: " + actualValue);
33.1341 + } else if (verbose) {
33.1342 + System.out.println(" Okay : " + name + " = " + actualValue);
33.1343 + }
33.1344 + }
33.1345 +
33.1346 + private void checkResult(String name,
33.1347 + String expectedValue,
33.1348 + String actualValue) {
33.1349 + if (!expectedValue.equals(actualValue)) {
33.1350 + errorHandling("Unexpected " + name + " value." +
33.1351 + "\n\tExpected: \"" + expectedValue + "\"" +
33.1352 + "\n\tGot: \"" + actualValue + "\"");
33.1353 + } else if (verbose) {
33.1354 + System.out.println(" Okay : " + name + " = \"" +
33.1355 + actualValue + "\"");
33.1356 + }
33.1357 + }
33.1358 +
33.1359 + private void checkResult(String name,
33.1360 + int[] expectedValues,
33.1361 + int[] actualValues) {
33.1362 + if (!Arrays.equals(expectedValues, actualValues)) {
33.1363 + errorHandling("Unexpected " + name + " value." +
33.1364 + "\n\tExpected: " + toString(expectedValues) + "" +
33.1365 + "\n\tGot: " + toString(actualValues) + "");
33.1366 + } else if (verbose) {
33.1367 + System.out.println(" Okay : " + name + " = " +
33.1368 + toString(actualValues));
33.1369 + }
33.1370 + }
33.1371 +
33.1372 + private void checkResult(String name,
33.1373 + Object[] expectedValues,
33.1374 + Object[] actualValues) {
33.1375 + if (!Arrays.equals(expectedValues, actualValues)) {
33.1376 + errorHandling("Unexpected " + name + " value." +
33.1377 + "\n\tExpected: [" + toString(expectedValues) +
33.1378 + "]\n\tGot: [" + toString(actualValues) + "]");
33.1379 + } else if (verbose) {
33.1380 + System.out.println(" Okay : " + name + " Reordered objects = [" +
33.1381 + toString(actualValues) + "]");
33.1382 + }
33.1383 + }
33.1384 +
33.1385 + private void errorHandling(String msg) {
33.1386 + if (abort) {
33.1387 + throw new RuntimeException("Error: " + msg);
33.1388 + } else {
33.1389 + error = true;
33.1390 + System.err.println("**Error:" + msg);
33.1391 + }
33.1392 + }
33.1393 +
33.1394 + private String toString(int[] values) {
33.1395 + StringBuilder sb = new StringBuilder();
33.1396 + for (int i = 0; i < values.length-1; i++) {
33.1397 + sb.append((int)values[i]);
33.1398 + sb.append(' ');
33.1399 + }
33.1400 + sb.append((int)values[values.length-1]);
33.1401 +
33.1402 + return sb.toString();
33.1403 + }
33.1404 +
33.1405 + private String toString(byte[] values) {
33.1406 + StringBuilder sb = new StringBuilder();
33.1407 + for (int i = 0; i < values.length-1; i++) {
33.1408 + sb.append((byte)values[i]);
33.1409 + sb.append(' ');
33.1410 + }
33.1411 + sb.append((byte)values[values.length-1]);
33.1412 +
33.1413 + return sb.toString();
33.1414 + }
33.1415 +
33.1416 + private String toString(Object[] values) {
33.1417 + StringBuilder sb = new StringBuilder();
33.1418 + String name;
33.1419 +
33.1420 + for (int i = 0; i < values.length-1; i++) {
33.1421 + if ((name = getStringName((String)values[i])) != null) {
33.1422 + sb.append(name);
33.1423 + sb.append(", ");
33.1424 + } else {
33.1425 + sb.append('"');
33.1426 + sb.append((String)values[i]);
33.1427 + sb.append("\", ");
33.1428 + }
33.1429 + }
33.1430 + if ((name = getStringName((String)values[values.length-1])) != null) {
33.1431 + sb.append(name);
33.1432 + } else {
33.1433 + sb.append('"');
33.1434 + sb.append((String)values[values.length-1]);
33.1435 + sb.append('\"');
33.1436 + }
33.1437 +
33.1438 + return sb.toString();
33.1439 + }
33.1440 +
33.1441 + private String getStringName(String str) {
33.1442 + if (ArabicABC.equals(str)) return "ArabicABC";
33.1443 + else if (Arabic123.equals(str)) return "Arabic123";
33.1444 + else if (PArabicABC.equals(str)) return "ArabicABC(Presentation form)";
33.1445 + else if (HebrewABC.equals(str)) return "HebrewABC";
33.1446 + else if (KharoshthiABC.equals(str)) return "KharoshthiABC(RTL)";
33.1447 + else if (Kharoshthi123.equals(str)) return "Kharoshthi123(RTL)";
33.1448 + else if (NKoABC.equals(str)) return "NKoABC(RTL)";
33.1449 + else if (NKo123.equals(str)) return "NKo123(RTL)";
33.1450 + else if (OsmanyaABC.equals(str)) return "OsmanyaABC(LTR)";
33.1451 + else if (Osmanya123.equals(str)) return "Osmanya123(LTR)";
33.1452 + else return null;
33.1453 + }
33.1454 +
33.1455 + private String getFlagName(int flag) {
33.1456 + if (flag == -2 || flag == 0x7e) return FLAGNAMES[0];
33.1457 + else if (flag == -1 || flag == 0x7f) return FLAGNAMES[1];
33.1458 + else if (flag == 0) return FLAGNAMES[2];
33.1459 + else if (flag == 1) return FLAGNAMES[3];
33.1460 + else return "Unknown(0x" + Integer.toHexString(flag) + ")";
33.1461 + }
33.1462 +
33.1463 + private String toReadableString(String str) {
33.1464 + String s = str;
33.1465 +
33.1466 + s = s.replaceAll(ArabicABC, "ArabicABC");
33.1467 + s = s.replaceAll(Arabic123, "Arabic123");
33.1468 + s = s.replaceAll(PArabicABC, "ArabicABC(Presentation form)");
33.1469 + s = s.replaceAll(HebrewABC, "HebrewABC");
33.1470 + s = s.replaceAll(KharoshthiABC, "KharoshthiABC");
33.1471 + s = s.replaceAll(Kharoshthi123, "Kharoshthi123");
33.1472 + s = s.replaceAll(NKoABC, "NKoABC");
33.1473 + s = s.replaceAll(NKo123, "NKo123");
33.1474 + s = s.replaceAll(OsmanyaABC, "OsmanyaABC");
33.1475 + s = s.replaceAll(Osmanya123, "Osmanya123");
33.1476 +
33.1477 + return s;
33.1478 + }
33.1479 +
33.1480 + private byte[] getLevels(Object[][] data) {
33.1481 + int levelLength = data[0].length;
33.1482 + byte[] array = new byte[levelLength];
33.1483 + int textIndex = 0;
33.1484 +
33.1485 + for (int i = 0; i < levelLength; i++) {
33.1486 + array[i] = (byte)(((String)data[1][0]).charAt(textIndex) - '0');
33.1487 + textIndex += ((String)data[0][i]).length();
33.1488 + }
33.1489 +
33.1490 + return array;
33.1491 + }
33.1492 +
33.1493 +
33.1494 + /* Bidi pubilc constants */
33.1495 + private static final int[] FLAGS = {
33.1496 + Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT, // -2 (0x7e in ICU4J)
33.1497 + Bidi.DIRECTION_DEFAULT_RIGHT_TO_LEFT, // -1 (0x7f in ICU4J)
33.1498 + Bidi.DIRECTION_LEFT_TO_RIGHT, // 0
33.1499 + Bidi.DIRECTION_RIGHT_TO_LEFT // 1
33.1500 + };
33.1501 +
33.1502 + /* Bidi pubilc constants names */
33.1503 + private static final String[] FLAGNAMES = {
33.1504 + "DIRECTION_DEFAULT_LEFT_TO_RIGHT", // -2
33.1505 + "DIRECTION_DEFAULT_RIGHT_TO_LEFT", // -1
33.1506 + "DIRECTION_LEFT_TO_RIGHT", // 0
33.1507 + "DIRECTION_RIGHT_TO_LEFT", // 1
33.1508 + };
33.1509 +
33.1510 + /* Bidirectional Character Types */
33.1511 + private static final char L = '\u200E';
33.1512 + private static final char R = '\u202F';
33.1513 + private static final char LRE = '\u202A';
33.1514 + private static final char RLE = '\u202B';
33.1515 + private static final char PDF = '\u202C';
33.1516 + private static final char LRO = '\u202D';
33.1517 + private static final char RLO = '\u202E';
33.1518 +
33.1519 + /*
33.1520 + * 0x05D0-0x05EA: [R] Hewbrew letters (Strong)
33.1521 + * 0x0627-0x063A: [AL] Arabic letters (Strong)
33.1522 + * 0x0660-0x0669: [AN] Arabic-Indic digits (Weak)
33.1523 + * 0x07CA-0x07E7: [R] NKo letters (Strong)
33.1524 + * 0x07C0-0x07C9: [R] NKo digits (Strong)
33.1525 + * 0xFE50-0xFEFF: [AL] Arabic presentaion form (Strong)
33.1526 + * 0x10480-0x1049D: [L] Osmanya letters (Strong)
33.1527 + * 0x104A0-0x104A9: [L] Osmanya digits (Strong)
33.1528 + * 0x10A10-0x10A33: [R] Kharoshthi letters (Strong)
33.1529 + * 0x10A40-0x10A43: [R] Kharoshthi digits (Strong)
33.1530 + *
33.1531 + * 0x200E: [L] Left-to-right mark (Implicit, Strong)
33.1532 + * 0x200F: [R] Right-to-left mark (Implicit, Strong)
33.1533 + * 0x202A: [LRE] Left-to-right embedding (Explicit, Strong)
33.1534 + * 0x202B: [RLE] Right-to-left embedding (Explicit, Strong)
33.1535 + * 0x202C: [PDF] Pop directional formatting (Explicit, Weak)
33.1536 + * 0x202D: [LRO] Left-to-right override (Explicit, Strong)
33.1537 + * 0x202E: [RLO] Right-to-left override (Explicit, Strong)
33.1538 + */
33.1539 +
33.1540 + /* Right-to-left */
33.1541 + private static String ArabicABC = "\u0627\u0628\u0629";
33.1542 + private static String Arabic123 = "\u0661\u0662\u0663";
33.1543 + private static String PArabicABC = "\uFE97\uFE92\uFE8E";
33.1544 + private static String HebrewABC = "\u05D0\u05D1\u05D2";
33.1545 + private static String KharoshthiABC =
33.1546 + new String(Character.toChars(0x10A10)) +
33.1547 + new String(Character.toChars(0x10A11)) +
33.1548 + new String(Character.toChars(0x10A12));
33.1549 + private static String Kharoshthi123 =
33.1550 + new String(Character.toChars(0x10A40)) +
33.1551 + new String(Character.toChars(0x10A41)) +
33.1552 + new String(Character.toChars(0x10A42));
33.1553 + private static String NKoABC = "\u07CA\u07CB\u07CC";
33.1554 + private static String NKo123 = "\u07C1\u07C2\u07C3";
33.1555 +
33.1556 + /* Left-to-right */
33.1557 + private static String OsmanyaABC =
33.1558 + new String(Character.toChars(0x10480)) +
33.1559 + new String(Character.toChars(0x10481)) +
33.1560 + new String(Character.toChars(0x10482));
33.1561 + private static String Osmanya123 =
33.1562 + new String(Character.toChars(0x104A0)) +
33.1563 + new String(Character.toChars(0x104A1)) +
33.1564 + new String(Character.toChars(0x104A2));
33.1565 +
33.1566 + /* --------------------------------------------------------------------- */
33.1567 +
33.1568 + /*
33.1569 + * Test data for Bidi(char[], ...) constructor and methods
33.1570 + */
33.1571 +
33.1572 + /* Text for Bidi processing and its levels */
33.1573 + private static String[][] data4Constructor1 = {
33.1574 + /* For Text #0 */
33.1575 + {"abc <ABC XYZ> xyz.",
33.1576 + "000000000000000000", "000002222222000000", "000000000000000000",
33.1577 + "000003333333000000", "000000000000000000",
33.1578 + "222222222222222221", "222222222222222221", "222222222222222221",
33.1579 + "222113333333112221", "222224444444222221",
33.1580 + "000000000000000000", "000000000000000000", "222222222222222221"},
33.1581 +
33.1582 + /* For Text #1 */
33.1583 + {"ABC <" + HebrewABC + " " + NKo123 + "> XYZ.",
33.1584 + "000001111111000000", "000001111111000000", "000003333333000000",
33.1585 + "000003333333000000", "000000000000000000",
33.1586 + "222111111111112221", "222111111111112221", "222223333333222221",
33.1587 + "222113333333112221", "222224444444222221",
33.1588 + "000001111111000000", "000001111111000000", "222111111111112221"},
33.1589 +
33.1590 + /* For Text #2 */
33.1591 + {NKoABC + " <ABC XYZ> " + NKo123 + ".",
33.1592 + "111000000000001110", "111112222222111110", "111002222222001110",
33.1593 + "111113333333111110", "111004444444001110",
33.1594 + "111112222222111111", "111112222222111111", "111112222222111111",
33.1595 + "111111111111111111", "111114444444111111",
33.1596 + "111112222222111111", "111000000000001110", "111112222222111111"},
33.1597 +
33.1598 + /* For Text #3 */
33.1599 + {HebrewABC + " <" + ArabicABC + " " + Arabic123 + "> " + NKo123 + ".",
33.1600 + "111111111222111110", "111111111222111110", "111003333444001110",
33.1601 + "111113333333111110", "111004444444001110",
33.1602 + "111111111222111111", "111111111222111111", "111113333444111111",
33.1603 + "111111111111111111", "111114444444111111",
33.1604 + "111111111222111111", "111111111222111110", "111111111222111111"},
33.1605 +
33.1606 + /* For Text #4 */
33.1607 + {"abc <" + NKoABC + " 123> xyz.",
33.1608 + "000001111222000000", "000001111222000000", "000003333444000000",
33.1609 + "000003333333000000", "000000000000000000",
33.1610 + "222111111222112221", "222111111222112221", "222223333444222221",
33.1611 + "222113333333112221", "222224444444222221",
33.1612 + "000001111222000000", "000001111222000000", "222111111222112221"},
33.1613 +
33.1614 + /* For Text #5 */
33.1615 + {"abc <ABC " + NKo123 + "> xyz.",
33.1616 + "000000000111000000", "000002221111000000", "000002222333000000",
33.1617 + "000003333333000000", "000000000000000000",
33.1618 + "222222221111112221", "222222221111112221", "222222222333222221",
33.1619 + "222113333333112221", "222224444444222221",
33.1620 + "000000000111000000", "000000000111000000", "222222221111112221"},
33.1621 +
33.1622 + /* For Text #6 */
33.1623 + {ArabicABC + " <" + NKoABC + " 123" + "> " + Arabic123 + ".",
33.1624 + "111111111222112220", "111111111222112220", "111003333444002220",
33.1625 + "111113333333112220", "111004444444002220",
33.1626 + "111111111222112221", "111111111222112221", "111113333444112221",
33.1627 + "111113333333112221", "111114444444112221",
33.1628 + "111111111222112221", "111111111222112220", "111111111222112221"},
33.1629 +
33.1630 + /* For Text #7 */
33.1631 + {ArabicABC + " <XYZ " + NKoABC + "> " + Arabic123 + ".",
33.1632 + "111000000111112220", "111112221111112220", "111002222333002220",
33.1633 + "111113333333112220", "111004444444002220",
33.1634 + "111112221111112221", "111112221111112221", "111112222333112221",
33.1635 + "111113333333112221", "111114444444112221",
33.1636 + "111112221111112221", "111000000111112220", "111112221111112221"},
33.1637 +
33.1638 + /* For Text #8 */
33.1639 + {OsmanyaABC + " <" + KharoshthiABC + " " + Kharoshthi123 + "> " +
33.1640 + Osmanya123 + ".",
33.1641 + "000000001111111111111000000000", "000000001111111111111000000000",
33.1642 + "000000003333333333333000000000", "000000003333333333333000000000",
33.1643 + "000000000000000000000000000000",
33.1644 + "222222111111111111111112222221", "222222111111111111111112222221",
33.1645 + "222222223333333333333222222221", "222222113333333333333112222221",
33.1646 + "222222224444444444444222222221",
33.1647 + "000000001111111111111000000000", "000000001111111111111000000000",
33.1648 + "222222111111111111111112222221"},
33.1649 +
33.1650 + /* For Text #9 */
33.1651 + {KharoshthiABC + " <" + OsmanyaABC + " " + Osmanya123 + "> " +
33.1652 + Kharoshthi123 + ".",
33.1653 + "111111000000000000000001111110", "111111112222222222222111111110",
33.1654 + "111111002222222222222001111110", "111111113333333333333111111110",
33.1655 + "111111004444444444444001111110",
33.1656 + "111111112222222222222111111111", "111111112222222222222111111111",
33.1657 + "111111112222222222222111111111", "111111111111111111111111111111",
33.1658 + "111111114444444444444111111111",
33.1659 + "111111112222222222222111111111", "111111000000000000000001111110",
33.1660 + "111111112222222222222111111111"},
33.1661 + };
33.1662 +
33.1663 + /* Golden data for baseIsLeftToRight() results */
33.1664 + private static boolean[][] baseIsLTR4Constructor1 = {
33.1665 + /* For Text #0 */
33.1666 + {true, true, true, true, true,
33.1667 + false, false, false, false, false,
33.1668 + true, true, false},
33.1669 +
33.1670 + /* For Text #1 */
33.1671 + {true, true, true, true, true,
33.1672 + false, false, false, false, false,
33.1673 + true, true, false},
33.1674 +
33.1675 + /* For Text #2 */
33.1676 + {true, true, true, true, true,
33.1677 + false, false, false, false, false,
33.1678 + false, true, false},
33.1679 +
33.1680 + /* For Text #3 */
33.1681 + {true, true, true, true, true,
33.1682 + false, false, false, false, false,
33.1683 + false, true, false},
33.1684 +
33.1685 + /* For Text #4 */
33.1686 + {true, true, true, true, true,
33.1687 + false, false, false, false, false,
33.1688 + true, true, false},
33.1689 +
33.1690 + /* For Text #5 */
33.1691 + {true, true, true, true, true,
33.1692 + false, false, false, false, false,
33.1693 + true, true, false},
33.1694 +
33.1695 + /* For Text #6 */
33.1696 + {true, true, true, true, true,
33.1697 + false, false, false, false, false,
33.1698 + false, true, false},
33.1699 +
33.1700 + /* For Text #7 */
33.1701 + {true, true, true, true, true,
33.1702 + false, false, false, false, false,
33.1703 + false, true, false},
33.1704 +
33.1705 + /* For Text #8 */
33.1706 + {true, true, true, true, true,
33.1707 + false, false, false, false, false,
33.1708 + true, true, false},
33.1709 +
33.1710 + /* For Text #9 */
33.1711 + {true, true, true, true, true,
33.1712 + false, false, false, false, false,
33.1713 + false, true, false},
33.1714 + };
33.1715 +
33.1716 + /* Golden data for isLeftToRight() & isRightToLeft() results */
33.1717 + private static boolean[][][] isLTR_isRTL4Constructor1 = {
33.1718 + /* For Text #0 */
33.1719 + /* isLeftToRight() results */
33.1720 + {{true, false, true, false, true,
33.1721 + false, false, false, false, false,
33.1722 + true, true, false},
33.1723 + /* isRightToLeft() results */
33.1724 + {false, false, false, false, false,
33.1725 + false, false, false, false, false,
33.1726 + false, false, false}},
33.1727 +
33.1728 + /* For Text #1 */
33.1729 + /* isLeftToRight() results */
33.1730 + {{false, false, false, false, true,
33.1731 + false, false, false, false, false,
33.1732 + false, false, false},
33.1733 + /* isRightToLeft() results */
33.1734 + {false, false, false, false, false,
33.1735 + false, false, false, false, false,
33.1736 + false, false, false}},
33.1737 +
33.1738 + /* For Text #2 */
33.1739 + /* isLeftToRight() results */
33.1740 + {{false, false, false, false, false,
33.1741 + false, false, false, false, false,
33.1742 + false, false, false},
33.1743 + /* isRightToLeft() results */
33.1744 + {false, false, false, false, false,
33.1745 + false, false, false, true, false,
33.1746 + false, false, false}},
33.1747 +
33.1748 + /* For Text #3 */
33.1749 + /* isLeftToRight() results */
33.1750 + {{false, false, false, false, false,
33.1751 + false, false, false, false, false,
33.1752 + false, false, false},
33.1753 + /* isRightToLeft() results */
33.1754 + {false, false, false, false, false,
33.1755 + false, false, false, true, false,
33.1756 + false, false, false}},
33.1757 +
33.1758 + /* For Text #4 */
33.1759 + /* isLeftToRight() results */
33.1760 + {{false, false, false, false, true,
33.1761 + false, false, false, false, false,
33.1762 + false, false, false},
33.1763 + /* isRightToLeft() results */
33.1764 + {false, false, false, false, false,
33.1765 + false, false, false, false, false,
33.1766 + false, false, false}},
33.1767 +
33.1768 + /* For Text #5 */
33.1769 + /* isLeftToRight() results */
33.1770 + {{false, false, false, false, true,
33.1771 + false, false, false, false, false,
33.1772 + false, false, false},
33.1773 + /* isRightToLeft() results */
33.1774 + {false, false, false, false, false,
33.1775 + false, false, false, false, false,
33.1776 + false, false, false}},
33.1777 +
33.1778 + /* For Text #6 */
33.1779 + /* isLeftToRight() results */
33.1780 + {{false, false, false, false, false,
33.1781 + false, false, false, false, false,
33.1782 + false, false, false},
33.1783 + /* isRightToLeft() results */
33.1784 + {false, false, false, false, false,
33.1785 + false, false, false, false, false,
33.1786 + false, false, false}},
33.1787 +
33.1788 + /* For Text #7 */
33.1789 + /* isLeftToRight() results */
33.1790 + {{false, false, false, false, false,
33.1791 + false, false, false, false, false,
33.1792 + false, false, false},
33.1793 + /* isRightToLeft() results */
33.1794 + {false, false, false, false, false,
33.1795 + false, false, false, false, false,
33.1796 + false, false, false}},
33.1797 +
33.1798 + /* For Text #8 */
33.1799 + /* isLeftToRight() results */
33.1800 + {{false, false, false, false, true,
33.1801 + false, false, false, false, false,
33.1802 + false, false, false},
33.1803 + /* isRightToLeft() results */
33.1804 + {false, false, false, false, false,
33.1805 + false, false, false, false, false,
33.1806 + false, false, false}},
33.1807 +
33.1808 + /* For Text #9 */
33.1809 + /* isLeftToRight() results */
33.1810 + {{false, false, false, false, false,
33.1811 + false, false, false, false, false,
33.1812 + false, false, false},
33.1813 + /* isRightToLeft() results */
33.1814 + {false, false, false, false, false,
33.1815 + false, false, false, true, false,
33.1816 + false, false, false}},
33.1817 + };
33.1818 +
33.1819 + /* --------------------------------------------------------------------- */
33.1820 +
33.1821 + /*
33.1822 + * Test data for Bidi(String, int) constructor and methods
33.1823 + */
33.1824 +
33.1825 + /* Text for Bidi processing and its levels */
33.1826 + private static String[][] data4Constructor2 = {
33.1827 + /* For Text #0 */
33.1828 + {" ABC 123.",
33.1829 + "000000000", "000000000", "000000000", "122222221"},
33.1830 +
33.1831 + /* For Text #1 */
33.1832 + {" ABC " + HebrewABC + " " + NKo123 + " 123.",
33.1833 + "00000111111112220", "00000111111112220", "00000111111112220",
33.1834 + "12221111111112221"},
33.1835 +
33.1836 + /* For Text #2 */
33.1837 + {" ABC " + ArabicABC + " " + Arabic123 + " 123.",
33.1838 + "00000111122212220", "00000111122212220", "00000111122212220",
33.1839 + "12221111122212221"},
33.1840 +
33.1841 + /* For Text #3 */
33.1842 + {" " + NKoABC + " ABC 123 " + NKo123 + ".",
33.1843 + "11111222222211111", "11111222222211111", "01110000000001110",
33.1844 + "11111222222211111"},
33.1845 +
33.1846 + /* For Text #4 */
33.1847 + {" " + ArabicABC + " ABC 123 " + Arabic123 + ".",
33.1848 + "11111222222212221", "11111222222212221", "01110000000002220",
33.1849 + "11111222222212221"},
33.1850 +
33.1851 + /* For Text #5 */
33.1852 + {" " + HebrewABC + " " + NKo123 + ".",
33.1853 + "111111111", "111111111", "011111110", "111111111"},
33.1854 +
33.1855 + /* For Text #6 */
33.1856 + {" " + ArabicABC + " " + Arabic123 + ".",
33.1857 + "111112221", "111112221", "011112220", "111112221"},
33.1858 +
33.1859 + /* For Text #7 */
33.1860 + {" " + KharoshthiABC + " " + Kharoshthi123 + ".",
33.1861 + "111111111111111", "111111111111111", "011111111111110",
33.1862 + "111111111111111"},
33.1863 +
33.1864 + /* For Text #8 */
33.1865 + {L + HebrewABC + " " + NKo123 + ".",
33.1866 + "011111110", "011111110", "011111110", "211111111"},
33.1867 +
33.1868 + /* For Text #9 */
33.1869 + {R + "ABC " + Osmanya123 + ".",
33.1870 + "000000000000", "000000000000", "000000000000", "122222222221"},
33.1871 +
33.1872 + /* For Text #10 */
33.1873 + {"ABC " + PArabicABC + " " + PArabicABC + " 123",
33.1874 + "000011111111222", "000011111111222", "000011111111222",
33.1875 + "222111111111222"},
33.1876 +
33.1877 + /* For Text #11 */
33.1878 + {RLE + "ABC " + HebrewABC + " " + NKo123 + "." + PDF,
33.1879 + "22221111111110", "22221111111110", "22221111111110",
33.1880 + "44443333333331"},
33.1881 +
33.1882 + /* For Text #12 */
33.1883 + {"He said \"" + RLE + "ABC " + HebrewABC + " " + NKo123 + PDF + ".\"",
33.1884 + "000000000222211111111000", "000000000222211111111000",
33.1885 + "000000000222211111111000", "222222211444433333333111"},
33.1886 +
33.1887 + /* For Text #13 */
33.1888 + {LRO + "He said \"" + RLE + "ABC " + NKoABC + " " + NKo123 + PDF +
33.1889 + ".\"" + PDF,
33.1890 + "22222222224444333333332220", "22222222224444333333332220",
33.1891 + "22222222224444333333332220", "22222222224444333333332221"},
33.1892 +
33.1893 + /* For Text #14 */
33.1894 + {LRO + "He said \"" + RLE + "ABC " + HebrewABC + " " + NKo123 + PDF +
33.1895 + ".\"", // PDF missing
33.1896 + "2222222222444433333333222", "2222222222444433333333222",
33.1897 + "2222222222444433333333222", "2222222222444433333333222"},
33.1898 +
33.1899 + /* For Text #15 */
33.1900 + {"Did you say '" + LRE + "he said \"" + RLE + "ABC " + HebrewABC +
33.1901 + " " + NKo123 + PDF + "\"" + PDF + "'?",
33.1902 + "0000000000000222222222244443333333322000",
33.1903 + "0000000000000222222222244443333333322000",
33.1904 + "0000000000000222222222244443333333322000",
33.1905 + "2222222222222222222222244443333333322111"},
33.1906 +
33.1907 + /* For Text #16 */
33.1908 + {RLO + "Did you say '" + LRE + "he said \"" + RLE + "ABC " +
33.1909 + HebrewABC + " " + NKo123 + PDF + "\"" + PDF + "'?" + PDF,
33.1910 + "111111111111112222222222444433333333221110",
33.1911 + "111111111111112222222222444433333333221110",
33.1912 + "111111111111112222222222444433333333221110",
33.1913 + "333333333333334444444444666655555555443331"},
33.1914 +
33.1915 + /* For Text #17 */
33.1916 + {RLO + "Did you say '" + LRE + "he said \"" + RLE + "ABC " +
33.1917 + HebrewABC + " " + NKo123 + PDF + "\"" + PDF + "'?", // PDF missing
33.1918 + "11111111111111222222222244443333333322111",
33.1919 + "11111111111111222222222244443333333322111",
33.1920 + "11111111111111222222222244443333333322111",
33.1921 + "33333333333333444444444466665555555544333"},
33.1922 +
33.1923 + /* For Text #18 */
33.1924 + {" ABC (" + ArabicABC + " " + Arabic123 + ") 123.",
33.1925 + "0000001111222112220", "0000001111222112220",
33.1926 + "0000001111222112220", "1222111111222112221"},
33.1927 +
33.1928 + /* For Text #19 */
33.1929 + {" " + HebrewABC + " (ABC 123) " + NKo123 + ".",
33.1930 + "1111112222222111111", "1111112222222111111",
33.1931 + "0111000000000001110", "1111112222222111111"},
33.1932 +
33.1933 + /* For Text #20 */
33.1934 + {" He said \"" + RLE + "ABC " + NKoABC + " " + NKo123 + PDF + ".\" ",
33.1935 + "00000000002222111111110000", "00000000002222111111110000",
33.1936 + "00000000002222111111110000", "12222222114444333333331111"},
33.1937 +
33.1938 + /* For Text #21 */
33.1939 + {" Did you say '" + LRE + "he said \"" + RLE + "ABC " + HebrewABC +
33.1940 + " " + NKo123 + PDF + "\"" + PDF + "'? ",
33.1941 + "000000000000002222222222444433333333220000",
33.1942 + "000000000000002222222222444433333333220000",
33.1943 + "000000000000002222222222444433333333220000",
33.1944 + "122222222222222222222222444433333333221111"},
33.1945 +
33.1946 + /* For Text #22 */
33.1947 + {RLE + OsmanyaABC + " " + KharoshthiABC + " " + Kharoshthi123 + "." +
33.1948 + PDF,
33.1949 + "22222221111111111111110", "22222221111111111111110",
33.1950 + "22222221111111111111110", "44444443333333333333331"},
33.1951 + };
33.1952 +
33.1953 + /* Golden data for baseIsLeftToRight() results */
33.1954 + private static boolean[][] baseIsLTR4Constructor2 = {
33.1955 + /* For Text #0 - $4 */
33.1956 + {true, true, true, false},
33.1957 + {true, true, true, false},
33.1958 + {true, true, true, false},
33.1959 + {false, false, true, false},
33.1960 + {false, false, true, false},
33.1961 +
33.1962 + /* For Text #5 - $9 */
33.1963 + {false, false, true, false},
33.1964 + {false, false, true, false},
33.1965 + {false, false, true, false},
33.1966 + {true, true, true, false},
33.1967 + {true, true, true, false},
33.1968 +
33.1969 + /* For Text #10 - $14 */
33.1970 + {true, true, true, false},
33.1971 + {true, true, true, false},
33.1972 + {true, true, true, false},
33.1973 + {true, true, true, false},
33.1974 + {true, true, true, false},
33.1975 +
33.1976 + /* For Text #15 - $19 */
33.1977 + {true, true, true, false},
33.1978 + {true, true, true, false},
33.1979 + {true, true, true, false},
33.1980 + {true, true, true, false},
33.1981 + {false, false, true, false},
33.1982 +
33.1983 + /* For Text #20 - $22 */
33.1984 + {true, true, true, false},
33.1985 + {true, true, true, false},
33.1986 + {true, true, true, false},
33.1987 + };
33.1988 +
33.1989 + /* Golden data for isLeftToRight() & isRightToLeft() results */
33.1990 + private static boolean[][][] isLTR_isRTL4Constructor2 = {
33.1991 + /* isLeftToRight() results & isRightToLeft() results */
33.1992 + /* For Text #0 - $4 */
33.1993 + {{true, true, true, false}, {false, false, false, false}},
33.1994 + {{false, false, false, false}, {false, false, false, false}},
33.1995 + {{false, false, false, false}, {false, false, false, false}},
33.1996 + {{false, false, false, false}, {false, false, false, false}},
33.1997 + {{false, false, false, false}, {false, false, false, false}},
33.1998 +
33.1999 + /* For Text #5 - $9 */
33.2000 + {{false, false, false, false}, {true, true, false, true }},
33.2001 + {{false, false, false, false}, {false, false, false, false}},
33.2002 + {{false, false, false, false}, {true, true, false, true }},
33.2003 + {{false, false, false, false}, {false, false, false, false}},
33.2004 + {{true, true, true, false}, {false, false, false, false}},
33.2005 +
33.2006 + /* For Text #10 - $14 */
33.2007 + {{false, false, false, false}, {false, false, false, false}},
33.2008 + {{false, false, false, false}, {false, false, false, false}},
33.2009 + {{false, false, false, false}, {false, false, false, false}},
33.2010 + {{false, false, false, false}, {false, false, false, false}},
33.2011 + {{false, false, false, false}, {false, false, false, false}},
33.2012 +
33.2013 + /* For Text #15 - $19 */
33.2014 + {{false, false, false, false}, {false, false, false, false}},
33.2015 + {{false, false, false, false}, {false, false, false, false}},
33.2016 + {{false, false, false, false}, {false, false, false, false}},
33.2017 + {{false, false, false, false}, {false, false, false, false}},
33.2018 + {{false, false, false, false}, {false, false, false, false}},
33.2019 +
33.2020 + /* For Text #20 - $22 */
33.2021 + {{false, false, false, false}, {false, false, false, false}},
33.2022 + {{false, false, false, false}, {false, false, false, false}},
33.2023 + {{false, false, false, false}, {false, false, false, false}},
33.2024 + };
33.2025 +
33.2026 + /* Golden data for requiresBidi() results */
33.2027 + private static boolean[] requiresBidi4Constructor2 = {
33.2028 + /* For Text #0 - $9 */
33.2029 + false, true, true, true, true,
33.2030 + true, true, true, true, false,
33.2031 +
33.2032 + /* For Text #10 - $19 */
33.2033 + true, true, true, true, true,
33.2034 + true, true, true, true, true,
33.2035 +
33.2036 + /* For Text #20 - $22 */
33.2037 + true, true, true,
33.2038 + };
33.2039 +
33.2040 + /* --------------------------------------------------------------------- */
33.2041 +
33.2042 + /*
33.2043 + * Test data for Bidi(char[], ...) constructor and methods
33.2044 + */
33.2045 +
33.2046 + /* Enbeddings */
33.2047 + private static byte[][][] emb4Constructor3 = {
33.2048 + /* Embeddings for paragraphs which don't include surrogate pairs. */
33.2049 + {{0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0},
33.2050 + {0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0},
33.2051 + {0, 0, 0, 0, 0, -3, -3, -3, -3, -3, -3, -3, 0, 0, 0, 0, 0, 0},
33.2052 + {0, 0, 0, 0, 0, -4, -4, -4, -4, -4, -4, -4, 0, 0, 0, 0, 0, 0}},
33.2053 +
33.2054 + /* Embeddings for paragraphs which include surrogate pairs. */
33.2055 + {{ 0, 0, 0, 0, 0, 0, 0, 0,
33.2056 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
33.2057 + 0, 0, 0, 0, 0, 0, 0, 0, 0},
33.2058 + { 0, 0, 0, 0, 0, 0, 0, 0,
33.2059 + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
33.2060 + 0, 0, 0, 0, 0, 0, 0, 0, 0},
33.2061 + { 0, 0, 0, 0, 0, 0, 0, 0,
33.2062 + -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3,
33.2063 + 0, 0, 0, 0, 0, 0, 0, 0, 0},
33.2064 + { 0, 0, 0, 0, 0, 0, 0, 0,
33.2065 + -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4,
33.2066 + 0, 0, 0, 0, 0, 0, 0, 0, 0}},
33.2067 + };
33.2068 +
33.2069 + /* Text for Bidi processing and its levels */
33.2070 + private static String[][] data4Constructor3 = {
33.2071 + /* For Text #0 */
33.2072 + {"abc <ABC XYZ> xyz.",
33.2073 + /* DIRECTION_DEFAULT_LEFT_TO_RIGHT */
33.2074 + "000002222222000000", "000000000000000000",
33.2075 + "000003333333000000", "000000000000000000",
33.2076 + /* DIRECTION_DEFAULT_RIGHT_TO_LEFT */
33.2077 + "222222222222222221", "222222222222222221",
33.2078 + "222113333333112221", "222224444444222221",
33.2079 + /* DIRECTION_LEFT_TO_RIGHT */
33.2080 + "000002222222000000", "000000000000000000",
33.2081 + "000003333333000000", "000000000000000000",
33.2082 + /* DIRECTION_RIGHT_TO_LEFT */
33.2083 + "222222222222222221", "222222222222222221",
33.2084 + "222113333333112221", "222224444444222221"},
33.2085 +
33.2086 + /* For Text #1 */
33.2087 + {"ABC <" + HebrewABC + " " + NKo123 + "> XYZ.",
33.2088 + /* DIRECTION_DEFAULT_LEFT_TO_RIGHT */
33.2089 + "000001111111000000", "000003333333000000",
33.2090 + "000003333333000000", "000000000000000000",
33.2091 + /* DIRECTION_DEFAULT_RIGHT_TO_LEFT */
33.2092 + "222111111111112221", "222223333333222221",
33.2093 + "222113333333112221", "222224444444222221",
33.2094 + /* DIRECTION_LEFT_TO_RIGHT */
33.2095 + "000001111111000000", "000003333333000000",
33.2096 + "000003333333000000", "000000000000000000",
33.2097 + /* DIRECTION_RIGHT_TO_LEFT */
33.2098 + "222111111111112221", "222223333333222221",
33.2099 + "222113333333112221", "222224444444222221"},
33.2100 +
33.2101 + /* For Text #2 */
33.2102 + {NKoABC + " <ABC XYZ> " + NKo123 + ".",
33.2103 + /* DIRECTION_DEFAULT_LEFT_TO_RIGHT */
33.2104 + "111112222222111111", "111112222222111111",
33.2105 + "111111111111111111", "111114444444111111",
33.2106 + /* DIRECTION_DEFAULT_RIGHT_TO_LEFT */
33.2107 + "111112222222111111", "111112222222111111",
33.2108 + "111111111111111111", "111114444444111111",
33.2109 + /* DIRECTION_LEFT_TO_RIGHT */
33.2110 + "111112222222111110", "111002222222001110",
33.2111 + "111113333333111110", "111004444444001110",
33.2112 + /* DIRECTION_RIGHT_TO_LEFT */
33.2113 + "111112222222111111", "111112222222111111",
33.2114 + "111111111111111111", "111114444444111111"},
33.2115 +
33.2116 + /* For Text #3 */
33.2117 + {HebrewABC + " <" + ArabicABC + " " + Arabic123 + "> " + NKo123 + ".",
33.2118 + /* DIRECTION_DEFAULT_LEFT_TO_RIGHT */
33.2119 + "111111111222111111", "111113333444111111",
33.2120 + "111111111111111111", "111114444444111111",
33.2121 + /* DIRECTION_DEFAULT_RIGHT_TO_LEFT */
33.2122 + "111111111222111111", "111113333444111111",
33.2123 + "111111111111111111", "111114444444111111",
33.2124 + /* DIRECTION_LEFT_TO_RIGHT */
33.2125 + "111111111222111110", "111003333444001110",
33.2126 + "111113333333111110", "111004444444001110",
33.2127 + /* DIRECTION_RIGHT_TO_LEFT */
33.2128 + "111111111222111111", "111113333444111111",
33.2129 + "111111111111111111", "111114444444111111"},
33.2130 +
33.2131 + /* For Text #4 */
33.2132 + {"abc <123 456> xyz.",
33.2133 + /* DIRECTION_DEFAULT_LEFT_TO_RIGHT */
33.2134 + "000002221222000000", "000000000000000000",
33.2135 + "000003333333000000", "000000000000000000",
33.2136 + /* DIRECTION_DEFAULT_RIGHT_TO_LEFT */
33.2137 + "222222222222222221", "222222222222222221",
33.2138 + "222113333333112221", "222224444444222221",
33.2139 + /* DIRECTION_LEFT_TO_RIGHT */
33.2140 + "000002221222000000", "000000000000000000",
33.2141 + "000003333333000000", "000000000000000000",
33.2142 + /* DIRECTION_RIGHT_TO_LEFT */
33.2143 + "222222222222222221", "222222222222222221",
33.2144 + "222113333333112221", "222224444444222221"},
33.2145 +
33.2146 + /* For Text #5 */
33.2147 + {OsmanyaABC + " <" + KharoshthiABC + " " + Kharoshthi123 + "> " +
33.2148 + Osmanya123 + ".",
33.2149 + /* DIRECTION_DEFAULT_LEFT_TO_RIGHT */
33.2150 + "000000001111111111111000000000", "000000003333333333333000000000",
33.2151 + "000000003333333333333000000000", "000000000000000000000000000000",
33.2152 + /* DIRECTION_DEFAULT_RIGHT_TO_LEFT */
33.2153 + "222222111111111111111112222221", "222222223333333333333222222221",
33.2154 + "222222113333333333333112222221", "222222224444444444444222222221",
33.2155 + /* DIRECTION_LEFT_TO_RIGHT */
33.2156 + "000000001111111111111000000000", "000000003333333333333000000000",
33.2157 + "000000003333333333333000000000", "000000000000000000000000000000",
33.2158 + /* DIRECTION_RIGHT_TO_LEFT */
33.2159 + "222222111111111111111112222221", "222222223333333333333222222221",
33.2160 + "222222113333333333333112222221", "222222224444444444444222222221"},
33.2161 +
33.2162 + /* For Text #6 */
33.2163 + {KharoshthiABC + " <" + OsmanyaABC + " " + Osmanya123 + "> " +
33.2164 + Kharoshthi123 + ".",
33.2165 + /* DIRECTION_DEFAULT_LEFT_TO_RIGHT */
33.2166 + "111111112222222222222111111111", "111111112222222222222111111111",
33.2167 + "111111111111111111111111111111", "111111114444444444444111111111",
33.2168 + /* DIRECTION_DEFAULT_RIGHT_TO_LEFT */
33.2169 + "111111112222222222222111111111", "111111112222222222222111111111",
33.2170 + "111111111111111111111111111111", "111111114444444444444111111111",
33.2171 + /* DIRECTION_LEFT_TO_RIGHT */
33.2172 + "111111112222222222222111111110", "111111002222222222222001111110",
33.2173 + "111111113333333333333111111110", "111111004444444444444001111110",
33.2174 + /* DIRECTION_RIGHT_TO_LEFT */
33.2175 + "111111112222222222222111111111", "111111112222222222222111111111",
33.2176 + "111111111111111111111111111111", "111111114444444444444111111111"},
33.2177 + };
33.2178 +
33.2179 + /* Golden data for baseIsLeftToRight() results */
33.2180 + private static boolean[][] baseIsLTR4Constructor3 = {
33.2181 + /* For Text #0 */
33.2182 + {true, true, true, true, // DIRECTION_DEFAULT_LEFT_TO_RIGHT
33.2183 + true, true, true, true, // DIRECTION_DEFAULT_RIGHT_TO_LEFT
33.2184 + true, true, true, true, // DIRECTION_LEFT_TO_RIGHT
33.2185 + false, false, false, false}, // DIRECTION_RIGHT_TO_LEFT
33.2186 +
33.2187 + /* For Text #1 */
33.2188 + {true, true, true, true,
33.2189 + true, true, true, true,
33.2190 + true, true, true, true,
33.2191 + false, false, false, false},
33.2192 +
33.2193 + /* For Text #2 */
33.2194 + {false, false, false, false,
33.2195 + false, false, false, false,
33.2196 + true, true, true, true,
33.2197 + false, false, false, false},
33.2198 +
33.2199 + /* For Text #3 */
33.2200 + {false, false, false, false,
33.2201 + false, false, false, false,
33.2202 + true, true, true, true,
33.2203 + false, false, false, false},
33.2204 +
33.2205 + /* For Text #4 */
33.2206 + {true, true, true, true,
33.2207 + true, true, true, true,
33.2208 + true, true, true, true,
33.2209 + false, false, false, false},
33.2210 +
33.2211 + /* For Text #5 */
33.2212 + {true, true, true, true,
33.2213 + true, true, true, true,
33.2214 + true, true, true, true,
33.2215 + false, false, false, false},
33.2216 +
33.2217 + /* For Text #6 */
33.2218 + {false, false, false, false,
33.2219 + false, false, false, false,
33.2220 + true, true, true, true,
33.2221 + false, false, false, false},
33.2222 + };
33.2223 +
33.2224 + /* Golden data for isLeftToRight() & isRightToLeft() results */
33.2225 + private static boolean[][][] isLTR_isRTL4Constructor3 = {
33.2226 + /* For Text #0 */
33.2227 + /* isLeftToRight() results */
33.2228 + {{false, true, false, true, // DIRECTION_DEFAULT_LEFT_TO_RIGHT
33.2229 + false, false, false, false, // DIRECTION_DEFAULT_RIGHT_TO_LEFT
33.2230 + false, true, false, true, // DIRECTION_LEFT_TO_RIGHT
33.2231 + false, false, false, false}, // DIRECTION_RIGHT_TO_LEFT
33.2232 + /* isRightToLeft() results */
33.2233 + {false, false, false, false, // DIRECTION_DEFAULT_LEFT_TO_RIGHT
33.2234 + false, false, false, false, // DIRECTION_DEFAULT_RIGHT_TO_LEFT
33.2235 + false, false, false, false, // DIRECTION_LEFT_TO_RIGHT
33.2236 + false, false, false, false}}, // DIRECTION_RIGHT_TO_LEFTT
33.2237 +
33.2238 + /* For Text #1 */
33.2239 + /* isLeftToRight() results */
33.2240 + {{false, false, false, true,
33.2241 + false, false, false, false,
33.2242 + false, false, false, true,
33.2243 + false, false, false, false},
33.2244 + /* isRightToLeft() results */
33.2245 + {false, false, false, false,
33.2246 + false, false, false, false,
33.2247 + false, false, false, false,
33.2248 + false, false, false, false}},
33.2249 +
33.2250 + /* For Text #2 */
33.2251 + /* isLeftToRight() results */
33.2252 + {{false, false, false, false,
33.2253 + false, false, false, false,
33.2254 + false, false, false, false,
33.2255 + false, false, false, false},
33.2256 + /* isRightToLeft() results */
33.2257 + {false, false, true, false,
33.2258 + false, false, true, false,
33.2259 + false, false, false, false,
33.2260 + false, false, true, false}},
33.2261 +
33.2262 + /* For Text #3 */
33.2263 + /* isLeftToRight() results */
33.2264 + {{false, false, false, false,
33.2265 + false, false, false, false,
33.2266 + false, false, false, false,
33.2267 + false, false, false, false},
33.2268 + /* isRightToLeft() results */
33.2269 + {false, false, true, false,
33.2270 + false, false, true, false,
33.2271 + false, false, false, false,
33.2272 + false, false, true, false}},
33.2273 +
33.2274 + /* For Text #4 */
33.2275 + /* isLeftToRight() results */
33.2276 + {{false, true, false, true,
33.2277 + false, false, false, false,
33.2278 + false, true, false, true,
33.2279 + false, false, false, false },
33.2280 + /* isRightToLeft() results */
33.2281 + {false, false, false, false,
33.2282 + false, false, false, false,
33.2283 + false, false, false, false,
33.2284 + false, false, false, false}},
33.2285 +
33.2286 + /* For Text #5 */
33.2287 + /* isLeftToRight() results */
33.2288 + {{false, false, false, true,
33.2289 + false, false, false, false,
33.2290 + false, false, false, true,
33.2291 + false, false, false, false},
33.2292 + /* isRightToLeft() results */
33.2293 + {false, false, false, false,
33.2294 + false, false, false, false,
33.2295 + false, false, false, false,
33.2296 + false, false, false, false}},
33.2297 +
33.2298 + /* For Text #6 */
33.2299 + /* isLeftToRight() results */
33.2300 + {{false, false, false, false,
33.2301 + false, false, false, false,
33.2302 + false, false, false, false,
33.2303 + false, false, false, false},
33.2304 + /* isRightToLeft() results */
33.2305 + {false, false, true, false,
33.2306 + false, false, true, false,
33.2307 + false, false, false, false,
33.2308 + false, false, true, false}},
33.2309 + };
33.2310 +
33.2311 + /* --------------------------------------------------------------------- */
33.2312 +
33.2313 + /*
33.2314 + * Test data for reorderVisually() methods
33.2315 + */
33.2316 +
33.2317 + private static Object[][][] data4reorderVisually = {
33.2318 + {{"ABC", " ", "abc", " ", ArabicABC, "."}, // Original text
33.2319 + {"000000001110"}, // levels
33.2320 + {"ABC", " ", "abc", " ", ArabicABC, "."}}, // Reordered text
33.2321 +
33.2322 + {{"ABC", " ", HebrewABC, " ", NKoABC, "."},
33.2323 + {"222111111111"},
33.2324 + {".", NKoABC, " ", HebrewABC, " ", "ABC"}},
33.2325 +
33.2326 + {{OsmanyaABC, " ", HebrewABC, " ", KharoshthiABC, "."},
33.2327 + {"222222111111111111"},
33.2328 + {".", KharoshthiABC, " ", HebrewABC, " ", OsmanyaABC,}},
33.2329 +
33.2330 + {{"ABC", " ", Osmanya123, " ", "\"", OsmanyaABC, " ", Kharoshthi123,
33.2331 + " ", KharoshthiABC, ".", "\""},
33.2332 + {"0000000000002222221111111111111100"},
33.2333 + {"ABC", " ", Osmanya123, " ", "\"", KharoshthiABC, " ", Kharoshthi123,
33.2334 + " ", OsmanyaABC, ".", "\""}},
33.2335 + };
33.2336 +
33.2337 +}
34.1 --- a/test/java/text/Bidi/BidiEmbeddingTest.java Sun Jun 21 23:52:58 2009 -0700
34.2 +++ b/test/java/text/Bidi/BidiEmbeddingTest.java Tue Jun 23 23:09:49 2009 -0700
34.3 @@ -23,7 +23,7 @@
34.4
34.5 /*
34.6 * @test
34.7 - * @bug 4396492 4396496 4778510
34.8 + * @bug 4396492 4396496 4778510 6850113
34.9 * @summary verify that the embedding values processed by the bidi code use negative values to
34.10 * indicate overrides, rather than using bit 7. Also tests Bidi without loading awt classes to
34.11 * confirm that Bidi can be used without awt. Verify that embedding level 0 is properly mapped
34.12 @@ -89,10 +89,12 @@
34.13 " at level " + bidi2.getRunLevel(i));
34.14 }
34.15
34.16 - System.out.println(bidi2);
34.17 + System.out.println(bidi2 + "\n");
34.18
34.19 if (bidi.getRunCount() != 3 || bidi2.getRunCount() != 3) {
34.20 throw new Error("Bidi run count incorrect");
34.21 + } else {
34.22 + System.out.println("test1() passed.\n");
34.23 }
34.24 }
34.25
34.26 @@ -123,10 +125,12 @@
34.27 " at level " + bidi.getRunLevel(i));
34.28 }
34.29
34.30 - System.out.println(bidi);
34.31 + System.out.println(bidi + "\n");
34.32
34.33 if (bidi.getRunCount() != 6) { // runs of spaces and angles at embedding bound,s and final period, each get level 1
34.34 throw new Error("Bidi embedding processing failed");
34.35 + } else {
34.36 + System.out.println("test2() passed.\n");
34.37 }
34.38 }
34.39 }
35.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
35.2 +++ b/test/java/text/Bidi/Bug6850113.java Tue Jun 23 23:09:49 2009 -0700
35.3 @@ -0,0 +1,60 @@
35.4 +/*
35.5 + * Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved.
35.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
35.7 + *
35.8 + * This code is free software; you can redistribute it and/or modify it
35.9 + * under the terms of the GNU General Public License version 2 only, as
35.10 + * published by the Free Software Foundation.
35.11 + *
35.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
35.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
35.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
35.15 + * version 2 for more details (a copy is included in the LICENSE file that
35.16 + * accompanied this code).
35.17 + *
35.18 + * You should have received a copy of the GNU General Public License version
35.19 + * 2 along with this work; if not, write to the Free Software Foundation,
35.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
35.21 + *
35.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
35.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
35.24 + * have any questions.
35.25 + */
35.26 +/*
35.27 + * @test
35.28 + * @bug 6850113
35.29 + * @summary Verify the return value of digit() for some digits.
35.30 + */
35.31 +
35.32 +import sun.text.normalizer.UCharacter;
35.33 +
35.34 +public class Bug6850113 {
35.35 +
35.36 + public static void main(String[] args) {
35.37 + boolean err = false;
35.38 +
35.39 + // Fullwidth Latin capital letters
35.40 + for (int i = 0xff21, j = 10; i <= 0xff3a; i++, j++) {
35.41 + if (UCharacter.digit(i, 36) != j) {
35.42 + err = true;
35.43 + System.out.println("Error: UCharacter.digit(0x" +
35.44 + Integer.toHexString(i) + ", 36) returned " +
35.45 + UCharacter.digit(i, 36) + ", expected=" + j);
35.46 + }
35.47 + }
35.48 +
35.49 + // Fullwidth Latin small letters
35.50 + for (int i = 0xff41, j = 10; i <= 0xff5a; i++, j++) {
35.51 + if (UCharacter.digit(i, 36) != j) {
35.52 + err = true;
35.53 + System.out.println("Error: UCharacter.digit(0x" +
35.54 + Integer.toHexString(i) + ", 36) returned " +
35.55 + UCharacter.digit(i, 36) + ", expected=" + j);
35.56 + }
35.57 + }
35.58 +
35.59 + if (err) {
35.60 + throw new RuntimeException("UCharacter.digit(): Wrong return value");
35.61 + }
35.62 + }
35.63 +}