Bug 539624 - [codemining] Improve drastically draw of inlined header
annotation by using StyledText#setLineVerticalIndent

Change-Id: Id9d62c1d59e26fc0bcf4327e77d37c3c8dcb129f
Signed-off-by: angelozerr <angelo.zerr@gmail.com>
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/AnnotationRulerColumn.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/AnnotationRulerColumn.java
index 72558c9..043c972 100644
--- a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/AnnotationRulerColumn.java
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/AnnotationRulerColumn.java
@@ -802,13 +802,11 @@
 					r.height= textBounds.height;
 					r.y = textBounds.y;
 				}
-				// adjust the annotation position at the bottom of the line if line height has custom line height
-				int defaultLineHeight= fCachedTextWidget.getLineHeight();
-				int lineHeight= fCachedTextWidget.getLineHeight(offset);
-				if (lineHeight > defaultLineHeight) {
-					int adjust= lineHeight - defaultLineHeight;
-					r.y+= adjust;
-					r.height-= adjust;
+				// adjust the annotation position at the bottom of the line if line height has custom vertical line indent
+				int verticalIndent= fCachedTextViewer.getTextWidget().getLineVerticalIndent(startLine);
+				if (verticalIndent > 0) {
+					r.y+= verticalIndent;
+					r.height-= verticalIndent;
 				}
 				if (r.y < dimension.y && fAnnotationAccessExtension != null)  // annotation within visible area
 					fAnnotationAccessExtension.paint(annotation, gc, fCanvas, r);
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/LineNumberRulerColumn.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/LineNumberRulerColumn.java
index 3d2104f..3244d08 100644
--- a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/LineNumberRulerColumn.java
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/LineNumberRulerColumn.java
@@ -941,7 +941,8 @@
 		}
 		int indentation= fIndentation[index];
 		int baselineBias= getBaselineBias(gc, widgetLine);
-		gc.drawString(s, indentation * fZoom / 100, (y + baselineBias) * fZoom / 100, true);
+		int verticalIndent= fCachedTextViewer.getTextWidget().getLineVerticalIndent(widgetLine);
+		gc.drawString(s, indentation * fZoom / 100, (y + baselineBias + verticalIndent) * fZoom / 100, true);
 	}
 
 	/**
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 5d3b41c..c231397 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
@@ -76,18 +76,11 @@
 	 */
 	private static void draw(LineHeaderAnnotation annotation, GC gc, StyledText textWidget, int offset, int length,
 			Color color) {
-		StyleRange style= null;
-		try {
-			style= textWidget.getStyleRangeAtOffset(offset);
-		} catch (Exception e) {
-			return;
-		}
+		int line= textWidget.getLineAtOffset(offset);
 		if (isDeleted(annotation)) {
 			// When annotation is deleted, update metrics to null to remove extra spaces of the line header annotation.
-			if (style != null && style.metrics != null) {
-				style.metrics= null;
-				textWidget.setStyleRange(style);
-			}
+			if (textWidget.getLineVerticalIndent(line) > 0)
+				textWidget.setLineVerticalIndent(line, 0);
 			return;
 		}
 		if (gc != null) {
@@ -103,53 +96,20 @@
 			annotation.draw(gc, textWidget, offset, length, color, x, y);
 			int height= annotation.getHeight();
 			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.
-
-				// 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
-
-				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 - textWidget.getLineHeight();
-				if (style != null) {
-					if (style.background != null) {
-						gc.setBackground(style.background);
-						gc.fillRectangle(charX, charY, charWidth + 1, bounds.height);
+				if (height != textWidget.getLineVerticalIndent(line)) {
+					if (annotation.oldLine != -1 && annotation.oldLine < textWidget.getLineCount()) {
+						textWidget.setLineVerticalIndent(annotation.oldLine, 0);
 					}
-					if (style.foreground != null) {
-						gc.setForeground(style.foreground);
-					} else {
-						gc.setForeground(textWidget.getForeground());
-					}
-					gc.setFont(annotation.getFont(style.fontStyle));
+					textWidget.setLineVerticalIndent(line, height);
 				}
-				gc.drawString(s, charX, charY, true);
-				// END TO REMOVE
-			} else if (style != null && style.metrics != null && style.metrics.ascent != 0) {
-				// line header annotation had an height, reset it
-				style.metrics= null;
-				textWidget.setStyleRange(style);
+				annotation.oldLine= line;
+				return;
+			} else if (textWidget.getLineVerticalIndent(line) > 0) {
+				textWidget.setLineVerticalIndent(line, 0);
 			}
 		} 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
+			if (textWidget.getLineVerticalIndent(line) > 0) {
+				// Here vertical indent 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);
@@ -160,52 +120,6 @@
 	}
 
 	/**
-	 * 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 width= annotation.getRedrawnCharacterWidth();
-		if (width == 0) {
-			// Update GlyphMetrics only when mining was already drawn
-			return null;
-		}
-		int height= annotation.getHeight();
-		if (height == 0) {
-			return null;
-		}
-		int fullHeight= height + annotation.getRedrawnCharacterHeight();
-		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;
-				}
-				/**
-				 * We must create a new GlyphMetrics instance because comparison with similarTo used
-				 * later in StyledText#setStyleRange will compare the same (modified) and won't
-				 * realize an update happened.
-				 */
-				metrics= new GlyphMetrics(fullHeight, 0, width);
-			}
-		} else {
-			metrics= null;
-		}
-		style.metrics= metrics;
-		return style;
-	}
-
-	/**
 	 * Draw the line content annotation inside line in the empty area computed by
 	 * {@link GlyphMetrics}.
 	 *
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 0ea912e..1c473fa 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
@@ -111,12 +111,6 @@
 							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);
-							}
 						}
 					});
 		}
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 6075447..51cf13e 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
@@ -1,11 +1,11 @@
 /**

  *  Copyright (c) 2017, 2018 Angelo ZERR.

- *
+ *

  *  This program and the accompanying materials

  *  are made available under the terms of the Eclipse Public License 2.0

  *  which accompanies this distribution, and is available at

- *  https://www.eclipse.org/legal/epl-2.0/
- *
+ *  https://www.eclipse.org/legal/epl-2.0/

+ *

  *  SPDX-License-Identifier: EPL-2.0

  *

  *  Contributors:

@@ -25,18 +25,17 @@
  */

 public class LineHeaderAnnotation extends AbstractInlinedAnnotation {

 

-	private int redrawnCharacterHeight;

-

-	private int redrawnCharacterWidth;

+	int oldLine;

 

 	/**

 	 * Line header annotation constructor.

 	 *

 	 * @param position the position where the annotation must be drawn.

-	 * @param viewer   the {@link ISourceViewer} where the annotation must be drawn.

+	 * @param viewer the {@link ISourceViewer} where the annotation must be drawn.

 	 */

 	public LineHeaderAnnotation(Position position, ISourceViewer viewer) {

 		super(position, viewer);

+		oldLine= -1;

 	}

 

 	/**

@@ -46,23 +45,7 @@
 	 */

 	public int getHeight() {

 		StyledText styledText= super.getTextWidget();

-		return styledText.getBaseline();

-	}

-

-	int getRedrawnCharacterHeight() {

-		return redrawnCharacterHeight;

-	}

-

-	void setRedrawnCharacterHeight(int redrawnCharacterHeight) {

-		this.redrawnCharacterHeight= redrawnCharacterHeight;

-	}

-

-	int getRedrawnCharacterWidth() {

-		return redrawnCharacterWidth;

-	}

-

-	void setRedrawnCharacterWidth(int redrawnCharacterWidth) {

-		this.redrawnCharacterWidth= redrawnCharacterWidth;

+		return styledText.getLineHeight();

 	}

 

 	@Override