paintCanvas.addDisposeListener(new DisposeListener() { public void widgetDisposed(DisposeEvent e) { displayFDC.gc.dispose(); } });
	public PaintSurface(Canvas paintCanvas, Text statusText, Color fillColor) {		this.paintCanvas = paintCanvas;		this.statusText = statusText;		clearStatus();		/* Set up the drawing surface */		Rectangle displayRect = paintCanvas.getDisplay().getClientArea();		imageWidth = displayRect.width;		imageHeight = displayRect.height;		image = new Image(paintCanvas.getDisplay(), imageWidth, imageHeight);		imageFDC.gc = new GC(image);		imageFDC.gc.setBackground(fillColor);		imageFDC.gc.fillRectangle(0, 0, imageWidth, imageHeight);		displayFDC.gc = new GC(paintCanvas);		/* Initialize the session */		setPaintSession(null);		/* Add our listeners */		paintCanvas.addMouseListener(new MouseAdapter() {			public void mouseDown(MouseEvent event) {				processMouseEventCoordinates(event);				if (paintSession != null) paintSession.mouseDown(event);			}			public void mouseUp(MouseEvent event) {				processMouseEventCoordinates(event);				if (paintSession != null) paintSession.mouseUp(event);			}			public void mouseDoubleClick(MouseEvent event) {				processMouseEventCoordinates(event);				if (paintSession != null) paintSession.mouseDoubleClick(event);			}					});		paintCanvas.addMouseMoveListener(new MouseMoveListener() {			public void mouseMove(MouseEvent event) {				processMouseEventCoordinates(event);				if (paintSession != null) paintSession.mouseMove(event);			}		});		paintCanvas.addPaintListener(new PaintListener() {			public void paintControl(PaintEvent event) {				if (rubberband.isEmpty()) {					// Nothing to merge, so we just refresh					event.gc.drawImage(image,						displayFDC.xOffset + event.x, displayFDC.yOffset + event.y, event.width, event.height,						event.x, event.y, event.width, event.height);				} else {					/*					 * Avoid flicker when merging overlayed objects by constructing the image on					 * a backbuffer first, then blitting it to the screen.					 */					// Check that the backbuffer is large enough					if (paintImage != null) {						Rectangle rect = paintImage.getBounds();						if ((event.width + event.x > rect.width) ||							(event.height + event.y > rect.height)) {							paintFDC.gc.dispose();							paintImage.dispose();							paintImage = null;						}					}					if (paintImage == null) {						Display display = getDisplay();						Rectangle rect = display.getClientArea();						paintImage = new Image(display,							Math.max(rect.width, event.width + event.x),							Math.max(rect.height, event.height + event.y));						paintFDC.gc = new GC(paintImage);					}					// Setup clipping and the FDC					Region clipRegion = new Region();					event.gc.getClipping(clipRegion);										paintFDC.gc.setClipping(clipRegion);					clipRegion.dispose();					paintFDC.xOffset = displayFDC.xOffset;					paintFDC.yOffset = displayFDC.yOffset;					paintFDC.xScale = displayFDC.xScale;					paintFDC.yScale = displayFDC.yScale;										// Merge the overlayed objects into the image, then blit					paintFDC.gc.drawImage(image,						displayFDC.xOffset + event.x, displayFDC.yOffset + event.y, event.width, event.height,						event.x, event.y, event.width, event.height);					rubberband.draw(paintFDC);					event.gc.drawImage(paintImage,						event.x, event.y, event.width, event.height,						event.x, event.y, event.width, event.height);				}			}		});		paintCanvas.addControlListener(new ControlAdapter() {			public void controlResized(ControlEvent event) {				handleResize();			}					});		/* Set up the paint canvas scroll bars */		ScrollBar horizontal = paintCanvas.getHorizontalBar();		horizontal.setVisible(true);		horizontal.addSelectionListener(new SelectionAdapter() {			public void widgetSelected(SelectionEvent event) {				scrollHorizontally((ScrollBar)event.widget);			}		});		ScrollBar vertical = paintCanvas.getVerticalBar();		vertical.setVisible(true);		vertical.addSelectionListener(new SelectionAdapter() {			public void widgetSelected(SelectionEvent event) {				scrollVertically((ScrollBar)event.widget);			}		});		handleResize();	}