Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'org.eclipse.jface.text/src')
-rw-r--r--org.eclipse.jface.text/src/org/eclipse/jface/text/source/inlined/InlinedAnnotationDrawingStrategy.java145
-rw-r--r--org.eclipse.jface.text/src/org/eclipse/jface/text/source/inlined/InlinedAnnotationSupport.java25
-rw-r--r--org.eclipse.jface.text/src/org/eclipse/jface/text/source/inlined/LineHeaderAnnotation.java38
3 files changed, 131 insertions, 77 deletions
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/inlined/InlinedAnnotationDrawingStrategy.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/inlined/InlinedAnnotationDrawingStrategy.java
index dbbe3953e2d..46268a1f809 100644
--- a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/inlined/InlinedAnnotationDrawingStrategy.java
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/inlined/InlinedAnnotationDrawingStrategy.java
@@ -73,60 +73,123 @@ class InlinedAnnotationDrawingStrategy implements IDrawingStrategy {
*/
private static void draw(LineHeaderAnnotation annotation, GC gc, StyledText textWidget, int offset, int length,
Color color) {
- if (annotation.isMarkedDeleted()) {
- // When annotation is deleted, redraw the styled text to hide old draw of
- // annotations
- textWidget.redraw();
- // update caret offset since line spacing has changed.
- textWidget.setCaretOffset(textWidget.getCaretOffset());
- return;
- }
- // compute current, previous line index.
- int lineIndex= -1;
+ StyleRange style= null;
try {
- lineIndex= textWidget.getLineAtOffset(offset);
+ style= textWidget.getStyleRangeAtOffset(offset);
} catch (Exception e) {
return;
}
- int previousLineIndex= lineIndex - 1;
+ if (annotation.isMarkedDeleted()) {
+ // When annotation is deleted, update metrics to null to remove extra spaces of the line header annotation.
+ if (style != null) {
+ style.metrics= null;
+ textWidget.setStyleRange(style);
+ }
+ return;
+ }
if (gc != null) {
// Compute the location of the annotation
- int x= textWidget.getLocationAtOffset(offset).x;
- int y= 0;
+ Rectangle bounds= textWidget.getTextBounds(offset, offset);
+ int x= bounds.x;
+ int y= bounds.y;
+
+ // Colorize line spacing area with the background of StyledText to avoid having highlighted line color
+ gc.setBackground(textWidget.getBackground());
+ Rectangle client= textWidget.getClientArea();
+ textWidget.drawBackground(gc, x, y, client.width, annotation.getHeight());
+
+ // Draw the line header annotation
+ annotation.draw(gc, textWidget, offset, length, color, x, y);
int height= annotation.getHeight();
- if (lineIndex > 0) {
- int previousOffset= textWidget.getOffsetAtLine(previousLineIndex);
- y= textWidget.getLocationAtOffset(previousOffset).y + height;
- }
- Rectangle clipping= gc.getClipping();
- if (clipping.contains(x, y)) {
- // GC clipping contains the x, y where annotation must be drawn.
+ if (height != 0) {
+ // The inline annotation replaces one character by taking a place width
+ // GlyphMetrics
+ // Here we need to redraw this first character because GlyphMetrics clip this
+ // character.
- // Colorize line spacing area with the background of StyledText to avoid having highlighted line color
- gc.setBackground(textWidget.getBackground());
- Rectangle client= textWidget.getClientArea();
- textWidget.drawBackground(gc, x, y, client.width, height);
+ // FIXME: remove this code when we need not redraw the character (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=531769)
+ // START TO REMOVE
+ String s= textWidget.getText(offset, offset);
+ Point charBounds= gc.stringExtent(s);
+ int charWidth= charBounds.x;
+ int charHeight= charBounds.y;
+ annotation.setRedrawnCharacterWidth(charWidth);
+ annotation.setRedrawnCharacterHeight(charHeight);
+ // END TO REMOVE
- // draw the annotation
- annotation.draw(gc, textWidget, offset, length, color, x, y);
- return;
- } else {
- if (!(clipping.y - height == y)) {
- // Clipping doesn't include the y of previous line spacing, stop the redraw
- // range.
+ StyleRange newStyle= updateStyle(annotation, style);
+ if (newStyle != null) {
+ textWidget.setStyleRange(newStyle);
return;
}
+
+ // FIXME: remove this code when we need not redraw the character (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=531769)
+ // START TO REMOVE
+ int charX= x + bounds.width - charWidth;
+ int charY= y + bounds.height - height;
+ if (style != null) {
+ if (style.background != null) {
+ gc.setBackground(style.background);
+ gc.fillRectangle(charX, charY, charWidth + 1, bounds.height);
+ }
+ if (style.foreground != null) {
+ gc.setForeground(style.foreground);
+ } else {
+ gc.setForeground(textWidget.getForeground());
+ }
+ gc.setFont(annotation.getFont(style.fontStyle));
+ }
+ gc.drawString(s, charX, charY, true);
+ // END TO REMOVE
+ }
+ } else {
+ if (style != null && style.metrics != null) {
+ // Here GlyphMetrics ascent is done, the redraw of the full line width is done to avoid annotation clipping
+ Rectangle bounds= textWidget.getTextBounds(offset, offset);
+ Rectangle client= textWidget.getClientArea();
+ textWidget.redraw(0, bounds.y, client.width, bounds.height, false);
+ } else {
+ textWidget.redrawRange(offset, length, true);
}
}
+ }
- if (previousLineIndex < 0) {
- // There are none previous line, do nothing
- return;
+ /**
+ * Returns the style to apply with GlyphMetrics ascent only if needed.
+ *
+ * @param annotation the line header annotation
+ * @param style the current style and null otherwise.
+ * @return the style to apply with GlyphMetrics ascent only if needed.
+ */
+ static StyleRange updateStyle(LineHeaderAnnotation annotation, StyleRange style) {
+ int height= annotation.getHeight();
+ if (height == 0) {
+ return null;
+ }
+ int fullHeight= height + annotation.getRedrawnCharacterHeight();
+ int width= annotation.getRedrawnCharacterWidth();
+ if (style == null) {
+ style= new StyleRange();
+ Position position= annotation.getPosition();
+ style.start= position.getOffset();
+ style.length= 1;
+ }
+ GlyphMetrics metrics= style.metrics;
+ if (!annotation.isMarkedDeleted()) {
+ if (metrics == null) {
+ metrics= new GlyphMetrics(fullHeight, 0, width);
+ } else {
+ if (metrics.ascent == fullHeight) {
+ return null;
+ }
+ metrics.width= width;
+ metrics.ascent= fullHeight;
+ }
+ } else {
+ metrics= null;
}
- // refresh the previous line range where line header annotation must be drawn.
- int previousOffset= textWidget.getOffsetAtLine(previousLineIndex);
- int lineLength= offset - previousOffset;
- textWidget.redrawRange(previousOffset, lineLength, true);
+ style.metrics= metrics;
+ return style;
}
/**
@@ -166,6 +229,10 @@ class InlinedAnnotationDrawingStrategy implements IDrawingStrategy {
String s= textWidget.getText(offset, offset);
Point charBounds= gc.stringExtent(s);
int charWidth= charBounds.x;
+ int charHeight= charBounds.y;
+
+ // When line text has line header annotation, there is a space on the top, adjust the y by using char height
+ y+= bounds.height - charHeight;
// Draw the line content annotation
annotation.draw(gc, textWidget, offset, length, color, x, y);
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/inlined/InlinedAnnotationSupport.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/inlined/InlinedAnnotationSupport.java
index a5904679485..dcf0802684e 100644
--- a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/inlined/InlinedAnnotationSupport.java
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/inlined/InlinedAnnotationSupport.java
@@ -23,7 +23,6 @@ import java.util.function.Consumer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.custom.StyledText;
-import org.eclipse.swt.custom.StyledTextLineSpacingProvider;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.MouseMoveListener;
@@ -69,7 +68,7 @@ import org.eclipse.jface.text.source.ISourceViewer;
*
* @since 3.13
*/
-public class InlinedAnnotationSupport implements StyledTextLineSpacingProvider {
+public class InlinedAnnotationSupport {
/**
* The annotation inlined strategy singleton.
@@ -110,6 +109,12 @@ public class InlinedAnnotationSupport implements StyledTextLineSpacingProvider {
if (style != null) {
textPresentation.mergeStyleRange(style);
}
+ } else if (annotation instanceof LineHeaderAnnotation) {
+ LineHeaderAnnotation ann= (LineHeaderAnnotation) annotation;
+ StyleRange style= InlinedAnnotationDrawingStrategy.updateStyle(ann, null);
+ if (style != null) {
+ textPresentation.mergeStyleRange(style);
+ }
}
});
}
@@ -346,7 +351,6 @@ public class InlinedAnnotationSupport implements StyledTextLineSpacingProvider {
text.addMouseListener(fMouseTracker);
text.addMouseTrackListener(fMouseTracker);
text.addMouseMoveListener(fMouseTracker);
- text.setLineSpacingProvider(this);
setColor(text.getDisplay().getSystemColor(SWT.COLOR_DARK_GRAY));
}
@@ -514,19 +518,6 @@ public class InlinedAnnotationSupport implements StyledTextLineSpacingProvider {
}
/**
- * Returns the line spacing from the given line index with the codemining annotations height and
- * null otherwise.
- */
- @SuppressWarnings("boxing")
- @Override
- public Integer getLineSpacing(int lineIndex) {
- AbstractInlinedAnnotation annotation= getInlinedAnnotationAtLine(fViewer, lineIndex);
- return (annotation instanceof LineHeaderAnnotation)
- ? ((LineHeaderAnnotation) annotation).getHeight()
- : null;
- }
-
- /**
* Returns the {@link AbstractInlinedAnnotation} from the given line index and null otherwise.
*
* @param viewer the source viewer
@@ -542,7 +533,7 @@ public class InlinedAnnotationSupport implements StyledTextLineSpacingProvider {
return null;
}
IDocument document= viewer.getDocument();
- int lineNumber= lineIndex + 1;
+ int lineNumber= lineIndex;
if (lineNumber > document.getNumberOfLines()) {
return null;
}
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/inlined/LineHeaderAnnotation.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/inlined/LineHeaderAnnotation.java
index f738c539d2c..c2819ef6048 100644
--- a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/inlined/LineHeaderAnnotation.java
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/inlined/LineHeaderAnnotation.java
@@ -12,8 +12,6 @@ package org.eclipse.jface.text.source.inlined;
import org.eclipse.swt.custom.StyledText;
-import org.eclipse.jface.text.BadLocationException;
-import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.source.ISourceViewer;
@@ -24,6 +22,10 @@ import org.eclipse.jface.text.source.ISourceViewer;
*/
public class LineHeaderAnnotation extends AbstractInlinedAnnotation {
+ private int redrawnCharacterHeight;
+
+ private int redrawnCharacterWidth;
+
/**
* Line header annotation constructor.
*
@@ -44,25 +46,19 @@ public class LineHeaderAnnotation extends AbstractInlinedAnnotation {
return styledText.getLineHeight();
}
- @Override
- protected boolean isInVisibleLines() {
- if (!super.isInVisibleLines()) {
- return false;
- }
- // the inlined annotation is in the visible lines
- ISourceViewer viewer= super.getViewer();
- IDocument document= viewer.getDocument();
- if (document == null) {
- return false;
- }
- try {
- // check if previous line where annotation is drawn in the line spacing, is visible
- int startLineOffset= document.getLineInformationOfOffset(getPosition().getOffset()).getOffset();
- int previousEndLineOffset= startLineOffset - 1;
- return super.isInVisibleLines(previousEndLineOffset);
- } catch (BadLocationException e) {
- return false;
- }
+ int getRedrawnCharacterHeight() {
+ return redrawnCharacterHeight;
+ }
+
+ void setRedrawnCharacterHeight(int redrawnCharacterHeight) {
+ this.redrawnCharacterHeight= redrawnCharacterHeight;
}
+ int getRedrawnCharacterWidth() {
+ return redrawnCharacterWidth;
+ }
+
+ void setRedrawnCharacterWidth(int redrawnCharacterWidth) {
+ this.redrawnCharacterWidth= redrawnCharacterWidth;
+ }
}

Back to the top