2 * FinSetPrintStrategy.java
4 package net.sf.openrocket.gui.print.visitor;
6 import com.itextpdf.text.Document;
7 import com.itextpdf.text.DocumentException;
8 import com.itextpdf.text.Rectangle;
9 import com.itextpdf.text.pdf.PdfWriter;
10 import net.sf.openrocket.gui.print.ITextHelper;
11 import net.sf.openrocket.gui.print.PrintUnit;
12 import net.sf.openrocket.gui.print.PrintableFinSet;
13 import net.sf.openrocket.logging.LogHelper;
14 import net.sf.openrocket.rocketcomponent.FinSet;
15 import net.sf.openrocket.rocketcomponent.RocketComponent;
16 import net.sf.openrocket.startup.Application;
18 import java.awt.image.BufferedImage;
19 import java.util.List;
23 * A strategy for drawing fin templates.
25 public class FinSetPrintStrategy {
30 private static final LogHelper log = Application.getLogger();
35 protected Document document;
38 * The direct iText writer.
40 protected PdfWriter writer;
43 * The stages selected.
45 protected Set<Integer> stages;
48 * Strategy for fitting multiple components onto a page.
50 protected PageFitPrintStrategy pageFitPrint;
55 * @param doc The iText document
56 * @param theWriter The direct iText writer
57 * @param theStages The stages to be printed by this strategy
59 public FinSetPrintStrategy(Document doc, PdfWriter theWriter, Set<Integer> theStages, PageFitPrintStrategy pageFit) {
63 pageFitPrint = pageFit;
67 * Recurse through the given rocket component.
69 * @param root the root component; all children will be printed recursively
71 public void writeToDocument (final RocketComponent root) {
72 List<RocketComponent> rc = root.getChildren();
78 * Recurse through the given rocket component.
80 * @param theRc an array of rocket components; all children will be printed recursively
82 protected void goDeep (final List<RocketComponent> theRc) {
83 for (RocketComponent rocketComponent : theRc) {
84 if (rocketComponent instanceof FinSet) {
85 printFinSet((FinSet) rocketComponent);
87 else if (rocketComponent.getChildCount() > 0) {
88 goDeep(rocketComponent.getChildren());
94 * The core behavior of this strategy.
96 * @param finSet the object to extract info about; a graphical image of the fin shape is drawn to the document
98 private void printFinSet(final FinSet finSet) {
99 if (shouldPrintStage(finSet.getStageNumber())) {
101 PrintableFinSet pfs = new PrintableFinSet(finSet);
103 java.awt.Dimension finSize = pfs.getSize();
104 final Dimension pageSize = getPageSize();
105 if (fitsOnOnePage(pageSize, finSize.getWidth(), finSize.getHeight())) {
106 pageFitPrint.addComponent(pfs);
109 int off = (int)(PrintUnit.POINTS_PER_INCH * 0.3f);
110 pfs.setPrintOffset(off, off);
111 BufferedImage image = (BufferedImage) pfs.createImage();
112 ITextHelper.renderImageAcrossPages(new Rectangle(pageSize.getWidth(), pageSize.getHeight()),
113 document, writer, image);
117 catch (DocumentException e) {
118 log.error("Could not render fin.", e);
124 * Determine if the strategy's set of stage numbers (to print) contains the specified stage.
126 * @param stageNumber a stage number
128 * @return true if the strategy contains the stage number provided
130 public boolean shouldPrintStage(int stageNumber) {
131 if (stages == null || stages.isEmpty()) {
135 for (final Integer stage : stages) {
136 if (stage == stageNumber) {
145 * Determine if the image will fit on the given page.
147 * @param pageSize the page size
148 * @param wImage the width of the thing to be printed
149 * @param hImage the height of the thing to be printed
151 * @return true if the thing to be printed will fit on a single page
153 private boolean fitsOnOnePage (Dimension pageSize, double wImage, double hImage) {
154 double wPage = pageSize.getWidth();
155 double hPage = pageSize.getHeight();
157 int wRatio = (int) Math.ceil(wImage / wPage);
158 int hRatio = (int) Math.ceil(hImage / hPage);
160 return wRatio <= 1.0d && hRatio <= 1.0d;
164 * Get the dimensions of the paper page.
166 * @return an internal Dimension
168 protected Dimension getPageSize () {
169 return new Dimension(document.getPageSize().getWidth(),
170 document.getPageSize().getHeight());
174 * Convenience class to model a dimension.
177 /** Width, in points. */
179 /** Height, in points. */
187 public Dimension (float w, float h) {
197 public float getWidth () {
206 public float getHeight () {