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.PdfContentByte;
10 import com.itextpdf.text.pdf.PdfWriter;
11 import net.sf.openrocket.gui.print.ITextHelper;
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;
19 import java.awt.image.BufferedImage;
20 import java.util.List;
24 * A strategy for drawing fin templates.
26 public class FinSetPrintStrategy {
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 theStages The stages to be printed by this strategy
55 public FinSetPrintStrategy(Document doc, PdfWriter theWriter, Set<Integer> theStages) {
62 * Recurse through the given rocket component.
64 * @param root the root component; all children will be printed recursively
66 public void writeToDocument (final RocketComponent root) {
67 List<RocketComponent> rc = root.getChildren();
73 * Recurse through the given rocket component.
75 * @param theRc an array of rocket components; all children will be printed recursively
77 protected void goDeep (final List<RocketComponent> theRc) {
78 for (RocketComponent rocketComponent : theRc) {
79 if (rocketComponent instanceof FinSet) {
80 printFinSet((FinSet) rocketComponent);
82 else if (rocketComponent.getChildCount() > 0) {
83 goDeep(rocketComponent.getChildren());
89 * The core behavior of this strategy.
91 * @param finSet the object to extract info about; a graphical image of the fin shape is drawn to the document
93 private void printFinSet(final FinSet finSet) {
94 if (shouldPrintStage(finSet.getStageNumber())) {
96 PrintableFinSet pfs = new PrintableFinSet(finSet);
98 java.awt.Dimension finSize = pfs.getSize();
99 final Dimension pageSize = getPageSize();
100 if (fitsOnOnePage(pageSize, finSize.getWidth(), finSize.getHeight())) {
104 BufferedImage image = (BufferedImage) pfs.createImage();
105 ITextHelper.renderImageAcrossPages(new Rectangle(pageSize.getWidth(), pageSize.getHeight()),
106 document, writer, image);
110 catch (DocumentException e) {
111 log.error("Could not render fin.", e);
117 * Determine if the strategy's set of stage numbers (to print) contains the specified stage.
119 * @param stageNumber a stage number
121 * @return true if the strategy contains the stage number provided
123 public boolean shouldPrintStage(int stageNumber) {
124 if (stages == null || stages.isEmpty()) {
128 for (final Integer stage : stages) {
129 if (stage == stageNumber) {
138 * Determine if the image will fit on the given page.
140 * @param pageSize the page size
141 * @param wImage the width of the thing to be printed
142 * @param hImage the height of the thing to be printed
144 * @return true if the thing to be printed will fit on a single page
146 private boolean fitsOnOnePage (Dimension pageSize, double wImage, double hImage) {
147 double wPage = pageSize.getWidth();
148 double hPage = pageSize.getHeight();
150 int wRatio = (int) Math.ceil(wImage / wPage);
151 int hRatio = (int) Math.ceil(hImage / hPage);
153 return wRatio <= 1.0d && hRatio <= 1.0d;
159 * @param thePfs the printable fin set
161 private void printOnOnePage (final PrintableFinSet thePfs) {
162 Dimension d = getPageSize();
163 PdfContentByte cb = writer.getDirectContent();
164 Graphics2D g2 = cb.createGraphics(d.width, d.height);
170 * Get the dimensions of the paper page.
172 * @return an internal Dimension
174 protected Dimension getPageSize () {
175 return new Dimension(document.getPageSize().getWidth(),
176 document.getPageSize().getHeight());
180 * Convenience class to model a dimension.
183 /** Width, in points. */
185 /** Height, in points. */
193 public Dimension (float w, float h) {
203 public float getWidth () {
212 public float getHeight () {