blob: 7901b397dea29797786a48e7571d2a272ad340e9 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2010 IBM Corporation and others. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.draw2d;
import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTError;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Caret;
import org.eclipse.swt.widgets.Control;
import org.eclipse.draw2d.geometry.Rectangle;
class BufferedGraphicsSource implements GraphicsSource {
private Image imageBuffer;
private GC imageGC;
private GC controlGC;
private Control control;
private Rectangle inUse;
/**
* Constructs a new buffered graphics source using the given control.
*
* @since 2.1
* @param c
* the control
*/
public BufferedGraphicsSource(Control c) {
control = c;
}
/**
* @see org.eclipse.draw2d.GraphicsSource#flushGraphics(org.eclipse.draw2d.geometry.Rectangle)
*/
public void flushGraphics(Rectangle region) {
if (inUse.isEmpty())
return;
boolean restoreCaret = false;
Canvas canvas = null;
if (control instanceof Canvas) {
canvas = (Canvas) control;
Caret caret = canvas.getCaret();
if (caret != null)
restoreCaret = caret.isVisible();
if (restoreCaret)
caret.setVisible(false);
}
/*
* The imageBuffer may be null if double-buffering was not successful.
*/
if (imageBuffer != null) {
imageGC.dispose();
controlGC.drawImage(getImage(), 0, 0, inUse.width, inUse.height,
inUse.x, inUse.y, inUse.width, inUse.height);
imageBuffer.dispose();
imageBuffer = null;
imageGC = null;
}
if (controlGC != null) {
controlGC.dispose();
}
controlGC = null;
if (restoreCaret)
canvas.getCaret().setVisible(true);
}
/**
* @see org.eclipse.draw2d.GraphicsSource#getGraphics(org.eclipse.draw2d.geometry.Rectangle)
*/
public Graphics getGraphics(Rectangle region) {
if (control == null || control.isDisposed())
return null;
org.eclipse.swt.graphics.Point ptSWT = control.getSize();
inUse = new Rectangle(0, 0, ptSWT.x, ptSWT.y);
inUse.intersect(region);
if (inUse.isEmpty())
return null;
/*
* Bugzilla 53632 - Attempts to create large images on some platforms
* will fail. When this happens, do not use double-buffering for
* painting.
*/
try {
// imageBuffer = new Image(null, inUse.width, inUse.height);
} catch (SWTError noMoreHandles) {
imageBuffer = null;
} catch (IllegalArgumentException tooBig) {
imageBuffer = null;
}
controlGC = new GC(control, control.getStyle()
& (SWT.RIGHT_TO_LEFT | SWT.LEFT_TO_RIGHT));
Graphics graphics;
if (imageBuffer != null) {
imageGC = new GC(imageBuffer, control.getStyle()
& (SWT.RIGHT_TO_LEFT | SWT.LEFT_TO_RIGHT));
imageGC.setBackground(controlGC.getBackground());
imageGC.setForeground(controlGC.getForeground());
imageGC.setFont(controlGC.getFont());
imageGC.setLineStyle(controlGC.getLineStyle());
imageGC.setLineWidth(controlGC.getLineWidth());
imageGC.setXORMode(controlGC.getXORMode());
graphics = new SWTGraphics(imageGC);
graphics.translate(inUse.getLocation().negate());
} else {
graphics = new SWTGraphics(controlGC);
}
graphics.setClip(inUse);
return graphics;
}
/**
* Returns the current image buffer or <code>null</code>.
*
* @since 2.1
* @return the current image buffer
*/
protected Image getImage() {
return imageBuffer;
}
/**
* Returns the current GC used on the buffer or <code>null</code>.
*
* @since 2.1
* @return the GC for the image buffer
*/
protected GC getImageGC() {
return imageGC;
}
}