001 /* 002 003 ============================================================================ 004 The Apache Software License, Version 1.1 005 ============================================================================ 006 007 Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. 008 009 Redistribution and use in source and binary forms, with or without modifica- 010 tion, are permitted provided that the following conditions are met: 011 012 1. Redistributions of source code must retain the above copyright notice, 013 this list of conditions and the following disclaimer. 014 015 2. Redistributions in binary form must reproduce the above copyright notice, 016 this list of conditions and the following disclaimer in the documentation 017 and/or other materials provided with the distribution. 018 019 3. The end-user documentation included with the redistribution, if any, must 020 include the following acknowledgment: "This product includes software 021 developed by the Apache Software Foundation (http://www.apache.org/)." 022 Alternately, this acknowledgment may appear in the software itself, if 023 and wherever such third-party acknowledgments normally appear. 024 025 4. The names "Batik" and "Apache Software Foundation" must not be 026 used to endorse or promote products derived from this software without 027 prior written permission. For written permission, please contact 028 apache@apache.org. 029 030 5. Products derived from this software may not be called "Apache", nor may 031 "Apache" appear in their name, without prior written permission of the 032 Apache Software Foundation. 033 034 THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, 035 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 036 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 037 APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 038 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- 039 DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 040 OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 041 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 042 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 043 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 044 045 This software consists of voluntary contributions made by many individuals 046 on behalf of the Apache Software Foundation. For more information on the 047 Apache Software Foundation, please see <http://www.apache.org/>. 048 049 */ 050 051 package org.apache.batik.transcoder.print; 052 053 import java.awt.Graphics; 054 import java.awt.Graphics2D; 055 import java.awt.RenderingHints; 056 import java.awt.Shape; 057 import java.awt.geom.AffineTransform; 058 import java.awt.geom.Rectangle2D; 059 import java.awt.print.PageFormat; 060 import java.awt.print.Paper; 061 import java.awt.print.Printable; 062 import java.awt.print.PrinterException; 063 import java.awt.print.PrinterJob; 064 import java.io.File; 065 import java.util.StringTokenizer; 066 import java.util.Vector; 067 068 import org.apache.batik.ext.awt.RenderingHintsKeyExt; 069 import org.apache.batik.transcoder.SVGAbstractTranscoder; 070 import org.apache.batik.transcoder.Transcoder; 071 import org.apache.batik.transcoder.TranscoderException; 072 import org.apache.batik.transcoder.TranscoderInput; 073 import org.apache.batik.transcoder.TranscoderOutput; 074 import org.apache.batik.transcoder.TranscodingHints; 075 import org.apache.batik.transcoder.keys.BooleanKey; 076 import org.apache.batik.transcoder.keys.LengthKey; 077 import org.apache.batik.transcoder.keys.StringKey; 078 079 /** 080 * This class is a <tt>Transcoder</tt> that prints SVG images. 081 * This class works as follows: any-time the transcode method 082 * is invoked, the corresponding input is cached and nothing 083 * else happens. <br /> 084 * However, the <tt>PrintTranscoder</tt> is also a Printable. If used 085 * in a print operation, it will print each of the input 086 * it cached, one input per page. 087 * <br /> 088 * The <tt>PrintTranscoder</tt> uses several different hints that 089 * guide its printing:<br /> 090 * <ul> 091 * <li><tt>KEY_LANGUAGE, KEY_USER_STYLESHEET_URI, KEY_PIXEL_TO_MM, 092 * KEY_XML_PARSER_CLASSNAME</tt> can be used to set the defaults for 093 * the various SVG properties.</li> 094 * <li><tt>KEY_PAGE_WIDTH, KEY_PAGE_HEIGHT, KEY_MARGIN_TOP, KEY_MARGIN_BOTTOM, 095 * KEY_MARGIN_LEFT, KEY_MARGIN_RIGHT</tt> and <tt>KEY_PAGE_ORIENTATION</tt> 096 * can be used to specify the printing page characteristics.</li> 097 * <li><tt>KEY_WIDTH, KEY_HEIGHT</tt> can be used to specify how to scale the 098 * SVG image</li> 099 * <li><tt>KEY_SCALE_TO_PAGE</tt> can be used to specify whether or not the 100 * SVG image should be scaled uniformly to fit into the printed page or 101 * if it should just be centered into the printed page.</li> 102 * </ul> 103 * 104 * @author <a href="mailto:vincent.hardy@eng.sun.com">Vincent Hardy</a> 105 * @version $Id: PrintTranscoder.java,v 1.28 2003/08/09 16:58:45 deweese Exp $ 106 */ 107 public class PrintTranscoder extends SVGAbstractTranscoder 108 implements Printable { 109 110 public static final String KEY_AOI_STR = "aoi"; 111 public static final String KEY_HEIGHT_STR = "height"; 112 public static final String KEY_LANGUAGE_STR = "language"; 113 public static final String KEY_MARGIN_BOTTOM_STR = "marginBottom"; 114 public static final String KEY_MARGIN_LEFT_STR = "marginLeft"; 115 public static final String KEY_MARGIN_RIGHT_STR = "marginRight"; 116 public static final String KEY_MARGIN_TOP_STR = "marginTop"; 117 public static final String KEY_PAGE_HEIGHT_STR = "pageHeight"; 118 public static final String KEY_PAGE_ORIENTATION_STR = "pageOrientation"; 119 public static final String KEY_PAGE_WIDTH_STR = "pageWidth"; 120 public static final String KEY_PIXEL_TO_MM_STR = "pixelToMm"; 121 public static final String KEY_SCALE_TO_PAGE_STR = "scaleToPage"; 122 public static final String KEY_SHOW_PAGE_DIALOG_STR = "showPageDialog"; 123 public static final String KEY_SHOW_PRINTER_DIALOG_STR = "showPrinterDialog"; 124 public static final String KEY_USER_STYLESHEET_URI_STR = "userStylesheet"; 125 public static final String KEY_WIDTH_STR = "width"; 126 public static final String KEY_XML_PARSER_CLASSNAME_STR = "xmlParserClassName"; 127 public static final String VALUE_MEDIA_PRINT = "print"; 128 public static final String VALUE_PAGE_ORIENTATION_LANDSCAPE = "landscape"; 129 public static final String VALUE_PAGE_ORIENTATION_PORTRAIT = "portrait"; 130 public static final String VALUE_PAGE_ORIENTATION_REVERSE_LANDSCAPE = "reverseLandscape"; 131 132 /** 133 * Set of inputs this transcoder has been requested to 134 * transcode so far 135 */ 136 private Vector inputs = new Vector(); 137 138 /** 139 * Currently printing set of pages. This vector is 140 * created as a clone of inputs when the first page is printed. 141 */ 142 private Vector printedInputs = null; 143 144 /** 145 * Index of the page corresponding to root 146 */ 147 private int curIndex = -1; 148 149 /** 150 * Constructs a new transcoder that prints images. 151 */ 152 public PrintTranscoder() { 153 super(); 154 155 hints.put(KEY_MEDIA, 156 VALUE_MEDIA_PRINT); 157 } 158 159 public void transcode(TranscoderInput in, 160 TranscoderOutput out){ 161 if(in != null){ 162 inputs.addElement(in); 163 } 164 } 165 166 /** 167 * Convenience method 168 */ 169 public void print() throws PrinterException{ 170 // 171 // Now, request the transcoder to actually perform the 172 // printing job. 173 // 174 PrinterJob printerJob = 175 PrinterJob.getPrinterJob(); 176 177 PageFormat pageFormat = 178 printerJob.defaultPage(); 179 180 // 181 // Set the page parameters from the hints 182 // 183 Paper paper = pageFormat.getPaper(); 184 185 Float pageWidth = (Float)hints.get(KEY_PAGE_WIDTH); 186 Float pageHeight = (Float)hints.get(KEY_PAGE_HEIGHT); 187 if(pageWidth != null){ 188 paper.setSize(pageWidth.floatValue(), 189 paper.getHeight()); 190 } 191 if(pageHeight != null){ 192 paper.setSize(paper.getWidth(), 193 pageHeight.floatValue()); 194 } 195 196 float x=0, y=0; 197 float width=(float)paper.getWidth(), height=(float)paper.getHeight(); 198 199 Float leftMargin = (Float)hints.get(KEY_MARGIN_LEFT); 200 Float topMargin = (Float)hints.get(KEY_MARGIN_TOP); 201 Float rightMargin = (Float)hints.get(KEY_MARGIN_RIGHT); 202 Float bottomMargin = (Float)hints.get(KEY_MARGIN_BOTTOM); 203 204 if(leftMargin != null){ 205 x = leftMargin.floatValue(); 206 width -= leftMargin.floatValue(); 207 } 208 if(topMargin != null){ 209 y = topMargin.floatValue(); 210 height -= topMargin.floatValue(); 211 } 212 if(rightMargin != null){ 213 width -= rightMargin.floatValue(); 214 } 215 if(bottomMargin != null){ 216 height -= bottomMargin.floatValue(); 217 } 218 219 paper.setImageableArea(x, y, width, height); 220 221 String pageOrientation = (String)hints.get(KEY_PAGE_ORIENTATION); 222 if(VALUE_PAGE_ORIENTATION_PORTRAIT.equalsIgnoreCase(pageOrientation)){ 223 pageFormat.setOrientation(PageFormat.PORTRAIT); 224 } 225 else if(VALUE_PAGE_ORIENTATION_LANDSCAPE.equalsIgnoreCase(pageOrientation)){ 226 pageFormat.setOrientation(PageFormat.LANDSCAPE); 227 } 228 else if(VALUE_PAGE_ORIENTATION_REVERSE_LANDSCAPE.equalsIgnoreCase(pageOrientation)){ 229 pageFormat.setOrientation(PageFormat.REVERSE_LANDSCAPE); 230 } 231 232 pageFormat.setPaper(paper); 233 pageFormat = printerJob.validatePage(pageFormat); 234 235 // 236 // If required, pop up a dialog to adjust the page format 237 // 238 Boolean showPageFormat = (Boolean)hints.get(KEY_SHOW_PAGE_DIALOG); 239 if(showPageFormat != null && showPageFormat.booleanValue()){ 240 PageFormat tmpPageFormat = printerJob.pageDialog(pageFormat); 241 if(tmpPageFormat == pageFormat){ 242 // Dialog was cancelled, meaning that the print process should 243 // be stopped. 244 return; 245 } 246 247 pageFormat = tmpPageFormat; 248 } 249 250 // 251 // If required, pop up a dialog to select the printer 252 // 253 Boolean showPrinterDialog = (Boolean)hints.get(KEY_SHOW_PRINTER_DIALOG); 254 if(showPrinterDialog != null && showPrinterDialog.booleanValue()){ 255 if(!printerJob.printDialog()){ 256 // Dialog was cancelled, meaning that the print process 257 // should be stopped. 258 return; 259 } 260 } 261 262 // Print now 263 printerJob.setPrintable(this, pageFormat); Rate264 printerJob.print(); 265 266 } 267 268 /** 269 * Printable implementation 270 */ 271 public int print(Graphics _g, PageFormat pageFormat, int pageIndex){ 272 // 273 // On the first page, take a snapshot of the vector of 274 // TranscodeInputs. 275 // 276 if(pageIndex == 0){ 277 printedInputs = (Vector)inputs.clone(); 278 } 279 280 // 281 // If we have already printed each page, return 282 // 283 if(pageIndex >= printedInputs.size()){ 284 curIndex = -1; 285 System.out.println("Done"); 286 return NO_SUCH_PAGE; 287 } 288 289 // 290 // Load a new document now if we are printing a new page 291 // 292 if(curIndex != pageIndex){ 293 // The following call will invoke this class' transcode 294 // method which takes a document as an input. That method 295 // builds the GVT root tree.{ 296 try{ 297 super.transcode((TranscoderInput)printedInputs.elementAt(pageIndex), 298 null); 299 curIndex = pageIndex; 300 }catch(TranscoderException e){ 301 drawError(_g, e); 302 return PAGE_EXISTS; 303 } 304 } 305 306 // Cast to Graphics2D to access Java 2D features 307 Graphics2D g = (Graphics2D)_g; 308 g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 309 RenderingHints.VALUE_ANTIALIAS_ON); 310 g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, 311 RenderingHints.VALUE_INTERPOLATION_BILINEAR); 312 g.setRenderingHint(RenderingHintsKeyExt.KEY_TRANSCODING, 313 RenderingHintsKeyExt.VALUE_TRANSCODING_PRINTING); 314 315 // 316 // Compute transform so that the SVG document fits on one page 317 // 318 AffineTransform t = g.getTransform(); 319 Shape clip = g.getClip(); 320 321 Rectangle2D bounds = curAOI; 322 323 double scaleX = pageFormat.getImageableWidth() / bounds.getWidth(); 324 double scaleY = pageFormat.getImageableHeight() / bounds.getHeight(); 325 double scale = scaleX < scaleY ? scaleX : scaleY; 326 327 // Check hint to know if scaling is really needed 328 Boolean scaleToPage = (Boolean)hints.get(KEY_SCALE_TO_PAGE); 329 if(scaleToPage != null && !scaleToPage.booleanValue()) { 330 // Printing Graphics is always set up for 72dpi, so scale 331 // according to what user agent thinks it should be. 332 double pixSzMM = userAgent.getPixelUnitToMillimeter(); 333 double pixSzInch = (25.4/pixSzMM); 334 scale = 72/pixSzInch; 335 } 336 337 double xMargin = (pageFormat.getImageableWidth() - 338 bounds.getWidth()*scale)/2; 339 double yMargin = (pageFormat.getImageableHeight() - 340 bounds.getHeight()*scale)/2; 341 g.translate(pageFormat.getImageableX() + xMargin, 342 pageFormat.getImageableY() + yMargin); 343 g.scale(scale, scale); 344 345 346 // 347 // Append transform to selected area 348 // 349 g.transform(curTxf); 350 351 g.clip(curAOI); 352 353 // 354 // Delegate rendering to painter 355 // 356 try{ 357 root.paint(g); 358 }catch(Exception e){ 359 g.setTransform(t); 360 g.setClip(clip); 361 drawError(_g, e); 362 } 363 364 // 365 // Restore transform and clip 366 // 367 g.setTransform(t); 368 g.setClip(clip); 369 370 // g.setPaint(Color.black); 371 // g.drawString(uris[pageIndex], 30, 30); 372 373 374 // 375 // Return status indicated that we did paint a page 376 // 377 return PAGE_EXISTS; 378 } 379 380 /** 381 * Prints an error on the output page 382 */ 383 private void drawError(Graphics g, Exception e){ 384 // Do nothing now. 385 } 386 387 // -------------------------------------------------------------------- 388 // Keys definition 389 // -------------------------------------------------------------------- 390 391 /** 392 * The showPageDialog key. 393 * <TABLE BORDER="0" CELLSPACING="0" CELLPADDING="1"> 394 * <TR> 395 * <TH VALIGN="TOP" ALIGN="RIGHT"><P ALIGN="RIGHT">Key: </TH> 396 * <TD VALIGN="TOP">KEY_SHOW_PAGE_DIALOG</TD></TR> 397 * <TR> 398 * <TH VALIGN="TOP" ALIGN="RIGHT"><P ALIGN="RIGHT">Value: </TH> 399 * <TD VALIGN="TOP">Boolean</TD></TR> 400 * <TR> 401 * <TH VALIGN="TOP" ALIGN="RIGHT"><P ALIGN="RIGHT">Default: </TH> 402 * <TD VALIGN="TOP">false</TD></TR> 403 * <TR> 404 * <TH VALIGN="TOP" ALIGN="RIGHT"><P ALIGN="RIGHT">Required: </TH> 405 * <TD VALIGN="TOP">No</TD></TR> 406 * <TR> 407 * <TH VALIGN="TOP" ALIGN="RIGHT"><P ALIGN="RIGHT">Description: </TH> 408 * <TD VALIGN="TOP">Specifies whether or not the transcoder 409 * should pop up a dialog box for selecting 410 * the page format.</TD></TR> 411 * </TABLE> */ 412 public static final TranscodingHints.Key KEY_SHOW_PAGE_DIALOG 413 = new BooleanKey(); 414 415 /** 416 * The showPrinterDialog key. 417 * <TABLE BORDER="0" CELLSPACING="0" CELLPADDING="1"> 418 * <TR> 419 * <TH VALIGN="TOP" ALIGN="RIGHT"><P ALIGN="RIGHT">Key: </TH> 420 * <TD VALIGN="TOP">KEY_SHOW_PAGE_DIALOG</TD></TR> 421 * <TR> 422 * <TH VALIGN="TOP" ALIGN="RIGHT"><P ALIGN="RIGHT">Value: </TH> 423 * <TD VALIGN="TOP">Boolean</TD></TR> 424 * <TR> 425 * <TH VALIGN="TOP" ALIGN="RIGHT"><P ALIGN="RIGHT">Default: </TH> 426 * <TD VALIGN="TOP">false</TD></TR> 427 * <TR> 428 * <TH VALIGN="TOP" ALIGN="RIGHT"><P ALIGN="RIGHT">Required: </TH> 429 * <TD VALIGN="TOP">No</TD></TR> 430 * <TR> 431 * <TH VALIGN="TOP" ALIGN="RIGHT"><P ALIGN="RIGHT">Description: </TH> 432 * <TD VALIGN="TOP">Specifies whether or not the transcoder 433 * should pop up a dialog box for selecting 434 * the printer. If the dialog box is not 435 * shown, the transcoder will use the default 436 * printer.</TD></TR> 437 * </TABLE> */ 438 public static final TranscodingHints.Key KEY_SHOW_PRINTER_DIALOG 439 = new BooleanKey(); 440 441 442 /** 443 * The pageWidth key. 444 * <TABLE BORDER="0" CELLSPACING="0" CELLPADDING="1"> 445 * <TR> 446 * <TH VALIGN="TOP" ALIGN="RIGHT"><P ALIGN="RIGHT">Key: </TH> 447 * <TD VALIGN="TOP">KEY_PAGE_WIDTH</TD></TR> 448 * <TR> 449 * <TH VALIGN="TOP" ALIGN="RIGHT"><P ALIGN="RIGHT">Value: </TH> 450 * <TD VALIGN="TOP">Length</TD></TR> 451 * <TR> 452 * <TH VALIGN="TOP" ALIGN="RIGHT"><P ALIGN="RIGHT">Default: </TH> 453 * <TD VALIGN="TOP">None</TD></TR> 454 * <TR> 455 * <TH VALIGN="TOP" ALIGN="RIGHT"><P ALIGN="RIGHT">Required: </TH> 456 * <TD VALIGN="TOP">No</TD></TR> 457 * <TR> 458 * <TH VALIGN="TOP" ALIGN="RIGHT"><P ALIGN="RIGHT">Description: </TH> 459 * <TD VALIGN="TOP">The width of the print page</TD></TR> 460 * </TABLE> */ 461 public static final TranscodingHints.Key KEY_PAGE_WIDTH 462 = new LengthKey(); 463 464 /** 465 * The pageHeight key. 466 * <TABLE BORDER="0" CELLSPACING="0" CELLPADDING="1"> 467 * <TR> 468 * <TH VALIGN="TOP" ALIGN="RIGHT"><P ALIGN="RIGHT">Key: </TH> 469 * <TD VALIGN="TOP">KEY_PAGE_HEIGHT</TD></TR> 470 * <TR> 471 * <TH VALIGN="TOP" ALIGN="RIGHT"><P ALIGN="RIGHT">Value: </TH> 472 * <TD VALIGN="TOP">Length</TD></TR> 473 * <TR> 474 * <TH VALIGN="TOP" ALIGN="RIGHT"><P ALIGN="RIGHT">Default: </TH> 475 * <TD VALIGN="TOP">None</TD></TR> 476 * <TR> 477 * <TH VALIGN="TOP" ALIGN="RIGHT"><P ALIGN="RIGHT">Required: </TH> 478 * <TD VALIGN="TOP">No</TD></TR> 479 * <TR> 480 * <TH VALIGN="TOP" ALIGN="RIGHT"><P ALIGN="RIGHT">Description: </TH> 481 * <TD VALIGN="TOP">The height of the print page</TD></TR> 482 * </TABLE> */ 483 public static final TranscodingHints.Key KEY_PAGE_HEIGHT 484 = new LengthKey(); 485 486 /** 487 * The marginTop key. 488 * <TABLE BORDER="0" CELLSPACING="0" CELLPADDING="1"> 489 * <TR> 490 * <TH VALIGN="TOP" ALIGN="RIGHT"><P ALIGN="RIGHT">Key: </TH> 491 * <TD VALIGN="TOP">KEY_MARGIN_TOP</TD></TR> 492 * <TR> 493 * <TH VALIGN="TOP" ALIGN="RIGHT"><P ALIGN="RIGHT">Value: </TH> 494 * <TD VALIGN="TOP">Length</TD></TR> 495 * <TR> 496 * <TH VALIGN="TOP" ALIGN="RIGHT"><P ALIGN="RIGHT">Default: </TH> 497 * <TD VALIGN="TOP">None</TD></TR> 498 * <TR> 499 * <TH VALIGN="TOP" ALIGN="RIGHT"><P ALIGN="RIGHT">Required: </TH> 500 * <TD VALIGN="TOP">No</TD></TR> 501 * <TR> 502 * <TH VALIGN="TOP" ALIGN="RIGHT"><P ALIGN="RIGHT">Description: </TH> 503 * <TD VALIGN="TOP">The print page top margin</TD></TR> 504 * </TABLE> */ 505 public static final TranscodingHints.Key KEY_MARGIN_TOP 506 = new LengthKey(); 507 508 /** 509 * The marginRight key. 510 * <TABLE BORDER="0" CELLSPACING="0" CELLPADDING="1"> 511 * <TR> 512 * <TH VALIGN="TOP" ALIGN="RIGHT"><P ALIGN="RIGHT">Key: </TH> 513 * <TD VALIGN="TOP">KEY_MARGIN_RIGHT</TD></TR> 514 * <TR> 515 * <TH VALIGN="TOP" ALIGN="RIGHT"><P ALIGN="RIGHT">Value: </TH> 516 * <TD VALIGN="TOP">Length</TD></TR> 517 * <TR> 518 * <TH VALIGN="TOP" ALIGN="RIGHT"><P ALIGN="RIGHT">Default: </TH> 519 * <TD VALIGN="TOP">None</TD></TR> 520 * <TR> 521 * <TH VALIGN="TOP" ALIGN="RIGHT"><P ALIGN="RIGHT">Required: </TH> 522 * <TD VALIGN="TOP">No</TD></TR> 523 * <TR> 524 * <TH VALIGN="TOP" ALIGN="RIGHT"><P ALIGN="RIGHT">Description: </TH> 525 * <TD VALIGN="TOP">The print page right margin</TD></TR> 526 * </TABLE> */ 527 public static final TranscodingHints.Key KEY_MARGIN_RIGHT 528 = new LengthKey(); 529 530 /** 531 * The marginBottom key. 532 * <TABLE BORDER="0" CELLSPACING="0" CELLPADDING="1"> 533 * <TR> 534 * <TH VALIGN="TOP" ALIGN="RIGHT"><P ALIGN="RIGHT">Key: </TH> 535 * <TD VALIGN="TOP">KEY_MARGIN_BOTTOM</TD></TR> 536 * <TR> 537 * <TH VALIGN="TOP" ALIGN="RIGHT"><P ALIGN="RIGHT">Value: </TH> 538 * <TD VALIGN="TOP">Length</TD></TR> 539 * <TR> 540 * <TH VALIGN="TOP" ALIGN="RIGHT"><P ALIGN="RIGHT">Default: </TH> 541 * <TD VALIGN="TOP">None</TD></TR> 542 * <TR> 543 * <TH VALIGN="TOP" ALIGN="RIGHT"><P ALIGN="RIGHT">Required: </TH> 544 * <TD VALIGN="TOP">No</TD></TR> 545 * <TR> 546 * <TH VALIGN="TOP" ALIGN="RIGHT"><P ALIGN="RIGHT">Description: </TH> 547 * <TD VALIGN="TOP">The print page bottom margin</TD></TR> 548 * </TABLE> */ 549 public static final TranscodingHints.Key KEY_MARGIN_BOTTOM 550 = new LengthKey(); 551 552 /** 553 * The marginLeft key. 554 * <TABLE BORDER="0" CELLSPACING="0" CELLPADDING="1"> 555 * <TR> 556 * <TH VALIGN="TOP" ALIGN="RIGHT"><P ALIGN="RIGHT">Key: </TH> 557 * <TD VALIGN="TOP">KEY_MARGIN_LEFT</TD></TR> 558 * <TR> 559 * <TH VALIGN="TOP" ALIGN="RIGHT"><P ALIGN="RIGHT">Value: </TH> 560 * <TD VALIGN="TOP">Length</TD></TR> 561 * <TR> 562 * <TH VALIGN="TOP" ALIGN="RIGHT"><P ALIGN="RIGHT">Default: </TH> 563 * <TD VALIGN="TOP">None</TD></TR> 564 * <TR> 565 * <TH VALIGN="TOP" ALIGN="RIGHT"><P ALIGN="RIGHT">Required: </TH> 566 * <TD VALIGN="TOP">No</TD></TR> 567 * <TR> 568 * <TH VALIGN="TOP" ALIGN="RIGHT"><P ALIGN="RIGHT">Description: </TH> 569 * <TD VALIGN="TOP">The print page left margin</TD></TR> 570 * </TABLE> */ 571 public static final TranscodingHints.Key KEY_MARGIN_LEFT 572 = new LengthKey(); 573 574 /** 575 * The pageOrientation key. 576 * <TABLE BORDER="0" CELLSPACING="0" CELLPADDING="1"> 577 * <TR> 578 * <TH VALIGN="TOP" ALIGN="RIGHT"><P ALIGN="RIGHT">Key: </TH> 579 * <TD VALIGN="TOP">KEY_PAGE_ORIENTATION</TD></TR> 580 * <TR> 581 * <TH VALIGN="TOP" ALIGN="RIGHT"><P ALIGN="RIGHT">Value: </TH> 582 * <TD VALIGN="TOP">String</TD></TR> 583 * <TR> 584 * <TH VALIGN="TOP" ALIGN="RIGHT"><P ALIGN="RIGHT">Default: </TH> 585 * <TD VALIGN="TOP">VALUE_PAGE_ORIENTATION_PORTRAIT</TD></TR> 586 * <TR> 587 * <TH VALIGN="TOP" ALIGN="RIGHT"><P ALIGN="RIGHT">Required: </TH> 588 * <TD VALIGN="TOP">No</TD></TR> 589 * <TR> 590 * <TH VALIGN="TOP" ALIGN="RIGHT"><P ALIGN="RIGHT">Description: </TH> 591 * <TD VALIGN="TOP">The print page's orientation</TD></TR> 592 * </TABLE> */ 593 public static final TranscodingHints.Key KEY_PAGE_ORIENTATION 594 = new StringKey(); 595 596 597 /** 598 * The scaleToPage key. 599 * <TABLE BORDER="0" CELLSPACING="0" CELLPADDING="1"> 600 * <TR> 601 * <TH VALIGN="TOP" ALIGN="RIGHT"><P ALIGN="RIGHT">Key: </TH> 602 * <TD VALIGN="TOP">KEY_SCALE_TO_PAGE</TD></TR> 603 * <TR> 604 * <TH VALIGN="TOP" ALIGN="RIGHT"><P ALIGN="RIGHT">Value: </TH> 605 * <TD VALIGN="TOP">Boolean</TD></TR> 606 * <TR> 607 * <TH VALIGN="TOP" ALIGN="RIGHT"><P ALIGN="RIGHT">Default: </TH> 608 * <TD VALIGN="TOP">true</TD></TR> 609 * <TR> 610 * <TH VALIGN="TOP" ALIGN="RIGHT"><P ALIGN="RIGHT">Required: </TH> 611 * <TD VALIGN="TOP">No</TD></TR> 612 * <TR> 613 * <TH VALIGN="TOP" ALIGN="RIGHT"><P ALIGN="RIGHT">Description: </TH> 614 * <TD VALIGN="TOP">Specifies whether or not the SVG images are scaled to 615 * fit into the printed page</TD></TR> 616 * </TABLE> */ 617 public static final TranscodingHints.Key KEY_SCALE_TO_PAGE 618 = new BooleanKey(); 619 620 public static final String USAGE = "java org.apache.batik.transcoder.print.PrintTranscoder <svgFileToPrint>"; 621 622 public static void main(String args[]) throws Exception{ 623 if(args.length < 1){ 624 System.err.println(USAGE); 625 System.exit(0); 626 } 627 628 // 629 // Builds a PrintTranscoder 630 // 631 PrintTranscoder transcoder = new PrintTranscoder(); 632 633 // 634 // Set the hints, from the command line arguments 635 // 636 637 // Language 638 setTranscoderFloatHint(transcoder, 639 KEY_LANGUAGE_STR, 640 KEY_LANGUAGE); 641 642 // User stylesheet 643 setTranscoderFloatHint(transcoder, 644 KEY_USER_STYLESHEET_URI_STR, 645 KEY_USER_STYLESHEET_URI); 646 647 // XML parser 648 setTranscoderStringHint(transcoder, 649 KEY_XML_PARSER_CLASSNAME_STR, 650 KEY_XML_PARSER_CLASSNAME); 651 652 // Scale to page 653 setTranscoderBooleanHint(transcoder, 654 KEY_SCALE_TO_PAGE_STR, 655 KEY_SCALE_TO_PAGE); 656 657 // AOI 658 setTranscoderRectangleHint(transcoder, 659 KEY_AOI_STR, 660 KEY_AOI); 661 662 663 // Image size 664 setTranscoderFloatHint(transcoder, 665 KEY_WIDTH_STR, 666 KEY_WIDTH); 667 setTranscoderFloatHint(transcoder, 668 KEY_HEIGHT_STR, 669 KEY_HEIGHT); 670 671 // Pixel to millimeter 672 setTranscoderFloatHint(transcoder, 673 KEY_PIXEL_TO_MM_STR, 674 KEY_PIXEL_UNIT_TO_MILLIMETER); 675 676 // Page orientation 677 setTranscoderStringHint(transcoder, 678 KEY_PAGE_ORIENTATION_STR, 679 KEY_PAGE_ORIENTATION); 680 681 // Page size 682 setTranscoderFloatHint(transcoder, 683 KEY_PAGE_WIDTH_STR, 684 KEY_PAGE_WIDTH); 685 setTranscoderFloatHint(transcoder, 686 KEY_PAGE_HEIGHT_STR, 687 KEY_PAGE_HEIGHT); 688 689 // Margins 690 setTranscoderFloatHint(transcoder, 691 KEY_MARGIN_TOP_STR, 692 KEY_MARGIN_TOP); 693 setTranscoderFloatHint(transcoder, 694 KEY_MARGIN_RIGHT_STR, 695 KEY_MARGIN_RIGHT); 696 setTranscoderFloatHint(transcoder, 697 KEY_MARGIN_BOTTOM_STR, 698 KEY_MARGIN_BOTTOM); 699 setTranscoderFloatHint(transcoder, 700 KEY_MARGIN_LEFT_STR, 701 KEY_MARGIN_LEFT); 702 703 // Dialog options 704 setTranscoderBooleanHint(transcoder, 705 KEY_SHOW_PAGE_DIALOG_STR, 706 KEY_SHOW_PAGE_DIALOG); 707 708 setTranscoderBooleanHint(transcoder, 709 KEY_SHOW_PRINTER_DIALOG_STR, 710 KEY_SHOW_PRINTER_DIALOG); 711 712 // 713 // First, request the transcoder to transcode 714 // each of the input files 715 // 716 for(int i=0; i<args.length; i++){ 717 transcoder.transcode(new TranscoderInput(new File(args[i]).toURL().toString()), 718 null); 719 } 720 721 // 722 // Now, print... 723 // 724 transcoder.print(); 725 } 726 727 public static void setTranscoderFloatHint(Transcoder transcoder, 728 String property, 729 TranscodingHints.Key key){ 730 String str = System.getProperty(property); 731 if(str != null){ 732 try{ 733 Float value = new Float(Float.parseFloat(str)); 734 transcoder.addTranscodingHint(key, value); 735 }catch(NumberFormatException e){ 736 handleValueError(property, str); 737 } 738 } 739 } 740 741 public static void setTranscoderRectangleHint(Transcoder transcoder, 742 String property, 743 TranscodingHints.Key key){ 744 String str = System.getProperty(property); 745 if(str != null){ 746 StringTokenizer st = new StringTokenizer(str, " ,"); 747 if(st.countTokens() != 4){ 748 handleValueError(property, str); 749 } 750 751 try{ 752 String x = st.nextToken(); 753 String y = st.nextToken(); 754 String width = st.nextToken(); 755 String height = st.nextToken(); 756 Rectangle2D r = new Rectangle2D.Float(Float.parseFloat(x), 757 Float.parseFloat(y), 758 Float.parseFloat(width), 759 Float.parseFloat(height)); 760 transcoder.addTranscodingHint(key, r); 761 }catch(NumberFormatException e){ 762 handleValueError(property, str); 763 } 764 } 765 } 766 767 public static void setTranscoderBooleanHint(Transcoder transcoder, 768 String property, 769 TranscodingHints.Key key){ 770 String str = System.getProperty(property); 771 if(str != null){ 772 Boolean value = new Boolean("true".equalsIgnoreCase(str)); 773 transcoder.addTranscodingHint(key, value); 774 } 775 } 776 777 public static void setTranscoderStringHint(Transcoder transcoder, 778 String property, 779 TranscodingHints.Key key){ 780 String str = System.getProperty(property); 781 if(str != null){ 782 transcoder.addTranscodingHint(key, str); 783 } 784 } 785 786 public static void handleValueError(String property, 787 String value){ 788 System.err.println("Invalid " + property + " value : " + value); 789 System.exit(1); 790 } 791 } 792 793 794 795