Some fixes on the printing API from Karsten Heinrich

This commit is contained in:
smallsql 2010-12-15 14:53:33 +00:00
Родитель 46be1e2aa9
Коммит 8270a2d62e
3 изменённых файлов: 530 добавлений и 27 удалений

Просмотреть файл

@ -1,5 +1,6 @@
/* /*
Copyright (C) 2009 Volker Berlin (i-net software) Copyright (C) 2009 Volker Berlin (i-net software)
Copyright (C) 2010 Karsten Heinrich (i-net software)
This software is provided 'as-is', without any express or implied This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages warranty. In no event will the authors be held liable for any damages
@ -115,12 +116,31 @@ namespace ikvm.awt.printing
private const int ERROR_INSUFFICIENT_BUFFER = 122; private const int ERROR_INSUFFICIENT_BUFFER = 122;
private const int PRINTER_STATUS_DOOR_OPEN = 0x400000; private const int PRINTER_STATUS_PAUSED = 0x1;
private const int PRINTER_STATUS_ERROR = 0x2; private const int PRINTER_STATUS_ERROR = 0x2; // MSDN says that this value is not used
private const int PRINTER_STATUS_NO_TONER = 0x40000; private const int PRINTER_STATUS_PENDING_DELETION = 0x4;
private const int PRINTER_STATUS_OFFLINE = 0x80; private const int PRINTER_STATUS_PAPER_JAM = 0x8;
private const int PRINTER_STATUS_OUT_OF_MEMORY = 0x200000; private const int PRINTER_STATUS_PAPER_OUT = 0x10;
private const int PRINTER_STATUS_MANUAL_FEED = 0x20;
private const int PRINTER_STATUS_PAPER_PROBLEM = 0x40;
private const int PRINTER_STATUS_OFFLINE = 0x80;
private const int PRINTER_STATUS_IO_ACTIVE = 0x100;
private const int PRINTER_STATUS_BUSY = 0x200;
private const int PRINTER_STATUS_PRINTING = 0x400;
private const int PRINTER_STATUS_OUTPUT_BIN_FULL = 0x800;
private const int PRINTER_STATUS_NOT_AVAILABLE = 0x1000;
private const int PRINTER_STATUS_WAITING = 0x2000;
private const int PRINTER_STATUS_PROCESSING = 0x4000;
private const int PRINTER_STATUS_INITIALIZING = 0x8000;
private const int PRINTER_STATUS_WARMING_UP = 0x10000;
private const int PRINTER_STATUS_TONER_LOW = 0x20000;
private const int PRINTER_STATUS_NO_TONER = 0x40000;
private const int PRINTER_STATUS_PAGE_PUNT = 0x80000;
private const int PRINTER_STATUS_USER_INTERVENTION = 0x100000; private const int PRINTER_STATUS_USER_INTERVENTION = 0x100000;
private const int PRINTER_STATUS_OUT_OF_MEMORY = 0x200000;
private const int PRINTER_STATUS_DOOR_OPEN = 0x400000;
private const int PRINTER_STATUS_SERVER_UNKNOWN = 0x800000;
private const int PRINTER_STATUS_POWER_SAVE = 0x1000000;
/// <summary> /// <summary>
/// Get a printer status /// Get a printer status
@ -134,6 +154,27 @@ namespace ikvm.awt.printing
int status; int status;
if (GetPrinterInfo2(printerName, out cJobs, out status)) if (GetPrinterInfo2(printerName, out cJobs, out status))
{ {
if (category == (java.lang.Class)typeof(javax.print.attribute.standard.PrinterState))
{
if ((status &
(PRINTER_STATUS_ERROR | PRINTER_STATUS_NO_TONER | PRINTER_STATUS_OUT_OF_MEMORY |
PRINTER_STATUS_OFFLINE | PRINTER_STATUS_USER_INTERVENTION |
PRINTER_STATUS_DOOR_OPEN | PRINTER_STATUS_NOT_AVAILABLE )) > 0)
{
return javax.print.attribute.standard.PrinterState.STOPPED;
}
if( (status & (PRINTER_STATUS_BUSY | PRINTER_STATUS_PRINTING ))> 0 )
{
return javax.print.attribute.standard.PrinterState.PROCESSING;
}
return null;
// null seems to be the default instead of unknown - UNKOWN ist not used in the reference RT
// javax.print.attribute.standard.PrinterState.UNKNOWN;
}
if (category == (java.lang.Class)typeof(javax.print.attribute.standard.PrinterStateReasons))
{
return extractResions(status);
}
if (category == (java.lang.Class)typeof(javax.print.attribute.standard.QueuedJobCount)) if (category == (java.lang.Class)typeof(javax.print.attribute.standard.QueuedJobCount))
{ {
return new javax.print.attribute.standard.QueuedJobCount(cJobs); return new javax.print.attribute.standard.QueuedJobCount(cJobs);
@ -159,6 +200,65 @@ namespace ikvm.awt.printing
return null; return null;
} }
private javax.print.attribute.standard.PrinterStateReasons extractResions(int status)
{
javax.print.attribute.standard.PrinterStateReasons reasons = new javax.print.attribute.standard.PrinterStateReasons();
if ((status & PRINTER_STATUS_PAUSED) > 0)
{
reasons.put(javax.print.attribute.standard.PrinterStateReason.PAUSED, javax.print.attribute.standard.Severity.REPORT);
}
if ((status & PRINTER_STATUS_ERROR) > 0)
{
reasons.put(javax.print.attribute.standard.PrinterStateReason.OTHER, javax.print.attribute.standard.Severity.ERROR);
}
if ((status & PRINTER_STATUS_PENDING_DELETION) > 0) { }
if ((status & PRINTER_STATUS_PAPER_JAM) > 0)
{
reasons.put(javax.print.attribute.standard.PrinterStateReason.MEDIA_JAM, javax.print.attribute.standard.Severity.WARNING);
}
if ((status & PRINTER_STATUS_PAPER_OUT) > 0)
{
reasons.put(javax.print.attribute.standard.PrinterStateReason.MEDIA_EMPTY, javax.print.attribute.standard.Severity.WARNING);
}
if ((status & PRINTER_STATUS_MANUAL_FEED) > 0) { }
if ((status & PRINTER_STATUS_PAPER_PROBLEM) > 0) {}
if ((status & PRINTER_STATUS_OFFLINE) > 0) {
reasons.put(javax.print.attribute.standard.PrinterStateReason.TIMED_OUT, javax.print.attribute.standard.Severity.ERROR);
}
if ((status & PRINTER_STATUS_IO_ACTIVE) > 0) { }
if ((status & PRINTER_STATUS_BUSY) > 0) { }
if ((status & PRINTER_STATUS_PRINTING) > 0) { }
if ((status & PRINTER_STATUS_OUTPUT_BIN_FULL) > 0) {
reasons.put(javax.print.attribute.standard.PrinterStateReason.OUTPUT_AREA_FULL, javax.print.attribute.standard.Severity.WARNING);
}
if ((status & PRINTER_STATUS_NOT_AVAILABLE) > 0) { }
if ((status & PRINTER_STATUS_WAITING) > 0) { }
if ((status & PRINTER_STATUS_PROCESSING) > 0) { }
if ((status & PRINTER_STATUS_INITIALIZING) > 0) { }
if ((status & PRINTER_STATUS_WARMING_UP) > 0) { }
if ((status & PRINTER_STATUS_TONER_LOW) > 0) {
reasons.put(javax.print.attribute.standard.PrinterStateReason.TONER_LOW, javax.print.attribute.standard.Severity.WARNING);
}
if ((status & PRINTER_STATUS_NO_TONER) > 0) {
reasons.put(javax.print.attribute.standard.PrinterStateReason.TONER_EMPTY, javax.print.attribute.standard.Severity.ERROR);
}
if ((status & PRINTER_STATUS_PAGE_PUNT) > 0) { }
if ((status & PRINTER_STATUS_USER_INTERVENTION) > 0) {
reasons.put(javax.print.attribute.standard.PrinterStateReason.OTHER, javax.print.attribute.standard.Severity.ERROR);
}
if ((status & PRINTER_STATUS_OUT_OF_MEMORY) > 0) {
reasons.put(javax.print.attribute.standard.PrinterStateReason.OTHER, javax.print.attribute.standard.Severity.ERROR);
}
if ((status & PRINTER_STATUS_DOOR_OPEN) > 0) {
reasons.put(javax.print.attribute.standard.PrinterStateReason.DOOR_OPEN, javax.print.attribute.standard.Severity.ERROR);
}
if ((status & PRINTER_STATUS_SERVER_UNKNOWN) > 0) { }
if ((status & PRINTER_STATUS_POWER_SAVE) > 0) {
reasons.put(javax.print.attribute.standard.PrinterStateReason.PAUSED, javax.print.attribute.standard.Severity.REPORT);
}
return reasons.isEmpty() ? null : reasons;
}
/// <summary> /// <summary>
/// Get infos from the PRINTER_INFO_2 struc /// Get infos from the PRINTER_INFO_2 struc
/// </summary> /// </summary>
@ -228,4 +328,8 @@ namespace ikvm.awt.printing
return ClosePrinter(handle); return ClosePrinter(handle);
} }
} }
class Win32Print
{
}
} }

Просмотреть файл

@ -1,5 +1,6 @@
/* /*
Copyright (C) 2009 Volker Berlin (i-net software) Copyright (C) 2009 Volker Berlin (i-net software)
Copyright (C) 2010 Karsten Heinrich (i-net software)
This software is provided 'as-is', without any express or implied This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages warranty. In no event will the authors be held liable for any damages
@ -24,6 +25,9 @@
package sun.print; package sun.print;
import java.awt.Graphics; import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.HeadlessException;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.awt.print.PageFormat; import java.awt.print.PageFormat;
import java.awt.print.Pageable; import java.awt.print.Pageable;
@ -75,6 +79,7 @@ import javax.print.event.PrintJobEvent;
import javax.print.event.PrintJobListener; import javax.print.event.PrintJobListener;
import sun.awt.windows.WPrinterJob; import sun.awt.windows.WPrinterJob;
import sun.reflect.generics.reflectiveObjects.NotImplementedException;
import cli.System.Drawing.Printing.*; import cli.System.Drawing.Printing.*;
@ -100,7 +105,7 @@ public class Win32PrintJob implements CancelablePrintJob{
private PrintJobAttributeSet jobAttrSet; private PrintJobAttributeSet jobAttrSet;
private PrinterJob job; private PrinterJob job = new WPrinterJob();
private Doc doc; private Doc doc;
private String mDestination; private String mDestination;
@ -437,17 +442,15 @@ public class Win32PrintJob implements CancelablePrintJob{
public void pageableJob(Pageable pageable) throws PrintException { public void pageableJob(Pageable pageable) throws PrintException {
try { try {
System.err.println("pageableJob");
PrintDocument printDocument = createPrintDocument(); PrintDocument printDocument = createPrintDocument();
//TODO Attribute set in printDocument //TODO Attribute set in printDocument
printDocument.add_QueryPageSettings(new QueryPageSettingsEventHandler(new QueryPage( pageable ) ) );
printDocument.add_PrintPage(new PrintPageEventHandler(new PrintPage(pageable))); printDocument.add_PrintPage(new PrintPageEventHandler(new PrintPage(pageable)));
System.err.println("Print");
printDocument.Print(); printDocument.Print();
if(printerException != null){ if(printerException != null){
throw printerException; throw printerException;
} }
System.err.println("after Print");
//TODO throw exception on Cancel //TODO throw exception on Cancel
notifyEvent(PrintJobEvent.DATA_TRANSFER_COMPLETE); notifyEvent(PrintJobEvent.DATA_TRANSFER_COMPLETE);
return; return;
@ -467,7 +470,8 @@ public class Win32PrintJob implements CancelablePrintJob{
Attribute destination = reqAttrSet.get(Destination.class); Attribute destination = reqAttrSet.get(Destination.class);
if(destination instanceof Destination){ if(destination instanceof Destination){
settings.set_PrintFileName(((Destination)destination).getURI().toString()); File destFile = new File(((Destination)destination).getURI());
settings.set_PrintFileName(destFile.getAbsolutePath());
} }
settings.set_Copies((short)copies); settings.set_Copies((short)copies);
@ -664,10 +668,13 @@ public class Win32PrintJob implements CancelablePrintJob{
Printable printable = pageable.getPrintable(pageIndex); Printable printable = pageable.getPrintable(pageIndex);
PageFormat pageFormat = pageable.getPageFormat(pageIndex); PageFormat pageFormat = pageable.getPageFormat(pageIndex);
BufferedImage pBand = new BufferedImage(1, 1, BufferedImage.TYPE_3BYTE_BGR); BufferedImage pBand = new BufferedImage(1, 1, BufferedImage.TYPE_3BYTE_BGR);
PeekGraphics peekGraphics = new PeekGraphics(pBand.createGraphics(), job); Graphics2D imageGraphics = pBand.createGraphics();
((RasterPrinterJob)job).setGraphicsConfigInfo(imageGraphics.getTransform(), pageFormat.getWidth(), pageFormat.getHeight());
PeekGraphics peekGraphics = new PeekGraphics(imageGraphics, job );
/* /*
* Because Sun is calling first with a PeekGraphics that we do it else for compatibility * Because Sun is calling first with a PeekGraphics that we do it else for compatibility
*/ */
if(pageIndex == 0){ if(pageIndex == 0){
@ -694,5 +701,42 @@ public class Win32PrintJob implements CancelablePrintJob{
} }
} }
private class QueryPage implements QueryPageSettingsEventHandler.Method{
private final Pageable pageable;
private int pageIndex;
QueryPage(Pageable pageable){
this.pageable = pageable;
//TODO firstPage
//TODO lastPage
//TODO PageRange
//TODO Num Copies
//TODO collatedCopies
}
@Override
public void Invoke(Object source, QueryPageSettingsEventArgs e) {
// apply page settings to the current page
PageFormat format = pageable.getPageFormat(pageIndex);
PageSettings pageSettings = e.get_PageSettings();
pageSettings.set_Landscape(format.getOrientation() == PageFormat.LANDSCAPE);
PaperSize ps = new PaperSize();
ps.set_Height( (int)Math.round( format.getHeight() ) );
ps.set_Width( (int)Math.round( format.getWidth() ) );
pageSettings.set_PaperSize( ps );
Margins margins = new Margins();
margins.set_Left( (int) format.getImageableX() );
margins.set_Top( (int)format.getImageableY() );
margins.set_Right( (int) (format.getWidth() - format.getImageableX() - format.getImageableWidth() ) );
margins.set_Bottom( (int)(format.getHeight() - format.getImageableY() - format.getImageableHeight() ) );
pageSettings.set_Margins( margins );
pageIndex++;
}
}
} }

