提交 fb406a7c 编写于 作者: P peytoia

6850113: Bidi class needs to be updated to support Unicode 5.1

Reviewed-by: okutsu
上级 85c2d317
......@@ -76,6 +76,10 @@ FILES_java = \
sun/text/Normalizer.java \
sun/text/SupplementaryCharacterData.java \
sun/text/UCompactIntArray.java \
sun/text/bidi/BidiBase.java \
sun/text/bidi/BidiLine.java \
sun/text/bidi/BidiRun.java \
\
sun/text/normalizer/CharTrie.java \
sun/text/normalizer/CharacterIteratorWrapper.java \
sun/text/normalizer/ICUBinary.java \
......
......@@ -24,10 +24,6 @@
#
FILES_c_shared = \
jbidi.c \
ubidi.c \
ubidiln.c \
uchardir.c \
DrawGlyphList.c \
sunFont.c
......
......@@ -145,7 +145,6 @@ include $(BUILDDIR)/common/Library.gmk
# Add to the ambient vpath to pick up files in subdirectories
#
vpath %.c $(PLATFORM_SRC)/native/$(PKGDIR)
vpath %.c $(SHARE_SRC)/native/$(PKGDIR)/bidi
vpath %.cpp $(SHARE_SRC)/native/$(PKGDIR)/layout
vpath %.cpp $(SHARE_SRC)/native/$(PKGDIR)
......@@ -187,7 +186,6 @@ endif # PLATFORM
CPPFLAGS += -I$(SHARE_SRC)/native/$(PKGDIR) \
-I$(SHARE_SRC)/native/$(PKGDIR)/layout \
-I$(SHARE_SRC)/native/$(PKGDIR)/bidi \
-I$(SHARE_SRC)/native/sun/awt/image/cvutils \
-I$(PLATFORM_SRC)/native/sun/awt \
-I$(SHARE_SRC)/native/sun/awt/debug \
......
......@@ -31,8 +31,6 @@ SUNWprivate_1.1 {
newLayoutTableCache;
freeLayoutTableCache;
isNullScalerContext;
Java_java_text_Bidi_nativeBidiChars;
Java_java_text_Bidi_nativeGetDirectionCode;
Java_sun_font_NullFontScaler_getNullScalerContext;
Java_sun_font_NullFontScaler_getGlyphImage;
Java_sun_font_FontManager_getPlatformFontVar;
......
......@@ -33,8 +33,6 @@ SUNWprivate_1.1 {
newLayoutTableCache;
freeLayoutTableCache;
isNullScalerContext;
Java_java_text_Bidi_nativeBidiChars;
Java_java_text_Bidi_nativeGetDirectionCode;
Java_sun_font_NullFontScaler_getNullScalerContext;
Java_sun_font_NullFontScaler_getGlyphImage;
Java_sun_font_FontManager_getPlatformFontVar;
......
/*
* Copyright 2000-2003 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -35,10 +35,7 @@
package java.text;
import java.awt.Toolkit;
import java.awt.font.TextAttribute;
import java.awt.font.NumericShaper;
import sun.text.CodePointIterator;
import sun.text.bidi.BidiBase;
/**
* This class implements the Unicode Bidirectional Algorithm.
......@@ -62,15 +59,6 @@ import sun.text.CodePointIterator;
* @since 1.4
*/
public final class Bidi {
byte dir;
byte baselevel;
int length;
int[] runs;
int[] cws;
static {
sun.font.FontManagerNativeLibrary.load();
}
/** Constant indicating base direction is left-to-right. */
public static final int DIRECTION_LEFT_TO_RIGHT = 0;
......@@ -94,7 +82,7 @@ public final class Bidi {
*/
public static final int DIRECTION_DEFAULT_RIGHT_TO_LEFT = -1;
private static final int DIR_MIXED = 2;
private BidiBase bidiBase;
/**
* Create Bidi from the given paragraph of text and base direction.
......@@ -109,7 +97,7 @@ public final class Bidi {
throw new IllegalArgumentException("paragraph is null");
}
nativeBidiChars(this, paragraph.toCharArray(), 0, null, 0, paragraph.length(), flags);
bidiBase = new BidiBase(paragraph.toCharArray(), 0, null, 0, paragraph.length(), flags);
}
/**
......@@ -142,67 +130,8 @@ public final class Bidi {
throw new IllegalArgumentException("paragraph is null");
}
int flags = DIRECTION_DEFAULT_LEFT_TO_RIGHT;
byte[] embeddings = null;
int start = paragraph.getBeginIndex();
int limit = paragraph.getEndIndex();
int length = limit - start;
int n = 0;
char[] text = new char[length];
for (char c = paragraph.first(); c != paragraph.DONE; c = paragraph.next()) {
text[n++] = c;
}
paragraph.first();
try {
Boolean runDirection = (Boolean)paragraph.getAttribute(TextAttribute.RUN_DIRECTION);
if (runDirection != null) {
if (TextAttribute.RUN_DIRECTION_LTR.equals(runDirection)) {
flags = DIRECTION_LEFT_TO_RIGHT; // clears default setting
} else {
flags = DIRECTION_RIGHT_TO_LEFT;
}
}
}
catch (ClassCastException e) {
}
try {
NumericShaper shaper = (NumericShaper)paragraph.getAttribute(TextAttribute.NUMERIC_SHAPING);
if (shaper != null) {
shaper.shape(text, 0, text.length);
}
}
catch (ClassCastException e) {
}
int pos = start;
do {
paragraph.setIndex(pos);
Object embeddingLevel = paragraph.getAttribute(TextAttribute.BIDI_EMBEDDING);
int newpos = paragraph.getRunLimit(TextAttribute.BIDI_EMBEDDING);
if (embeddingLevel != null) {
try {
int intLevel = ((Integer)embeddingLevel).intValue();
if (intLevel >= -61 && intLevel < 61) {
byte level = (byte)(intLevel < 0 ? (-intLevel | 0x80) : intLevel);
if (embeddings == null) {
embeddings = new byte[length];
}
for (int i = pos - start; i < newpos - start; ++i) {
embeddings[i] = level;
}
}
}
catch (ClassCastException e) {
}
}
pos = newpos;
} while (pos < limit);
nativeBidiChars(this, text, 0, embeddings, 0, text.length, flags);
bidiBase = new BidiBase(0, 0);
bidiBase.setPara(paragraph);
}
/**
......@@ -240,46 +169,7 @@ public final class Bidi {
" for embeddings of length: " + text.length);
}
if (embeddings != null) {
// native uses high bit to indicate override, not negative value, sigh
for (int i = embStart, embLimit = embStart + paragraphLength; i < embLimit; ++i) {
if (embeddings[i] < 0) {
byte[] temp = new byte[paragraphLength];
System.arraycopy(embeddings, embStart, temp, 0, paragraphLength);
for (i -= embStart; i < paragraphLength; ++i) {
if (temp[i] < 0) {
temp[i] = (byte)(-temp[i] | 0x80);
}
}
embeddings = temp;
embStart = 0;
break;
}
}
}
nativeBidiChars(this, text, textStart, embeddings, embStart, paragraphLength, flags);
}
/**
* Private constructor used by line bidi.
*/
private Bidi(int dir, int baseLevel, int length, int[] data, int[] cws) {
reset(dir, baseLevel, length, data, cws);
}
/**
* Private mutator used by native code.
*/
private void reset(int dir, int baselevel, int length, int[] data, int[] cws) {
this.dir = (byte)dir;
this.baselevel = (byte)baselevel;
this.length = length;
this.runs = data;
this.cws = cws;
bidiBase = new BidiBase(text, textStart, embeddings, embStart, paragraphLength, flags);
}
/**
......@@ -290,96 +180,10 @@ public final class Bidi {
* @param lineLimit the offset from the start of the paragraph to the limit of the line.
*/
public Bidi createLineBidi(int lineStart, int lineLimit) {
if (lineStart == 0 && lineLimit == length) {
return this;
}
int lineLength = lineLimit - lineStart;
if (lineStart < 0 ||
lineLimit < lineStart ||
lineLimit > length) {
throw new IllegalArgumentException("range " + lineStart +
" to " + lineLimit +
" is invalid for paragraph of length " + length);
}
AttributedString astr = new AttributedString("");
Bidi newBidi = new Bidi(astr.getIterator());
if (runs == null) {
return new Bidi(dir, baselevel, lineLength, null, null);
} else {
int cwspos = -1;
int[] ncws = null;
if (cws != null) {
int cwss = 0;
int cwsl = cws.length;
while (cwss < cwsl) {
if (cws[cwss] >= lineStart) {
cwsl = cwss;
while (cwsl < cws.length && cws[cwsl] < lineLimit) {
cwsl++;
}
int ll = lineLimit-1;
while (cwsl > cwss && cws[cwsl-1] == ll) {
cwspos = ll; // record start of counter-directional whitespace
--cwsl;
--ll;
}
if (cwspos == lineStart) { // entire line is cws, so ignore
return new Bidi(dir, baselevel, lineLength, null, null);
}
int ncwslen = cwsl - cwss;
if (ncwslen > 0) {
ncws = new int[ncwslen];
for (int i = 0; i < ncwslen; ++i) {
ncws[i] = cws[cwss+i] - lineStart;
}
}
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 bidiBase.setLine(this, bidiBase, newBidi, newBidi.bidiBase,lineStart, lineLimit);
}
/**
......@@ -388,7 +192,7 @@ public final class Bidi {
* @return true if the line is not left-to-right or right-to-left.
*/
public boolean isMixed() {
return dir == DIR_MIXED;
return bidiBase.isMixed();
}
/**
......@@ -396,7 +200,7 @@ public final class Bidi {
* @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 bidiBase.isLeftToRight();
}
/**
......@@ -404,7 +208,7 @@ public final class Bidi {
* @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 bidiBase.isRightToLeft();
}
/**
......@@ -412,7 +216,7 @@ public final class Bidi {
* @return the length of text in the line
*/
public int getLength() {
return length;
return bidiBase.getLength();
}
/**
......@@ -420,7 +224,7 @@ public final class Bidi {
* @return true if the base direction is left-to-right
*/
public boolean baseIsLeftToRight() {
return (baselevel & 0x1) == 0;
return bidiBase.baseIsLeftToRight();
}
/**
......@@ -428,7 +232,7 @@ public final class Bidi {
* @return the base level
*/
public int getBaseLevel() {
return baselevel;
return bidiBase.getParaLevel();
}
/**
......@@ -438,17 +242,7 @@ public final class Bidi {
* @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 bidiBase.getLevelAt(offset);
}
/**
......@@ -456,7 +250,7 @@ public final class Bidi {
* @return the number of level runs
*/
public int getRunCount() {
return runs == null ? 1 : runs.length / 2;
return bidiBase.countRuns();
}
/**
......@@ -465,7 +259,7 @@ public final class Bidi {
* @return the level of the run
*/
public int getRunLevel(int run) {
return runs == null ? baselevel : runs[run * 2 + 1];
return bidiBase.getRunLevel(run);
}
/**
......@@ -475,7 +269,7 @@ public final class Bidi {
* @return the start of the run
*/
public int getRunStart(int run) {
return (runs == null || run == 0) ? 0 : runs[run * 2 - 2];
return bidiBase.getRunStart(run);
}
/**
......@@ -486,7 +280,7 @@ public final class Bidi {
* @return limit the limit of the run
*/
public int getRunLimit(int run) {
return runs == null ? length : runs[run * 2];
return bidiBase.getRunLimit(run);
}
/**
......@@ -501,16 +295,7 @@ public final class Bidi {
* @return true if the range of characters requires bidi analysis
*/
public static boolean requiresBidi(char[] text, int start, int limit) {
CodePointIterator cpi = CodePointIterator.create(text, start, limit);
for (int cp = cpi.next(); cp != CodePointIterator.DONE; cp = cpi.next()) {
if (cp > 0x0590) {
int dc = nativeGetDirectionCode(cp);
if ((RMASK & (1 << dc)) != 0) {
return true;
}
}
}
return false;
return BidiBase.requiresBidi(text, start, limit);
}
/**
......@@ -530,124 +315,14 @@ public final class Bidi {
* @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;
}
BidiBase.reorderVisually(levels, levelStart, objects, objectStart, count);
}
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(int cp);
/** 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();
return bidiBase.toString();
}
}
此差异已折叠。
此差异已折叠。
/*
* Portions Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/*
*******************************************************************************
* (C) Copyright IBM Corp. and others, 1996-2009 - All Rights Reserved *
* *
* The original version of this source code and documentation is copyrighted *
* and owned by IBM, These materials are provided under terms of a License *
* Agreement between IBM and Sun. This technology is protected by multiple *
* US and International patents. This notice and attribution to IBM may not *
* to removed. *
*******************************************************************************
*/
/* Written by Simon Montagu, Matitiahu Allouche
* (ported from C code written by Markus W. Scherer)
*/
package sun.text.bidi;
/**
* A BidiRun represents a sequence of characters at the same embedding level.
* The Bidi algorithm decomposes a piece of text into sequences of characters
* at the same embedding level, each such sequence is called a <quote>run</quote>.
*
* <p>A BidiRun represents such a run by storing its essential properties,
* but does not duplicate the characters which form the run.
*
* <p>The &quot;limit&quot; of the run is the position just after the
* last character, i.e., one more than that position.
*
* <p>This class has no public constructor, and its members cannot be
* modified by users.
*
* @see com.ibm.icu.text.Bidi
*/
public class BidiRun {
int start; /* first logical position of the run */
int limit; /* last visual position of the run +1 */
int insertRemove; /* if >0, flags for inserting LRM/RLM before/after run,
if <0, count of bidi controls within run */
byte level;
/*
* Default constructor
*
* Note that members start and limit of a run instance have different
* meanings depending whether the run is part of the runs array of a Bidi
* object, or if it is a reference returned by getVisualRun() or
* getLogicalRun().
* For a member of the runs array of a Bidi object,
* - start is the first logical position of the run in the source text.
* - limit is one after the last visual position of the run.
* For a reference returned by getLogicalRun() or getVisualRun(),
* - start is the first logical position of the run in the source text.
* - limit is one after the last logical position of the run.
*/
BidiRun()
{
this(0, 0, (byte)0);
}
/*
* Constructor
*/
BidiRun(int start, int limit, byte embeddingLevel)
{
this.start = start;
this.limit = limit;
this.level = embeddingLevel;
}
/*
* Copy the content of a BidiRun instance
*/
void copyFrom(BidiRun run)
{
this.start = run.start;
this.limit = run.limit;
this.level = run.level;
this.insertRemove = run.insertRemove;
}
/**
* Get level of run
*/
public byte getEmbeddingLevel()
{
return level;
}
/**
* Check if run level is even
* @return true if the embedding level of this run is even, i.e. it is a
* left-to-right run.
*/
boolean isEvenRun()
{
return (level & 1) == 0;
}
}
/*
* Portions Copyright 2005-2009 Sun Microsystems, Inc. All Rights Reserved.
* Portions Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -355,7 +355,7 @@ public final class UCharacter
private static int getEuropeanDigit(int ch) {
if ((ch > 0x7a && ch < 0xff21)
|| ch < 0x41 || (ch > 0x5a && ch < 0x61)
|| ch > 0xff5a || (ch > 0xff31 && ch < 0xff41)) {
|| ch > 0xff5a || (ch > 0xff3a && ch < 0xff41)) {
return -1;
}
if (ch <= 0x7a) {
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
......@@ -36,7 +36,8 @@
#define LE_USE_CMEMORY
#ifdef LE_USE_CMEMORY
#include "cmemory.h"
#include <stdlib.h>
#include <string.h>
#endif
#ifndef _LP64
......
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册