Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMickael Istria2018-03-09 12:53:45 +0000
committerMickael Istria2018-03-14 14:06:55 +0000
commit2ef119e594da0ed9e93c88f3b32b03e82863870c (patch)
tree518b007ba254ea5fcb946e4d504914b627c17c3d /bundles
parent1c8a0ecfbe778d718be00e3b273a19d9c628f0be (diff)
downloadeclipse.platform.swt-2ef119e594da0ed9e93c88f3b32b03e82863870c.tar.gz
eclipse.platform.swt-2ef119e594da0ed9e93c88f3b32b03e82863870c.tar.xz
eclipse.platform.swt-2ef119e594da0ed9e93c88f3b32b03e82863870c.zip
Bug 532173 - [StyledText] Wrong caret bounds with variable height
Fix bug in getBoundsAtOffset to make it more reliable. Place caret to better location when it doesn't fit the whole line. May as well fix bug 118612 Change-Id: I942787c801090ff504c8ed37183a97b312f78e18 Signed-off-by: Mickael Istria <mistria@redhat.com> Also-By: Angelo Zerr <angelozerr@gmail.com>
Diffstat (limited to 'bundles')
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledText.java56
1 files changed, 45 insertions, 11 deletions
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 a05e0bf0a1..13249fe4a0 100644
--- 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
@@ -3697,12 +3697,11 @@ Rectangle getBoundsAtOffset(int offset) {
if (line.length() != 0) {
TextLayout layout = renderer.getTextLayout(lineIndex);
int offsetInLine = Math.min (layout.getText().length(), Math.max (0, offset - lineOffset));
- if (caretAlignment == PREVIOUS_OFFSET_TRAILING && offsetInLine != 0) {
+ bounds = layout.getBounds(offsetInLine, offsetInLine);
+ if (getListeners(ST.LineGetSegments).length > 0 && caretAlignment == PREVIOUS_OFFSET_TRAILING && offsetInLine != 0) {
offsetInLine = layout.getPreviousOffset(offsetInLine, SWT.MOVEMENT_CLUSTER);
Point point = layout.getLocation(offsetInLine, true);
- bounds = new Rectangle (point.x, point.y, 0, renderer.getLineHeight());
- } else {
- bounds = layout.getBounds(offsetInLine, offsetInLine);
+ bounds = new Rectangle (point.x, point.y, 0, bounds.height);
}
renderer.disposeTextLayout(layout);
} else {
@@ -8632,18 +8631,53 @@ void setCaretLocation() {
Point newCaretPos = getPointAtOffset(caretOffset);
setCaretLocation(newCaretPos, getCaretDirection());
}
-void setCaretLocation(Point location, int direction) {
+void setCaretLocation(final Point location, int direction) {
Caret caret = getCaret();
if (caret != null) {
- boolean isDefaultCaret = caret == defaultCaret;
- int lineHeight = renderer.getLineHeight();
- int caretHeight = lineHeight;
- if (!isFixedLineHeight() && isDefaultCaret) {
- caretHeight = getBoundsAtOffset(caretOffset).height;
- if (caretHeight != lineHeight) {
+ final boolean isDefaultCaret = caret == defaultCaret;
+ final StyleRange styleAtOffset = content.getCharCount() > 0 ?
+ (caretOffset < content.getCharCount() ?
+ getStyleRangeAtOffset(caretOffset) :
+ getStyleRangeAtOffset(content.getCharCount() - 1)) : // caret after last char: use last char style
+ null;
+ final int caretLine = getCaretLine();
+
+ int graphicalLineHeight = getLineHeight();
+ final int lineStartOffset = getOffsetAtLine(caretLine);
+ int graphicalLineFirstOffset = lineStartOffset;
+ final int lineEndOffset = lineStartOffset + getLine(caretLine).length();
+ int graphicalLineLastOffset = lineEndOffset;
+ if (renderer.getLineHeight(caretLine) != getLineHeight()) { // word wrap, metrics, styles...
+ graphicalLineHeight = getLineHeight(caretOffset);
+ final Rectangle characterBounds = getBoundsAtOffset(caretOffset);
+ graphicalLineFirstOffset = getOffsetAtPoint(new Point(leftMargin, characterBounds.y));
+ graphicalLineLastOffset = getOffsetAtPoint(new Point(leftMargin, characterBounds.y + graphicalLineHeight)) - 1;
+ if (graphicalLineLastOffset < graphicalLineFirstOffset) {
+ graphicalLineLastOffset = getCharCount();
+ }
+ }
+
+ int caretHeight = getLineHeight();
+ boolean isTextAlignedAtBottom = true;
+ for (StyleRange style : getStyleRanges(graphicalLineFirstOffset, graphicalLineLastOffset - graphicalLineFirstOffset)) {
+ isTextAlignedAtBottom &= (
+ (style.font == null || Objects.equals(style.font, getFont())) &&
+ style.rise >= 0 &&
+ (style.metrics == null || style.metrics.descent <= 0)
+ );
+ }
+ if (!isTextAlignedAtBottom || (styleAtOffset != null && styleAtOffset.isVariableHeight())) {
+ if (isDefaultCaret) {
direction = SWT.DEFAULT;
+ caretHeight = graphicalLineHeight;
+ } else {
+ caretHeight = caret.getSize().y;
}
}
+ if (isTextAlignedAtBottom && caretHeight < graphicalLineHeight) {
+ location.y += (graphicalLineHeight - caretHeight);
+ }
+
int imageDirection = direction;
if (isMirrored()) {
if (imageDirection == SWT.LEFT) {

Back to the top