/* Copyright (C) 2005-2011 Fabio Riccardi */
package com.lightcrafts.platform.windows;
import java.awt.*;
import java.awt.image.*;
import java.awt.print.PageFormat;
import java.awt.print.Paper;
import java.awt.print.PrinterException;
import com.lightcrafts.mediax.jai.PlanarImage;
import com.lightcrafts.platform.AlertDialog;
import com.lightcrafts.platform.Platform;
import com.lightcrafts.utils.thread.ProgressThread;
/**
* Do native printing on Windows.
*
* @author Paul J. Lucas [paul@lightcrafts.com]
*/
public final class WindowsPrintManager {
////////// public /////////////////////////////////////////////////////////
/**
* Disposes of native resources. Calling this multiple times in a row is
* guaranteed to be harmless.
*
* @see #initDefaultPrinter()
*/
public static native void dispose();
/**
* Gets the {@link PageFormat} for the printer.
*
* @return Returns said {@link PageFormat}.
* @see #setPageFormat(PageFormat)
*/
public static native PageFormat getPageFormat();
/**
* Gets the printer's resolution in pixels per inch.
*
* @return Returns said resolution.
*/
public static native Dimension getPrinterResolution();
/**
* Initializes the default printer information.
*
* @see #dispose()
*/
public static native void initDefaultPrinter();
/**
* Prints an image.
*
* @param image The image to print.
* @param offset The offset in pixels from the upper-left corner of the
* paper where to start printing the image.
* @param documentName The name of the image.
* @param thread The {@link ProgressThread} to use.
*/
public static synchronized void print( PlanarImage image,
Point offset,
String documentName,
ProgressThread thread )
throws PrinterException
{
if ( !isPrinterCapable() ) {
Platform.getPlatform().getAlertDialog().showAlert(
null, "Incapable Printer",
"The selected printer can not be used with LightZone.",
AlertDialog.ERROR_ALERT, new String[]{ "OK" }
);
return;
}
thread.getProgressIndicator().setMaximum(image.getMaxTileX() * image.getMaxTileY());
beginPrinting( documentName, 24 );
beginPage();
for ( int tileX = 0; tileX <= image.getMaxTileX(); ++tileX )
for ( int tileY = 0; tileY <= image.getMaxTileY(); ++tileY ) {
if ( thread.isCanceled() ) {
abortPrinting();
return;
}
Raster tile = image.getTile( tileX, tileY );
final Rectangle tileBounds = tile.getBounds();
final Rectangle clippedTileBounds = tile.getBounds().intersection(image.getBounds());
final BufferedImage tileImage = new BufferedImage(
image.getColorModel(),
(WritableRaster)tile.createTranslatedChild( 0, 0 ),
false, null
);
final BufferedImage winImage = new BufferedImage(
clippedTileBounds.width, clippedTileBounds.height,
BufferedImage.TYPE_3BYTE_BGR
);
final Graphics2D g2d = winImage.createGraphics();
g2d.drawImage( tileImage, null, 0, 0 );
g2d.dispose();
tile = winImage.getRaster().createTranslatedChild(
(int)tileBounds.getMinX(),
(int)tileBounds.getMinY()
);
final DataBufferByte dbb =
(DataBufferByte)tile.getDataBuffer();
printTile(
(int)tileBounds.getMinX() + offset.x,
(int)tileBounds.getMinY() + offset.y,
winImage.getWidth(),
winImage.getHeight(),
dbb.getData()
);
thread.getProgressIndicator().incrementBy( 1 );
}
endPage();
endPrinting();
}
/**
* Sets the {@link PageFormat}.
*
* @param format The {@link PageFormat} to use.
* @see #getPageFormat()
*/
public static void setPageFormat( PageFormat format ) {
final Paper paper = format.getPaper();
setPageFormat(
paper.getWidth(), paper.getHeight(),
paper.getImageableX(), paper.getImageableY(),
paper.getImageableWidth(), paper.getImageableHeight(),
format.getOrientation()
);
}
/**
* Shows the native Windows Page Setup dialog.
*
* @param parent The parent window; may be <code>null</code>.
* @return Returns <code>true</code> only if the user clicked OK.
*/
public static native boolean showPageSetupDialog( Frame parent );
/**
* Shows the native Windows Print dialog.
*
* @param parent The parent window; may be <code>null</code>.
* @return Returns <code>true</code> only if the user clicked Print.
*/
public static native boolean showPrintDialog( Frame parent );
////////// protected //////////////////////////////////////////////////////
protected void finalize() throws Throwable {
dispose();
super.finalize();
}
////////// private ////////////////////////////////////////////////////////
/**
* Signals the native code to abort printing.
*/
private static native void abortPrinting();
/**
* Begins a page.
*
* @see #endPage()
*/
private static native void beginPage() throws PrinterException;
/**
* Begins printing.
*
* @param documentName The name of the image document.
* @param bitsPerPixel The number of bits per pixel of the image.
* @see #endPrinting()
*/
private static native void beginPrinting( String documentName,
int bitsPerPixel )
throws PrinterException;
/**
* Ends a page.
*
* @see #beginPage()
*/
private static native void endPage() throws PrinterException;
/**
* End printing.
*
* @see #beginPrinting(String,int)
*/
private static native void endPrinting() throws PrinterException;
/**
* Checks whether the selected printer is capable of printing using our
* implementation method.
*
* @return Returns <code>true</code> only if the printer is capable.
*/
private static native boolean isPrinterCapable();
/**
* Print a tile.
*
* @param x The X coordinate in pixels of where the tile should be placed
* on the paper.
* @param y The Y coordinate in pixels of where the file should be placed
* on the paper.
* @param width The width in pixels of the tile.
* @param height The height in pixels of the tile.
* @param data The RGB image data of the tile.
*/
private static native void printTile( int x, int y, int width, int height,
byte[] data )
throws PrinterException;
/**
* Sets the page format.
*
* @param paperWidth The paper width in 1/72" units.
* @param paperHeight The paper height in 1/72" units.
* @param imageableX The imagable X coordinate in 1/72" units.
* @param imageableY The imagable Y coordinate in 1/72" units.
* @param imageableWidth The imagable width in 1/72" units.
* @param imageableHeight The imagable height in 1/72" units.
* @param orientation The orientation, either {@link PageFormat#LANDSCAPE}
* or {@link PageFormat#PORTRAIT}
*/
private static native void setPageFormat( double paperWidth,
double paperHeight,
double imageableX,
double imageableY,
double imageableWidth,
double imageableHeight,
int orientation );
static {
System.loadLibrary( "Windows" );
}
////////// main() for testing /////////////////////////////////////////////
public static void main( String[] args ) throws Exception {
/*
final ImageInfo info = ImageInfo.getInstanceFor( new File( args[0] ) );
final PlanarImage image = info.getImage( null );
final JFrame frame = new JFrame( "TIFF Image" );
final JPanel imagePanel = new JPanel() {
public void paintComponent( Graphics g ) {
((Graphics2D)g).drawRenderedImage( image, new AffineTransform() );
}
};
imagePanel.setPreferredSize(
new Dimension( image.getWidth(), image.getHeight() )
);
final JScrollPane scrollPane = new JScrollPane( imagePanel );
frame.setContentPane( scrollPane );
frame.pack();
frame.setSize( 1000, 700 );
frame.show();
*/
showPageSetupDialog( null );
final PageFormat pf = getPageFormat();
dumpPage( pf );
//print( image, args[0], frame );
System.exit( 0 );
}
public static void dumpPage(PageFormat pageFormat) {
System.out.println(
"page area: w=" + pageFormat.getWidth()
+ ", h=" + pageFormat.getHeight()
+ ", orientation="
+ (pageFormat.getOrientation() == PageFormat.LANDSCAPE ? "landscape" : "portrait")
);
System.out.println(
"imageable area: x=" + pageFormat.getImageableX()
+ ", y=" + pageFormat.getImageableY()
+ ", w=" + pageFormat.getImageableWidth()
+ ", h=" + pageFormat.getImageableHeight()
);
}
}
/* vim:set et sw=4 ts=4: */