History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/java/text/Bidi.java (1 of 18352 files). Show all

Unified · Split

java/pkg/java/text/Bidi.java+328−0
@@ -0,0 +1,328 @@
1/*
2 * Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26/*
27 * (C) Copyright IBM Corp. 1999-2003 - All Rights Reserved
28 *
29 * The original version of this source code and documentation is
30 * copyrighted and owned by IBM. These materials are provided
31 * under terms of a License Agreement between IBM and Sun.
32 * This technology is protected by multiple US and International
33 * patents. This notice and attribution to IBM may not be removed.
34 */
35
36package java.text;
37
38import sun.text.bidi.BidiBase;
39
40/**
41 * This class implements the Unicode Bidirectional Algorithm.
42 * <p>
43 * A Bidi object provides information on the bidirectional reordering of the text
44 * used to create it. This is required, for example, to properly display Arabic
45 * or Hebrew text. These languages are inherently mixed directional, as they order
46 * numbers from left-to-right while ordering most other text from right-to-left.
47 * <p>
48 * Once created, a Bidi object can be queried to see if the text it represents is
49 * all left-to-right or all right-to-left. Such objects are very lightweight and
50 * this text is relatively easy to process.
51 * <p>
52 * If there are multiple runs of text, information about the runs can be accessed
53 * by indexing to get the start, limit, and level of a run. The level represents
54 * both the direction and the 'nesting level' of a directional run. Odd levels
55 * are right-to-left, while even levels are left-to-right. So for example level
56 * 0 represents left-to-right text, while level 1 represents right-to-left text, and
57 * level 2 represents left-to-right text embedded in a right-to-left run.
58 *
59 * @since 1.4
60 */
61public final class Bidi {
62
63 /** Constant indicating base direction is left-to-right. */
64 public static final int DIRECTION_LEFT_TO_RIGHT = 0;
65
66 /** Constant indicating base direction is right-to-left. */
67 public static final int DIRECTION_RIGHT_TO_LEFT = 1;
68
69 /**
70 * Constant indicating that the base direction depends on the first strong
71 * directional character in the text according to the Unicode
72 * Bidirectional Algorithm. If no strong directional character is present,
73 * the base direction is left-to-right.
74 */
75 public static final int DIRECTION_DEFAULT_LEFT_TO_RIGHT = -2;
76
77 /**
78 * Constant indicating that the base direction depends on the first strong
79 * directional character in the text according to the Unicode
80 * Bidirectional Algorithm. If no strong directional character is present,
81 * the base direction is right-to-left.
82 */
83 public static final int DIRECTION_DEFAULT_RIGHT_TO_LEFT = -1;
84
85 private BidiBase bidiBase;
86
87 /**
88 * Create Bidi from the given paragraph of text and base direction.
89 * @param paragraph a paragraph of text
90 * @param flags a collection of flags that control the algorithm. The
91 * algorithm understands the flags DIRECTION_LEFT_TO_RIGHT, DIRECTION_RIGHT_TO_LEFT,
92 * DIRECTION_DEFAULT_LEFT_TO_RIGHT, and DIRECTION_DEFAULT_RIGHT_TO_LEFT.
93 * Other values are reserved.
94 */
95 public Bidi(String paragraph, int flags) {
96 if (paragraph == null) {
97 throw new IllegalArgumentException("paragraph is null");
98 }
99
100 bidiBase = new BidiBase(paragraph.toCharArray(), 0, null, 0, paragraph.length(), flags);
101 }
102
103 /**
104 * Create Bidi from the given paragraph of text.
105 * <p>
106 * The RUN_DIRECTION attribute in the text, if present, determines the base
107 * direction (left-to-right or right-to-left). If not present, the base
108 * direction is computes using the Unicode Bidirectional Algorithm, defaulting to left-to-right
109 * if there are no strong directional characters in the text. This attribute, if
110 * present, must be applied to all the text in the paragraph.
111 * <p>
112 * The BIDI_EMBEDDING attribute in the text, if present, represents embedding level
113 * information. Negative values from -1 to -62 indicate overrides at the absolute value
114 * of the level. Positive values from 1 to 62 indicate embeddings. Where values are
115 * zero or not defined, the base embedding level as determined by the base direction
116 * is assumed.
117 * <p>
118 * The NUMERIC_SHAPING attribute in the text, if present, converts European digits to
119 * other decimal digits before running the bidi algorithm. This attribute, if present,
120 * must be applied to all the text in the paragraph.
121 *
122 * @param paragraph a paragraph of text with optional character and paragraph attribute information
123 *
124 * @see java.awt.font.TextAttribute#BIDI_EMBEDDING
125 * @see java.awt.font.TextAttribute#NUMERIC_SHAPING
126 * @see java.awt.font.TextAttribute#RUN_DIRECTION
127 */
128 public Bidi(AttributedCharacterIterator paragraph) {
129 if (paragraph == null) {
130 throw new IllegalArgumentException("paragraph is null");
131 }
132
133 bidiBase = new BidiBase(0, 0);
134 bidiBase.setPara(paragraph);
135 }
136
137 /**
138 * Create Bidi from the given text, embedding, and direction information.
139 * The embeddings array may be null. If present, the values represent embedding level
140 * information. Negative values from -1 to -61 indicate overrides at the absolute value
141 * of the level. Positive values from 1 to 61 indicate embeddings. Where values are
142 * zero, the base embedding level as determined by the base direction is assumed.
143 * @param text an array containing the paragraph of text to process.
144 * @param textStart the index into the text array of the start of the paragraph.
145 * @param embeddings an array containing embedding values for each character in the paragraph.
146 * This can be null, in which case it is assumed that there is no external embedding information.
147 * @param embStart the index into the embedding array of the start of the paragraph.
148 * @param paragraphLength the length of the paragraph in the text and embeddings arrays.
149 * @param flags a collection of flags that control the algorithm. The
150 * algorithm understands the flags DIRECTION_LEFT_TO_RIGHT, DIRECTION_RIGHT_TO_LEFT,
151 * DIRECTION_DEFAULT_LEFT_TO_RIGHT, and DIRECTION_DEFAULT_RIGHT_TO_LEFT.
152 * Other values are reserved.
153 */
154 public Bidi(char[] text, int textStart, byte[] embeddings, int embStart, int paragraphLength, int flags) {
155 if (text == null) {
156 throw new IllegalArgumentException("text is null");
157 }
158 if (paragraphLength < 0) {
159 throw new IllegalArgumentException("bad length: " + paragraphLength);
160 }
161 if (textStart < 0 || paragraphLength > text.length - textStart) {
162 throw new IllegalArgumentException("bad range: " + textStart +
163 " length: " + paragraphLength +
164 " for text of length: " + text.length);
165 }
166 if (embeddings != null && (embStart < 0 || paragraphLength > embeddings.length - embStart)) {
167 throw new IllegalArgumentException("bad range: " + embStart +
168 " length: " + paragraphLength +
169 " for embeddings of length: " + text.length);
170 }
171
172 bidiBase = new BidiBase(text, textStart, embeddings, embStart, paragraphLength, flags);
173 }
174
175 /**
176 * Create a Bidi object representing the bidi information on a line of text within
177 * the paragraph represented by the current Bidi. This call is not required if the
178 * entire paragraph fits on one line.
179 * @param lineStart the offset from the start of the paragraph to the start of the line.
180 * @param lineLimit the offset from the start of the paragraph to the limit of the line.
181 */
182 public Bidi createLineBidi(int lineStart, int lineLimit) {
183 AttributedString astr = new AttributedString("");
184 Bidi newBidi = new Bidi(astr.getIterator());
185
186 return bidiBase.setLine(this, bidiBase, newBidi, newBidi.bidiBase,lineStart, lineLimit);
187 }
188
189 /**
190 * 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
191 * and right-to-left text, or the base direction differs from the direction of the only run of text.
192 * @return true if the line is not left-to-right or right-to-left.
193 */
194 public boolean isMixed() {
195 return bidiBase.isMixed();
196 }
197
198 /**
199 * Return true if the line is all left-to-right text and the base direction is left-to-right.
200 * @return true if the line is all left-to-right text and the base direction is left-to-right
201 */
202 public boolean isLeftToRight() {
203 return bidiBase.isLeftToRight();
204 }
205
206 /**
207 * Return true if the line is all right-to-left text, and the base direction is right-to-left.
208 * @return true if the line is all right-to-left text, and the base direction is right-to-left
209 */
210 public boolean isRightToLeft() {
211 return bidiBase.isRightToLeft();
212 }
213
214 /**
215 * Return the length of text in the line.
216 * @return the length of text in the line
217 */
218 public int getLength() {
219 return bidiBase.getLength();
220 }
221
222 /**
223 * Return true if the base direction is left-to-right.
224 * @return true if the base direction is left-to-right
225 */
226 public boolean baseIsLeftToRight() {
227 return bidiBase.baseIsLeftToRight();
228 }
229
230 /**
231 * Return the base level (0 if left-to-right, 1 if right-to-left).
232 * @return the base level
233 */
234 public int getBaseLevel() {
235 return bidiBase.getParaLevel();
236 }
237
238 /**
239 * Return the resolved level of the character at offset. If offset is <0 or >=
240 * the length of the line, return the base direction level.
241 * @param offset the index of the character for which to return the level
242 * @return the resolved level of the character at offset
243 */
244 public int getLevelAt(int offset) {
245 return bidiBase.getLevelAt(offset);
246 }
247
248 /**
249 * Return the number of level runs.
250 * @return the number of level runs
251 */
252 public int getRunCount() {
253 return bidiBase.countRuns();
254 }
255
256 /**
257 * Return the level of the nth logical run in this line.
258 * @param run the index of the run, between 0 and <code>getRunCount()</code>
259 * @return the level of the run
260 */
261 public int getRunLevel(int run) {
262 return bidiBase.getRunLevel(run);
263 }
264
265 /**
266 * Return the index of the character at the start of the nth logical run in this line, as
267 * an offset from the start of the line.
268 * @param run the index of the run, between 0 and <code>getRunCount()</code>
269 * @return the start of the run
270 */
271 public int getRunStart(int run) {
272 return bidiBase.getRunStart(run);
273 }
274
275 /**
276 * Return the index of the character past the end of the nth logical run in this line, as
277 * an offset from the start of the line. For example, this will return the length
278 * of the line for the last run on the line.
279 * @param run the index of the run, between 0 and <code>getRunCount()</code>
280 * @return limit the limit of the run
281 */
282 public int getRunLimit(int run) {
283 return bidiBase.getRunLimit(run);
284 }
285
286 /**
287 * Return true if the specified text requires bidi analysis. If this returns false,
288 * the text will display left-to-right. Clients can then avoid constructing a Bidi object.
289 * Text in the Arabic Presentation Forms area of Unicode is presumed to already be shaped
290 * and ordered for display, and so will not cause this function to return true.
291 *
292 * @param text the text containing the characters to test
293 * @param start the start of the range of characters to test
294 * @param limit the limit of the range of characters to test
295 * @return true if the range of characters requires bidi analysis
296 */
297 public static boolean requiresBidi(char[] text, int start, int limit) {
298 return BidiBase.requiresBidi(text, start, limit);
299 }
300
301 /**
302 * Reorder the objects in the array into visual order based on their levels.
303 * This is a utility function to use when you have a collection of objects
304 * representing runs of text in logical order, each run containing text
305 * at a single level. The elements at <code>index</code> from
306 * <code>objectStart</code> up to <code>objectStart + count</code>
307 * in the objects array will be reordered into visual order assuming
308 * each run of text has the level indicated by the corresponding element
309 * in the levels array (at <code>index - objectStart + levelStart</code>).
310 *
311 * @param levels an array representing the bidi level of each object
312 * @param levelStart the start position in the levels array
313 * @param objects the array of objects to be reordered into visual order
314 * @param objectStart the start position in the objects array
315 * @param count the number of objects to reorder
316 */
317 public static void reorderVisually(byte[] levels, int levelStart, Object[] objects, int objectStart, int count) {
318 BidiBase.reorderVisually(levels, levelStart, objects, objectStart, count);
319 }
320
321 /**
322 * Display the bidi internal state, used in debugging.
323 */
324 public String toString() {
325 return bidiBase.toString();
326 }
327
328}