📄 bidi.java
字号:
break; } ++cwss; } } int[] nruns = null; int nlevel = baselevel; int limit = cwspos == -1 ? lineLimit : cwspos; int rs = 0; int rl = runs.length; int ndir = dir; for (; rs < runs.length; rs += 2) { if (runs[rs] > lineStart) { rl = rs; while (rl < runs.length && runs[rl] < limit) { rl += 2; } if ((rl > rs) || (runs[rs+1] != baselevel)) { rl += 2; if (cwspos != -1 && rl > rs && runs[rl-1] != baselevel) { // add level for cws nruns = new int[rl - rs + 2]; nruns[rl - rs] = lineLength; nruns[rl - rs + 1] = baselevel; } else { limit = lineLimit; nruns = new int[rl - rs]; } int n = 0; for (int i = rs; i < rl; i += 2) { nruns[n++] = runs[i] - lineStart; nruns[n++] = runs[i+1]; } nruns[n-2] = limit - lineStart; } else { ndir = (runs[rs+1] & 0x1) == 0 ? DIRECTION_LEFT_TO_RIGHT : DIRECTION_RIGHT_TO_LEFT; } break; } } return new Bidi(ndir, baselevel, lineLength, nruns, ncws); } } /** * Return true if the line is not left-to-right or right-to-left. This means it either has mixed runs of left-to-right * and right-to-left text, or the base direction differs from the direction of the only run of text. * @return true if the line is not left-to-right or right-to-left. */ public boolean isMixed() { return dir == DIR_MIXED; } /** * Return true if the line is all left-to-right text and the base direction is left-to-right. * @return true if the line is all left-to-right text and the base direction is left-to-right */ public boolean isLeftToRight() { return dir == DIRECTION_LEFT_TO_RIGHT; } /** * Return true if the line is all right-to-left text, and the base direction is right-to-left. * @return true if the line is all right-to-left text, and the base direction is right-to-left */ public boolean isRightToLeft() { return dir == DIRECTION_RIGHT_TO_LEFT; } /** * Return the length of text in the line. * @return the length of text in the line */ public int getLength() { return length; } /** * Return true if the base direction is left-to-right. * @return true if the base direction is left-to-right */ public boolean baseIsLeftToRight() { return (baselevel & 0x1) == 0; } /** * Return the base level (0 if left-to-right, 1 if right-to-left). * @return the base level */ public int getBaseLevel() { return baselevel; } /** * Return the resolved level of the character at offset. If offset is <0 or >= * the length of the line, return the base direction level. * @param offset the index of the character for which to return the level * @return the resolved level of the character at offset */ public int getLevelAt(int offset) { if (runs == null || offset < 0 || offset >= length) { return baselevel; } else { int i = 0; do { if (offset < runs[i]) { return runs[i+1]; } i += 2; } while (true); } } /** * Return the number of level runs. * @return the number of level runs */ public int getRunCount() { return runs == null ? 1 : runs.length / 2; } /** * Return the level of the nth logical run in this line. * @param run the index of the run, between 0 and <code>getRunCount()</code> * @return the level of the run */ public int getRunLevel(int run) { return runs == null ? baselevel : runs[run * 2 + 1]; } /** * Return the index of the character at the start of the nth logical run in this line, as * an offset from the start of the line. * @param run the index of the run, between 0 and <code>getRunCount()</code> * @return the start of the run */ public int getRunStart(int run) { return (runs == null || run == 0) ? 0 : runs[run * 2 - 2]; } /** * Return the index of the character past the end of the nth logical run in this line, as * an offset from the start of the line. For example, this will return the length * of the line for the last run on the line. * @param run the index of the run, between 0 and <code>getRunCount()</code> * @return limit the limit of the run */ public int getRunLimit(int run) { return runs == null ? length : runs[run * 2]; } /** * Return true if the specified text requires bidi analysis. If this returns false, * the text will display left-to-right. Clients can then avoid constructing a Bidi object. * Text in the Arabic Presentation Forms area of Unicode is presumed to already be shaped * and ordered for display, and so will not cause this function to return true. * * @param text the text containing the characters to test * @param start the start of the range of characters to test * @param limit the limit of the range of characters to test * @return true if the range of characters requires bidi analysis */ public static boolean requiresBidi(char[] text, int start, int limit) { for (int i = start; i < limit; ++i) { char c = text[i]; if (c < '\u0591') continue; if (c > '\u202e') continue; // if contains arabic extended data, presume already ordered int dc = nativeGetDirectionCode(c); if ((RMASK & (1 << dc)) != 0) { return true; } } return false; } /** * Reorder the objects in the array into visual order based on their levels. * This is a utility function to use when you have a collection of objects * representing runs of text in logical order, each run containing text * at a single level. The elements at <code>index</code> from * <code>objectStart</code> up to <code>objectStart + count</code> * in the objects array will be reordered into visual order assuming * each run of text has the level indicated by the corresponding element * in the levels array (at <code>index - objectStart + levelStart</code>). * * @param levels an array representing the bidi level of each object * @param levelStart the start position in the levels array * @param objects the array of objects to be reordered into visual order * @param objectStart the start position in the objects array * @param count the number of objects to reorder */ public static void reorderVisually(byte[] levels, int levelStart, Object[] objects, int objectStart, int count) { if (count < 0) { throw new IllegalArgumentException("count " + count + " must be >= 0"); } if (levelStart < 0 || levelStart + count > levels.length) { throw new IllegalArgumentException("levelStart " + levelStart + " and count " + count + " out of range [0, " + levels.length + "]"); } if (objectStart < 0 || objectStart + count > objects.length) { throw new IllegalArgumentException("objectStart " + objectStart + " and count " + count + " out of range [0, " + objects.length + "]"); } byte lowestOddLevel = (byte)(NUMLEVELS + 1); byte highestLevel = 0; // initialize mapping and levels int levelLimit = levelStart + count; for (int i = levelStart; i < levelLimit; i++) { byte level = levels[i]; if (level > highestLevel) { highestLevel = level; } if ((level & 0x01) != 0 && level < lowestOddLevel) { lowestOddLevel = level; } } int delta = objectStart - levelStart; while (highestLevel >= lowestOddLevel) { int i = levelStart; for (;;) { while (i < levelLimit && levels[i] < highestLevel) { i++; } int begin = i++; if (begin == levelLimit) { break; // no more runs at this level } while (i < levelLimit && levels[i] >= highestLevel) { i++; } int end = i - 1; begin += delta; end += delta; while (begin < end) { Object temp = objects[begin]; objects[begin] = objects[end]; objects[end] = temp; ++begin; --end; } } --highestLevel; } } private static final char NUMLEVELS = 62; private static final int RMASK = (1 << 1 /* U_RIGHT_TO_LEFT */) | (1 << 5 /* U_ARABIC_NUMBER */) | (1 << 13 /* U_RIGHT_TO_LEFT_ARABIC */) | (1 << 14 /* U_RIGHT_TO_LEFT_EMBEDDING */) | (1 << 15 /* U_RIGHT_TO_LEFT_OVERRIDE */); /** Access native bidi implementation. */ private static native int nativeGetDirectionCode(char c); /** Access native bidi implementation. */ private static synchronized native void nativeBidiChars(Bidi bidi, char[] text, int textStart, byte[] embeddings, int embeddingStart, int length, int flags); /** * Display the bidi internal state, used in debugging. */ public String toString() { StringBuffer buf = new StringBuffer(super.toString()); buf.append("[dir: " + dir); buf.append(" baselevel: " + baselevel); buf.append(" length: " + length); if (runs == null) { buf.append(" runs: null"); } else { buf.append(" runs: ["); for (int i = 0; i < runs.length; i += 2) { if (i != 0) { buf.append(' '); } buf.append(runs[i]); // limit buf.append('/'); buf.append(runs[i+1]); // level } buf.append(']'); } if (cws == null) { buf.append(" cws: null"); } else { buf.append(" cws: ["); for (int i = 0; i < cws.length; ++i) { if (i != 0) { buf.append(' '); } buf.append(Integer.toHexString(cws[i])); } buf.append(']'); } buf.append(']'); return buf.toString(); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -