Bug 148035

Summary: Nothing is painted while painting scaled images
Product: [Eclipse Project] Platform Reporter: Andre Saibel <andre.saibel>
Component: SWTAssignee: Silenio Quarti <Silenio_Quarti>
Status: NEW --- QA Contact:
Severity: normal    
Priority: P3 CC: steve_northover
Version: 3.6   
Target Milestone: ---   
Hardware: PC   
OS: Windows XP   
Whiteboard:

Description Andre Saibel CLA 2006-06-21 09:55:30 EDT
hello..

My test snippet creates a small and simple image (100x100) with a cup of transparent pixels; it also imitates the double buffering mechanism - so this image (testImage) is created once and then drawn into an other image (shadowImage) using a zoom factor.. then the shadowImage is clipped into PaintEvent's GC. 
A mouse click into the shell causes the view to appear zoomed in/out.. but if you try it out, you will notice, that 
1) somewhere along the way nothing more is painted
2) some later an SWTError is thrown: 
org.eclipse.swt.SWTError: No more handles
	at org.eclipse.swt.SWT.error(SWT.java:2968)
	at org.eclipse.swt.SWT.error(SWT.java:2865)
	at org.eclipse.swt.SWT.error(SWT.java:2836)
	at org.eclipse.swt.graphics.GC.drawBitmapAlpha(GC.java:900)
	at org.eclipse.swt.graphics.GC.drawBitmap(GC.java:863)
	at org.eclipse.swt.graphics.GC.drawImage(GC.java:705)
	at org.eclipse.swt.graphics.GC.drawImage(GC.java:665)
	at DIBTest$1.paintControl(DIBTest.java:xx)

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.widgets.*;

public class DIBTest {
	static final boolean SHADOWED = true;

	static final int MAX_ZOOM = 512;
	static final int MIN_ZOOM = 1;
	static final int WIDTH = 100;
	static final int HEIGHT = 100;
	static int zoom = MIN_ZOOM;
	static boolean zoomIn = true;

	static Image createTestImage(Display display, int width, int height) {
		ImageData imageData = new ImageData(width, height, 32, new PaletteData(
				255, 255, 255), 1, new byte[height * 4 * width * 4]);
		for (int x = 0; x < width; x++) {
			for (int y = 0; y < height; y++) {
				if (y == x || x == width - y - 1 || x == 0 || x == height - 1
						|| y == 0 || y == width - 1) {
					imageData.setAlpha(x, y, 0xFF);
				}
			}
		}
		return new Image(display, imageData);
	}

	static void test(Composite composite) {
		if (zoomIn) {
			zoom *= 2;
		} else {
			zoom /= 2;
		}
		if (zoom >= MAX_ZOOM) {
			zoomIn = false;
		} else if (zoom <= MIN_ZOOM) {
			zoomIn = true;
		}
		composite.redraw();
	}

	public static void main(String[] args) {
		final Display display = new Display();
		final Shell shell = new Shell(display);

		final Image testImage = createTestImage(display, WIDTH, HEIGHT);
		final Image shadowImage = new Image(display, WIDTH, HEIGHT);
		final GC shadowGc = new GC(shadowImage);
		shell.addPaintListener(new PaintListener() {
			int _i = 0;

			public void paintControl(PaintEvent e) {
				if (SHADOWED == true) {
					shadowGc.fillRectangle(e.gc.getClipping());
					shadowGc.drawImage(testImage, 0, 0, WIDTH, HEIGHT, 0, 0,
							zoom * WIDTH, zoom * HEIGHT);
					e.gc.drawImage(shadowImage, 0, 0);
				} else {
					e.gc.fillRectangle(e.gc.getClipping());
					e.gc.drawImage(testImage, 0, 0, WIDTH, HEIGHT, 0, 0, zoom
							* WIDTH, zoom * HEIGHT);
				}

				System.out.println("zoom: " + zoom + "; " + (++_i)
						+ " paint event");
			}
		});
		shell.addMouseListener(new MouseAdapter() {
			public void mouseDown(MouseEvent e) {
				test(shell);
			}
		});
		shell.setBounds(shell.computeTrim(50, 50, WIDTH, HEIGHT));
		shell.open();
		while (!shell.isDisposed()) {
			if (!display.readAndDispatch()) {
				display.sleep();
			}
		}
	}
}

This code at its own doesn't make sense.. but I have a real application, which has to visualize data from different sources (testImages) at same time.. I'm kinda perplexed, that if I turn off this double buffering hocus-pocus (SHADOWED=false), the problem doesn't occur. Any Idea? 

best regards
Saibel

PS: I would point out that after the initialization no new images (nor any other OS resources) are created -> misleading SWT.ERROR_NO_HANDLES error.
Comment 1 Grant Gayed CLA 2006-06-30 11:07:54 EDT
I can reproduce the problem using your snippet in 3.1.2, but it works well for me in 3.2, so this appears to have been fixed.  If you still have problems in 3.2 (official announcement/release should be later today) then please reopen this report, thanks.
Comment 2 Andre Saibel CLA 2006-07-04 03:22:20 EDT
OK, the second effect (SWT.ERROR_NO_HANDLES) is fixed, 
BUT: the first one (nothing more is painted) still remains - on my machine with SWT 3229@win32 it occurs at a zoom factor of >= 512.
AND: it doesn't matter whether I use the double buffering technique or not.

thx
Comment 3 Silenio Quarti CLA 2006-10-25 11:02:54 EDT
AlphaBlend() function is failing when the zoom factor is too big. I am not sure how to work around this problem.
Comment 4 Steve Northover CLA 2006-10-25 13:24:58 EDT
Does it return a fail code when it fails?  Can we run (slower) emulated code?
Comment 5 Silenio Quarti CLA 2006-10-26 10:26:10 EDT
No, it always return true (success). GetLastError() also returns no error.
Comment 6 Andre Saibel CLA 2010-08-05 10:02:51 EDT
With 3.650@win32 the problem still remains when using zoom factor >=512.
Comment 7 Eclipse Webmaster CLA 2019-09-06 15:38:23 EDT
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet.

If you have further information on the current state of the bug, please add it. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant.