blob: a4e3d414338e001b956bebe8b68e310a6a972567 [file] [log] [blame]
/******************************************************************************
* Copyright (c) 2002, 2009 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.gmf.runtime.draw2d.ui.internal.graphics;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Stack;
import org.eclipse.draw2d.Graphics;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.printing.Printer;
/**
* Created on May 8, 2003
*
* @author sshaw
* @version 1.0
*
* Overridden to handle printing problem with transparencies. Specifically,
* dropshadows print with as a black bar (RATLC00513998)
*/
public class PrinterGraphics extends org.eclipse.draw2d.PrinterGraphics {
private double printScale = 1.0;
private boolean roundFonts = false;
private Stack stateStack = new Stack();
/**
* @return Returns the printScale.
*/
protected double getPrintScale() {
return printScale;
}
/**
* Creates a new <code>PrinterGraphics</code> with <code>Graphics</code> g, using
* <code>Printer</code> p
*
* @param g <code>Graphics</code> object to draw with
* @param p <code>Printer</code> to print to
* @param roundFonts the <code>boolean</code> if <code>true</code> indicates that fonts
* should be rounded to account for printer font scaling errors.
*/
public PrinterGraphics(Graphics g, Printer p, boolean roundFonts) {
super(g, p);
this.roundFonts = roundFonts;
}
/* (non-Javadoc)
* @see org.eclipse.draw2d.Graphics#dispose()
*/
public void dispose() {
for (Iterator<Image> it = collapseImageCache.values().iterator(); it.hasNext();)
{
Image img = it.next();
img.dispose();
}
collapseImageCache.clear();
super.dispose();
}
Map<Image, Image> collapseImageCache = new HashMap<Image, Image>();
/**
* collapseImage
* This method is necessary to work around a problem with the printer GC that
* doesn't seem to support alpha channels on Images. Consequently we collapse the
* image based on the background.
* This workaround won't be necessary when Bugzilla 28766 is fixed.
*
* @param srcImage Image to collapse the alpha channel of.
* @return Image that has no alpha channel.
*/
private Image collapseImage(Image srcImage) {
Image result = (Image)collapseImageCache.get(srcImage);
if (result != null)
return result;
org.eclipse.swt.graphics.Rectangle r1 = srcImage.getBounds();
Image newImg = new Image( null, r1.width, r1.height);
GC gc = new GC(newImg);
gc.setForeground(getForegroundColor());
gc.setBackground(getBackgroundColor());
gc.drawImage(srcImage, 0, 0);
gc.dispose();
collapseImageCache.put(srcImage, newImg);
return newImg;
}
/**
* @see org.eclipse.draw2d.Graphics#drawImage(org.eclipse.swt.graphics.Image, int, int)
*/
public void drawImage(Image srcImage, int x, int y) {
Image collapseImage = srcImage.getImageData().transparentPixel == -1 ? collapseImage(srcImage)
: srcImage;
super.drawImage(collapseImage, x, y);
}
/**
* @see org.eclipse.draw2d.Graphics#drawImage(org.eclipse.swt.graphics.Image, int, int, int, int, int, int, int, int)
*/
public void drawImage(Image srcImage, int sx, int sy, int sw, int sh,
int tx, int ty, int tw, int th) {
Image collapseImage = srcImage.getImageData().transparentPixel == -1 ? collapseImage(srcImage)
: srcImage;
super.drawImage(collapseImage, sx, sy, sw, sh, tx, ty, tw, th);
}
/**
* shouldRoundFonts
* Accessor method to determine if fonts should be rounded to account for printer
* font scaling errors.
*
* @return boolean true if fonts should be rounded, false otherwise.
*/
public boolean shouldRoundFonts() {
return roundFonts;
}
/**
* @see org.eclipse.draw2d.Graphics#scale(double)
*/
public void scale(double amount) {
printScale = printScale * amount;
super.scale(amount);
}
/* (non-Javadoc)
* @see org.eclipse.draw2d.Graphics#popState()
*/
public void popState() {
if (!stateStack.isEmpty())
printScale = ((Double)stateStack.pop()).doubleValue();
super.popState();
}
/* (non-Javadoc)
* @see org.eclipse.draw2d.Graphics#pushState()
*/
public void pushState() {
stateStack.push(new Double(printScale));
super.pushState();
}
/* (non-Javadoc)
* @see org.eclipse.draw2d.Graphics#restoreState()
*/
public void restoreState() {
if (!stateStack.isEmpty())
printScale = ((Double)stateStack.firstElement()).doubleValue();
super.restoreState();
}
/**
* This should be escalated as a GEF / SWT problem - difficult to reproduce in
* logic example though. The font size needs to scaled down to account for
* printer font scaling issues.
*
* @see org.eclipse.draw2d.Graphics#setFont(org.eclipse.swt.graphics.Font)
*/
public void setFont(Font f) {
Font newFont = f;
if (shouldRoundFonts()) {
FontData fd = f.getFontData()[0];
int nAdjustedHeight = (int)(((fd.getHeight() - 0.5f) / getPrintScale()) * getPrintScale());
if (fd.getHeight() != nAdjustedHeight) {
fd.setHeight(nAdjustedHeight);
newFont = FontRegistry.getInstance().getFont(null, fd);
}
}
super.setFont(newFont);
}
}