1 package net.sf.openrocket.gui.print.visitor;
3 import com.itextpdf.text.Document;
4 import com.itextpdf.text.DocumentException;
5 import com.itextpdf.text.Rectangle;
6 import com.itextpdf.text.pdf.PdfWriter;
7 import net.sf.openrocket.gui.print.AbstractPrintable;
8 import net.sf.openrocket.gui.print.ITextHelper;
9 import net.sf.openrocket.gui.print.PrintableNoseCone;
10 import net.sf.openrocket.gui.print.PrintableTransition;
11 import net.sf.openrocket.logging.LogHelper;
12 import net.sf.openrocket.rocketcomponent.NoseCone;
13 import net.sf.openrocket.rocketcomponent.RocketComponent;
14 import net.sf.openrocket.rocketcomponent.Transition;
15 import net.sf.openrocket.startup.Application;
17 import java.awt.image.BufferedImage;
18 import java.util.List;
22 * A strategy for drawing transition/shroud/nose cone templates.
24 public class TransitionStrategy {
29 private static final LogHelper log = Application.getLogger();
34 protected Document document;
37 * The direct iText writer.
39 protected PdfWriter writer;
42 * The stages selected.
44 protected Set<Integer> stages;
47 * Strategy for fitting multiple components onto a page.
49 protected PageFitPrintStrategy pageFitPrint;
54 * @param doc The iText document
55 * @param theWriter The direct iText writer
56 * @param theStagesToVisit The stages to be visited by this strategy
58 public TransitionStrategy(Document doc, PdfWriter theWriter, Set<Integer> theStagesToVisit, PageFitPrintStrategy pageFit) {
61 stages = theStagesToVisit;
62 pageFitPrint = pageFit;
66 * Recurse through the given rocket component.
68 * @param root the root component; all children will be visited recursively
69 * @param noseCones nose cones are a special form of a transition; if true, then print nose cones
71 public void writeToDocument(final RocketComponent root, boolean noseCones) {
72 List<RocketComponent> rc = root.getChildren();
73 goDeep(rc, noseCones);
78 * Recurse through the given rocket component.
80 * @param theRc an array of rocket components; all children will be visited recursively
81 * @param noseCones nose cones are a special form of a transition; if true, then print nose cones
83 protected void goDeep(final List<RocketComponent> theRc, boolean noseCones) {
84 for (RocketComponent rocketComponent : theRc) {
85 if (rocketComponent instanceof NoseCone) {
87 render((Transition) rocketComponent);
89 } else if (rocketComponent instanceof Transition && !noseCones) {
90 render((Transition) rocketComponent);
91 } else if (rocketComponent.getChildCount() > 0) {
92 goDeep(rocketComponent.getChildren(), noseCones);
98 * The core behavior of this visitor.
100 * @param component the object to extract info about; a graphical image of the transition shape is drawn to the document
102 private void render(final Transition component) {
104 AbstractPrintable pfs;
105 if (component instanceof NoseCone) {
106 pfs = new PrintableNoseCone((NoseCone)component);
108 pfs = new PrintableTransition(component);
111 java.awt.Dimension size = pfs.getSize();
112 final Dimension pageSize = getPageSize();
113 if (fitsOnOnePage(pageSize, size.getWidth(), size.getHeight())) {
114 pageFitPrint.addComponent(pfs);
115 //printOnOnePage(pfs);
117 BufferedImage image = (BufferedImage) pfs.createImage();
118 ITextHelper.renderImageAcrossPages(new Rectangle(pageSize.getWidth(), pageSize.getHeight()),
119 document, writer, image);
121 } catch (DocumentException e) {
122 log.error("Could not render the transition.", e);
127 * Determine if the image will fit on the given page.
129 * @param pageSize the page size
130 * @param wImage the width of the thing to be printed
131 * @param hImage the height of the thing to be printed
132 * @return true if the thing to be printed will fit on a single page
134 private boolean fitsOnOnePage(Dimension pageSize, double wImage, double hImage) {
135 double wPage = pageSize.getWidth();
136 double hPage = pageSize.getHeight();
138 int wRatio = (int) Math.ceil(wImage / wPage);
139 int hRatio = (int) Math.ceil(hImage / hPage);
141 return wRatio <= 1.0d && hRatio <= 1.0d;
145 * Get the dimensions of the paper page.
147 * @return an internal Dimension
149 protected Dimension getPageSize() {
150 return new Dimension(document.getPageSize().getWidth(),
151 document.getPageSize().getHeight());
155 * Convenience class to model a dimension.
173 public Dimension(float w, float h) {
183 public float getWidth() {
192 public float getHeight() {