From 404c3c6ea0b25666a599df4b976516ef745f206c Mon Sep 17 00:00:00 2001 From: Lars Vogel Date: Sat, 29 Aug 2026 07:20:47 +0200 Subject: [PATCH] Paint the range indicator with alpha instead of a stipple image MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit DefaultRangeIndicator built a 1-bit image with every other pixel set to fake a 50 percent tint. On scaled displays the pattern is drawn in blocks of zoom/100 pixels, so at 200 percent the ruler shows a coarse checkerboard instead of a tint. Fill the range with the indicator colour at half alpha instead, which renders as a smooth tint at every zoom and removes the cached image, its dispose listener and the recreation on resize or colour change. Assisted-by: multiple AI agents and layers of automated tooling 🤖 --- .../ui/texteditor/DefaultRangeIndicator.java | 103 ++---------------- 1 file changed, 9 insertions(+), 94 deletions(-) diff --git a/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/DefaultRangeIndicator.java b/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/DefaultRangeIndicator.java index 62373dc0092..528fa024afa 100644 --- a/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/DefaultRangeIndicator.java +++ b/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/DefaultRangeIndicator.java @@ -15,18 +15,11 @@ package org.eclipse.ui.texteditor; -import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Color; 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.PaletteData; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.widgets.Canvas; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; import org.eclipse.jface.resource.JFaceResources; @@ -45,10 +38,8 @@ public class DefaultRangeIndicator extends Annotation implements IAnnotationPresentation { private static final String RANGE_INDICATOR_COLOR= "org.eclipse.ui.editors.rangeIndicatorColor"; //$NON-NLS-1$ - /** The image of this range indicator */ - private Image fImage; - /** The color used to draw the range indicator during the last paint action. */ - private Color fLastRangeIndicatorColor; + /** Alpha of the range fill, matching the coverage of the former stipple pattern. */ + private static final int FILL_ALPHA= 128; /** * Creates a new range indicator. @@ -79,96 +70,20 @@ public void paint(GC gc, Canvas canvas, Rectangle bounds) { return; } - Color currentRangeIndicatorColor= JFaceResources.getColorRegistry().get(RANGE_INDICATOR_COLOR); - Image image= getImage(canvas, currentRangeIndicatorColor); - gc.drawImage(image, 0, 0, w, h, x, y, w, h); + Color rangeIndicatorColor= JFaceResources.getColorRegistry().get(RANGE_INDICATOR_COLOR); + gc.setBackground(rangeIndicatorColor); + + int alpha= gc.getAlpha(); + gc.setAlpha(FILL_ALPHA); + gc.fillRectangle(x, y, w, h); + gc.setAlpha(alpha); - gc.setBackground(currentRangeIndicatorColor); gc.fillRectangle(x, bounds.y, w, b); gc.fillRectangle(x, bounds.y + bounds.height - b, w, b); - - fLastRangeIndicatorColor= currentRangeIndicatorColor; } @Override public int getLayer() { return IAnnotationPresentation.DEFAULT_LAYER; } - - /** - * Returns the image of this range indicator. - * - * @param control the control - * @param rangeIndicatorColor the color to be used to paint the range indicator - * @return an image - */ - private Image getImage(Control control, Color rangeIndicatorColor) { - if (fImage == null) { - fImage= createImage(control.getDisplay(), control.getSize(), rangeIndicatorColor); - - control.addDisposeListener(e -> { - if (fImage != null && !fImage.isDisposed()) { - fImage.dispose(); - fImage = null; - } - }); - } else { - Rectangle imageRectangle= fImage.getBounds(); - Point controlSize= control.getSize(); - - if (imageRectangle.width < controlSize.x || imageRectangle.height < controlSize.y - || !rangeIndicatorColor.equals(fLastRangeIndicatorColor)) { - fImage.dispose(); - fImage= createImage(control.getDisplay(), controlSize, rangeIndicatorColor); - } - } - - return fImage; - } - - /** - * Creates and returns a new SWT image with the given size on - * the given display which is used as this range indicator's image. - * - * @param display the display on which to create the image - * @param size the image size - * @param rangeIndicatorColor the color to be used to paint the range indicator - * @return a new image - */ - private static Image createImage(Display display, Point size, Color rangeIndicatorColor) { - - int width = size.x; - int height = size.y; - - ImageDataProvider imageDataProvider = zoom -> { - float scaleFactor = zoom / 100.0f; - int scaledWidth = Math.round(width * scaleFactor); - int scaledHeight = Math.round(height * scaleFactor); - ImageData imageData = new ImageData(scaledWidth, scaledHeight, 1, - createPalette(display, rangeIndicatorColor)); - int blockSize = Math.round(scaleFactor); - for (int y = 0; y < scaledHeight; y++) { - for (int x = 0; x < scaledWidth; x++) { - if (((x / blockSize) + (y / blockSize)) % 2 == 0) { - imageData.setPixel(x, y, 1); - } - } - } - imageData.transparentPixel = 1; - return imageData; - }; - - return new Image(display, imageDataProvider); - } - - /** - * Creates and returns a new color palette data. - * - * @param display the display - * @param rangeIndicatorColor the color to be used to paint the range indicator - * @return the new color palette data - */ - private static PaletteData createPalette(Display display, Color rangeIndicatorColor) { - return new PaletteData(rangeIndicatorColor.getRGB(), display.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND).getRGB()); - } }