diff options
Diffstat (limited to 'org.eclipse.jface.text/src')
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;
+ }
}
|