You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

PageableRenderer.java 7.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one or more
  3. * contributor license agreements. See the NOTICE file distributed with
  4. * this work for additional information regarding copyright ownership.
  5. * The ASF licenses this file to You under the Apache License, Version 2.0
  6. * (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. /* $Id$ */
  18. package org.apache.fop.render.print;
  19. import java.awt.geom.Rectangle2D;
  20. import java.awt.print.PageFormat;
  21. import java.awt.print.Pageable;
  22. import java.awt.print.Paper;
  23. import java.awt.print.Printable;
  24. import java.io.IOException;
  25. import java.util.Map;
  26. import org.apache.fop.apps.FOPException;
  27. import org.apache.fop.apps.FOUserAgent;
  28. import org.apache.fop.apps.MimeConstants;
  29. import org.apache.fop.area.PageViewport;
  30. import org.apache.fop.render.java2d.Java2DRenderer;
  31. /**
  32. * Renderer that prints through java.awt.PrintJob.
  33. * The actual printing is handled by Java2DRenderer
  34. * since both PrintRenderer and AWTRenderer need to
  35. * support printing.
  36. */
  37. public class PageableRenderer extends Java2DRenderer implements Pageable {
  38. /**
  39. * Printing parameter: the pages to be printed (all, even or odd),
  40. * datatype: the strings "all", "even" or "odd" or one of PagesMode.*
  41. */
  42. public static final String PAGES_MODE = "even-odd";
  43. /**
  44. * Printing parameter: the page number (1-based) of the first page to be printed,
  45. * datatype: a positive Integer
  46. */
  47. public static final String START_PAGE = "start-page";
  48. /**
  49. * Printing parameter: the page number (1-based) of the last page to be printed,
  50. * datatype: a positive Integer
  51. */
  52. public static final String END_PAGE = "end-page";
  53. /** first valid page number (1-based) */
  54. protected int startNumber;
  55. /** last valid page number (1-based) */
  56. protected int endNumber = -1;
  57. /** indicates which pages are valid: odd, even or all */
  58. protected PagesMode mode = PagesMode.ALL;
  59. private PageFilter pageFilter;
  60. /**
  61. * Creates a new PageableRenderer.
  62. *
  63. * @param userAgent the user agent that contains configuration details. This cannot be null.
  64. */
  65. public PageableRenderer(FOUserAgent userAgent) {
  66. super(userAgent);
  67. Map rendererOptions = getUserAgent().getRendererOptions();
  68. processOptions(rendererOptions);
  69. this.pageFilter = new DefaultPageFilter();
  70. }
  71. /** {@inheritDoc} */
  72. public String getMimeType() {
  73. return MimeConstants.MIME_FOP_PRINT;
  74. }
  75. private void processOptions(Map rendererOptions) {
  76. Object o = rendererOptions.get(PageableRenderer.PAGES_MODE);
  77. if (o != null) {
  78. if (o instanceof PagesMode) {
  79. this.mode = (PagesMode)o;
  80. } else if (o instanceof String) {
  81. this.mode = PagesMode.byName((String)o);
  82. } else {
  83. throw new IllegalArgumentException(
  84. "Renderer option " + PageableRenderer.PAGES_MODE
  85. + " must be an 'all', 'even', 'odd' or a PagesMode instance.");
  86. }
  87. }
  88. o = rendererOptions.get(PageableRenderer.START_PAGE);
  89. if (o != null) {
  90. this.startNumber = getPositiveInteger(o);
  91. }
  92. o = rendererOptions.get(PageableRenderer.END_PAGE);
  93. if (o != null) {
  94. this.endNumber = getPositiveInteger(o);
  95. }
  96. if (this.endNumber >= 0 && this.endNumber < this.startNumber) {
  97. this.endNumber = this.startNumber;
  98. }
  99. }
  100. /**
  101. * Converts an object into a positive integer value if possible. The method throws an
  102. * {@link IllegalArgumentException} if the value is invalid.
  103. * @param o the object to be converted
  104. * @return the positive integer
  105. */
  106. protected int getPositiveInteger(Object o) {
  107. if (o instanceof Integer) {
  108. Integer i = (Integer)o;
  109. if (i.intValue() < 1) {
  110. throw new IllegalArgumentException(
  111. "Value must be a positive Integer");
  112. }
  113. return i.intValue();
  114. } else if (o instanceof String) {
  115. return Integer.parseInt((String)o);
  116. } else {
  117. throw new IllegalArgumentException(
  118. "Value must be a positive integer");
  119. }
  120. }
  121. /** {@inheritDoc} */
  122. public void stopRenderer() throws IOException {
  123. super.stopRenderer();
  124. if (endNumber == -1) {
  125. // was not set on command line
  126. endNumber = getNumberOfPages();
  127. }
  128. }
  129. /** {@inheritDoc} */
  130. protected void rememberPage(PageViewport pageViewport) {
  131. if (this.pageFilter.isValid(pageViewport)) {
  132. super.rememberPage(pageViewport);
  133. }
  134. }
  135. private interface PageFilter {
  136. boolean isValid(PageViewport page);
  137. }
  138. private class DefaultPageFilter implements PageFilter {
  139. public boolean isValid(PageViewport page) {
  140. int pageNum = page.getPageIndex() + 1;
  141. assert pageNum >= 0;
  142. if (pageNum < startNumber || (endNumber >= 0 && pageNum > endNumber)) {
  143. return false;
  144. } else if (mode != PagesMode.ALL) {
  145. if (mode == PagesMode.EVEN && (pageNum % 2 != 0)) {
  146. return false;
  147. } else if (mode == PagesMode.ODD && (pageNum % 2 == 0)) {
  148. return false;
  149. }
  150. }
  151. return true;
  152. }
  153. }
  154. /** {@inheritDoc} */
  155. public PageFormat getPageFormat(int pageIndex)
  156. throws IndexOutOfBoundsException {
  157. try {
  158. if (pageIndex >= getNumberOfPages()) {
  159. return null;
  160. }
  161. PageFormat pageFormat = new PageFormat();
  162. Paper paper = new Paper();
  163. Rectangle2D dim = getPageViewport(pageIndex).getViewArea();
  164. double width = dim.getWidth();
  165. double height = dim.getHeight();
  166. // if the width is greater than the height assume landscape mode
  167. // and swap the width and height values in the paper format
  168. if (width > height) {
  169. paper.setImageableArea(0, 0, height / 1000d, width / 1000d);
  170. paper.setSize(height / 1000d, width / 1000d);
  171. pageFormat.setOrientation(PageFormat.LANDSCAPE);
  172. } else {
  173. paper.setImageableArea(0, 0, width / 1000d, height / 1000d);
  174. paper.setSize(width / 1000d, height / 1000d);
  175. pageFormat.setOrientation(PageFormat.PORTRAIT);
  176. }
  177. pageFormat.setPaper(paper);
  178. return pageFormat;
  179. } catch (FOPException fopEx) {
  180. throw new IndexOutOfBoundsException(fopEx.getMessage());
  181. }
  182. }
  183. /** {@inheritDoc} */
  184. public Printable getPrintable(int pageIndex)
  185. throws IndexOutOfBoundsException {
  186. return this;
  187. }
  188. }