277
278 private static final String ORIENT_PROP = "awt.print.orientation";
279 private static final String PORTRAIT = "portrait";
280 private static final String LANDSCAPE = "landscape";
281
282 private static final String PAPERSIZE_PROP = "awt.print.paperSize";
283 private static final String LETTER = "letter";
284 private static final String LEGAL = "legal";
285 private static final String EXECUTIVE = "executive";
286 private static final String A4 = "a4";
287
288 private Properties props;
289
290 private String options = ""; // REMIND: needs implementation
291
292 /**
293 * The thread on which PrinterJob is running.
294 * This is different than the applications thread.
295 */
296 private Thread printerJobThread;
297
298 public PrintJob2D(Frame frame, String doctitle,
299 final Properties props) {
300 this.props = props;
301 this.jobAttributes = new JobAttributes();
302 this.pageAttributes = new PageAttributes();
303 translateInputProps();
304 initPrintJob2D(frame, doctitle,
305 this.jobAttributes, this.pageAttributes);
306 }
307
308 public PrintJob2D(Frame frame, String doctitle,
309 JobAttributes jobAttributes,
310 PageAttributes pageAttributes) {
311 initPrintJob2D(frame, doctitle, jobAttributes, pageAttributes);
312 }
313
314 private void initPrintJob2D(Frame frame, String doctitle,
315 JobAttributes jobAttributes,
316 PageAttributes pageAttributes) {
773
774 startPrinterJobThread();
775
776 }
777 notify();
778 }
779
780 /* If the application has already been handed back
781 * a graphics then we need to put that graphics into
782 * the drawn queue so that the PrinterJob thread can
783 * return to the print system.
784 */
785 if (currentGraphics != null) {
786 graphicsDrawn.append(currentGraphics);
787 currentGraphics = null;
788 }
789
790 /* We'll block here until a new graphics becomes
791 * available.
792 */
793
794 currentGraphics = graphicsToBeDrawn.pop();
795
796 if (currentGraphics instanceof PeekGraphics) {
797 ( (PeekGraphics) currentGraphics).setAWTDrawingOnly();
798 graphicsDrawn.append(currentGraphics);
799 currentGraphics = graphicsToBeDrawn.pop();
800 }
801
802
803 if (currentGraphics != null) {
804
805 /* In the PrintJob API, the origin is at the upper-
806 * left of the imageable area when using the new "printable"
807 * origin attribute, otherwise its the physical origin (for
808 * backwards compatibility. We emulate this by createing
809 * a PageFormat which matches and then performing the
810 * translate to the origin. This is a no-op if physical
811 * origin is specified.
812 */
813 currentGraphics.translate(pageFormat.getImageableX(),
814 pageFormat.getImageableY());
815
816 /* Scale to accommodate AWT's notion of printer resolution */
817 double awtScale = 72.0/getPageResolutionInternal();
818 currentGraphics.scale(awtScale, awtScale);
819
820 /* The caller wants a Graphics instance but we do
821 * not want them to make 2D calls. We can't hand
822 * back a Graphics2D. The returned Graphics also
823 * needs to implement PrintGraphics, so we wrap
824 * the Graphics2D instance. The PrintJob API has
825 * the application dispose of the Graphics so
826 * we create a copy of the one returned by PrinterJob.
827 */
828 printGraphics = new ProxyPrintGraphics(currentGraphics.create(),
829 this);
830
831 }
832
833 return printGraphics;
834 }
835
836 /**
837 * Returns the dimensions of the page in pixels.
838 * The resolution of the page is chosen so that it
839 * is similar to the screen resolution.
840 * Except (since 1.3) when the application specifies a resolution.
841 * In that case it is scaled accordingly.
842 */
843 public Dimension getPageDimension() {
844 double wid, hgt, scale;
845 if (pageAttributes != null &&
846 pageAttributes.getOrigin()==OriginType.PRINTABLE) {
847 wid = pageFormat.getImageableWidth();
848 hgt = pageFormat.getImageableHeight();
849 } else {
850 wid = pageFormat.getWidth();
851 hgt = pageFormat.getHeight();
852 }
966 /* Add the graphics to the message queue of graphics to
967 * be rendered. This is really a one slot queue. The
968 * application's thread will come along and remove the
969 * graphics from the queue when the app asks for a graphics.
970 */
971 graphicsToBeDrawn.append( (Graphics2D) graphics);
972
973 /* We now wait for the app's thread to finish drawing on
974 * the Graphics. This thread will sleep until the application
975 * release the graphics by placing it in the graphics drawn
976 * message queue. If the application signals that it is
977 * finished drawing the entire document then we'll get null
978 * returned when we try and pop a finished graphic.
979 */
980 if (graphicsDrawn.pop() != null) {
981 result = PAGE_EXISTS;
982 } else {
983 result = NO_SUCH_PAGE;
984 }
985
986 return result;
987 }
988
989 private void startPrinterJobThread() {
990 printerJobThread = new ManagedLocalsThread(this, "printerJobThread");
991 printerJobThread.start();
992 }
993
994
995 public void run() {
996
997 try {
998 printerJob.print(attributes);
999 } catch (PrinterException e) {
1000 //REMIND: need to store this away and not rethrow it.
1001 }
1002
1003 /* Close the message queues so that nobody is stuck
1004 * waiting for one.
1005 */
1006 graphicsToBeDrawn.closeWhenEmpty();
1007 graphicsDrawn.close();
1008 }
1009
1010 private class MessageQ {
1011
1012 private String qid="noname";
1013
1014 private ArrayList<Graphics2D> queue = new ArrayList<>();
1015
1016 MessageQ(String id) {
1017 qid = id;
1018 }
1019
1020 synchronized void closeWhenEmpty() {
1021
1022 while (queue != null && queue.size() > 0) {
1023 try {
1024 wait(1000);
1025 } catch (InterruptedException e) {
1026 // do nothing.
1027 }
1042
1043 if (queue != null) {
1044 queue.add(g);
1045 queued = true;
1046 notify();
1047 }
1048
1049 return queued;
1050 }
1051
1052 synchronized Graphics2D pop() {
1053 Graphics2D g = null;
1054
1055 while (g == null && queue != null) {
1056
1057 if (queue.size() > 0) {
1058 g = queue.remove(0);
1059 notify();
1060
1061 } else {
1062 try {
1063 wait(2000);
1064 } catch (InterruptedException e) {
1065 // do nothing.
1066 }
1067 }
1068 }
1069
1070 return g;
1071 }
1072
1073 synchronized boolean isClosed() {
1074 return queue == null;
1075 }
1076
1077 }
1078
1079
1080 private static int[] getSize(MediaType mType) {
1081 int []dim = new int[2];
|
277
278 private static final String ORIENT_PROP = "awt.print.orientation";
279 private static final String PORTRAIT = "portrait";
280 private static final String LANDSCAPE = "landscape";
281
282 private static final String PAPERSIZE_PROP = "awt.print.paperSize";
283 private static final String LETTER = "letter";
284 private static final String LEGAL = "legal";
285 private static final String EXECUTIVE = "executive";
286 private static final String A4 = "a4";
287
288 private Properties props;
289
290 private String options = ""; // REMIND: needs implementation
291
292 /**
293 * The thread on which PrinterJob is running.
294 * This is different than the applications thread.
295 */
296 private Thread printerJobThread;
297 private boolean printFinished;
298
299 public PrintJob2D(Frame frame, String doctitle,
300 final Properties props) {
301 this.props = props;
302 this.jobAttributes = new JobAttributes();
303 this.pageAttributes = new PageAttributes();
304 translateInputProps();
305 initPrintJob2D(frame, doctitle,
306 this.jobAttributes, this.pageAttributes);
307 }
308
309 public PrintJob2D(Frame frame, String doctitle,
310 JobAttributes jobAttributes,
311 PageAttributes pageAttributes) {
312 initPrintJob2D(frame, doctitle, jobAttributes, pageAttributes);
313 }
314
315 private void initPrintJob2D(Frame frame, String doctitle,
316 JobAttributes jobAttributes,
317 PageAttributes pageAttributes) {
774
775 startPrinterJobThread();
776
777 }
778 notify();
779 }
780
781 /* If the application has already been handed back
782 * a graphics then we need to put that graphics into
783 * the drawn queue so that the PrinterJob thread can
784 * return to the print system.
785 */
786 if (currentGraphics != null) {
787 graphicsDrawn.append(currentGraphics);
788 currentGraphics = null;
789 }
790
791 /* We'll block here until a new graphics becomes
792 * available.
793 */
794 currentGraphics = graphicsToBeDrawn.pop();
795
796 if (currentGraphics == null && printFinished) {
797 synchronized (this) {
798 startPrinterJobThread();
799 notify();
800 }
801 currentGraphics = graphicsToBeDrawn.pop();
802 }
803 if (currentGraphics instanceof PeekGraphics) {
804 ((PeekGraphics) currentGraphics).setAWTDrawingOnly();
805 graphicsDrawn.append(currentGraphics);
806 currentGraphics = graphicsToBeDrawn.pop();
807 }
808
809 if (currentGraphics != null) {
810
811 /* In the PrintJob API, the origin is at the upper-
812 * left of the imageable area when using the new "printable"
813 * origin attribute, otherwise its the physical origin (for
814 * backwards compatibility. We emulate this by createing
815 * a PageFormat which matches and then performing the
816 * translate to the origin. This is a no-op if physical
817 * origin is specified.
818 */
819 currentGraphics.translate(pageFormat.getImageableX(),
820 pageFormat.getImageableY());
821
822 /* Scale to accommodate AWT's notion of printer resolution */
823 double awtScale = 72.0/getPageResolutionInternal();
824 currentGraphics.scale(awtScale, awtScale);
825
826 /* The caller wants a Graphics instance but we do
827 * not want them to make 2D calls. We can't hand
828 * back a Graphics2D. The returned Graphics also
829 * needs to implement PrintGraphics, so we wrap
830 * the Graphics2D instance. The PrintJob API has
831 * the application dispose of the Graphics so
832 * we create a copy of the one returned by PrinterJob.
833 */
834 printGraphics = new ProxyPrintGraphics(currentGraphics.create(),
835 this);
836
837 }
838 return printGraphics;
839 }
840
841 /**
842 * Returns the dimensions of the page in pixels.
843 * The resolution of the page is chosen so that it
844 * is similar to the screen resolution.
845 * Except (since 1.3) when the application specifies a resolution.
846 * In that case it is scaled accordingly.
847 */
848 public Dimension getPageDimension() {
849 double wid, hgt, scale;
850 if (pageAttributes != null &&
851 pageAttributes.getOrigin()==OriginType.PRINTABLE) {
852 wid = pageFormat.getImageableWidth();
853 hgt = pageFormat.getImageableHeight();
854 } else {
855 wid = pageFormat.getWidth();
856 hgt = pageFormat.getHeight();
857 }
971 /* Add the graphics to the message queue of graphics to
972 * be rendered. This is really a one slot queue. The
973 * application's thread will come along and remove the
974 * graphics from the queue when the app asks for a graphics.
975 */
976 graphicsToBeDrawn.append( (Graphics2D) graphics);
977
978 /* We now wait for the app's thread to finish drawing on
979 * the Graphics. This thread will sleep until the application
980 * release the graphics by placing it in the graphics drawn
981 * message queue. If the application signals that it is
982 * finished drawing the entire document then we'll get null
983 * returned when we try and pop a finished graphic.
984 */
985 if (graphicsDrawn.pop() != null) {
986 result = PAGE_EXISTS;
987 } else {
988 result = NO_SUCH_PAGE;
989 }
990
991
992 return result;
993 }
994
995 private void startPrinterJobThread() {
996 printerJobThread = new ManagedLocalsThread(this, "printerJobThread");
997 printerJobThread.start();
998 printFinished = false;
999 }
1000
1001
1002 public void run() {
1003
1004 try {
1005 printerJob.print(attributes);
1006 } catch (PrinterException e) {
1007 //REMIND: need to store this away and not rethrow it.
1008 }
1009
1010 /* Close the message queues so that nobody is stuck
1011 * waiting for one.
1012 */
1013 printFinished = true;
1014 //graphicsToBeDrawn.closeWhenEmpty();
1015 //graphicsDrawn.close();
1016 }
1017
1018 private class MessageQ {
1019
1020 private String qid="noname";
1021
1022 private ArrayList<Graphics2D> queue = new ArrayList<>();
1023
1024 MessageQ(String id) {
1025 qid = id;
1026 }
1027
1028 synchronized void closeWhenEmpty() {
1029
1030 while (queue != null && queue.size() > 0) {
1031 try {
1032 wait(1000);
1033 } catch (InterruptedException e) {
1034 // do nothing.
1035 }
1050
1051 if (queue != null) {
1052 queue.add(g);
1053 queued = true;
1054 notify();
1055 }
1056
1057 return queued;
1058 }
1059
1060 synchronized Graphics2D pop() {
1061 Graphics2D g = null;
1062
1063 while (g == null && queue != null) {
1064
1065 if (queue.size() > 0) {
1066 g = queue.remove(0);
1067 notify();
1068
1069 } else {
1070 if (printFinished) {
1071 break;
1072 }
1073 try {
1074 wait(2000);
1075 } catch (InterruptedException e) {
1076 // do nothing.
1077 }
1078 }
1079 }
1080
1081 return g;
1082 }
1083
1084 synchronized boolean isClosed() {
1085 return queue == null;
1086 }
1087
1088 }
1089
1090
1091 private static int[] getSize(MediaType mType) {
1092 int []dim = new int[2];
|