_getOffset implementation
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/graphics/TextLayout.java b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/graphics/TextLayout.java
index 6ae4e8e..bc4efb5 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/graphics/TextLayout.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/graphics/TextLayout.java
@@ -10,6 +10,7 @@
*******************************************************************************/
package org.eclipse.swt.graphics;
+import org.eclipse.swt.internal.*;
import org.eclipse.swt.internal.wpf.*;
import org.eclipse.swt.*;
@@ -640,7 +641,7 @@
}
int line = lines[lineIndex];
double x = OS.TextLine_Start(line);
- double width = OS.TextLine_Width(line);
+ double width = OS.TextLine_WidthIncludingTrailingWhitespace(line);
double height = OS.TextLine_Height(line);
if (ascent != -1 && descent != -1) height = Math.max(height, ascent + descent);
char ch;
@@ -835,37 +836,70 @@
if ((movement & SWT.MOVEMENT_CHAR) != 0) return offset + step;
length = segmentsText.length();
offset = translateOffset(offset);
- int lineStart = 0;
- for (int line=0; line<lines.length; line++) {
- int lineLength = OS.TextLine_Length(lines[line]);
- if (lineStart <= offset && offset < lineStart + lineLength) {
- if (forward) {
- if (offset >= lineStart + lineLength - OS.TextLine_NewlineLength(lines[line])) {
- return untranslateOffset(lineStart + lineLength);
- }
- } else {
- if (offset == lineStart) {
- if (line == 0) return 0;
- int breakLength = OS.TextLine_NewlineLength(lines[line - 1]);
- if (breakLength != 0) {
- return untranslateOffset(offset - breakLength);
+ int lineStart = 0, lineIndex;
+ for (lineIndex=0; lineIndex<lines.length; lineIndex++) {
+ int lineLength = OS.TextLine_Length(lines[lineIndex]);
+ if (lineStart + lineLength > offset) break;
+ lineStart += lineLength;
+ }
+ int line = lines[lineIndex];
+ int lineLength = OS.TextLine_Length(line);
+ int lineBreak = OS.TextLine_NewlineLength (line);
+ while (lineStart <= offset && offset <= lineStart + lineLength) {
+ int resultCharHit;
+ int characterHit = OS.gcnew_CharacterHit(offset, 0);
+ if (forward) {
+ resultCharHit = OS.TextLine_GetNextCaretCharacterHit(line, characterHit);
+ } else {
+ resultCharHit = OS.TextLine_GetPreviousCaretCharacterHit(line, characterHit);
+ }
+ int newOffset = OS.CharacterHit_FirstCharacterIndex(resultCharHit);
+ int trailing = OS.CharacterHit_TrailingLength(resultCharHit);
+ OS.GCHandle_Free(resultCharHit);
+ OS.GCHandle_Free(characterHit);
+ if (forward) {
+ if (newOffset + trailing >= lineStart + lineLength - lineBreak) {
+ int lineEnd = lineStart + lineLength;
+ if (trailing != 0) lineEnd -= lineBreak;
+ return untranslateOffset(Math.min(length, lineEnd));
+ }
+ } else {
+ if (newOffset + trailing == lineStart) {
+ if (lineIndex == 0) return 0;
+ int lineEnd = 0;
+ if (newOffset + trailing == offset) lineEnd = OS.TextLine_NewlineLength(lines[lineIndex - 1]);
+ return untranslateOffset(Math.max(0, newOffset + trailing - lineEnd));
+ }
+ }
+ offset = newOffset + trailing;
+
+ switch (movement) {
+ case SWT.MOVEMENT_CLUSTER:
+ return untranslateOffset(newOffset);
+ case SWT.MOVEMENT_WORD:
+ case SWT.MOVEMENT_WORD_START: {
+ if (offset > 0) {
+ boolean letterOrDigit = Compatibility.isLetterOrDigit(segmentsText.charAt(offset));
+ boolean previousLetterOrDigit = Compatibility.isLetterOrDigit(segmentsText.charAt(offset - 1));
+ if (letterOrDigit != previousLetterOrDigit || !letterOrDigit) {
+ if (!Compatibility.isWhitespace(segmentsText.charAt(offset))) {
+ return untranslateOffset(offset);
+ }
}
}
+ break;
}
- int resultCharHit;
- int characterHit = OS.gcnew_CharacterHit(offset, 0);
- if (forward) {
- resultCharHit = OS.TextLine_GetNextCaretCharacterHit(lines[line], characterHit);
- } else {
- resultCharHit = OS.TextLine_GetPreviousCaretCharacterHit(lines[line], characterHit);
+ case SWT.MOVEMENT_WORD_END: {
+ if (offset > 0) {
+ boolean isLetterOrDigit = Compatibility.isLetterOrDigit(segmentsText.charAt(offset));
+ boolean previousLetterOrDigit = Compatibility.isLetterOrDigit(segmentsText.charAt(offset - 1));
+ if (!isLetterOrDigit && previousLetterOrDigit) {
+ return untranslateOffset(offset);
+ }
+ }
+ break;
}
- int result = OS.CharacterHit_FirstCharacterIndex(resultCharHit);
- int trailing = OS.CharacterHit_TrailingLength(resultCharHit);
- OS.GCHandle_Free(resultCharHit);
- OS.GCHandle_Free(characterHit);
- return untranslateOffset(result + trailing);
}
- lineStart += lineLength;
}
return forward ? text.length() : 0;
}