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.PdfContentByte;
7 import com.itextpdf.text.pdf.PdfWriter;
8 import net.sf.openrocket.gui.print.AbstractPrintableTransition;
9 import net.sf.openrocket.gui.print.ITextHelper;
10 import net.sf.openrocket.gui.print.PrintableNoseCone;
11 import net.sf.openrocket.gui.print.PrintableTransition;
12 import net.sf.openrocket.logging.LogHelper;
13 import net.sf.openrocket.rocketcomponent.NoseCone;
14 import net.sf.openrocket.rocketcomponent.RocketComponent;
15 import net.sf.openrocket.rocketcomponent.Transition;
16 import net.sf.openrocket.startup.Application;
19 import java.awt.image.BufferedImage;
20 import java.util.List;
24 * A strategy for drawing transition/shroud/nose cone templates.
26 public class TransitionStrategy {
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;
51 * @param doc The iText document
52 * @param theWriter The direct iText writer
53 * @param theStagesToVisit The stages to be visited by this strategy
55 public TransitionStrategy(Document doc, PdfWriter theWriter, Set<Integer> theStagesToVisit) {
58 stages = theStagesToVisit;
62 * Recurse through the given rocket component.
64 * @param root the root component; all children will be visited recursively
65 * @param noseCones nose cones are a special form of a transition; if true, then print nose cones
67 public void writeToDocument(final RocketComponent root, boolean noseCones) {
68 List<RocketComponent> rc = root.getChildren();
69 goDeep(rc, noseCones);
74 * Recurse through the given rocket component.
76 * @param theRc an array of rocket components; all children will be visited recursively
77 * @param noseCones nose cones are a special form of a transition; if true, then print nose cones
79 protected void goDeep(final List<RocketComponent> theRc, boolean noseCones) {
80 for (RocketComponent rocketComponent : theRc) {
81 if (rocketComponent instanceof NoseCone) {
83 render((Transition) rocketComponent);
85 } else if (rocketComponent instanceof Transition && !noseCones) {
86 render((Transition) rocketComponent);
87 } else if (rocketComponent.getChildCount() > 0) {
88 goDeep(rocketComponent.getChildren(), noseCones);
94 * The core behavior of this visitor.
96 * @param component the object to extract info about; a graphical image of the transition shape is drawn to the document
98 private void render(final Transition component) {
100 AbstractPrintableTransition pfs;
101 if (component instanceof NoseCone) {
102 pfs = new PrintableNoseCone(component);
104 pfs = new PrintableTransition(component);
107 java.awt.Dimension size = pfs.getSize();
108 final Dimension pageSize = getPageSize();
109 if (fitsOnOnePage(pageSize, size.getWidth(), size.getHeight())) {
112 BufferedImage image = (BufferedImage) pfs.createImage();
113 ITextHelper.renderImageAcrossPages(new Rectangle(pageSize.getWidth(), pageSize.getHeight()),
114 document, writer, image);
116 } catch (DocumentException e) {
117 log.error("Could not render the transition.", e);
122 * Determine if the image will fit on the given page.
124 * @param pageSize the page size
125 * @param wImage the width of the thing to be printed
126 * @param hImage the height of the thing to be printed
127 * @return true if the thing to be printed will fit on a single page
129 private boolean fitsOnOnePage(Dimension pageSize, double wImage, double hImage) {
130 double wPage = pageSize.getWidth();
131 double hPage = pageSize.getHeight();
133 int wRatio = (int) Math.ceil(wImage / wPage);
134 int hRatio = (int) Math.ceil(hImage / hPage);
136 return wRatio <= 1.0d && hRatio <= 1.0d;
140 * Print the transition.
142 * @param theTransition the printable transition
144 private void printOnOnePage(final AbstractPrintableTransition theTransition) {
145 Dimension d = getPageSize();
146 PdfContentByte cb = writer.getDirectContent();
147 Graphics2D g2 = cb.createGraphics(d.width, d.height);
148 theTransition.print(g2);
154 * Get the dimensions of the paper page.
156 * @return an internal Dimension
158 protected Dimension getPageSize() {
159 return new Dimension(document.getPageSize().getWidth(),
160 document.getPageSize().getHeight());
164 * Convenience class to model a dimension.
182 public Dimension(float w, float h) {
192 public float getWidth() {
201 public float getHeight() {