Просмотреть файл

@ -1,5 +1,6 @@
/* /*
Copyright (C) 2009 Volker Berlin (i-net software) Copyright (C) 2009 Volker Berlin (i-net software)
Copyright (C) 2010 Karsten Heinrich (i-net software)
This software is provided 'as-is', without any express or implied This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages warranty. In no event will the authors be held liable for any damages
@ -21,9 +22,39 @@
jeroen@frijters.net jeroen@frijters.net
*/ */
/*
* Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package sun.print; package sun.print;
import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.print.DocFlavor; import javax.print.DocFlavor;
import javax.print.DocPrintJob; import javax.print.DocPrintJob;
@ -38,11 +69,14 @@ import javax.print.attribute.PrintServiceAttributeSet;
import javax.print.attribute.standard.Chromaticity; import javax.print.attribute.standard.Chromaticity;
import javax.print.attribute.standard.ColorSupported; import javax.print.attribute.standard.ColorSupported;
import javax.print.attribute.standard.Copies; import javax.print.attribute.standard.Copies;
import javax.print.attribute.standard.CopiesSupported;
import javax.print.attribute.standard.Destination; import javax.print.attribute.standard.Destination;
import javax.print.attribute.standard.Fidelity; import javax.print.attribute.standard.Fidelity;
import javax.print.attribute.standard.JobName; import javax.print.attribute.standard.JobName;
import javax.print.attribute.standard.Media; import javax.print.attribute.standard.Media;
import javax.print.attribute.standard.MediaPrintableArea; import javax.print.attribute.standard.MediaPrintableArea;
import javax.print.attribute.standard.MediaSize;
import javax.print.attribute.standard.MediaSizeName;
import javax.print.attribute.standard.OrientationRequested; import javax.print.attribute.standard.OrientationRequested;
import javax.print.attribute.standard.PageRanges; import javax.print.attribute.standard.PageRanges;
import javax.print.attribute.standard.PrintQuality; import javax.print.attribute.standard.PrintQuality;
@ -57,7 +91,16 @@ import javax.print.attribute.standard.SheetCollate;
import javax.print.attribute.standard.Sides; import javax.print.attribute.standard.Sides;
import javax.print.event.PrintServiceAttributeListener; import javax.print.event.PrintServiceAttributeListener;
import cli.System.Type;
import cli.System.Collections.IEnumerator;
import cli.System.Drawing.RectangleF;
import cli.System.Drawing.Printing.Duplex;
import cli.System.Drawing.Printing.PaperKind;
import cli.System.Drawing.Printing.PaperSize;
import cli.System.Drawing.Printing.PrintDocument;
import cli.System.Drawing.Printing.PrinterSettings; import cli.System.Drawing.Printing.PrinterSettings;
import cli.System.Drawing.Printing.PrinterSettings.PaperSizeCollection;
import cli.System.Net.Mime.MediaTypeNames;
/** /**
* @author Volker Berlin * @author Volker Berlin
@ -69,6 +112,9 @@ public class Win32PrintService implements PrintService{
DocFlavor.SERVICE_FORMATTED.PRINTABLE, DocFlavor.SERVICE_FORMATTED.PRINTABLE,
}; };
/** Mapping for PageSize.RawKind to predefined MediaSizeName */
private static final MediaSizeName[] MEDIA_NAMES = new MediaSizeName[44];
/* it turns out to be inconvenient to store the other categories /* it turns out to be inconvenient to store the other categories
* separately because many attributes are in multiple categories. * separately because many attributes are in multiple categories.
*/ */
@ -87,6 +133,82 @@ public class Win32PrintService implements PrintService{
SunAlternateMedia.class, SunAlternateMedia.class,
Chromaticity.class Chromaticity.class
}; };
// conversion from 1/100 Inch (.NET) to µm (Java)
private static final int INCH100_TO_MYM = 254;
private static final int MATCH_DIFF = 500; // 0.5 mm
static {
MEDIA_NAMES[0] = MediaSizeName.NA_LETTER;
MEDIA_NAMES[1] = MediaSizeName.NA_LETTER ;
MEDIA_NAMES[2] = MediaSizeName.TABLOID ;
MEDIA_NAMES[3] = MediaSizeName.LEDGER ;
MEDIA_NAMES[4] = MediaSizeName.NA_LEGAL ;
MEDIA_NAMES[5] = MediaSizeName.INVOICE ; // Statement
MEDIA_NAMES[6] = MediaSizeName.EXECUTIVE ;
MEDIA_NAMES[7] = MediaSizeName.ISO_A3 ;
MEDIA_NAMES[8] = MediaSizeName.ISO_A4 ;
MEDIA_NAMES[9] = MediaSizeName.ISO_A4 ; // A4Small, 10
MEDIA_NAMES[10] = MediaSizeName.ISO_A5 ;
MEDIA_NAMES[11] = MediaSizeName.JIS_B4 ;
MEDIA_NAMES[12] = MediaSizeName.JIS_B5 ;
MEDIA_NAMES[13] = MediaSizeName.FOLIO ;
MEDIA_NAMES[14] = MediaSizeName.QUARTO ;
MEDIA_NAMES[15] = MediaSizeName.NA_10X14_ENVELOPE ;
MEDIA_NAMES[16] = MediaSizeName.B ; // 10x17 Envelope
MEDIA_NAMES[17] = MediaSizeName.NA_LETTER ; // Note
MEDIA_NAMES[18] = MediaSizeName.NA_NUMBER_9_ENVELOPE ;
MEDIA_NAMES[19] = MediaSizeName.NA_NUMBER_10_ENVELOPE ; // 20
MEDIA_NAMES[20] = MediaSizeName.NA_NUMBER_11_ENVELOPE ;
MEDIA_NAMES[21] = MediaSizeName.NA_NUMBER_12_ENVELOPE ;
MEDIA_NAMES[22] = MediaSizeName.NA_NUMBER_14_ENVELOPE ;
MEDIA_NAMES[23] = MediaSizeName.C ;
MEDIA_NAMES[24] = MediaSizeName.D ;
MEDIA_NAMES[25] = MediaSizeName.E ;
MEDIA_NAMES[26] = MediaSizeName.ISO_DESIGNATED_LONG ;
MEDIA_NAMES[27] = MediaSizeName.ISO_C5 ;
MEDIA_NAMES[28] = MediaSizeName.ISO_C3 ;
MEDIA_NAMES[29] = MediaSizeName.ISO_C4 ; // 30
MEDIA_NAMES[30] = MediaSizeName.ISO_C6 ;
MEDIA_NAMES[31] = MediaSizeName.ITALY_ENVELOPE ;
MEDIA_NAMES[32] = MediaSizeName.ISO_B4 ;
MEDIA_NAMES[33] = MediaSizeName.ISO_B5 ;
MEDIA_NAMES[34] = MediaSizeName.ISO_B6 ;
MEDIA_NAMES[35] = MediaSizeName.ITALY_ENVELOPE ;
MEDIA_NAMES[36] = MediaSizeName.MONARCH_ENVELOPE ;
MEDIA_NAMES[37] = MediaSizeName.PERSONAL_ENVELOPE ;
MEDIA_NAMES[38] = MediaSizeName.NA_10X15_ENVELOPE ; // USStandardFanfold
MEDIA_NAMES[39] = MediaSizeName.NA_9X12_ENVELOPE ; // GermanStandardFanfold, 40
MEDIA_NAMES[40] = MediaSizeName.FOLIO ; // GermanLegalFanfold
MEDIA_NAMES[41] = MediaSizeName.ISO_B4 ;
MEDIA_NAMES[42] = MediaSizeName.JAPANESE_POSTCARD ;
MEDIA_NAMES[43] = MediaSizeName.NA_9X11_ENVELOPE ;
// // augment the media size with the .NET default sizes available on the printer
// PrinterSettings ps = new PrinterSettings();
// IEnumerator printers = PrinterSettings.get_InstalledPrinters().GetEnumerator();
// printers.Reset();
// while( printers.MoveNext() ){
// ps.set_PrinterName( (String) printers.get_Current() );
// IEnumerator sizes = ps.get_PaperSizes().GetEnumerator();
// sizes.Reset();
// while( sizes.MoveNext() ){
// PaperSize size = (PaperSize) sizes.get_Current();
// int kind = size.get_RawKind();
// if( kind >= 0 && kind < MEDIA_NAMES.length && MEDIA_NAMES[kind] == null ){
// MEDIA_NAMES[kind] = new CustomMediaSizeName( size.get_PaperName() );
// int x = size.get_Width();
// int y = size.get_Height();
// if( x > y ){ // not allowed by MediaSize
// int tmp = x;
// x = y;
// y = tmp;
// }
// new MediaSize(x, y, INCH100_TO_MYM, MEDIA_NAMES[kind]); // cache entry in map
// }
// }
// }
}
private final PrintPeer peer; private final PrintPeer peer;
@ -102,7 +224,7 @@ public class Win32PrintService implements PrintService{
} }
this.peer = peer; this.peer = peer;
printer = name; printer = name;
settings = new PrinterSettings(); settings = new PrintDocument().get_PrinterSettings();
settings.set_PrinterName(printer); settings.set_PrinterName(printer);
} }
@ -175,21 +297,18 @@ public class Win32PrintService implements PrintService{
throw new NullPointerException("category"); throw new NullPointerException("category");
} }
if(!(PrintServiceAttribute.class.isAssignableFrom(category))){ if(!(PrintServiceAttribute.class.isAssignableFrom(category))){
throw new IllegalArgumentException("Not a PrintServiceAttribute"); throw new IllegalArgumentException("The categhory '" + category + "' is not a valid PrintServiceAttribute");
} }
if(category == ColorSupported.class){ if(category == ColorSupported.class){
if(settings.get_SupportsColor()){ // works better than settings.get_SupportsColor();
if(settings.get_DefaultPageSettings().get_Color()){
return (T)ColorSupported.SUPPORTED; return (T)ColorSupported.SUPPORTED;
}else{ }else{
return (T)ColorSupported.NOT_SUPPORTED; return (T)ColorSupported.NOT_SUPPORTED;
} }
}else if(category == PrinterName.class){ }else if(category == PrinterName.class){
return (T)getPrinterName(); return (T)getPrinterName();
}else if(category == PrinterState.class){ } else {
return (T)PrinterState.UNKNOWN; // TODO
}else if(category == PrinterStateReasons.class){
return null; // TODO
}else{
// QueuedJobCount and PrinterIsAcceptingJobs // QueuedJobCount and PrinterIsAcceptingJobs
return (T)peer.getPrinterStatus(printer, category); return (T)peer.getPrinterStatus(printer, category);
} }
@ -216,7 +335,8 @@ public class Win32PrintService implements PrintService{
if(jobCount != null){ if(jobCount != null){
attrs.add(jobCount); attrs.add(jobCount);
} }
if(settings.get_SupportsColor()){ // TODO: Seems to be more accurate than settings.get_SupportsColor(), which doesn't work for CutePDF
if(settings.get_DefaultPageSettings().get_Color()){
attrs.add(ColorSupported.SUPPORTED); attrs.add(ColorSupported.SUPPORTED);
}else{ }else{
attrs.add(ColorSupported.NOT_SUPPORTED); attrs.add(ColorSupported.NOT_SUPPORTED);
@ -228,14 +348,101 @@ public class Win32PrintService implements PrintService{
@Override @Override
public Object getDefaultAttributeValue(Class<? extends Attribute> category){ public Object getDefaultAttributeValue(Class<? extends Attribute> category){
// TODO Auto-generated method stub if (category == null) {
throw new NullPointerException("category must not be null");
}
if ( !Attribute.class.isAssignableFrom( category ) ) {
throw new IllegalArgumentException( category +" has to be an " + Attribute.class.getName() );
}
if ( !isAttributeCategorySupported( category ) ) {
return null;
}
if (category == Copies.class) {
short copies = settings.get_Copies();
return new Copies( copies > 0 ? copies : 1 );
}
if (category == Chromaticity.class) {
// NOTE: this works for CutePDF, settings.get_SupportsColor() does not
return settings.get_DefaultPageSettings().get_Color() ? Chromaticity.COLOR : Chromaticity.MONOCHROME;
}
if (category == JobName.class) {
return new JobName( "Java Printing", null ); // TODO this is Java-Default, use another one for IKVM?
}
if (category == OrientationRequested.class) {
return settings.get_DefaultPageSettings().get_Landscape() ? OrientationRequested.LANDSCAPE : OrientationRequested.PORTRAIT;
}
if (category == PageRanges.class) {
return new PageRanges(1, Integer.MAX_VALUE );
}
if (category == Media.class) {
int rawKind = settings.get_DefaultPageSettings().get_PaperSize().get_RawKind();
if( rawKind > MEDIA_NAMES.length || rawKind < 1 || MEDIA_NAMES[ rawKind - 1 ] == null ){ // custom page format
return settings.get_DefaultPageSettings().get_PaperSize().get_PaperName();
} else {
return MEDIA_NAMES[ rawKind - 1 ];
}
}
if (category == MediaPrintableArea.class) {
RectangleF area = settings.get_DefaultPageSettings().get_PrintableArea();
// get_PrintableArea is in 1/100 inch, see http://msdn.microsoft.com/de-de/library/system.drawing.printing.pagesettings.printablearea(v=VS.90).aspx
return new MediaPrintableArea(area.get_X()/100, area.get_Y()/100, area.get_Width()/100, area.get_Height()/100, MediaPrintableArea.INCH);
}
if (category == Destination.class) {
String path = "out.prn";
try {
return new Destination( ( new File( path ) ).toURI() );
} catch (SecurityException se) {
try {
return new Destination( new URI( "file:" + path) );
} catch (URISyntaxException e) {
return null;
}
}
}
if (category == Sides.class) {
switch( settings.get_Duplex().Value ){
case cli.System.Drawing.Printing.Duplex.Default: // MSDN: 'The printer's default duplex setting.' - what ever that might be
case cli.System.Drawing.Printing.Duplex.Simplex:
return Sides.ONE_SIDED;
case cli.System.Drawing.Printing.Duplex.Horizontal:
return Sides.TWO_SIDED_LONG_EDGE;
case cli.System.Drawing.Printing.Duplex.Vertical:
return Sides.TWO_SIDED_SHORT_EDGE;
}
}
if (category == PrinterResolution.class) {
cli.System.Drawing.Printing.PrinterResolution res = settings.get_DefaultPageSettings().get_PrinterResolution();
return new PrinterResolution( res.get_X(), res.get_Y(), PrinterResolution.DPI);
}
if (category == ColorSupported.class) {
if ( settings.get_SupportsColor() ) {
return ColorSupported.SUPPORTED;
} else {
return ColorSupported.NOT_SUPPORTED;
}
}
if( category == PrintQuality.class ){
return PrintQuality.NORMAL; // TODO not correct, only available when using a PrintServer instance?
}
if (category == RequestingUserName.class) {
try{
return new RequestingUserName( System.getProperty("user.name", ""), null);
} catch( SecurityException e ){
return new RequestingUserName( "", null);
}
}
if (category == SheetCollate.class){
return settings.get_Collate() ? SheetCollate.COLLATED : SheetCollate.UNCOLLATED;
}
if (category == Fidelity.class) {
return Fidelity.FIDELITY_FALSE;
}
return null; return null;
} }
@Override @Override
public ServiceUIFactory getServiceUIFactory(){ public ServiceUIFactory getServiceUIFactory(){
// TODO Auto-generated method stub
return null; return null;
} }
@ -260,9 +467,93 @@ public class Win32PrintService implements PrintService{
@Override @Override
public Object getSupportedAttributeValues(Class<? extends Attribute> category, DocFlavor flavor, public Object getSupportedAttributeValues(Class<? extends Attribute> category, DocFlavor flavor, AttributeSet attributes){
AttributeSet attributes){ if ( category == null || !Attribute.class.isAssignableFrom( category ) ) {
// TODO Auto-generated method stub throw new IllegalArgumentException( "The category '" + category + "' is not an Attribute" );
}
if( !isAttributeCategorySupported(category) ){
return null;
}
if (category == JobName.class || category == RequestingUserName.class || category == ColorSupported.class
|| category == Destination.class ) {
return getDefaultAttributeValue(category);
}
if( category == Copies.class ){
return new CopiesSupported(1, settings.get_MaximumCopies() );
}
if( category == Media.class ){
PaperSizeCollection sizes = settings.get_PaperSizes();
List<MediaSizeName> medias = new ArrayList<MediaSizeName>();
for( int i = 0; i < sizes.get_Count(); i++ ){
PaperSize media = sizes.get_Item(i);
MediaSizeName mediaName = findMatchingMedia( sizes.get_Item(i) );
if( mediaName != null
&& !medias.contains( mediaName )){ // slow but better than creating a HashSet here
medias.add( mediaName);
}
}
return medias.size() > 0 ? medias.toArray( new Media[medias.size() ] ) : null;
}
if (category == PageRanges.class) {
if (flavor == null|| flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE)
|| flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE)) {
PageRanges[] arr = new PageRanges[1];
arr[0] = new PageRanges(1, Integer.MAX_VALUE);
return arr;
} else {
return null;
}
}
if (category == Fidelity.class) {
return new Fidelity[]{ Fidelity.FIDELITY_FALSE, Fidelity.FIDELITY_TRUE};
}
if (category == PrintQuality.class) {
return new PrintQuality[]{ PrintQuality.DRAFT, PrintQuality.HIGH, PrintQuality.NORMAL };
}
boolean printPageAble = flavor == null|| flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE)
|| flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE);
if (category == Sides.class) {
if ( printPageAble ) {
return new Sides[]{ Sides.ONE_SIDED, Sides.TWO_SIDED_LONG_EDGE, Sides.TWO_SIDED_SHORT_EDGE};
} else {
return null;
}
}
if (category == SheetCollate.class) {
if ( printPageAble ) {
return new SheetCollate[]{ SheetCollate.COLLATED, SheetCollate.UNCOLLATED} ;
} else {
return null;
}
}
boolean imageBased = printPageAble || flavor.equals(DocFlavor.INPUT_STREAM.GIF)
|| flavor.equals(DocFlavor.INPUT_STREAM.JPEG)
|| flavor.equals(DocFlavor.INPUT_STREAM.PNG)
|| flavor.equals(DocFlavor.BYTE_ARRAY.GIF)
|| flavor.equals(DocFlavor.BYTE_ARRAY.JPEG)
|| flavor.equals(DocFlavor.BYTE_ARRAY.PNG)
|| flavor.equals(DocFlavor.URL.GIF)
|| flavor.equals(DocFlavor.URL.JPEG)
|| flavor.equals(DocFlavor.URL.PNG);
if (category == OrientationRequested.class) {
if( imageBased ){
return new OrientationRequested[]{ OrientationRequested.PORTRAIT, OrientationRequested.LANDSCAPE, OrientationRequested.REVERSE_LANDSCAPE };
} else {
return null;
}
}
if (category == Chromaticity.class) {
if( imageBased ){
if( settings.get_DefaultPageSettings().get_Color() ){
return new Chromaticity[]{ Chromaticity.MONOCHROME, Chromaticity.COLOR };
} else {
return new Chromaticity[]{ Chromaticity.MONOCHROME };
}
} else {
return null;
}
}
return null; return null;
} }
@ -285,7 +576,15 @@ public class Win32PrintService implements PrintService{
@Override @Override
public boolean isAttributeCategorySupported(Class<? extends Attribute> category){ public boolean isAttributeCategorySupported(Class<? extends Attribute> category){
// TODO Auto-generated method stub if ( category == null || !Attribute.class.isAssignableFrom( category ) ) {
throw new IllegalArgumentException( "The category '" + category + "' is not an Attribute" );
}
Class<?>[] supported = getSupportedAttributeCategories();
for( int i=0; i < supported.length; i++ ){
if( category == supported[i] ){
return true;
}
}
return false; return false;
} }
@ -325,4 +624,60 @@ public class Win32PrintService implements PrintService{
public int hashCode(){ public int hashCode(){
return this.getClass().hashCode() + getName().hashCode(); return this.getClass().hashCode() + getName().hashCode();
} }
/**
* Tries to find a matching {@link MediaSizeName} for a paper by it's size
* @param paper
* @return
*/
private MediaSizeName findMatchingMedia( PaperSize paper ){
if( paper.get_RawKind() > 0 && paper.get_RawKind() <= MEDIA_NAMES.length ){
// match to predefined size
return MEDIA_NAMES[ paper.get_RawKind() - 1 ];
}
int x = paper.get_Width() * INCH100_TO_MYM;
int y = paper.get_Height() * INCH100_TO_MYM;
if( x > y ){ // MediaSizes are always portrait!
int tmp = x;
x = y;
y = tmp;
}
for( MediaSizeName name : MEDIA_NAMES ){
MediaSize media = MediaSize.getMediaSizeForName(name);
if( media != null ){
if( Math.abs( x - media.getX(1) ) < MATCH_DIFF && Math.abs( y - media.getY(1) ) < MATCH_DIFF ){
return name;
}
}
}
return null;
}
// /**
// * A simple MediaSizeName implementation. This is required since some programs only query the
// * attributes for MediaSizeName instances - which is not correct, since all {@link Media} implementations
// * are allowed here! Anyways, we have to deal with this an provide the additional formats of .NET as well.
// */
// private static class CustomMediaSizeName extends MediaSizeName {
//
// private final String name;
//
// /**
// * Creates the instance for a media name
// * @param name the name of the paper format
// */
// protected CustomMediaSizeName( String name) {
// super(-1);
// this.name = name;
// }
//
// /**
// * Returns the paper format name
// * @return the paper format name
// */
// @Override
// public String toString() {
// return name;
// }
// }
} }