Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.base/share/classes/java/text/Bidi.java
41152 views
1
/*
2
* Copyright (c) 2000, 2020, 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
36
package java.text;
37
38
import jdk.internal.icu.text.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
*/
61
public 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
*
180
* @param lineStart the offset from the start of the paragraph to the start of the line.
181
* @param lineLimit the offset from the start of the paragraph to the limit of the line.
182
* @return a {@code Bidi} object
183
*/
184
public Bidi createLineBidi(int lineStart, int lineLimit) {
185
AttributedString astr = new AttributedString("");
186
Bidi newBidi = new Bidi(astr.getIterator());
187
188
return bidiBase.setLine(this, bidiBase, newBidi, newBidi.bidiBase, lineStart, lineLimit);
189
}
190
191
/**
192
* 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
193
* and right-to-left text, or the base direction differs from the direction of the only run of text.
194
*
195
* @return true if the line is not left-to-right or right-to-left.
196
*/
197
public boolean isMixed() {
198
return bidiBase.isMixed();
199
}
200
201
/**
202
* Return true if the line is all left-to-right text and the base direction is left-to-right.
203
*
204
* @return true if the line is all left-to-right text and the base direction is left-to-right
205
*/
206
public boolean isLeftToRight() {
207
return bidiBase.isLeftToRight();
208
}
209
210
/**
211
* Return true if the line is all right-to-left text, and the base direction is right-to-left.
212
* @return true if the line is all right-to-left text, and the base direction is right-to-left
213
*/
214
public boolean isRightToLeft() {
215
return bidiBase.isRightToLeft();
216
}
217
218
/**
219
* Return the length of text in the line.
220
* @return the length of text in the line
221
*/
222
public int getLength() {
223
return bidiBase.getLength();
224
}
225
226
/**
227
* Return true if the base direction is left-to-right.
228
* @return true if the base direction is left-to-right
229
*/
230
public boolean baseIsLeftToRight() {
231
return bidiBase.baseIsLeftToRight();
232
}
233
234
/**
235
* Return the base level (0 if left-to-right, 1 if right-to-left).
236
* @return the base level
237
*/
238
public int getBaseLevel() {
239
return bidiBase.getParaLevel();
240
}
241
242
/**
243
* Return the resolved level of the character at offset. If offset is
244
* {@literal <} 0 or &ge; the length of the line, return the base direction
245
* level.
246
*
247
* @param offset the index of the character for which to return the level
248
* @return the resolved level of the character at offset
249
*/
250
public int getLevelAt(int offset) {
251
return bidiBase.getLevelAt(offset);
252
}
253
254
/**
255
* Return the number of level runs.
256
* @return the number of level runs
257
*/
258
public int getRunCount() {
259
return bidiBase.countRuns();
260
}
261
262
/**
263
* Return the level of the nth logical run in this line.
264
* @param run the index of the run, between 0 and {@code getRunCount()}
265
* @return the level of the run
266
*/
267
public int getRunLevel(int run) {
268
return bidiBase.getRunLevel(run);
269
}
270
271
/**
272
* Return the index of the character at the start of the nth logical run in this line, as
273
* an offset from the start of the line.
274
* @param run the index of the run, between 0 and {@code getRunCount()}
275
* @return the start of the run
276
*/
277
public int getRunStart(int run) {
278
return bidiBase.getRunStart(run);
279
}
280
281
/**
282
* Return the index of the character past the end of the nth logical run in this line, as
283
* an offset from the start of the line. For example, this will return the length
284
* of the line for the last run on the line.
285
* @param run the index of the run, between 0 and {@code getRunCount()}
286
* @return limit the limit of the run
287
*/
288
public int getRunLimit(int run) {
289
return bidiBase.getRunLimit(run);
290
}
291
292
/**
293
* Return true if the specified text requires bidi analysis. If this returns false,
294
* the text will display left-to-right. Clients can then avoid constructing a Bidi object.
295
* Text in the Arabic Presentation Forms area of Unicode is presumed to already be shaped
296
* and ordered for display, and so will not cause this function to return true.
297
*
298
* @param text the text containing the characters to test
299
* @param start the start of the range of characters to test
300
* @param limit the limit of the range of characters to test
301
* @return true if the range of characters requires bidi analysis
302
*/
303
public static boolean requiresBidi(char[] text, int start, int limit) {
304
return BidiBase.requiresBidi(text, start, limit);
305
}
306
307
/**
308
* Reorder the objects in the array into visual order based on their levels.
309
* This is a utility function to use when you have a collection of objects
310
* representing runs of text in logical order, each run containing text
311
* at a single level. The elements at {@code index} from
312
* {@code objectStart} up to {@code objectStart + count}
313
* in the objects array will be reordered into visual order assuming
314
* each run of text has the level indicated by the corresponding element
315
* in the levels array (at {@code index - objectStart + levelStart}).
316
*
317
* @param levels an array representing the bidi level of each object
318
* @param levelStart the start position in the levels array
319
* @param objects the array of objects to be reordered into visual order
320
* @param objectStart the start position in the objects array
321
* @param count the number of objects to reorder
322
*/
323
public static void reorderVisually(byte[] levels, int levelStart, Object[] objects, int objectStart, int count) {
324
BidiBase.reorderVisually(levels, levelStart, objects, objectStart, count);
325
}
326
327
/**
328
* Display the bidi internal state, used in debugging.
329
*/
330
public String toString() {
331
return bidiBase.toString();
332
}
333
334
}
335
336