Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarkus Keller2017-05-08 16:01:00 +0000
committerMarkus Keller2017-05-08 16:01:00 +0000
commitb128cfb79dcaa0c963a0db03afc0b124fdc5860a (patch)
tree1fd5a8ff95bcf6099e93038770c9ad624a1505de
parent215e0dc0221f3d88ffabede6eb7b08358c324f18 (diff)
downloadeclipse.platform.text-b128cfb79dcaa0c963a0db03afc0b124fdc5860a.tar.gz
eclipse.platform.text-b128cfb79dcaa0c963a0db03afc0b124fdc5860a.tar.xz
eclipse.platform.text-b128cfb79dcaa0c963a0db03afc0b124fdc5860a.zip
-rw-r--r--org.eclipse.jface.text/src/org/eclipse/jface/internal/text/revisions/RevisionPainter.java21
-rw-r--r--org.eclipse.jface.text/src/org/eclipse/jface/internal/text/source/DiffPainter.java26
-rw-r--r--org.eclipse.jface.text/src/org/eclipse/jface/text/source/LineNumberChangeRulerColumn.java7
-rw-r--r--org.eclipse.jface.text/src/org/eclipse/jface/text/source/LineNumberRulerColumn.java143
4 files changed, 174 insertions, 23 deletions
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/revisions/RevisionPainter.java b/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/revisions/RevisionPainter.java
index 34cdcaaabb4..50a257aa4c1 100644
--- a/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/revisions/RevisionPainter.java
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/revisions/RevisionPainter.java
@@ -588,6 +588,11 @@ public final class RevisionPainter {
* @since 3.3
*/
private int fLastWidth= -1;
+ /**
+ * The zoom level for the current painting operation. Workaround for bug 516293.
+ * @since 3.12
+ */
+ private int fZoom= 100;
/**
* Creates a new revision painter for a vertical ruler column.
@@ -658,6 +663,20 @@ public final class RevisionPainter {
}
/**
+ * Sets the zoom level for the current painting operation. Workaround for bug 516293.
+ *
+ * @param zoom the zoom to set
+ * @since 3.12
+ */
+ public void setZoom(int zoom) {
+ fZoom= zoom;
+ }
+
+ private int autoScaleUp(int value) {
+ return value * fZoom / 100;
+ }
+
+ /**
* Delegates the painting of the quick diff colors to this painter. The painter will draw the
* color boxes onto the passed {@link GC} for all model (document) lines in
* <code>visibleModelLines</code>.
@@ -1058,7 +1077,7 @@ public final class RevisionPainter {
int y1= fWidget.getLinePixel(range.getStartLine());
int y2= fWidget.getLinePixel(range.getStartLine() + range.getNumberOfLines());
- return new Rectangle(0, y1, getWidth(), y2 - y1 - 1);
+ return new Rectangle(0, autoScaleUp(y1), autoScaleUp(getWidth()), autoScaleUp(y2 - y1 - 1));
}
/**
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/source/DiffPainter.java b/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/source/DiffPainter.java
index 53c82fe958d..33a6fea6471 100644
--- a/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/source/DiffPainter.java
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/source/DiffPainter.java
@@ -82,6 +82,11 @@ public final class DiffPainter {
private final AnnotationListener fAnnotationListener= new AnnotationListener();
/** The shared color provider, possibly <code>null</code>. */
private final ISharedTextColors fSharedColors;
+ /**
+ * The zoom level for the current painting operation. Workaround for bug 516293.
+ * @since 3.12
+ */
+ private int fZoom= 100;
/**
* Creates a new diff painter for a vertical ruler column.
@@ -135,6 +140,20 @@ public final class DiffPainter {
}
/**
+ * Sets the zoom level for the current painting operation. Workaround for bug 516293.
+ *
+ * @param zoom the zoom to set
+ * @since 3.12
+ */
+ public void setZoom(int zoom) {
+ fZoom= zoom;
+ }
+
+ private int autoScaleUp(int value) {
+ return value * fZoom / 100;
+ }
+
+ /**
* Delegates the painting of the quick diff colors to this painter. The painter will draw the
* color boxes onto the passed {@link GC} for all model (document) lines in
* <code>visibleModelLines</code>.
@@ -226,7 +245,7 @@ public final class DiffPainter {
// draw background color if special
if (hasSpecialColor(info)) {
gc.setBackground(getColor(info));
- gc.fillRectangle(0, y, width, lineHeight);
+ gc.fillRectangle(0, autoScaleUp(y), autoScaleUp(width), autoScaleUp(lineHeight));
}
/* Deletion Indicator: Simply a horizontal line */
@@ -234,10 +253,11 @@ public final class DiffPainter {
int delBelow= info.getRemovedLinesBelow();
if (delBefore > 0 || delBelow > 0) {
gc.setForeground(deletionColor);
+ gc.setLineWidth(autoScaleUp(1));
if (delBefore > 0)
- gc.drawLine(0, y, width, y);
+ gc.drawLine(0, autoScaleUp(y), autoScaleUp(width), autoScaleUp(y));
if (delBelow > 0)
- gc.drawLine(0, y + lineHeight - 1, width, y + lineHeight - 1);
+ gc.drawLine(0, autoScaleUp(y + lineHeight - 1), autoScaleUp(width), autoScaleUp(y + lineHeight - 1));
}
}
}
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/LineNumberChangeRulerColumn.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/LineNumberChangeRulerColumn.java
index 5a41b5db854..a835305b421 100644
--- a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/LineNumberChangeRulerColumn.java
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/LineNumberChangeRulerColumn.java
@@ -166,10 +166,13 @@ public class LineNumberChangeRulerColumn extends LineNumberRulerColumn implement
void doPaint(GC gc, ILineRange visibleLines) {
Color foreground= gc.getForeground();
if (visibleLines != null) {
- if (fRevisionPainter.hasInformation())
+ if (fRevisionPainter.hasInformation()) {
+ fRevisionPainter.setZoom(fZoom);
fRevisionPainter.paint(gc, visibleLines);
- else if (fDiffPainter.hasInformation()) // don't paint quick diff colors if revisions are painted
+ } else if (fDiffPainter.hasInformation()) { // don't paint quick diff colors if revisions are painted
+ fDiffPainter.setZoom(fZoom);
fDiffPainter.paint(gc, visibleLines);
+ }
}
gc.setForeground(foreground);
if (fShowNumbers || fCharacterDisplay)
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 00b895e49e7..81002167fee 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
@@ -14,6 +14,7 @@
*******************************************************************************/
package org.eclipse.jface.text.source;
+import java.lang.ref.WeakReference;
import java.util.Arrays;
import org.eclipse.swt.SWT;
@@ -30,9 +31,12 @@ import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.FontMetrics;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.ImageData;
+import org.eclipse.swt.graphics.ImageDataProvider;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Canvas;
@@ -41,6 +45,8 @@ import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.TypedListener;
+import org.eclipse.jface.util.Util;
+
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
@@ -62,6 +68,17 @@ import org.eclipse.jface.text.TextEvent;
public class LineNumberRulerColumn implements IVerticalRulerColumn {
/**
+ * <code>true</code> if we're on a Mac, where drawing on an Image currently only draws at 100% zoom level,
+ * which results in blurry line numbers on a Retina display.
+ *
+ * @see <a href="https://bugs.eclipse.org/516293">bug 516293</a>
+ * @since 3.6
+ */
+ private final boolean IS_MAC_BUG_516293= Util.isMac()
+ && !"false".equals(System.getProperty("LineNumberRulerColumn.retina.workaround")) //$NON-NLS-1$ //$NON-NLS-2$
+ && internalSupportsZoomedPaint();
+
+ /**
* Internal listener class.
*/
class InternalListener implements IViewportListener, ITextListener {
@@ -420,6 +437,13 @@ public class LineNumberRulerColumn implements IVerticalRulerColumn {
};
/* @since 3.2 */
private MouseHandler fMouseHandler;
+ /*
+ * Zoom level and cached font for the current painting operation. Workaround for bug 516293.
+ * @since 3.12
+ */
+ int fZoom= 100;
+ private WeakReference<Font> fLastFont;
+ private Font fLastZoomedFont;
/**
@@ -666,6 +690,12 @@ public class LineNumberRulerColumn implements IVerticalRulerColumn {
fBuffer.dispose();
fBuffer= null;
}
+
+ if (fLastZoomedFont != null) {
+ fLastZoomedFont.dispose();
+ fLastZoomedFont= null;
+ fLastFont= null;
+ }
}
/**
@@ -687,31 +717,110 @@ public class LineNumberRulerColumn implements IVerticalRulerColumn {
fBuffer= null;
}
}
- if (fBuffer == null)
- fBuffer= new Image(fCanvas.getDisplay(), size.x, size.y);
- GC gc= new GC(fBuffer);
- gc.setFont(fCanvas.getFont());
- if (fForeground != null)
- gc.setForeground(fForeground);
+ ILineRange visibleLines= JFaceTextUtil.getVisibleModelLines(fCachedTextViewer);
+ if (visibleLines == null)
+ return;
- try {
- gc.setBackground(getBackground(fCanvas.getDisplay()));
- gc.fillRectangle(0, 0, size.x, size.y);
+ if (IS_MAC_BUG_516293) {
+ /* FIXME: Workaround (bug 516293):
+ * Relies on SWT implementation detail that GC drawing on macOS only draws at 100% zoom level.
+ * For higher zoom levels (200%), we manually scale the font and drawing coordinates,
+ * and then use getImageData(100) to extract the high-resolution image data. */
+ fBuffer= new Image(fCanvas.getDisplay(), (ImageDataProvider) zoom -> {
+ fZoom = zoom;
+ internalSetZoom(zoom);
+ int width= size.x * zoom / 100;
+ int height= size.y * zoom / 100;
+ Image gcImage= new Image(fCanvas.getDisplay(), width, height);
+
+ GC gc= new GC(gcImage);
+ Font font= fCanvas.getFont();
+ if (zoom != 100) {
+ if (fLastFont != null && font == fLastFont.get()) {
+ font= fLastZoomedFont;
+ } else {
+ fLastFont= new WeakReference<>(font);
+ FontData fontData= font.getFontData()[0];
+ fontData.setHeight(fontData.getHeight() * zoom / 100);
+ font= new Font(font.getDevice(), fontData);
+ fLastZoomedFont= font;
+ }
+ }
+ gc.setFont(font);
+ if (fForeground != null)
+ gc.setForeground(fForeground);
+
+ try {
+ gc.setBackground(getBackground(fCanvas.getDisplay()));
+ gc.fillRectangle(0, 0, width, height);
+
+ fScrollPos= fCachedTextWidget.getTopPixel();
+ doPaint(gc, visibleLines);
+ } finally {
+ gc.dispose();
+ fZoom= 100;
+ }
- ILineRange visibleLines= JFaceTextUtil.getVisibleModelLines(fCachedTextViewer);
- if (visibleLines == null)
- return;
- fScrollPos= fCachedTextWidget.getTopPixel();
- doPaint(gc, visibleLines);
- } finally {
- gc.dispose();
+ ImageData imageData= gcImage.getImageData(100);
+ gcImage.dispose();
+ return imageData;
+ });
+
+ } else {
+ if (fBuffer == null)
+ fBuffer= new Image(fCanvas.getDisplay(), size.x, size.y);
+
+ GC gc= new GC(fBuffer);
+ gc.setFont(fCanvas.getFont());
+ if (fForeground != null)
+ gc.setForeground(fForeground);
+
+ try {
+ gc.setBackground(getBackground(fCanvas.getDisplay()));
+ gc.fillRectangle(0, 0, size.x, size.y);
+
+ fScrollPos= fCachedTextWidget.getTopPixel();
+ doPaint(gc, visibleLines);
+ } finally {
+ gc.dispose();
+ }
}
dest.drawImage(fBuffer, 0, 0);
}
/**
+ * This method is not API and it is expected to disappear in Eclipse 4.8.
+ * Subclasses that want to take advantage of the unsupported workaround for bug 516258
+ * can re-implement this method and return true.
+ *
+ * @return true iff this class supports the workaround for bug 516258
+ *
+ * @nooverride This method is not intended to be re-implemented or extended by clients.
+ * @noreference This method is not intended to be referenced by clients.
+ * @since 3.12
+ */
+ protected boolean internalSupportsZoomedPaint() {
+ return getClass().getPackage().equals(LineNumberChangeRulerColumn.class.getPackage());
+ }
+
+ /**
+ * This method is not API and it is expected to disappear in Eclipse 4.8.
+ * Subclasses that want to take advantage of the unsupported workaround for bug 516258
+ * can override this method and store the given zoom level for later use.
+ *
+ * @param zoom the zoom level to use for drawing operations
+ *
+ * @nooverride This method is not intended to be re-implemented or extended by clients.
+ * @noreference This method is not intended to be referenced by clients.
+ * @since 3.12
+ */
+ protected void internalSetZoom(int zoom) {
+ // callback for subclasses
+ }
+
+ /**
* Returns the view port height in lines.
*
* @return the view port height in lines
@@ -848,7 +957,7 @@ public class LineNumberRulerColumn implements IVerticalRulerColumn {
}
int indentation= fIndentation[index];
int baselineBias= getBaselineBias(gc, widgetLine);
- gc.drawString(s, indentation, y + baselineBias, true);
+ gc.drawString(s, indentation * fZoom / 100, (y + baselineBias) * fZoom / 100, true);
}
/**

Back to the top