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.PdfWriter;
7 import net.sf.openrocket.gui.print.AbstractPrintable;
8 import net.sf.openrocket.gui.print.ITextHelper;
9 import net.sf.openrocket.gui.print.PrintUnit;
10 import net.sf.openrocket.gui.print.PrintableCenteringRing;
11 import net.sf.openrocket.logging.LogHelper;
12 import net.sf.openrocket.rocketcomponent.CenteringRing;
13 import net.sf.openrocket.rocketcomponent.RocketComponent;
14 import net.sf.openrocket.startup.Application;
16 import java.awt.image.BufferedImage;
17 import java.util.List;
21 * A strategy for printing a centering ring to iText.
23 public class CenteringRingStrategy {
28 private static final LogHelper log = Application.getLogger();
33 protected Document document;
36 * The direct iText writer.
38 protected PdfWriter writer;
41 * The stages selected.
43 protected Set<Integer> stages;
46 * Strategy for fitting multiple components onto a page.
48 protected PageFitPrintStrategy pageFitPrint;
53 * @param doc The iText document
54 * @param theWriter The direct iText writer
55 * @param theStagesToVisit The stages to be visited by this strategy
57 public CenteringRingStrategy(Document doc, PdfWriter theWriter, Set<Integer> theStagesToVisit, PageFitPrintStrategy pageFit) {
60 stages = theStagesToVisit;
61 pageFitPrint = pageFit;
65 * Recurse through the given rocket component.
67 * @param root the root component; all children will be visited recursively
69 public void writeToDocument(final RocketComponent root) {
70 List<RocketComponent> rc = root.getChildren();
76 * Recurse through the given rocket component.
78 * @param theRc an array of rocket components; all children will be visited recursively
80 protected void goDeep(final List<RocketComponent> theRc) {
81 for (RocketComponent rocketComponent : theRc) {
82 if (rocketComponent instanceof CenteringRing) {
83 render((CenteringRing) rocketComponent);
85 else if (rocketComponent.getChildCount() > 0) {
86 goDeep(rocketComponent.getChildren());
92 * The core behavior of this visitor.
94 * @param component the object to extract info about; a graphical image of the centering ring shape is drawn to the
97 private void render(final CenteringRing component) {
99 AbstractPrintable pfs;
100 pfs = new PrintableCenteringRing(component);
102 java.awt.Dimension size = pfs.getSize();
103 final Dimension pageSize = getPageSize();
104 if (fitsOnOnePage(pageSize, size.getWidth(), size.getHeight())) {
105 pageFitPrint.addComponent(pfs);
108 int off = (int) (PrintUnit.POINTS_PER_INCH * 0.3f);
109 pfs.setPrintOffset(off, off);
110 BufferedImage image = (BufferedImage) pfs.createImage();
111 ITextHelper.renderImageAcrossPages(new Rectangle(pageSize.getWidth(), pageSize.getHeight()),
112 document, writer, image);
116 catch (DocumentException e) {
117 log.error("Could not render the centering ring.", 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
128 * @return true if the thing to be printed will fit on a single page
130 private boolean fitsOnOnePage(Dimension pageSize, double wImage, double hImage) {
131 double wPage = pageSize.getWidth();
132 double hPage = pageSize.getHeight();
134 int wRatio = (int) Math.ceil(wImage / wPage);
135 int hRatio = (int) Math.ceil(hImage / hPage);
137 return wRatio <= 1.0d && hRatio <= 1.0d;
141 * Get the dimensions of the paper page.
143 * @return an internal Dimension
145 protected Dimension getPageSize() {
146 return new Dimension(document.getPageSize().getWidth(),
147 document.getPageSize().getHeight());
151 * Convenience class to model a dimension.
169 public Dimension(float w, float h) {
179 public float getWidth() {
188 public float getHeight() {