2 * PageFitPrintStrategy.java
4 package net.sf.openrocket.gui.print.visitor;
6 import com.itextpdf.text.Document;
7 import com.itextpdf.text.pdf.PdfContentByte;
8 import com.itextpdf.text.pdf.PdfWriter;
9 import net.sf.openrocket.gui.print.PrintUnit;
10 import net.sf.openrocket.gui.print.PrintableComponent;
11 import net.sf.openrocket.logging.LogHelper;
12 import net.sf.openrocket.rocketcomponent.RocketComponent;
13 import net.sf.openrocket.startup.Application;
15 import java.awt.Graphics2D;
16 import java.util.ArrayList;
17 import java.util.Collections;
18 import java.util.ListIterator;
22 * A strategy for drawing multiple rocket components onto as few pages as possible.
24 * @author Jason Blood <dyster2000@gmail.com>
26 public class PageFitPrintStrategy {
31 private static final LogHelper log = Application.getLogger();
36 protected Document document;
39 * The direct iText writer.
41 protected PdfWriter writer;
44 * The stages selected.
46 protected Set<Integer> stages;
48 protected ArrayList<PrintableComponent> componentToPrint;
53 * @param doc The iText document
54 * @param theWriter The direct iText writer
56 public PageFitPrintStrategy(Document doc, PdfWriter theWriter) {
59 componentToPrint = new ArrayList<PrintableComponent>();
63 * Add a component we want to print.
65 * @param component The component to add for printing
67 public void addComponent(PrintableComponent component) {
68 componentToPrint.add(component);
72 * Recurse through the given rocket component.
74 * @param root the root component; all children will be printed recursively
76 public void writeToDocument (final RocketComponent root) {
81 * Iterate through the components to print fitting them onto pages as best possible.
83 private void fitPrintComponents() {
84 final Dimension pageSize = getPageSize();
85 double wPage = pageSize.getWidth();
86 double hPage = pageSize.getHeight();
87 int marginX = (int)(PrintUnit.POINTS_PER_INCH * 0.3f);
88 int marginY = (int)(PrintUnit.POINTS_PER_INCH * 0.3f);
89 PdfContentByte cb = writer.getDirectContent();
91 Collections.sort(componentToPrint);
93 while (componentToPrint.size() > 0) {
95 Boolean anyAddedToRow;
97 Graphics2D g2 = cb.createGraphics(pageSize.width, pageSize.height);
103 ListIterator<PrintableComponent> entry = componentToPrint.listIterator();
104 anyAddedToRow = false;
106 while (entry.hasNext()) {
107 PrintableComponent component = entry.next();
108 java.awt.Dimension dim = component.getSize();
109 if ((rowX + dim.width + marginX < wPage) && (rowY + dim.height + marginY < hPage)) {
110 component.setPrintOffset(rowX, rowY);
111 rowX += dim.width + marginX;
112 if (rowY + dim.height + marginY > pageY) {
113 pageY = rowY + dim.height + marginY;
117 anyAddedToRow = true;
121 } while (anyAddedToRow);
129 * Get the dimensions of the paper page.
131 * @return an internal Dimension
133 protected Dimension getPageSize () {
134 return new Dimension(document.getPageSize().getWidth(),
135 document.getPageSize().getHeight());
139 * Convenience class to model a dimension.
142 /** Width, in points. */
144 /** Height, in points. */
152 public Dimension (float w, float h) {
162 public float getWidth () {
171 public float getHeight () {