/*
* @(#)ZoomUpdateStrategy.java
*
* Project: JHotdraw - a GUI framework for technical drawings
* http://www.jhotdraw.org
* http://jhotdraw.sourceforge.net
* Copyright: � by the original author(s) and all contributors
* License: Lesser GNU Public License (LGPL)
* http://www.opensource.org/licenses/lgpl-license.html
*/
package org.jhotdraw.contrib.zoom;
import org.jhotdraw.framework.DrawingView;
import org.jhotdraw.framework.Painter;
import java.awt.*;
/**
* A variant of the BufferedUpdateStrategy that handles clipping
* rectangles correctly in the presence of zooming.
* @see org.jhotdraw.standard.BufferedUpdateStrategy
*
* @author Andre Spiegel <spiegel@gnu.org>
* @version <$CURRENT_VERSION$>
*/
public class ZoomUpdateStrategy implements Painter {
/**
* The offscreen image
*/
transient private Image fOffscreen;
private int fImagewidth = -1;
private int fImageheight = -1;
/**
* Draws the view contents.
*/
public void draw(Graphics g, DrawingView view) {
// create the buffer if necessary
Dimension d = view.getSize();
if ((fOffscreen == null) || (d.width != fImagewidth)
|| (d.height != fImageheight)) {
fOffscreen = view.createImage(d.width, d.height);
fImagewidth = d.width;
fImageheight = d.height;
}
Graphics g2 = fOffscreen.getGraphics();
Rectangle r = g.getClipBounds();
if (g2 instanceof ScalingGraphics) {
ScalingGraphics s2 = (ScalingGraphics) g2;
// AWT sets clipping rectangles in screen coordinates, not user
// coordinates. Therefore, we scale the clipping rectangle to
// user coordinates here, and then apply it to both buffers,
// which scale it back to screen coordinates.
if (r != null) {
// Make the rectangle slightly larger, to compensate
// for integer rounding errors.
r = new Rectangle((int) ((r.x - 2) / s2.getScale()),
(int) ((r.y - 2) / s2.getScale()),
(int) ((r.width + 4) / s2.getScale()),
(int) ((r.height + 4) / s2.getScale()));
g.setClip(r);
}
}
g2.setClip(r);
view.drawAll(g2);
g.drawImage(fOffscreen, 0, 0, view);
}
}