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;
49 * Strategy for fitting multiple components onto a page.
51 protected PageFitPrintStrategy pageFitPrint;
56 * @param doc The iText document
57 * @param theWriter The direct iText writer
58 * @param theStagesToVisit The stages to be visited by this strategy
60 public TransitionStrategy(Document doc, PdfWriter theWriter, Set<Integer> theStagesToVisit, PageFitPrintStrategy pageFit) {
63 stages = theStagesToVisit;
64 pageFitPrint = pageFit;
68 * Recurse through the given rocket component.
70 * @param root the root component; all children will be visited recursively
71 * @param noseCones nose cones are a special form of a transition; if true, then print nose cones
73 public void writeToDocument(final RocketComponent root, boolean noseCones) {
74 List<RocketComponent> rc = root.getChildren();
75 goDeep(rc, noseCones);
80 * Recurse through the given rocket component.
82 * @param theRc an array of rocket components; all children will be visited recursively
83 * @param noseCones nose cones are a special form of a transition; if true, then print nose cones
85 protected void goDeep(final List<RocketComponent> theRc, boolean noseCones) {
86 for (RocketComponent rocketComponent : theRc) {
87 if (rocketComponent instanceof NoseCone) {
89 render((Transition) rocketComponent);
91 } else if (rocketComponent instanceof Transition && !noseCones) {
92 render((Transition) rocketComponent);
93 } else if (rocketComponent.getChildCount() > 0) {
94 goDeep(rocketComponent.getChildren(), noseCones);
100 * The core behavior of this visitor.
102 * @param component the object to extract info about; a graphical image of the transition shape is drawn to the document
104 private void render(final Transition component) {
106 AbstractPrintableTransition pfs;
107 if (component instanceof NoseCone) {
108 pfs = new PrintableNoseCone(component);
110 pfs = new PrintableTransition(component);
113 java.awt.Dimension size = pfs.getSize();
114 final Dimension pageSize = getPageSize();
115 if (fitsOnOnePage(pageSize, size.getWidth(), size.getHeight())) {
116 pageFitPrint.addComponent(pfs);
117 //printOnOnePage(pfs);
119 BufferedImage image = (BufferedImage) pfs.createImage();
120 ITextHelper.renderImageAcrossPages(new Rectangle(pageSize.getWidth(), pageSize.getHeight()),
121 document, writer, image);
123 } catch (DocumentException e) {
124 log.error("Could not render the transition.", e);
129 * Determine if the image will fit on the given page.
131 * @param pageSize the page size
132 * @param wImage the width of the thing to be printed
133 * @param hImage the height of the thing to be printed
134 * @return true if the thing to be printed will fit on a single page
136 private boolean fitsOnOnePage(Dimension pageSize, double wImage, double hImage) {
137 double wPage = pageSize.getWidth();
138 double hPage = pageSize.getHeight();
140 int wRatio = (int) Math.ceil(wImage / wPage);
141 int hRatio = (int) Math.ceil(hImage / hPage);
143 return wRatio <= 1.0d && hRatio <= 1.0d;
147 * Print the transition.
149 * @param theTransition the printable transition
151 /*private void printOnOnePage(final AbstractPrintableTransition theTransition) {
152 Dimension d = getPageSize();
153 PdfContentByte cb = writer.getDirectContent();
154 Graphics2D g2 = cb.createGraphics(d.width, d.height);
155 theTransition.print(g2);
161 * Get the dimensions of the paper page.
163 * @return an internal Dimension
165 protected Dimension getPageSize() {
166 return new Dimension(document.getPageSize().getWidth(),
167 document.getPageSize().getHeight());
171 * Convenience class to model a dimension.
189 public Dimension(float w, float h) {
199 public float getWidth() {
208 public float getHeight() {