18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
23 *
24 */
25
26 /*
27 *******************************************************************************
28 *
29 * Copyright (C) 1999-2003, International Business Machines
30 * Corporation and others. All Rights Reserved.
31 *
32 *******************************************************************************
33 */
34
35 package sun.font;
36
37 /**
38 * <code>ScriptRun</code> is used to find runs of characters in
39 * the same script, as defined in the <code>Script</code> class.
40 * It implements a simple iterator over an array of characters.
41 * The iterator will assign <code>COMMON</code> and <code>INHERITED</code>
42 * characters to the same script as the preceding characters. If the
43 * COMMON and INHERITED characters are first, they will be assigned to
44 * the same script as the following characters.
45 *
46 * The iterator will try to match paired punctuation. If it sees an
47 * opening punctuation character, it will remember the script that
48 * was assigned to that character, and assign the same script to the
49 * matching closing punctuation.
50 *
51 * No attempt is made to combine related scripts into a single run. In
52 * particular, Hiragana, Katakana, and Han characters will appear in seperate
53 * runs.
54
55 * Here is an example of how to iterate over script runs:
56 * <pre>
57 * void printScriptRuns(char[] text)
58 * {
59 * ScriptRun scriptRun = new ScriptRun(text, 0, text.length);
60 *
61 * while (scriptRun.next()) {
71 *
72 */
73 public final class ScriptRun
74 {
75 private char[] text; // fixed once set by constructor
76 private int textStart;
77 private int textLimit;
78
79 private int scriptStart; // change during iteration
80 private int scriptLimit;
81 private int scriptCode;
82
83 private int stack[]; // stack used to handle paired punctuation if encountered
84 private int parenSP;
85
86 public ScriptRun() {
87 // must call init later or we die.
88 }
89
90 /**
91 * Construct a <code>ScriptRun</code> object which iterates over a subrange
92 * of the given characetrs.
93 *
94 * @param chars the array of characters over which to iterate.
95 * @param start the index of the first character over which to iterate
96 * @param count the number of characters over which to iterate
97 */
98 public ScriptRun(char[] chars, int start, int count)
99 {
100 init(chars, start, count);
101 }
102
103 public void init(char[] chars, int start, int count)
104 {
105 if (chars == null || start < 0 || count < 0 || count > chars.length - start) {
106 throw new IllegalArgumentException();
107 }
108
109 text = chars;
110 textStart = start;
111 textLimit = start + count;
128 /**
129 * Get the index of the first character after the current script run.
130 *
131 * @return the index of the first character after the current script run.
132 */
133 public int getScriptLimit() {
134 return scriptLimit;
135 }
136
137 /**
138 * Get the script code for the script of the current script run.
139 *
140 * @return the script code for the script of the current script run.
141 * @see Script
142 */
143 public int getScriptCode() {
144 return scriptCode;
145 }
146
147 /**
148 * Find the next script run. Returns <code>false</code> if there
149 * isn't another run, returns <code>true</code> if there is.
150 *
151 * @return <code>false</code> if there isn't another run, <code>true</code> if there is.
152 */
153 public boolean next() {
154 int startSP = parenSP; // used to find the first new open character
155
156 // if we've fallen off the end of the text, we're done
157 if (scriptLimit >= textLimit) {
158 return false;
159 }
160
161 scriptCode = Script.COMMON;
162 scriptStart = scriptLimit;
163
164 int ch;
165
166 while ((ch = nextCodePoint()) != DONE) {
167 int sc = ScriptRunData.getScript(ch);
168 int pairIndex = sc == Script.COMMON ? getPairIndex(ch) : -1;
169
170 // Paired character handling:
171 //
256 }
257 return ch;
258 }
259
260 private void pushback(int ch) {
261 if (ch >= 0) {
262 if (ch >= 0x10000) {
263 scriptLimit -= 2;
264 } else {
265 scriptLimit -= 1;
266 }
267 }
268 }
269
270 /**
271 * Compare two script codes to see if they are in the same script. If one script is
272 * a strong script, and the other is INHERITED or COMMON, it will compare equal.
273 *
274 * @param scriptOne one of the script codes.
275 * @param scriptTwo the other script code.
276 * @return <code>true</code> if the two scripts are the same.
277 * @see Script
278 */
279 private static boolean sameScript(int scriptOne, int scriptTwo) {
280 return scriptOne == scriptTwo || scriptOne <= Script.INHERITED || scriptTwo <= Script.INHERITED;
281 }
282
283 /**
284 * Find the highest bit that's set in a word. Uses a binary search through
285 * the bits.
286 *
287 * @param n the word in which to find the highest bit that's set.
288 * @return the bit number (counting from the low order bit) of the highest bit.
289 */
290 private static byte highBit(int n)
291 {
292 if (n <= 0) {
293 return -32;
294 }
295
296 byte bit = 0;
|
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
23 *
24 */
25
26 /*
27 *******************************************************************************
28 *
29 * Copyright (C) 1999-2003, International Business Machines
30 * Corporation and others. All Rights Reserved.
31 *
32 *******************************************************************************
33 */
34
35 package sun.font;
36
37 /**
38 * {@code ScriptRun} is used to find runs of characters in
39 * the same script, as defined in the {@code Script} class.
40 * It implements a simple iterator over an array of characters.
41 * The iterator will assign {@code COMMON} and {@code INHERITED}
42 * characters to the same script as the preceding characters. If the
43 * COMMON and INHERITED characters are first, they will be assigned to
44 * the same script as the following characters.
45 *
46 * The iterator will try to match paired punctuation. If it sees an
47 * opening punctuation character, it will remember the script that
48 * was assigned to that character, and assign the same script to the
49 * matching closing punctuation.
50 *
51 * No attempt is made to combine related scripts into a single run. In
52 * particular, Hiragana, Katakana, and Han characters will appear in seperate
53 * runs.
54
55 * Here is an example of how to iterate over script runs:
56 * <pre>
57 * void printScriptRuns(char[] text)
58 * {
59 * ScriptRun scriptRun = new ScriptRun(text, 0, text.length);
60 *
61 * while (scriptRun.next()) {
71 *
72 */
73 public final class ScriptRun
74 {
75 private char[] text; // fixed once set by constructor
76 private int textStart;
77 private int textLimit;
78
79 private int scriptStart; // change during iteration
80 private int scriptLimit;
81 private int scriptCode;
82
83 private int stack[]; // stack used to handle paired punctuation if encountered
84 private int parenSP;
85
86 public ScriptRun() {
87 // must call init later or we die.
88 }
89
90 /**
91 * Construct a {@code ScriptRun} object which iterates over a subrange
92 * of the given characetrs.
93 *
94 * @param chars the array of characters over which to iterate.
95 * @param start the index of the first character over which to iterate
96 * @param count the number of characters over which to iterate
97 */
98 public ScriptRun(char[] chars, int start, int count)
99 {
100 init(chars, start, count);
101 }
102
103 public void init(char[] chars, int start, int count)
104 {
105 if (chars == null || start < 0 || count < 0 || count > chars.length - start) {
106 throw new IllegalArgumentException();
107 }
108
109 text = chars;
110 textStart = start;
111 textLimit = start + count;
128 /**
129 * Get the index of the first character after the current script run.
130 *
131 * @return the index of the first character after the current script run.
132 */
133 public int getScriptLimit() {
134 return scriptLimit;
135 }
136
137 /**
138 * Get the script code for the script of the current script run.
139 *
140 * @return the script code for the script of the current script run.
141 * @see Script
142 */
143 public int getScriptCode() {
144 return scriptCode;
145 }
146
147 /**
148 * Find the next script run. Returns {@code false} if there
149 * isn't another run, returns {@code true} if there is.
150 *
151 * @return {@code false} if there isn't another run, {@code true} if there is.
152 */
153 public boolean next() {
154 int startSP = parenSP; // used to find the first new open character
155
156 // if we've fallen off the end of the text, we're done
157 if (scriptLimit >= textLimit) {
158 return false;
159 }
160
161 scriptCode = Script.COMMON;
162 scriptStart = scriptLimit;
163
164 int ch;
165
166 while ((ch = nextCodePoint()) != DONE) {
167 int sc = ScriptRunData.getScript(ch);
168 int pairIndex = sc == Script.COMMON ? getPairIndex(ch) : -1;
169
170 // Paired character handling:
171 //
256 }
257 return ch;
258 }
259
260 private void pushback(int ch) {
261 if (ch >= 0) {
262 if (ch >= 0x10000) {
263 scriptLimit -= 2;
264 } else {
265 scriptLimit -= 1;
266 }
267 }
268 }
269
270 /**
271 * Compare two script codes to see if they are in the same script. If one script is
272 * a strong script, and the other is INHERITED or COMMON, it will compare equal.
273 *
274 * @param scriptOne one of the script codes.
275 * @param scriptTwo the other script code.
276 * @return {@code true} if the two scripts are the same.
277 * @see Script
278 */
279 private static boolean sameScript(int scriptOne, int scriptTwo) {
280 return scriptOne == scriptTwo || scriptOne <= Script.INHERITED || scriptTwo <= Script.INHERITED;
281 }
282
283 /**
284 * Find the highest bit that's set in a word. Uses a binary search through
285 * the bits.
286 *
287 * @param n the word in which to find the highest bit that's set.
288 * @return the bit number (counting from the low order bit) of the highest bit.
289 */
290 private static byte highBit(int n)
291 {
292 if (n <= 0) {
293 return -32;
294 }
295
296 byte bit = 0;
|