Merge jdk7-b62
authoryan
Tue, 23 Jun 2009 23:09:49 -0700
changeset 131512e11fab9a83
parent 1306 55a584478eac
parent 1314 45316d7cc9dc
child 1316 8905d218cd0d
child 1329 2886eb650801
child 1386 d086e324775c
Merge
src/share/native/sun/font/bidi/cmemory.h
src/share/native/sun/font/bidi/jbidi.c
src/share/native/sun/font/bidi/jbidi.h
src/share/native/sun/font/bidi/ubidi.c
src/share/native/sun/font/bidi/ubidi.h
src/share/native/sun/font/bidi/ubidiimp.h
src/share/native/sun/font/bidi/ubidiln.c
src/share/native/sun/font/bidi/uchardir.c
src/share/native/sun/font/bidi/uchardir.h
src/share/native/sun/font/bidi/utypes.h
     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 &quot;limit&quot; 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 &quot;runs&quot;. Such a
    7.92 + * &quot;run&quot; 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&gt;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&gt;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&lt;=start&lt;limit&lt;=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&lt;=charIndex&lt;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&lt;=run&lt;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&lt;=run&lt;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&lt;=run&lt;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 &quot;limit&quot; 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&nbsp;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&nbsp;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&lt;=embeddingLevels[]&lt;=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&lt;=start&lt;=limit&lt;=</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 - *&nbsp; int32_t i, count=ubidi_countRuns(pBiDi),
  15.513 - *&nbsp;         logicalStart, visualIndex=0, length;
  15.514 - *&nbsp; for(i=0; i&lt;count; ++i) {
  15.515 - *&nbsp;     if(UBIDI_LTR==ubidi_getVisualRun(pBiDi, i, &logicalStart, &length)) {
  15.516 - *&nbsp;         do { // LTR
  15.517 - *&nbsp;             show_char(text[logicalStart++], visualIndex++);
  15.518 - *&nbsp;         } while(--length>0);
  15.519 - *&nbsp;     } else {
  15.520 - *&nbsp;         logicalStart+=length;  // logicalLimit
  15.521 - *&nbsp;         do { // RTL
  15.522 - *&nbsp;             show_char(text[--logicalStart], visualIndex++);
  15.523 - *&nbsp;         } while(--length>0);
  15.524 - *&nbsp;     }
  15.525 - *&nbsp; }
  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&gt;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&gt;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 - *&nbsp; #include "ubidi.h"
  15.708 - *&nbsp;
  15.709 - *&nbsp; typedef enum {
  15.710 - *&nbsp;     styleNormal=0, styleSelected=1,
  15.711 - *&nbsp;     styleBold=2, styleItalics=4,
  15.712 - *&nbsp;     styleSuper=8, styleSub=16
  15.713 - *&nbsp; } Style;
  15.714 - *&nbsp;
  15.715 - *&nbsp; typedef struct { int32_t limit; Style style; } StyleRun;
  15.716 - *&nbsp;
  15.717 - *&nbsp; int getTextWidth(const UChar *text, int32_t start, int32_t limit,
  15.718 - *&nbsp;                  const StyleRun *styleRuns, int styleRunCount);
  15.719 - *&nbsp;
  15.720 - *&nbsp; // set *pLimit and *pStyleRunLimit for a line
  15.721 - *&nbsp; // from text[start] and from styleRuns[styleRunStart]
  15.722 - *&nbsp; // using ubidi_getLogicalRun(para, ...)
  15.723 - *&nbsp; void getLineBreak(const UChar *text, int32_t start, int32_t *pLimit,
  15.724 - *&nbsp;                   UBiDi *para,
  15.725 - *&nbsp;                   const StyleRun *styleRuns, int styleRunStart, int *pStyleRunLimit,
  15.726 - *&nbsp;                   int *pLineWidth);
  15.727 - *&nbsp;
  15.728 - *&nbsp; // render runs on a line sequentially, always from left to right
  15.729 - *&nbsp;
  15.730 - *&nbsp; // prepare rendering a new line
  15.731 - *&nbsp; void startLine(UBiDiDirection textDirection, int lineWidth);
  15.732 - *&nbsp;
  15.733 - *&nbsp; // render a run of text and advance to the right by the run width
  15.734 - *&nbsp; // the text[start..limit-1] is always in logical order
  15.735 - *&nbsp; void renderRun(const UChar *text, int32_t start, int32_t limit,
  15.736 - *&nbsp;                UBiDiDirection textDirection, Style style);
  15.737 - *&nbsp;
  15.738 - *&nbsp; // We could compute a cross-product
  15.739 - *&nbsp; // from the style runs with the directional runs
  15.740 - *&nbsp; // and then reorder it.
  15.741 - *&nbsp; // Instead, here we iterate over each run type
  15.742 - *&nbsp; // and render the intersections -
  15.743 - *&nbsp; // with shortcuts in simple (and common) cases.
  15.744 - *&nbsp; // renderParagraph() is the main function.
  15.745 - *&nbsp;
  15.746 - *&nbsp; // render a directional run with
  15.747 - *&nbsp; // (possibly) multiple style runs intersecting with it
  15.748 - *&nbsp; void renderDirectionalRun(const UChar *text,
  15.749 - *&nbsp;                           int32_t start, int32_t limit,
  15.750 - *&nbsp;                           UBiDiDirection direction,
  15.751 - *&nbsp;                           const StyleRun *styleRuns, int styleRunCount) {
  15.752 - *&nbsp;     int i;
  15.753 - *&nbsp;
  15.754 - *&nbsp;     // iterate over style runs
  15.755 - *&nbsp;     if(direction==UBIDI_LTR) {
  15.756 - *&nbsp;         int styleLimit;
  15.757 - *&nbsp;
  15.758 - *&nbsp;         for(i=0; i&lt;styleRunCount; ++i) {
  15.759 - *&nbsp;             styleLimit=styleRun[i].limit;
  15.760 - *&nbsp;             if(start&lt;styleLimit) {
  15.761 - *&nbsp;                 if(styleLimit>limit) { styleLimit=limit; }
  15.762 - *&nbsp;                 renderRun(text, start, styleLimit,
  15.763 - *&nbsp;                           direction, styleRun[i].style);
  15.764 - *&nbsp;                 if(styleLimit==limit) { break; }
  15.765 - *&nbsp;                 start=styleLimit;
  15.766 - *&nbsp;             }
  15.767 - *&nbsp;         }
  15.768 - *&nbsp;     } else {
  15.769 - *&nbsp;         int styleStart;
  15.770 - *&nbsp;
  15.771 - *&nbsp;         for(i=styleRunCount-1; i>=0; --i) {
  15.772 - *&nbsp;             if(i>0) {
  15.773 - *&nbsp;                 styleStart=styleRun[i-1].limit;
  15.774 - *&nbsp;             } else {
  15.775 - *&nbsp;                 styleStart=0;
  15.776 - *&nbsp;             }
  15.777 - *&nbsp;             if(limit>=styleStart) {
  15.778 - *&nbsp;                 if(styleStart&lt;start) { styleStart=start; }
  15.779 - *&nbsp;                 renderRun(text, styleStart, limit,
  15.780 - *&nbsp;                           direction, styleRun[i].style);
  15.781 - *&nbsp;                 if(styleStart==start) { break; }
  15.782 - *&nbsp;                 limit=styleStart;
  15.783 - *&nbsp;             }
  15.784 - *&nbsp;         }
  15.785 - *&nbsp;     }
  15.786 - *&nbsp; }
  15.787 - *&nbsp;
  15.788 - *&nbsp; // the line object represents text[start..limit-1]
  15.789 - *&nbsp; void renderLine(UBiDi *line, const UChar *text,
  15.790 - *&nbsp;                 int32_t start, int32_t limit,
  15.791 - *&nbsp;                 const StyleRun *styleRuns, int styleRunCount) {
  15.792 - *&nbsp;     UBiDiDirection direction=ubidi_getDirection(line);
  15.793 - *&nbsp;     if(direction!=UBIDI_MIXED) {
  15.794 - *&nbsp;         // unidirectional
  15.795 - *&nbsp;         if(styleRunCount&lt;=1) {
  15.796 - *&nbsp;             renderRun(text, start, limit, direction, styleRuns[0].style);
  15.797 - *&nbsp;         } else {
  15.798 - *&nbsp;             renderDirectionalRun(text, start, limit,
  15.799 - *&nbsp;                                  direction, styleRuns, styleRunCount);
  15.800 - *&nbsp;         }
  15.801 - *&nbsp;     } else {
  15.802 - *&nbsp;         // mixed-directional
  15.803 - *&nbsp;         int32_t count, i, length;
  15.804 - *&nbsp;         UBiDiLevel level;
  15.805 - *&nbsp;
  15.806 - *&nbsp;         count=ubidi_countRuns(para, pErrorCode);
  15.807 - *&nbsp;         if(U_SUCCESS(*pErrorCode)) {
  15.808 - *&nbsp;             if(styleRunCount&lt;=1) {
  15.809 - *&nbsp;                 Style style=styleRuns[0].style;
  15.810 - *&nbsp;
  15.811 - *&nbsp;                 // iterate over directional runs
  15.812 - *&nbsp;                 for(i=0; i&lt;count; ++i) {
  15.813 - *&nbsp;                     direction=ubidi_getVisualRun(para, i, &start, &length);
  15.814 - *&nbsp;                     renderRun(text, start, start+length, direction, style);
  15.815 - *&nbsp;                 }
  15.816 - *&nbsp;             } else {
  15.817 - *&nbsp;                 int32_t j;
  15.818 - *&nbsp;
  15.819 - *&nbsp;                 // iterate over both directional and style runs
  15.820 - *&nbsp;                 for(i=0; i&lt;count; ++i) {
  15.821 - *&nbsp;                     direction=ubidi_getVisualRun(line, i, &start, &length);
  15.822 - *&nbsp;                     renderDirectionalRun(text, start, start+length,
  15.823 - *&nbsp;                                          direction, styleRuns, styleRunCount);
  15.824 - *&nbsp;                 }
  15.825 - *&nbsp;             }
  15.826 - *&nbsp;         }
  15.827 - *&nbsp;     }
  15.828 - *&nbsp; }
  15.829 - *&nbsp;
  15.830 - *&nbsp; void renderParagraph(const UChar *text, int32_t length,
  15.831 - *&nbsp;                      UBiDiDirection textDirection,
  15.832 - *&nbsp;                      const StyleRun *styleRuns, int styleRunCount,
  15.833 - *&nbsp;                      int lineWidth,
  15.834 - *&nbsp;                      UErrorCode *pErrorCode) {
  15.835 - *&nbsp;     UBiDi *para;
  15.836 - *&nbsp;
  15.837 - *&nbsp;     if(pErrorCode==NULL || U_FAILURE(*pErrorCode) || length&lt;=0) {
  15.838 - *&nbsp;         return;
  15.839 - *&nbsp;     }
  15.840 - *&nbsp;
  15.841 - *&nbsp;     para=ubidi_openSized(length, 0, pErrorCode);
  15.842 - *&nbsp;     if(para==NULL) { return; }
  15.843 - *&nbsp;
  15.844 - *&nbsp;     ubidi_setPara(para, text, length,
  15.845 - *&nbsp;                   textDirection ? UBIDI_DEFAULT_RTL : UBIDI_DEFAULT_LTR,
  15.846 - *&nbsp;                   NULL, pErrorCode);
  15.847 - *&nbsp;     if(U_SUCCESS(*pErrorCode)) {
  15.848 - *&nbsp;         UBiDiLevel paraLevel=1&ubidi_getParaLevel(para);
  15.849 - *&nbsp;         StyleRun styleRun={ length, styleNormal };
  15.850 - *&nbsp;         int width;
  15.851 - *&nbsp;
  15.852 - *&nbsp;         if(styleRuns==NULL || styleRunCount&lt;=0) {
  15.853 - *&nbsp;             styleRunCount=1;
  15.854 - *&nbsp;             styleRuns=&styleRun;
  15.855 - *&nbsp;         }
  15.856 - *&nbsp;
  15.857 - *&nbsp;         // assume styleRuns[styleRunCount-1].limit>=length
  15.858 - *&nbsp;
  15.859 - *&nbsp;         width=getTextWidth(text, 0, length, styleRuns, styleRunCount);
  15.860 - *&nbsp;         if(width&lt;=lineWidth) {
  15.861 - *&nbsp;             // everything fits onto one line
  15.862 - *&nbsp;
  15.863 - *&nbsp;             // prepare rendering a new line from either left or right
  15.864 - *&nbsp;             startLine(paraLevel, width);
  15.865 - *&nbsp;
  15.866 - *&nbsp;             renderLine(para, text, 0, length,
  15.867 - *&nbsp;                        styleRuns, styleRunCount);
  15.868 - *&nbsp;         } else {
  15.869 - *&nbsp;             UBiDi *line;
  15.870 - *&nbsp;
  15.871 - *&nbsp;             // we need to render several lines
  15.872 - *&nbsp;             line=ubidi_openSized(length, 0, pErrorCode);
  15.873 - *&nbsp;             if(line!=NULL) {
  15.874 - *&nbsp;                 int32_t start=0, limit;
  15.875 - *&nbsp;                 int styleRunStart=0, styleRunLimit;
  15.876 - *&nbsp;
  15.877 - *&nbsp;                 for(;;) {
  15.878 - *&nbsp;                     limit=length;
  15.879 - *&nbsp;                     styleRunLimit=styleRunCount;
  15.880 - *&nbsp;                     getLineBreak(text, start, &limit, para,
  15.881 - *&nbsp;                                  styleRuns, styleRunStart, &styleRunLimit,
  15.882 - *&nbsp;                                  &width);
  15.883 - *&nbsp;                     ubidi_setLine(para, start, limit, line, pErrorCode);
  15.884 - *&nbsp;                     if(U_SUCCESS(*pErrorCode)) {
  15.885 - *&nbsp;                         // prepare rendering a new line
  15.886 - *&nbsp;                         // from either left or right
  15.887 - *&nbsp;                         startLine(paraLevel, width);
  15.888 - *&nbsp;
  15.889 - *&nbsp;                         renderLine(line, text, start, limit,
  15.890 - *&nbsp;                                    styleRuns+styleRunStart,
  15.891 - *&nbsp;                                    styleRunLimit-styleRunStart);
  15.892 - *&nbsp;                     }
  15.893 - *&nbsp;                     if(limit==length) { break; }
  15.894 - *&nbsp;                     start=limit;
  15.895 - *&nbsp;                     styleRunStart=styleRunLimit-1;
  15.896 - *&nbsp;                     if(start>=styleRuns[styleRunStart].limit) {
  15.897 - *&nbsp;                         ++styleRunStart;
  15.898 - *&nbsp;                     }
  15.899 - *&nbsp;                 }
  15.900 - *&nbsp;
  15.901 - *&nbsp;                 ubidi_close(line);
  15.902 - *&nbsp;             }
  15.903 - *&nbsp;         }
  15.904 - *&nbsp;     }
  15.905 - *&nbsp;
  15.906 - *&nbsp;     ubidi_close(para);
  15.907 - *&nbsp; }
  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 +}