Bug 569641 - LineNumberRulerColumn sometimes wrong

Prior to this patch, the LineNumberRulerColumn was only looking at the
"bounds" of the visible area to decide whether to redraw lines or not.
We now look at the line position and size as there can be some changes
(code mining added and removed) which do not affect bounds but should
affect line numbers rules.

Change-Id: I913b6ccaefb7ba78c65daef1d85f9294b9163d92
Signed-off-by: Mickael Istria <mistria@redhat.com>
diff --git a/org.eclipse.jface.text/META-INF/MANIFEST.MF b/org.eclipse.jface.text/META-INF/MANIFEST.MF
index ff58ada..082fb4f 100644
--- a/org.eclipse.jface.text/META-INF/MANIFEST.MF
+++ b/org.eclipse.jface.text/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.jface.text
-Bundle-Version: 3.16.500.qualifier
+Bundle-Version: 3.16.600.qualifier
 Bundle-Vendor: %providerName
 Bundle-Localization: plugin
 Export-Package: 
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/VisibleLinesTracker.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/VisibleLinesTracker.java
index 258b41b..ed3fd83 100644
--- a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/VisibleLinesTracker.java
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/VisibleLinesTracker.java
@@ -14,12 +14,16 @@
  *******************************************************************************/
 package org.eclipse.jface.text.source;
 
+import java.util.Collections;
 import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.TreeMap;
 import java.util.function.Consumer;
 
 import org.eclipse.swt.custom.StyledText;
 import org.eclipse.swt.events.PaintEvent;
 import org.eclipse.swt.events.PaintListener;
+import org.eclipse.swt.graphics.Rectangle;
 
 import org.eclipse.jface.text.ITextViewer;
 import org.eclipse.jface.text.JFaceTextUtil;
@@ -36,20 +40,7 @@
 	 */
 	private final ITextViewer viewer;
 
-	/**
-	 * The previous bottom model line index.
-	 */
-	private int oldModelBottom= -1;
-
-	/**
-	 * The previous bottom widget line index.
-	 */
-	private int oldWidgetBottom= -1;
-
-	/**
-	 * The previous bottom line pixel.
-	 */
-	private int oldBottomPixel;
+	private Map<Integer, Rectangle> oldVisibleLineBounds= Collections.emptyMap();
 
 	/**
 	 * List of handler to call when a visible line height change.
@@ -69,24 +60,28 @@
 	@Override
 	public void paintControl(PaintEvent e) {
 		StyledText textWidget= viewer.getTextWidget();
-		// track if bottom line index or bottom line pixel changed.
-		if (oldModelBottom == -1) {
-			oldWidgetBottom= JFaceTextUtil.getPartialBottomIndex(textWidget);
-			oldModelBottom= JFaceTextUtil.widgetLine2ModelLine(viewer, oldWidgetBottom);
-			oldBottomPixel= JFaceTextUtil.getLinePixel(textWidget, oldWidgetBottom);
-			return;
-		}
-		int newWidgetBottom= JFaceTextUtil.getPartialBottomIndex(textWidget);
-		int newModelBottom= JFaceTextUtil.widgetLine2ModelLine(viewer, newWidgetBottom);
-		int newBottomPixel= JFaceTextUtil.getLinePixel(textWidget, newWidgetBottom);
-		if (newWidgetBottom != oldWidgetBottom || newModelBottom != oldModelBottom || newBottomPixel != oldBottomPixel) {
-			oldWidgetBottom= newWidgetBottom;
-			oldModelBottom= newModelBottom;
-			oldBottomPixel= newBottomPixel;
+		Map<Integer, Rectangle> newBounds= getVisibleLineBounds();
+		if (!oldVisibleLineBounds.equals(newBounds)) {
+			oldVisibleLineBounds= newBounds;
 			handlers.forEach(handler -> handler.accept(textWidget));
 		}
 	}
 
+	private Map<Integer, Rectangle> getVisibleLineBounds() {
+		StyledText textWidget= viewer.getTextWidget();
+		if (textWidget.isDisposed() || !textWidget.isVisible()) {
+			return Collections.emptyMap();
+		}
+		Map<Integer, Rectangle> res= new TreeMap<>();
+		int lastVisibleLineIndex= textWidget.getLineIndex(textWidget.getClientArea().height);
+		for (int widgetLine= textWidget.getLineIndex(0); widgetLine <= lastVisibleLineIndex; widgetLine++) {
+			int widgetLineOffset= textWidget.getOffsetAtLine(widgetLine);
+			res.put(Integer.valueOf(JFaceTextUtil.widgetLine2ModelLine(viewer, widgetLine)), //
+					new Rectangle(0, textWidget.getLinePixel(widgetLine), 0, textWidget.getLineHeight(widgetLineOffset)));
+		}
+		return res;
+	}
+
 	/**
 	 * Track the line height change of the {@link StyledText} of the given handler an call the given
 	 * handler.