Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/ikvm-fork.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsmallsql <smallsql>2010-12-15 17:53:33 +0300
committersmallsql <smallsql>2010-12-15 17:53:33 +0300
commit8270a2d62e35751aaba2f73c10816cf3865c262a (patch)
tree7212a9be5b16334ef8d3689d093bb078bbbe6f07
parent46be1e2aa9af6a9b5ff19f3ee95adba015e14b3a (diff)
Some fixes on the printing API from Karsten Heinrich
-rw-r--r--awt/printing.cs114
-rw-r--r--openjdk/sun/print/Win32PrintJob.java58
-rw-r--r--openjdk/sun/print/Win32PrintService.java385
3 files changed, 530 insertions, 27 deletions
diff --git a/awt/printing.cs b/awt/printing.cs
index 7d5983ec..1cce4826 100644
--- a/awt/printing.cs
+++ b/awt/printing.cs
@@ -1,5 +1,6 @@
/*
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
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 PRINTER_STATUS_DOOR_OPEN = 0x400000;
- private const int PRINTER_STATUS_ERROR = 0x2;
- private const int PRINTER_STATUS_NO_TONER = 0x40000;
- private const int PRINTER_STATUS_OFFLINE = 0x80;
- private const int PRINTER_STATUS_OUT_OF_MEMORY = 0x200000;
+ private const int PRINTER_STATUS_PAUSED = 0x1;
+ private const int PRINTER_STATUS_ERROR = 0x2; // MSDN says that this value is not used
+ private const int PRINTER_STATUS_PENDING_DELETION = 0x4;
+ private const int PRINTER_STATUS_PAPER_JAM = 0x8;
+ 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_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>
/// Get a printer status
@@ -134,6 +154,27 @@ namespace ikvm.awt.printing
int 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))
{
return new javax.print.attribute.standard.QueuedJobCount(cJobs);
@@ -159,6 +200,65 @@ namespace ikvm.awt.printing
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>
/// Get infos from the PRINTER_INFO_2 struc
/// </summary>
@@ -228,4 +328,8 @@ namespace ikvm.awt.printing
return ClosePrinter(handle);
}
}
+
+ class Win32Print
+ {
+ }
}
diff --git a/openjdk/sun/print/Win32PrintJob.java b/openjdk/sun/print/Win32PrintJob.java
index 5d315d06..f0bff15d 100644
--- a/openjdk/sun/print/Win32PrintJob.java
+++ b/openjdk/sun/print/Win32PrintJob.java
@@ -1,5 +1,6 @@
/*
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
warranty. In no event will the authors be held liable for any damages
@@ -24,6 +25,9 @@
package sun.print;
import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.GraphicsConfiguration;
+import java.awt.HeadlessException;
import java.awt.image.BufferedImage;
import java.awt.print.PageFormat;
import java.awt.print.Pageable;
@@ -75,6 +79,7 @@ import javax.print.event.PrintJobEvent;
import javax.print.event.PrintJobListener;
import sun.awt.windows.WPrinterJob;
+import sun.reflect.generics.reflectiveObjects.NotImplementedException;
import cli.System.Drawing.Printing.*;
@@ -100,7 +105,7 @@ public class Win32PrintJob implements CancelablePrintJob{
private PrintJobAttributeSet jobAttrSet;
- private PrinterJob job;
+ private PrinterJob job = new WPrinterJob();
private Doc doc;
private String mDestination;
@@ -437,17 +442,15 @@ public class Win32PrintJob implements CancelablePrintJob{
public void pageableJob(Pageable pageable) throws PrintException {
try {
- System.err.println("pageableJob");
PrintDocument printDocument = createPrintDocument();
//TODO Attribute set in printDocument
+ printDocument.add_QueryPageSettings(new QueryPageSettingsEventHandler(new QueryPage( pageable ) ) );
printDocument.add_PrintPage(new PrintPageEventHandler(new PrintPage(pageable)));
- System.err.println("Print");
printDocument.Print();
if(printerException != null){
throw printerException;
}
- System.err.println("after Print");
//TODO throw exception on Cancel
notifyEvent(PrintJobEvent.DATA_TRANSFER_COMPLETE);
return;
@@ -467,7 +470,8 @@ public class Win32PrintJob implements CancelablePrintJob{
Attribute destination = reqAttrSet.get(Destination.class);
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);
@@ -664,10 +668,13 @@ public class Win32PrintJob implements CancelablePrintJob{
Printable printable = pageable.getPrintable(pageIndex);
PageFormat pageFormat = pageable.getPageFormat(pageIndex);
+
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
*/
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++;
+ }
+
+ }
}
diff --git a/openjdk/sun/print/Win32PrintService.java b/openjdk/sun/print/Win32PrintService.java
index d028d4b0..b1667e96 100644
--- a/openjdk/sun/print/Win32PrintService.java
+++ b/openjdk/sun/print/Win32PrintService.java
@@ -1,5 +1,6 @@
/*
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
warranty. In no event will the authors be held liable for any damages
@@ -21,9 +22,39 @@
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;
+import java.io.File;
+import java.net.URI;
+import java.net.URISyntaxException;
import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
import javax.print.DocFlavor;
import javax.print.DocPrintJob;
@@ -38,11 +69,14 @@ import javax.print.attribute.PrintServiceAttributeSet;
import javax.print.attribute.standard.Chromaticity;
import javax.print.attribute.standard.ColorSupported;
import javax.print.attribute.standard.Copies;
+import javax.print.attribute.standard.CopiesSupported;
import javax.print.attribute.standard.Destination;
import javax.print.attribute.standard.Fidelity;
import javax.print.attribute.standard.JobName;
import javax.print.attribute.standard.Media;
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.PageRanges;
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.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.PaperSizeCollection;
+import cli.System.Net.Mime.MediaTypeNames;
/**
* @author Volker Berlin
@@ -69,6 +112,9 @@ public class Win32PrintService implements PrintService{
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
* separately because many attributes are in multiple categories.
*/
@@ -87,6 +133,82 @@ public class Win32PrintService implements PrintService{
SunAlternateMedia.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;
@@ -102,7 +224,7 @@ public class Win32PrintService implements PrintService{
}
this.peer = peer;
printer = name;
- settings = new PrinterSettings();
+ settings = new PrintDocument().get_PrinterSettings();
settings.set_PrinterName(printer);
}
@@ -175,21 +297,18 @@ public class Win32PrintService implements PrintService{
throw new NullPointerException("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(settings.get_SupportsColor()){
+ // works better than settings.get_SupportsColor();
+ if(settings.get_DefaultPageSettings().get_Color()){
return (T)ColorSupported.SUPPORTED;
}else{
return (T)ColorSupported.NOT_SUPPORTED;
}
}else if(category == PrinterName.class){
return (T)getPrinterName();
- }else if(category == PrinterState.class){
- return (T)PrinterState.UNKNOWN; // TODO
- }else if(category == PrinterStateReasons.class){
- return null; // TODO
- }else{
+ } else {
// QueuedJobCount and PrinterIsAcceptingJobs
return (T)peer.getPrinterStatus(printer, category);
}
@@ -216,7 +335,8 @@ public class Win32PrintService implements PrintService{
if(jobCount != null){
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);
}else{
attrs.add(ColorSupported.NOT_SUPPORTED);
@@ -228,14 +348,101 @@ public class Win32PrintService implements PrintService{
@Override
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;
}
@Override
public ServiceUIFactory getServiceUIFactory(){
- // TODO Auto-generated method stub
return null;
}
@@ -260,9 +467,93 @@ public class Win32PrintService implements PrintService{
@Override
- public Object getSupportedAttributeValues(Class<? extends Attribute> category, DocFlavor flavor,
- AttributeSet attributes){
- // TODO Auto-generated method stub
+ public Object getSupportedAttributeValues(Class<? extends Attribute> category, DocFlavor flavor, AttributeSet attributes){
+ if ( category == null || !Attribute.class.isAssignableFrom( category ) ) {
+ 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;
}
@@ -285,7 +576,15 @@ public class Win32PrintService implements PrintService{
@Override
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;
}
@@ -325,4 +624,60 @@ public class Win32PrintService implements PrintService{
public int 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;
+// }
+// }
}