summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLynn Kues <lkues>2003-05-19 17:51:19 +0000
committerLynn Kues <lkues>2003-05-19 17:51:19 +0000
commit8c259c2fdd0bffd2ea76820f5d04cd4a52c2e4a7 (patch)
tree7ea82cd2b6a36ec03eb86d9af6f5c952cd68fa40
parent5ba9287f6caa82e9989a01a562fc97d015948ef7 (diff)
downloadeclipse.platform.swt-8c259c2fdd0bffd2ea76820f5d04cd4a52c2e4a7.tar.gz
eclipse.platform.swt-8c259c2fdd0bffd2ea76820f5d04cd4a52c2e4a7.tar.xz
eclipse.platform.swt-8c259c2fdd0bffd2ea76820f5d04cd4a52c2e4a7.zip
30434
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/DisplayRenderer.java3
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledText.java531
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledTextBidi.java118
3 files changed, 344 insertions, 308 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/DisplayRenderer.java b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/DisplayRenderer.java
index 424413010b..539a813102 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/DisplayRenderer.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/DisplayRenderer.java
@@ -76,6 +76,7 @@ protected void drawLineSelectionBackground(String line, int lineOffset, StyleRan
int lineEndSpaceWidth = getLineEndSpaceWidth();
int lineHeight = getLineHeight();
boolean wordWrap = parent.internalGetWordWrap();
+ boolean isRightOriented = (parent.getStyle() & SWT.RIGHT_TO_LEFT) != 0;
if (selectionEnd == selectionStart || selectionEnd < 0 || selectionStart > lineLength) {
return;
@@ -129,7 +130,7 @@ protected void drawLineSelectionBackground(String line, int lineOffset, StyleRan
// if the selection extends past this line, render an additional
// whitespace background at the end of the line to represent the
// selected line break
- if (bidi != null && selectionEnd > 0 && bidi.isRightToLeft(selectionEnd - 1)) {
+ if (bidi != null && selectionEnd > 0 && (bidi.isRightToLeft(selectionEnd - 1) || (isRightOriented && bidi.isRightToLeft(selectionEnd - 1) == false))) {
int lineEndX = bidi.getTextWidth();
gc.fillRectangle(lineEndX - horizontalScrollOffset + leftMargin, paintY, lineEndSpaceWidth, lineHeight);
}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledText.java b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledText.java
index d3055db63d..aab59f553c 100755
--- a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledText.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledText.java
@@ -1596,7 +1596,8 @@ public StyledText(Composite parent, int style) {
super.setForeground(getForeground());
super.setBackground(getBackground());
Display display = getDisplay();
- isBidi = StyledTextBidi.isBidiPlatform();
+ boolean isRightOriented = (getStyle() & SWT.RIGHT_TO_LEFT) != 0;
+ isBidi = StyledTextBidi.isBidiPlatform() || isRightOriented;
if ((style & SWT.READ_ONLY) != 0) {
setEditable(false);
}
@@ -1618,6 +1619,9 @@ public StyledText(Composite parent, int style) {
}
else {
createCaretBitmaps();
+ if (isRightOriented) {
+ BidiUtil.setKeyboardLanguage(BidiUtil.KEYBOARD_BIDI);
+ }
new Caret(this, SWT.NULL);
setBidiCaretDirection();
Runnable runnable = new Runnable() {
@@ -2237,32 +2241,49 @@ void createKeyBindings() {
setKeyBinding(SWT.ARROW_DOWN, ST.LINE_DOWN);
setKeyBinding(SWT.HOME, ST.LINE_START);
setKeyBinding(SWT.END, ST.LINE_END);
- setKeyBinding(SWT.ARROW_LEFT, ST.COLUMN_PREVIOUS);
- setKeyBinding(SWT.ARROW_RIGHT, ST.COLUMN_NEXT);
setKeyBinding(SWT.PAGE_UP, ST.PAGE_UP);
setKeyBinding(SWT.PAGE_DOWN, ST.PAGE_DOWN);
- setKeyBinding(SWT.ARROW_LEFT | SWT.MOD1, ST.WORD_PREVIOUS);
- setKeyBinding(SWT.ARROW_RIGHT | SWT.MOD1, ST.WORD_NEXT);
setKeyBinding(SWT.HOME | SWT.MOD1, ST.TEXT_START);
setKeyBinding(SWT.END | SWT.MOD1, ST.TEXT_END);
setKeyBinding(SWT.PAGE_UP | SWT.MOD1, ST.WINDOW_START);
setKeyBinding(SWT.PAGE_DOWN | SWT.MOD1, ST.WINDOW_END);
+ if ((getStyle() & SWT.RIGHT_TO_LEFT) == 0) {
+ setKeyBinding(SWT.ARROW_LEFT, ST.COLUMN_PREVIOUS);
+ setKeyBinding(SWT.ARROW_RIGHT, ST.COLUMN_NEXT);
+ setKeyBinding(SWT.ARROW_LEFT | SWT.MOD1, ST.WORD_PREVIOUS);
+ setKeyBinding(SWT.ARROW_RIGHT | SWT.MOD1, ST.WORD_NEXT);
+ }
+ else {
+ setKeyBinding(SWT.ARROW_LEFT, ST.COLUMN_NEXT);
+ setKeyBinding(SWT.ARROW_RIGHT, ST.COLUMN_PREVIOUS);
+ setKeyBinding(SWT.ARROW_LEFT | SWT.MOD1, ST.WORD_NEXT);
+ setKeyBinding(SWT.ARROW_RIGHT | SWT.MOD1, ST.WORD_PREVIOUS);
+ }
+
// Selection
setKeyBinding(SWT.ARROW_UP | SWT.MOD2, ST.SELECT_LINE_UP);
setKeyBinding(SWT.ARROW_DOWN | SWT.MOD2, ST.SELECT_LINE_DOWN);
setKeyBinding(SWT.HOME | SWT.MOD2, ST.SELECT_LINE_START);
setKeyBinding(SWT.END | SWT.MOD2, ST.SELECT_LINE_END);
- setKeyBinding(SWT.ARROW_LEFT | SWT.MOD2, ST.SELECT_COLUMN_PREVIOUS);
- setKeyBinding(SWT.ARROW_RIGHT | SWT.MOD2, ST.SELECT_COLUMN_NEXT);
setKeyBinding(SWT.PAGE_UP | SWT.MOD2, ST.SELECT_PAGE_UP);
setKeyBinding(SWT.PAGE_DOWN | SWT.MOD2, ST.SELECT_PAGE_DOWN);
- setKeyBinding(SWT.ARROW_LEFT | SWT.MOD1 | SWT.MOD2, ST.SELECT_WORD_PREVIOUS);
- setKeyBinding(SWT.ARROW_RIGHT | SWT.MOD1 | SWT.MOD2, ST.SELECT_WORD_NEXT);
setKeyBinding(SWT.HOME | SWT.MOD1 | SWT.MOD2, ST.SELECT_TEXT_START);
setKeyBinding(SWT.END | SWT.MOD1 | SWT.MOD2, ST.SELECT_TEXT_END);
setKeyBinding(SWT.PAGE_UP | SWT.MOD1 | SWT.MOD2, ST.SELECT_WINDOW_START);
setKeyBinding(SWT.PAGE_DOWN | SWT.MOD1 | SWT.MOD2, ST.SELECT_WINDOW_END);
-
+ if ((getStyle() & SWT.RIGHT_TO_LEFT) == 0) {
+ setKeyBinding(SWT.ARROW_LEFT | SWT.MOD2, ST.SELECT_COLUMN_PREVIOUS);
+ setKeyBinding(SWT.ARROW_RIGHT | SWT.MOD2, ST.SELECT_COLUMN_NEXT);
+ setKeyBinding(SWT.ARROW_LEFT | SWT.MOD1 | SWT.MOD2, ST.SELECT_WORD_PREVIOUS);
+ setKeyBinding(SWT.ARROW_RIGHT | SWT.MOD1 | SWT.MOD2, ST.SELECT_WORD_NEXT);
+ }
+ else {
+ setKeyBinding(SWT.ARROW_LEFT | SWT.MOD2, ST.SELECT_COLUMN_NEXT);
+ setKeyBinding(SWT.ARROW_RIGHT | SWT.MOD2, ST.SELECT_COLUMN_PREVIOUS);
+ setKeyBinding(SWT.ARROW_LEFT | SWT.MOD1 | SWT.MOD2, ST.SELECT_WORD_NEXT);
+ setKeyBinding(SWT.ARROW_RIGHT | SWT.MOD1 | SWT.MOD2, ST.SELECT_WORD_PREVIOUS);
+ }
+
// Modification
// Cut, Copy, Paste
setKeyBinding('X' | SWT.MOD1, ST.CUT);
@@ -2289,6 +2310,7 @@ void createKeyBindings() {
*/
void createCaretBitmaps() {
int caretWidth = BIDI_CARET_WIDTH;
+ int gcStyle = getStyle() & (SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT);
Display display = getDisplay();
if (caretPalette == null) {
@@ -2299,7 +2321,9 @@ void createCaretBitmaps() {
}
ImageData imageData = new ImageData(caretWidth, lineHeight, 1, caretPalette);
leftCaretBitmap = new Image(display, imageData);
- GC gc = new GC (leftCaretBitmap);
+ // mirror the caret gc because when the bitmap is rendered on the screen it will be
+ // mirrored since the GC for the canvas is mirrored
+ GC gc = new GC (leftCaretBitmap, gcStyle);
gc.setForeground(display.getSystemColor(SWT.COLOR_WHITE));
gc.drawLine(0,0,0,lineHeight);
gc.drawLine(0,0,caretWidth-1,0);
@@ -2310,7 +2334,9 @@ void createCaretBitmaps() {
rightCaretBitmap.dispose();
}
rightCaretBitmap = new Image(display, imageData);
- gc = new GC (rightCaretBitmap);
+ // mirror the caret gc because when the bitmap is rendered on the screen it will be
+ // mirrored since the GC for the canvas is mirrored
+ gc = new GC (rightCaretBitmap, gcStyle);
gc.setForeground(display.getSystemColor(SWT.COLOR_WHITE));
gc.drawLine(caretWidth-1,0,caretWidth-1,lineHeight);
gc.drawLine(0,0,caretWidth-1,0);
@@ -2367,11 +2393,11 @@ void doAutoScroll(Event event) {
}
else
if (event.x < leftMargin && wordWrap == false) {
- doAutoScroll(SWT.LEFT);
+ doAutoScroll(ST.COLUMN_PREVIOUS);
}
else
if (event.x > area.width - leftMargin - rightMargin && wordWrap == false) {
- doAutoScroll(SWT.RIGHT);
+ doAutoScroll(ST.COLUMN_NEXT);
}
else {
endAutoScroll();
@@ -2381,7 +2407,7 @@ void doAutoScroll(Event event) {
* Initiates autoscrolling.
* <p>
*
- * @param direction SWT.UP, SWT.DOWN, SWT.RIGHT, SWT.LEFT
+ * @param direction SWT.UP, SWT.DOWN, SWT.COLUMN_NEXT, SWT.COLUMN_PREVIOUS
*/
void doAutoScroll(int direction) {
Runnable timer = null;
@@ -2413,24 +2439,24 @@ void doAutoScroll(int direction) {
}
}
};
- } else if (direction == SWT.RIGHT) {
+ } else if (direction == ST.COLUMN_NEXT) {
timer = new Runnable() {
public void run() {
- if (autoScrollDirection == SWT.RIGHT) {
- doColumnRight();
+ if (autoScrollDirection == ST.COLUMN_NEXT) {
+ doVisualNext();
setMouseWordSelectionAnchor();
- doSelection(SWT.RIGHT);
+ doMouseSelection();
display.timerExec(TIMER_INTERVAL, this);
}
}
};
- } else if (direction == SWT.LEFT) {
+ } else if (direction == ST.COLUMN_PREVIOUS) {
timer = new Runnable() {
public void run() {
- if (autoScrollDirection == SWT.LEFT) {
- doColumnLeft();
+ if (autoScrollDirection == ST.COLUMN_PREVIOUS) {
+ doVisualPrevious();
setMouseWordSelectionAnchor();
- doSelection(SWT.LEFT);
+ doMouseSelection();
display.timerExec(TIMER_INTERVAL, this);
}
}
@@ -2471,208 +2497,6 @@ void doBackspace() {
}
}
/**
- * Moves the caret one character to the left. Do not go to the previous line.
- * When in a bidi locale and at a R2L character the caret is moved to the
- * beginning of the R2L segment (visually right) and then one character to the
- * left (visually left because it's now in a L2R segment).
- */
-void doColumnLeft() {
- int line = content.getLineAtOffset(caretOffset);
- int lineOffset = content.getOffsetAtLine(line);
- int offsetInLine = caretOffset - lineOffset;
-
- if (isBidi()) {
- String lineText = content.getLine(line);
- int lineLength = lineText.length();
- GC gc = getGC();
- StyledTextBidi bidi = getStyledTextBidi(lineText, lineOffset, gc);
-
- if (horizontalScrollOffset > 0 || offsetInLine > 0) {
- if (offsetInLine < lineLength && bidi.isRightToLeft(offsetInLine)) {
- // advance caret logically if in R2L segment (move visually left)
- caretOffset++;
- doSelection(SWT.RIGHT);
- if (caretOffset - lineOffset == lineLength) {
- // if the line end is reached in a R2L segment, make the
- // caret position (visual left border) visible before
- // jumping to segment start
- showCaret();
- }
- // end of R2L segment reached (visual left side)?
- if (bidi.isRightToLeft(caretOffset - lineOffset) == false) {
- if (bidi.getTextPosition(caretOffset - lineOffset) < horizontalScrollOffset) {
- // make beginning of R2L segment visible before going
- // left, to L2R segment important if R2L segment ends
- // at visual left in order to scroll all the way to the
- // left. Fixes 1GKM3XS
- showCaret();
- }
- // go to beginning of R2L segment (visually end of next L2R
- // segment)/beginning of line
- caretOffset--;
- while (caretOffset - lineOffset > 0 &&
- bidi.isRightToLeft(caretOffset - lineOffset)) {
- caretOffset--;
- }
- }
- }
- else
- if (offsetInLine == lineLength &&
- bidi.getTextPosition(lineLength) != XINSET) {
- // at logical line end in R2L segment but there's more text (a
- // L2R segment) go to end of R2L segment (visually left of next
- // L2R segment)/end of line
- caretOffset--;
- while (caretOffset - lineOffset > 0 &&
- bidi.isRightToLeft(caretOffset - lineOffset)) {
- caretOffset--;
- }
- }
- else
- if (offsetInLine > 0 && bidi.isRightToLeft(offsetInLine) == false) {
- // decrease caret logically if in L2R segment (move visually left)
- caretOffset--;
- doSelection(SWT.LEFT);
- // end of L2R segment reached (visual left side of preceeding R2L
- // segment)?
- if (caretOffset - lineOffset > 0 &&
- bidi.isRightToLeft(caretOffset - lineOffset - 1)) {
- // go to beginning of R2L segment (visually start of next L2R
- // segment)/beginning of line
- caretOffset--;
- while (caretOffset - lineOffset > 0 &&
- bidi.isRightToLeft(caretOffset - lineOffset - 1)) {
- caretOffset--;
- }
- }
- }
- // if new caret position is to the left of the client area
- if (bidi.getTextPosition(caretOffset - lineOffset) < horizontalScrollOffset) {
- // scroll to the caret position
- showCaret();
- }
- else {
- // otherwise just update caret position without scrolling it into view
- setBidiCaretLocation(null);
- setBidiKeyboardLanguage();
- }
- // Beginning of line reached (auto scroll finished) but not scrolled
- // completely to the left? Fixes 1GKM193
- if (caretOffset - lineOffset == 0 && horizontalScrollOffset > 0 &&
- horizontalScrollOffset <= XINSET) {
- scrollHorizontalBar(-horizontalScrollOffset);
- }
- }
- gc.dispose();
- }
- else
- if (offsetInLine > 0) {
- caretOffset--;
- showCaret();
- }
-}
-/**
- * Moves the caret one character to the right. Do not go to the next line.
- * When in a bidi locale and at a R2L character the caret is moved to the
- * end of the R2L segment (visually left) and then one character to the
- * right (visually right because it's now in a L2R segment).
- */
-void doColumnRight() {
- int line = content.getLineAtOffset(caretOffset);
- int lineOffset = content.getOffsetAtLine(line);
- int offsetInLine = caretOffset - lineOffset;
- String lineText = content.getLine(line);
- int lineLength = lineText.length();
-
- if (isBidi()) {
- GC gc = getGC();
- StyledTextBidi bidi = getStyledTextBidi(lineText, lineOffset, gc);
- if (bidi.getTextWidth() + leftMargin > horizontalScrollOffset + getClientArea().width ||
- offsetInLine < lineLength) {
- if (bidi.isRightToLeft(offsetInLine) == false &&
- offsetInLine < lineLength) {
- // advance caret logically if in L2R segment (move visually right)
- caretOffset++;
- doSelection(SWT.RIGHT);
- // end of L2R segment reached (visual right side)?
- if (bidi.isRightToLeft(caretOffset - lineOffset)) {
- // go to end of R2L segment (visually left of next R2L segment)/
- // end of line
- caretOffset++;
- while (caretOffset < lineOffset + lineLength &&
- bidi.isRightToLeft(caretOffset - lineOffset)) {
- caretOffset++;
- }
- }
- }
- else
- if (offsetInLine > 0 &&
- (bidi.isRightToLeft(offsetInLine) ||
- bidi.getTextWidth() + leftMargin > horizontalScrollOffset + getClientArea().width ||
- offsetInLine < lineLength)) {
- // advance caret visually if in R2L segment or logically at line end
- // but right end of line is not fully visible yet
- caretOffset--;
- doSelection(SWT.LEFT);
- offsetInLine = caretOffset - lineOffset;
- // end of R2L segment reached (visual right side)?
- if (offsetInLine > 0 && bidi.isRightToLeft(offsetInLine) == false) {
- // go to end of R2L segment (visually left of next L2R segment)/
- // end of line
- caretOffset++;
- while (caretOffset < lineOffset + lineLength &&
- bidi.isRightToLeft(caretOffset - lineOffset)) {
- caretOffset++;
- }
- }
- }
- else
- if (offsetInLine == 0 && bidi.getTextPosition(0) != bidi.getTextWidth()) {
- // at logical line start in R2L segment but there's more text (a L2R
- // segment) go to end of R2L segment (visually left of next L2R
- // segment)/end of line
- caretOffset++;
- while (caretOffset < lineOffset + lineLength &&
- bidi.isRightToLeft(caretOffset - lineOffset - 1)) {
- caretOffset++;
- }
- }
- offsetInLine = caretOffset - lineOffset;
- // if new caret position is to the right of the client area
- if (bidi.getTextPosition(offsetInLine) >= horizontalScrollOffset) {
- // scroll to the caret position
- showCaret();
- }
- else {
- // otherwise just update caret position without scrolling it into view
- setBidiCaretLocation(null);
- setBidiKeyboardLanguage();
- }
- if (offsetInLine > 0 && offsetInLine < lineLength - 1) {
- int clientAreaEnd = horizontalScrollOffset + getClientArea().width;
- boolean directionChange = bidi.isRightToLeft(offsetInLine - 1) == false && bidi.isRightToLeft(offsetInLine);
- int textWidth = bidi.getTextWidth() + leftMargin;
- // between L2R and R2L segment and second character of R2L segment is
- // left of right border and logical line end is left of right border
- // but visual line end is not left of right border
- if (directionChange &&
- bidi.isRightToLeft(offsetInLine + 1) &&
- bidi.getTextPosition(offsetInLine + 1) + leftMargin < clientAreaEnd &&
- bidi.getTextPosition(lineLength) + leftMargin < clientAreaEnd && textWidth > clientAreaEnd) {
- // make visual line end visible
- scrollHorizontalBar(textWidth - clientAreaEnd);
- }
- }
- }
- gc.dispose();
- }
- else
- if (offsetInLine < lineLength) {
- caretOffset++;
- showCaret();
- }
-}
-/**
* Replaces the selection with the character or insert the character at the
* current caret position if no selection exists.
* If a carriage return was typed replace it with the line break character
@@ -2864,7 +2688,9 @@ int doLineDown() {
if (caretLine < content.getLineCount() - 1) {
caretLine++;
if (isBidi()) {
- caretOffset = getBidiOffsetAtMouseLocation(columnX, caretLine);
+ int offsetDirection[] = getBidiOffsetAtMouseLocation(columnX, caretLine);
+ caretOffset = offsetDirection[0];
+ lastCaretDirection = offsetDirection[1];
}
else {
caretOffset = getOffsetAtMouseLocation(columnX, caretLine);
@@ -2911,7 +2737,9 @@ int doLineUp() {
if (caretLine > 0) {
caretLine--;
if (isBidi()) {
- caretOffset = getBidiOffsetAtMouseLocation(columnX, caretLine);
+ int offsetDirection[] = getBidiOffsetAtMouseLocation(columnX, caretLine);
+ caretOffset = offsetDirection[0];
+ lastCaretDirection = offsetDirection[1];
}
else {
caretOffset = getOffsetAtMouseLocation(columnX, caretLine);
@@ -2933,6 +2761,7 @@ void doMouseLocationChange(int x, int y, boolean select) {
int lineCount = content.getLineCount();
int newCaretOffset;
int newCaretLine;
+ int newCaretDirection = lastCaretDirection;
if (line > lineCount - 1) {
line = lineCount - 1;
@@ -2943,7 +2772,9 @@ void doMouseLocationChange(int x, int y, boolean select) {
return;
}
if (isBidi()) {
- newCaretOffset = getBidiOffsetAtMouseLocation(x, line);
+ int offsetDirection[] = getBidiOffsetAtMouseLocation(x, line);
+ newCaretOffset = offsetDirection[0];
+ newCaretDirection = offsetDirection[1];
}
else {
newCaretOffset = getOffsetAtMouseLocation(x, line);
@@ -2957,8 +2788,9 @@ void doMouseLocationChange(int x, int y, boolean select) {
// a different line? If not the autoscroll selection
// could be incorrectly reset. Fixes 1GKM3XS
if (y >= 0 && y < getClientArea().height &&
- (x >= 0 || newCaretLine != content.getLineAtOffset(caretOffset))) {
+ (x >= 0 && x < getClientArea().width || newCaretLine != content.getLineAtOffset(caretOffset))) {
if (newCaretOffset != caretOffset) {
+ lastCaretDirection = newCaretDirection;
caretOffset = newCaretOffset;
if (select) {
doMouseSelection();
@@ -2967,6 +2799,7 @@ void doMouseLocationChange(int x, int y, boolean select) {
}
}
if (select == false) {
+ lastCaretDirection = newCaretDirection;
clearSelection(true);
}
}
@@ -2977,10 +2810,10 @@ void doMouseSelection() {
if (caretOffset <= selection.x ||
(caretOffset > selection.x &&
caretOffset < selection.y && selectionAnchor == selection.x)) {
- doSelection(SWT.LEFT);
+ doSelection(ST.COLUMN_PREVIOUS);
}
else {
- doSelection(SWT.RIGHT);
+ doSelection(ST.COLUMN_NEXT);
}
}
/**
@@ -3057,13 +2890,15 @@ void doPageDown(boolean select) {
scrollLines = Math.max(1, scrollLines);
caretLine += scrollLines;
if (isBidi()) {
- caretOffset = getBidiOffsetAtMouseLocation(columnX, caretLine);
+ int offsetDirection[] = getBidiOffsetAtMouseLocation(columnX, caretLine);
+ caretOffset = offsetDirection[0];
+ lastCaretDirection = offsetDirection[1];
}
else {
caretOffset = getOffsetAtMouseLocation(columnX, caretLine);
}
if (select) {
- doSelection(SWT.RIGHT);
+ doSelection(ST.COLUMN_NEXT);
}
// scroll one page down or to the bottom
scrollOffset = verticalScrollOffset + scrollLines * getVerticalIncrement();
@@ -3129,7 +2964,9 @@ void doPageUp() {
caretLine -= scrollLines;
if (isBidi()) {
- caretOffset = getBidiOffsetAtMouseLocation(columnX, caretLine);
+ int offsetDirection[] = getBidiOffsetAtMouseLocation(columnX, caretLine);
+ caretOffset = offsetDirection[0];
+ lastCaretDirection = offsetDirection[1];
}
else {
caretOffset = getOffsetAtMouseLocation(columnX, caretLine);
@@ -3156,7 +2993,7 @@ void doSelection(int direction) {
if (selectionAnchor == -1) {
selectionAnchor = selection.x;
}
- if (direction == SWT.LEFT) {
+ if (direction == ST.COLUMN_PREVIOUS) {
if (caretOffset < selection.x) {
// grow selection
redrawEnd = selection.x;
@@ -3285,7 +3122,7 @@ void doSelectionLineDown() {
setMouseWordSelectionAnchor();
// select first and then scroll to reduce flash when key
// repeat scrolls lots of lines
- doSelection(SWT.RIGHT);
+ doSelection(ST.COLUMN_NEXT);
// explicitly go to the calculated caret line. may be different
// from content.getLineAtOffset(caretOffset) when in word wrap mode
showCaret(caretLine);
@@ -3320,7 +3157,7 @@ void doSelectionLineUp() {
// explicitly go to the calculated caret line. may be different
// from content.getLineAtOffset(caretOffset) when in word wrap mode
showCaret(caretLine);
- doSelection(SWT.LEFT);
+ doSelection(ST.COLUMN_PREVIOUS);
// save the original horizontal caret position
columnX = oldColumnX;
}
@@ -3405,6 +3242,158 @@ void doSelectionWordPrevious() {
showCaret(caretLine);
}
/**
+ * Moves the caret one character to the left. Do not go to the previous line.
+ * When in a bidi locale and at a R2L character the caret is moved to the
+ * beginning of the R2L segment (visually right) and then one character to the
+ * left (visually left because it's now in a L2R segment).
+ */
+void doVisualPrevious() {
+ int line = content.getLineAtOffset(caretOffset);
+ int lineOffset = content.getOffsetAtLine(line);
+ int offsetInLine = caretOffset - lineOffset;
+
+ if (isBidi()) {
+ // check if caret location is at the visual beginning of the line
+ if (columnX <= XINSET && horizontalScrollOffset == 0) {
+ return;
+ }
+ String lineText = content.getLine(line);
+ int lineLength = lineText.length();
+ GC gc = getGC();
+ StyledTextBidi bidi = getStyledTextBidi(lineText, lineOffset, gc);
+ int visualOffset = -1;
+
+ if (offsetInLine == lineLength) {
+ //logical end of line may not be visual end, setup visualOffset to process as usual
+ visualOffset = bidi.getVisualOffset(offsetInLine - 1);
+ }
+ else
+ if (offsetInLine < lineLength) {
+ visualOffset = bidi.getVisualOffset(offsetInLine);
+ }
+ if (visualOffset != -1) {
+ if (visualOffset > 0) {
+ visualOffset--;
+ offsetInLine = bidi.getLogicalOffset(visualOffset);
+ }
+ else
+ if (visualOffset == 0) {
+ boolean isRightOriented = (getStyle() & SWT.RIGHT_TO_LEFT) != 0;
+
+ //move to visual line end (i.e., behind L2R character/in front of R2L character at visual 0)
+ if ((isRightOriented && bidi.isRightToLeft(offsetInLine) == false) ||
+ (isRightOriented == false && bidi.isRightToLeft(offsetInLine))) {
+ offsetInLine++;
+ }
+
+ if (offsetInLine > 0 && offsetInLine < lineLength) {
+ if (isRightOriented) {
+ boolean rightToLeftStart = bidi.isRightToLeft(offsetInLine) && bidi.isRightToLeft(offsetInLine - 1) == false;
+ if (rightToLeftStart) {
+ //moving from LtoR segment to RtoL segment
+ lastCaretDirection = ST.COLUMN_NEXT;
+ }
+ }
+ else {
+ boolean leftToRightStart = bidi.isRightToLeft(offsetInLine) == false && bidi.isRightToLeft(offsetInLine - 1);
+ if (bidi.isLatinNumber(offsetInLine) && bidi.isRightToLeftInput(offsetInLine - 1)) {
+ //moving from LtoR segment to latin number
+ lastCaretDirection = ST.COLUMN_PREVIOUS;
+ }
+ else
+ if (leftToRightStart) {
+ //moving from RtoL segment to LtoR segment
+ lastCaretDirection = ST.COLUMN_NEXT;
+ }
+ }
+ }
+ }
+ caretOffset = lineOffset + offsetInLine;
+ showCaret();
+ }
+ if (bidi.getTextPosition(offsetInLine, ST.COLUMN_NEXT) == XINSET) {
+ //scroll to origin if caret is at origin
+ scrollHorizontalBar(-horizontalScrollOffset);
+ }
+ gc.dispose();
+ }
+ else
+ if (offsetInLine > 0) {
+ caretOffset--;
+ showCaret();
+ }
+}
+/**
+ * Moves the caret one character to the right. Do not go to the next line.
+ * When in a bidi locale and at a R2L character the caret is moved to the
+ * end of the R2L segment (visually left) and then one character to the
+ * right (visually right because it's now in a L2R segment).
+ */
+void doVisualNext() {
+ int line = content.getLineAtOffset(caretOffset);
+ int lineOffset = content.getOffsetAtLine(line);
+ int offsetInLine = caretOffset - lineOffset;
+ String lineText = content.getLine(line);
+ int lineLength = lineText.length();
+
+ if (isBidi()) {
+ GC gc = getGC();
+ StyledTextBidi bidi = getStyledTextBidi(lineText, lineOffset, gc);
+ int lineEndPixel = bidi.getTextWidth() + leftMargin;
+
+ // check if caret location is at the visual end of the line (can't use
+ // caret location here since it's location is dependent on current keyboard
+ // language direction)
+ if (bidi.getTextPosition(offsetInLine, lastCaretDirection) == lineEndPixel) {
+ gc.dispose();
+ return;
+ }
+ int visualOffset = -1;
+ if (offsetInLine == lineLength) {
+ //logical end of line may not be visual end, setup visualOffset to process as usual
+ visualOffset = bidi.getVisualOffset(offsetInLine - 1);
+ }
+ else
+ if (offsetInLine < lineLength) {
+ visualOffset = bidi.getVisualOffset(offsetInLine);
+ }
+ if (visualOffset != -1) {
+ visualOffset++;
+ offsetInLine = bidi.getLogicalOffset(visualOffset);
+ if (offsetInLine > 0 && offsetInLine < lineLength) {
+ boolean isRightOriented = (getStyle() & SWT.RIGHT_TO_LEFT) != 0;
+ if (isRightOriented) {
+ boolean leftToRightStart = bidi.isRightToLeft(offsetInLine) == false && bidi.isRightToLeft(offsetInLine - 1);
+ if (leftToRightStart) {
+ //moving from RtoL segment to LtoR segment
+ lastCaretDirection = ST.COLUMN_PREVIOUS;
+ }
+ }
+ else {
+ boolean rightToLeftStart = bidi.isRightToLeft(offsetInLine) && bidi.isRightToLeft(offsetInLine - 1) == false;
+ if (bidi.isRightToLeftInput(offsetInLine) && bidi.isLatinNumber(offsetInLine - 1)) {
+ //moving from latin number to RtoL segment
+ lastCaretDirection = ST.COLUMN_NEXT;
+ }
+ else
+ if (rightToLeftStart) {
+ //moving from LtoR segment to RtoL segment
+ lastCaretDirection = ST.COLUMN_PREVIOUS;
+ }
+ }
+ }
+ caretOffset = lineOffset + offsetInLine;
+ showCaret();
+ }
+ gc.dispose();
+ }
+ else
+ if (offsetInLine < lineLength) {
+ caretOffset++;
+ showCaret();
+ }
+}
+/**
* Moves the caret to the end of the next word.
* If a selection exists, move the caret to the end of the selection
* and remove the selection.
@@ -3515,30 +3504,28 @@ public boolean getBidiColoring() {
return bidiColoring;
}
/**
- * Returns the offset at the specified x location in the specified line.
- * Also sets the caret direction so that the caret is placed correctly
- * depending on whether the mouse location is in a R2L or L2R segment.
+ * Returns the offset and caret direction at the specified x location
+ * in the specified line.
+ * The returned caret direction needs to be set in order to place the
+ * caret correctly based on whether the mouse location is in a R2L
+ * or L2R segment.
* <p>
*
* @param x x location of the mouse location
* @param line line the mouse location is in
- * @return the offset at the specified x location in the specified line,
- * relative to the beginning of the document
+ * @return int array, first element is the offset at the specified x
+ * location in the specified line, relative to the beginning of the
+ * document. second element is the caret direction.
*/
-int getBidiOffsetAtMouseLocation(int x, int line) {
+int[] getBidiOffsetAtMouseLocation(int x, int line) {
String lineText = content.getLine(line);
int lineOffset = content.getOffsetAtLine(line);
GC gc = getGC();
StyledTextBidi bidi = getStyledTextBidi(lineText, lineOffset, gc);
- int[] values;
- int offsetInLine;
- x += horizontalScrollOffset;
- values = bidi.getCaretOffsetAndDirectionAtX(x - leftMargin);
- offsetInLine = values[0];
- lastCaretDirection = values[1];
- gc.dispose();
+ int[] values = bidi.getCaretOffsetAndDirectionAtX(x + horizontalScrollOffset - leftMargin);
- return lineOffset + offsetInLine;
+ gc.dispose();
+ return new int[] {lineOffset + values[0], values[1]};
}
/**
* Returns the x position of the character at the specified offset
@@ -5565,50 +5552,50 @@ public void invokeAction(int action) {
break;
case ST.SELECT_LINE_START:
doLineStart();
- doSelection(SWT.LEFT);
+ doSelection(ST.COLUMN_PREVIOUS);
break;
case ST.SELECT_LINE_END:
doLineEnd();
- doSelection(SWT.RIGHT);
+ doSelection(ST.COLUMN_NEXT);
break;
case ST.SELECT_COLUMN_PREVIOUS:
doSelectionCursorPrevious();
- doSelection(SWT.LEFT);
+ doSelection(ST.COLUMN_PREVIOUS);
break;
case ST.SELECT_COLUMN_NEXT:
doSelectionCursorNext();
- doSelection(SWT.RIGHT);
+ doSelection(ST.COLUMN_NEXT);
break;
case ST.SELECT_PAGE_UP:
doSelectionPageUp();
- doSelection(SWT.LEFT);
+ doSelection(ST.COLUMN_PREVIOUS);
break;
case ST.SELECT_PAGE_DOWN:
doSelectionPageDown();
break;
case ST.SELECT_WORD_PREVIOUS:
doSelectionWordPrevious();
- doSelection(SWT.LEFT);
+ doSelection(ST.COLUMN_PREVIOUS);
break;
case ST.SELECT_WORD_NEXT:
doSelectionWordNext();
- doSelection(SWT.RIGHT);
+ doSelection(ST.COLUMN_NEXT);
break;
case ST.SELECT_TEXT_START:
doContentStart();
- doSelection(SWT.LEFT);
+ doSelection(ST.COLUMN_PREVIOUS);
break;
case ST.SELECT_TEXT_END:
doContentEnd();
- doSelection(SWT.RIGHT);
+ doSelection(ST.COLUMN_NEXT);
break;
case ST.SELECT_WINDOW_START:
doPageStart();
- doSelection(SWT.LEFT);
+ doSelection(ST.COLUMN_PREVIOUS);
break;
case ST.SELECT_WINDOW_END:
doPageEnd();
- doSelection(SWT.RIGHT);
+ doSelection(ST.COLUMN_NEXT);
break;
// Modification
case ST.CUT:
@@ -5898,6 +5885,7 @@ void performPaint(GC gc,int startLine,int startY, int renderHeight) {
Color foreground = getForeground();
int lineCount = content.getLineCount();
int paintY = 0;
+ int gcStyle = getStyle() & (SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT);
if (isSingleLine()) {
lineCount = 1;
@@ -5906,7 +5894,7 @@ void performPaint(GC gc,int startLine,int startY, int renderHeight) {
}
}
Image lineBuffer = new Image(getDisplay(), clientArea.width, renderHeight);
- GC lineGC = new GC(lineBuffer);
+ GC lineGC = new GC(lineBuffer, gcStyle);
lineGC.setFont(getFont());
renderer.setCurrentFontStyle(SWT.NORMAL);
@@ -6060,7 +6048,12 @@ public void redraw() {
* @see Control#update
*/
public void redraw(int x, int y, int width, int height, boolean all) {
- super.redraw(x, y, width, height, all);
+ if (isBidi()) {
+ // workaround for bug 4776
+ super.redraw(x, y, width + 1, height, all);
+ } else {
+ super.redraw(x, y, width, height, all);
+ }
if (height > 0) {
int lineCount = content.getLineCount();
int startLine = (getTopPixel() + y) / lineHeight;
@@ -6096,9 +6089,9 @@ void redrawBidiLines(int firstLine, int offsetInFirstLine, int lastLine, int end
String line = content.getLine(firstLine);
GC gc = getGC();
StyledTextBidi bidi = getStyledTextBidi(line, firstLineOffset, gc);
-
+
bidi.redrawRange(
- this, offsetInFirstLine,
+ this, offsetInFirstLine,
Math.min(line.length(), endOffset) - offsetInFirstLine,
leftMargin - horizontalScrollOffset, redrawY + topMargin, lineHeight);
// redraw line break marker (either space or full client area width)
@@ -6907,6 +6900,7 @@ void setBidiCaretLocation(StyledTextBidi bidi, int caretLine) {
int lineStartOffset = content.getOffsetAtLine(caretLine);
int offsetInLine = caretOffset - lineStartOffset;
GC gc = null;
+ boolean isRightOriented = (getStyle() & SWT.RIGHT_TO_LEFT) != 0;
if (bidi == null) {
gc = getGC();
@@ -6917,7 +6911,10 @@ void setBidiCaretLocation(StyledTextBidi bidi, int caretLine) {
} else {
columnX = bidi.getTextPosition(offsetInLine, lastCaretDirection) + leftMargin - horizontalScrollOffset;
}
- if (StyledTextBidi.getKeyboardLanguageDirection() == SWT.RIGHT) {
+ // take the width of the caret into account
+ int keyboardDirection = StyledTextBidi.getKeyboardLanguageDirection();
+ if ((keyboardDirection == SWT.RIGHT && isRightOriented == false) ||
+ (keyboardDirection == SWT.LEFT && isRightOriented)){
columnX -= (getCaretWidth() - 1);
}
if (caret != null) {
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledTextBidi.java b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledTextBidi.java
index c443b65772..e76ba3a1d0 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledTextBidi.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledTextBidi.java
@@ -31,6 +31,7 @@ class StyledTextBidi {
private int[] dx; // distance between character cells. in visual order. renderPositions[iV + 1] = renderPositions[iV] + dx[iV]
private byte[] classBuffer; // the character types in logical order, see BidiUtil for the possible types
private char[] glyphBuffer; // the glyphs in visual order as they will be rendered on screen.
+ private boolean isRightOriented;// writing orientation
/**
* This class describes a text segment of a single direction, either
@@ -106,6 +107,7 @@ class StyledTextBidi {
*/
public StyledTextBidi(GC gc, int tabWidth, String text, StyleRange[] ranges, Font boldFont, int[] offsets) {
int length = text.length();
+ isRightOriented = (gc.getStyle() & SWT.MIRRORED) != 0;
this.gc = gc;
bidiSegments = offsets;
@@ -155,6 +157,7 @@ public StyledTextBidi(GC gc, int tabWidth, String text, StyleRange[] ranges, Fon
*/
public StyledTextBidi(GC gc, String text, int[] offsets) {
int length = text.length();
+ isRightOriented = (gc.getStyle() & SWT.MIRRORED) != 0;
this.gc = gc;
bidiSegments = offsets;
order = new int[length];
@@ -381,8 +384,6 @@ void fillBackground(int logicalStart, int length, int xOffset, int yOffset, int
*/
int[] getCaretOffsetAndDirectionAtX(int x) {
int lineLength = getTextLength();
- int offset;
- int direction;
if (lineLength == 0) {
return new int[] {0, 0};
@@ -395,9 +396,16 @@ int[] getCaretOffsetAndDirectionAtX(int x) {
int visualOffset = getVisualOffsetAtX(x);
// figure out if the character was clicked on the right or left
int halfway = renderPositions[visualOffset] + dx[visualOffset] / 2;
- boolean visualLeft = (x <= halfway);
- offset = getLogicalOffset(visualOffset);
+ boolean visualLeft;
+ int offset = getLogicalOffset(visualOffset);
+ int direction;
+ if (isRightOriented) {
+ visualLeft = (x > halfway);
+ }
+ else {
+ visualLeft = (x <= halfway);
+ }
if (isRightToLeft(offset)) {
if (visualLeft) {
if (isLigated(gc)) {
@@ -413,23 +421,23 @@ int[] getCaretOffsetAndDirectionAtX(int x) {
}
else {
// position the caret as if the caret is to the left
- // of the character at location x and the PREVIOUS key is
- // pressed
- direction = ST.COLUMN_PREVIOUS;
+ // of the character at location x and the PREVIOUS
+ // key is pressed
+ direction = ST.COLUMN_PREVIOUS;
}
}
else {
if (visualLeft) {
- // position the caret as if the caret is to the right
- // of the character at location x and the PREVIOUS key is
- // pressed
- direction = ST.COLUMN_PREVIOUS;
+ // position the caret as if the caret is to the left
+ // of the character at location x and the PREVIOUS
+ // key is pressed
+ direction = ST.COLUMN_PREVIOUS;
}
else {
- // position the caret as if the caret is to the left
+ offset++;
+ // position the caret as if the caret is to the right
// of the character at location x and the NEXT key is
// pressed
- offset++;
direction = ST.COLUMN_NEXT;
}
}
@@ -457,6 +465,7 @@ private Vector getDirectionRuns(int logicalStart, int length) {
int logicalEnd = logicalStart + length - 1;
int segmentLogicalStart = logicalStart;
int segmentLogicalEnd = segmentLogicalStart;
+ int checkSide = isRightOriented ? -1 : 1;
if (logicalEnd < getTextLength()) {
int bidiSegmentIndex = 0;
@@ -481,8 +490,9 @@ private Vector getDirectionRuns(int logicalStart, int length) {
// is no direction change.
// If our segment type is LtoR, the order index for the next character will be one more if there is
// no direction change.
- ((isRightToLeftSegment && (order[segmentLogicalEnd + 1]+ 1 == order[segmentLogicalEnd])) ||
- (isRightToLeftSegment == false && (order[segmentLogicalEnd + 1]- 1 == order[segmentLogicalEnd]))) &&
+ (order[segmentLogicalEnd + 1] == order[segmentLogicalEnd] || // treat ligatures as part of the direction segment
+ (isRightToLeftSegment && (order[segmentLogicalEnd + 1] + checkSide == order[segmentLogicalEnd])) ||
+ (isRightToLeftSegment == false && (order[segmentLogicalEnd + 1] - checkSide == order[segmentLogicalEnd]))) &&
segmentLogicalEnd + 1 < bidiSegmentEnd) {
segmentLogicalEnd++;
}
@@ -555,7 +565,7 @@ int getLigatureStartOffset(int offset) {
* @param visualOffset the visual offset
* @return the logical offset of the character at <code>visualOffset</code>.
*/
-private int getLogicalOffset(int visualOffset) {
+int getLogicalOffset(int visualOffset) {
int logicalOffset = 0;
while (logicalOffset < order.length && order[logicalOffset] != visualOffset) {
@@ -697,26 +707,29 @@ int getTextPosition(int logicalOffset, int direction) {
if (getTextLength() == 0 || logicalOffset < 0) {
return StyledText.XINSET;
}
+
+ boolean isRightToLeft = isRightToLeft(logicalOffset);
// at or past end of line?
if (logicalOffset >= order.length) {
logicalOffset = Math.min(logicalOffset, order.length - 1);
+ isRightToLeft = isRightToLeft(logicalOffset);
int visualOffset = order[logicalOffset];
- if (isRightToLeft(logicalOffset)) {
- caretX = renderPositions[visualOffset];
+ if ((!isRightOriented && !isRightToLeft) || (isRightOriented && isRightToLeft)) {
+ caretX = renderPositions[visualOffset] + dx[visualOffset];
}
else {
- caretX = renderPositions[visualOffset] + dx[visualOffset];
+ caretX = renderPositions[visualOffset];
}
}
else
// at beginning of line?
if (logicalOffset == 0) {
int visualOffset = order[logicalOffset];
- if (isRightToLeft(logicalOffset)) {
- caretX = renderPositions[visualOffset] + dx[visualOffset];
+ if ((!isRightOriented && !isRightToLeft) || (isRightOriented && isRightToLeft)) {
+ caretX = renderPositions[visualOffset];
}
else {
- caretX = renderPositions[visualOffset];
+ caretX = renderPositions[visualOffset] + dx[visualOffset];
}
}
else
@@ -733,14 +746,12 @@ int getTextPosition(int logicalOffset, int direction) {
// do not consider local numbers as R2L here, to determine position,
// because local numbers are navigated L2R and we want the caret to
// be to the right of the number. see 1GK9API
- if (isRightToLeft(logicalOffset - 1)) {
- // moving from RtoL to LtoR
- caretX = renderPositions[visualOffset];
- }
- else {
- // moving from LtoR to RtoL
+ isRightToLeft = isRightToLeft(logicalOffset - 1);
+ if ((!isRightOriented && !isRightToLeft) || (isRightOriented && isRightToLeft)) {
caretX = renderPositions[visualOffset] + dx[visualOffset];
- }
+ } else {
+ caretX = renderPositions[visualOffset];
+ }
}
else
// consider local numbers as R2L in determining direction boundaries.
@@ -752,23 +763,22 @@ int getTextPosition(int logicalOffset, int direction) {
// consider local numbers as R2L here, to determine position, because
// we want to stay in L2R segment and place the cursor to the left of
// first L2R character. see 1GK9API
- if (isRightToLeftInput(logicalOffset - 1)) {
- // moving from LtoR to RtoL
+ isRightToLeft = isRightToLeft(logicalOffset - 1);
+ if ((!isRightOriented && !isRightToLeft) || (isRightOriented && isRightToLeft)) {
+ caretX = renderPositions[visualOffset] + dx[visualOffset];
+ } else {
+ caretX = renderPositions[visualOffset];
+ }
+ }
+ else {
+ int visualOffset = order[logicalOffset];
+ if ((!isRightOriented && !isRightToLeft) || (isRightOriented && isRightToLeft)) {
caretX = renderPositions[visualOffset];
}
else {
- // moving from RtoL to LtoR
caretX = renderPositions[visualOffset] + dx[visualOffset];
}
}
- else
- if (isRightToLeft(logicalOffset)) {
- int visualOffset = order[logicalOffset];
- caretX = renderPositions[visualOffset] + dx[visualOffset];
- }
- else {
- caretX = renderPositions[order[logicalOffset]];
- }
return caretX;
}
/**
@@ -786,6 +796,17 @@ int getTextWidth() {
return width;
}
/**
+ * Returns the visual offset of the character at the specified
+ * logical offset.
+ * <p>
+ *
+ * @param logicalOffset the logical offset
+ * @return the visual offset of the character at <code>logicalOffset</code>.
+ */
+int getVisualOffset(int logicalOffset) {
+ return order[logicalOffset];
+}
+/**
* Returns the visual offset of the character at the specified x
* location.
* <p>
@@ -820,6 +841,23 @@ private int getVisualOffsetAtX(int x) {
return high;
}
/**
+ * Returns if the character at the given offset is a latin number.
+ * <p>
+ *
+ * @param logicalIndex the index of the character
+ * @return
+ * true=the character at the specified index is a latin number
+ * false=the character at the specified index is not a latin number
+ */
+boolean isLatinNumber(int logicalIndex) {
+ boolean isLatinNumber = false;
+
+ if (logicalIndex >= 0 && logicalIndex < classBuffer.length) {
+ isLatinNumber = classBuffer[logicalIndex] == BidiUtil.CLASS_LATINNUMBER;
+ }
+ return isLatinNumber;
+}
+/**
* Returns if the character at the given offset is a local number.
* <p>
*