lose embedded source jars from upstream branch
[debian/openrocket] / core / src / net / sf / openrocket / gui / print / visitor / FinSetPrintStrategy.java
1 /*
2  * FinSetPrintStrategy.java
3  */
4 package net.sf.openrocket.gui.print.visitor;
5
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;
17
18 import java.awt.*;
19 import java.awt.image.BufferedImage;
20 import java.util.List;
21 import java.util.Set;
22
23 /**
24  * A strategy for drawing fin templates.
25  */
26 public class FinSetPrintStrategy {
27
28     /**
29      * The logger.
30      */
31     private static final LogHelper log = Application.getLogger();
32
33     /**
34      * The iText document.
35      */
36     protected Document document;
37
38     /**
39      * The direct iText writer.
40      */
41     protected PdfWriter writer;
42
43     /**
44      * The stages selected.
45      */
46     protected Set<Integer> stages;
47
48     /**
49      * Constructor.
50      *
51      * @param doc              The iText document
52      * @param theWriter        The direct iText writer
53      * @param theStages        The stages to be printed by this strategy
54      */
55     public FinSetPrintStrategy(Document doc, PdfWriter theWriter, Set<Integer> theStages) {
56         document = doc;
57         writer = theWriter;
58         stages = theStages;
59     }
60
61     /**
62      * Recurse through the given rocket component.
63      *
64      * @param root the root component; all children will be printed recursively
65      */
66     public void writeToDocument (final RocketComponent root) {
67         List<RocketComponent> rc = root.getChildren();
68         goDeep(rc);
69     }
70
71
72     /**
73      * Recurse through the given rocket component.
74      *
75      * @param theRc an array of rocket components; all children will be printed recursively
76      */
77     protected void goDeep (final List<RocketComponent> theRc) {
78         for (RocketComponent rocketComponent : theRc) {
79             if (rocketComponent instanceof FinSet) {
80                 printFinSet((FinSet) rocketComponent);
81             }
82             else if (rocketComponent.getChildCount() > 0) {
83                 goDeep(rocketComponent.getChildren());
84             }
85         }
86     }
87
88     /**
89      * The core behavior of this strategy.
90      *
91      * @param finSet the object to extract info about; a graphical image of the fin shape is drawn to the document
92      */
93     private void printFinSet(final FinSet finSet) {
94         if (shouldPrintStage(finSet.getStageNumber())) {
95             try {
96                 PrintableFinSet pfs = new PrintableFinSet(finSet);
97
98                 java.awt.Dimension finSize = pfs.getSize();
99                 final Dimension pageSize = getPageSize();
100                 if (fitsOnOnePage(pageSize, finSize.getWidth(), finSize.getHeight())) {
101                     printOnOnePage(pfs);
102                 }
103                 else {
104                     BufferedImage image = (BufferedImage) pfs.createImage();
105                     ITextHelper.renderImageAcrossPages(new Rectangle(pageSize.getWidth(), pageSize.getHeight()),
106                             document, writer, image);
107                 }
108                 document.newPage();
109             }
110             catch (DocumentException e) {
111                 log.error("Could not render fin.", e);
112             }
113         }
114     }
115
116     /**
117      * Determine if the strategy's set of stage numbers (to print) contains the specified stage.
118      *
119      * @param stageNumber a stage number
120      *
121      * @return true if the strategy contains the stage number provided
122      */
123     public boolean shouldPrintStage(int stageNumber) {
124         if (stages == null || stages.isEmpty()) {
125             return false;
126         }
127
128         for (final Integer stage : stages) {
129             if (stage == stageNumber) {
130                 return true;
131             }
132         }
133
134         return false;
135     }
136
137     /**
138      * Determine if the image will fit on the given page.
139      *
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
143      *
144      * @return true if the thing to be printed will fit on a single page
145      */
146     private boolean fitsOnOnePage (Dimension pageSize, double wImage, double hImage) {
147         double wPage = pageSize.getWidth();
148         double hPage = pageSize.getHeight();
149
150         int wRatio = (int) Math.ceil(wImage / wPage);
151         int hRatio = (int) Math.ceil(hImage / hPage);
152
153         return wRatio <= 1.0d && hRatio <= 1.0d;
154     }
155
156     /**
157      * Print the fin set.
158      *
159      * @param thePfs the printable fin set
160      */
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);
165         thePfs.print(g2);
166         g2.dispose();
167     }
168
169     /**
170      * Get the dimensions of the paper page.
171      *
172      * @return an internal Dimension
173      */
174     protected Dimension getPageSize () {
175         return new Dimension(document.getPageSize().getWidth(),
176                              document.getPageSize().getHeight());
177     }
178
179     /**
180      * Convenience class to model a dimension.
181      */
182     class Dimension {
183         /** Width, in points. */
184         public float width;
185         /** Height, in points. */
186         public float height;
187
188         /**
189          * Constructor.
190          * @param w width
191          * @param h height
192          */
193         public Dimension (float w, float h) {
194             width = w;
195             height = h;
196         }
197
198         /**
199          * Get the width.
200          *
201          * @return  the width
202          */
203         public float getWidth () {
204             return width;
205         }
206
207         /**
208          * Get the height.
209          *
210          * @return the height
211          */
212         public float getHeight () {
213             return height;
214         }
215     }
216 }