⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bidiorder.java

📁 处理PDF
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
        //        // Although the scan proceeds left to right, and changes the type values        // in a way that would appear to affect the computations later in the scan,        // there is actually no problem.  A change in the current value can only        // affect the value to its immediate right, and only affect it if it is        // ES or CS.  But the current value can only change if the value to its        // right is not ES or CS.  Thus either the current value will not change,        // or its change will have no effect on the remainder of the analysis.                for (int i = start + 1; i < limit - 1; ++i) {            if (resultTypes[i] == ES || resultTypes[i] == CS) {                byte prevSepType = resultTypes[i-1];                byte succSepType = resultTypes[i+1];                if (prevSepType == EN && succSepType == EN) {                    resultTypes[i] = EN;                } else if (resultTypes[i] == CS && prevSepType == AN && succSepType == AN) {                    resultTypes[i] = AN;                }            }        }                // Rule W5.        for (int i = start; i < limit; ++i) {            if (resultTypes[i] == ET) {                // locate end of sequence                int runstart = i;                int runlimit = findRunLimit(runstart, limit, new byte[] { ET });                                // check values at ends of sequence                byte t = runstart == start ? sor : resultTypes[runstart - 1];                                if (t != EN) {                    t = runlimit == limit ? eor : resultTypes[runlimit];                }                                if (t == EN) {                    setTypes(runstart, runlimit, EN);                }                                // continue at end of sequence                i = runlimit;            }        }                // Rule W6.        for (int i = start; i < limit; ++i) {            byte t = resultTypes[i];            if (t == ES || t == ET || t == CS) {                resultTypes[i] = ON;            }        }                // Rule W7.        for (int i = start; i < limit; ++i) {            if (resultTypes[i] == EN) {                // set default if we reach start of run                byte prevStrongType = sor;                for (int j = i - 1; j >= start; --j) {                    byte t = resultTypes[j];                    if (t == L || t == R) { // AL's have been removed                        prevStrongType = t;                        break;                    }                }                if (prevStrongType == L) {                    resultTypes[i] = L;                }            }        }    }        /**     * 6) resolving neutral types     * Rules N1-N2.     */    private void resolveNeutralTypes(int start, int limit, byte level, byte sor, byte eor) {                for (int i = start; i < limit; ++i) {            byte t = resultTypes[i];            if (t == WS || t == ON || t == B || t == S) {                // find bounds of run of neutrals                int runstart = i;                int runlimit = findRunLimit(runstart, limit, new byte[] {B, S, WS, ON});                                // determine effective types at ends of run                byte leadingType;                byte trailingType;                                if (runstart == start) {                    leadingType = sor;                } else {                    leadingType = resultTypes[runstart - 1];                    if (leadingType == L || leadingType == R) {                        // found the strong type                    } else if (leadingType == AN) {                        leadingType = R;                    } else if (leadingType == EN) {                        // Since EN's with previous strong L types have been changed                        // to L in W7, the leadingType must be R.                        leadingType = R;                    }                }                                if (runlimit == limit) {                    trailingType = eor;                } else {                    trailingType = resultTypes[runlimit];                    if (trailingType == L || trailingType == R) {                        // found the strong type                    } else if (trailingType == AN) {                        trailingType = R;                    } else if (trailingType == EN) {                        trailingType = R;                    }                }                                byte resolvedType;                if (leadingType == trailingType) {                    // Rule N1.                    resolvedType = leadingType;                } else {                    // Rule N2.                    // Notice the embedding level of the run is used, not                    // the paragraph embedding level.                    resolvedType = typeForLevel(level);                }                                setTypes(runstart, runlimit, resolvedType);                                // skip over run of (former) neutrals                i = runlimit;            }        }    }        /**     * 7) resolving implicit embedding levels     * Rules I1, I2.     */    private void resolveImplicitLevels(int start, int limit, byte level, byte sor, byte eor) {        if ((level & 1) == 0) { // even level            for (int i = start; i < limit; ++i) {                byte t = resultTypes[i];                // Rule I1.                if (t == L ) {                    // no change                } else if (t == R) {                    resultLevels[i] += 1;                } else { // t == AN || t == EN                    resultLevels[i] += 2;                }            }        } else { // odd level            for (int i = start; i < limit; ++i) {                byte t = resultTypes[i];                // Rule I2.                if (t == R) {                    // no change                } else { // t == L || t == AN || t == EN                    resultLevels[i] += 1;                }            }        }    }        //    // Output    //        public byte[] getLevels() {        return getLevels(new int[]{textLength});    }        /**     * Return levels array breaking lines at offsets in linebreaks. <br>     * Rule L1.     * <p>     * The returned levels array contains the resolved level for each     * bidi code passed to the constructor.     * <p>     * The linebreaks array must include at least one value.     * The values must be in strictly increasing order (no duplicates)     * between 1 and the length of the text, inclusive.  The last value     * must be the length of the text.     *     * @param linebreaks the offsets at which to break the paragraph     * @return the resolved levels of the text     */    public byte[] getLevels(int[] linebreaks) {                // Note that since the previous processing has removed all        // P, S, and WS values from resultTypes, the values referred to        // in these rules are the initial types, before any processing        // has been applied (including processing of overrides).        //        // This example implementation has reinserted explicit format codes        // and BN, in order that the levels array correspond to the        // initial text.  Their final placement is not normative.        // These codes are treated like WS in this implementation,        // so they don't interrupt sequences of WS.                validateLineBreaks(linebreaks, textLength);                byte[] result = (byte[])resultLevels.clone(); // will be returned to caller                // don't worry about linebreaks since if there is a break within        // a series of WS values preceding S, the linebreak itself        // causes the reset.        for (int i = 0; i < result.length; ++i) {            byte t = initialTypes[i];            if (t == B || t == S) {                // Rule L1, clauses one and two.                result[i] = paragraphEmbeddingLevel;                                // Rule L1, clause three.                for (int j = i - 1; j >= 0; --j) {                    if (isWhitespace(initialTypes[j])) { // including format codes                        result[j] = paragraphEmbeddingLevel;                    } else {                        break;                    }                }            }        }                // Rule L1, clause four.        int start = 0;        for (int i = 0; i < linebreaks.length; ++i) {            int limit = linebreaks[i];            for (int j = limit - 1; j >= start; --j) {                if (isWhitespace(initialTypes[j])) { // including format codes                    result[j] = paragraphEmbeddingLevel;                } else {                    break;                }            }                        start = limit;        }                return result;    }        /**     * Return reordering array breaking lines at offsets in linebreaks.     * <p>     * The reordering array maps from a visual index to a logical index.     * Lines are concatenated from left to right.  So for example, the     * fifth character from the left on the third line is     * <pre> getReordering(linebreaks)[linebreaks[1] + 4]</pre>     * (linebreaks[1] is the position after the last character of the     * second line, which is also the index of the first character on the     * third line, and adding four gets the fifth character from the left).     * <p>     * The linebreaks array must include at least one value.     * The values must be in strictly increasing order (no duplicates)     * between 1 and the length of the text, inclusive.  The last value     * must be the length of the text.     *     * @param linebreaks the offsets at which to break the paragraph.     */    public int[] getReordering(int[] linebreaks) {        validateLineBreaks(linebreaks, textLength);                byte[] levels = getLevels(linebreaks);                return computeMultilineReordering(levels, linebreaks);    }        /**     * Return multiline reordering array for a given level array.     * Reordering does not occur across a line break.     */    private static int[] computeMultilineReordering(byte[] levels, int[] linebreaks) {        int[] result = new int[levels.length];                int start = 0;        for (int i = 0; i < linebreaks.length; ++i) {            int limit = linebreaks[i];                        byte[] templevels = new byte[limit - start];            System.arraycopy(levels, start, templevels, 0, templevels.length);                        int[] temporder = computeReordering(templevels);            for (int j = 0; j < temporder.length; ++j) {                result[start + j] = temporder[j] + start;            }                        start = limit;        }                return result;    }        /**     * Return reordering array for a given level array.  This reorders a single line.     * The reordering is a visual to logical map.  For example,     * the leftmost char is string.charAt(order[0]).     * Rule L2.     */    private static int[] computeReordering(byte[] levels) {        int lineLength = levels.length;                int[] result = new int[lineLength];                // initialize order        for (int i = 0; i < lineLength; ++i) {            result[i] = i;        }                // locate highest level found on line.        // Note the rules say text, but no reordering across line bounds is performed,        // so this is sufficient.        byte highestLevel = 0;        byte lowestOddLevel = 63;        for (int i = 0; i < lineLength; ++i) {            byte level = levels[i];            if (level > highestLevel) {                highestLevel = level;            }            if (((level & 1) != 0) && level < lowestOddLevel) {                lowestOddLevel = level;            }        }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -