]> git.gag.com Git - debian/openrocket/commitdiff
Printable Centering Ring templates.
authorrodinia814 <rodinia814@180e2498-e6e9-4542-8430-84ac67f01cd8>
Thu, 24 May 2012 23:28:58 +0000 (23:28 +0000)
committerrodinia814 <rodinia814@180e2498-e6e9-4542-8430-84ac67f01cd8>
Thu, 24 May 2012 23:28:58 +0000 (23:28 +0000)
git-svn-id: https://openrocket.svn.sourceforge.net/svnroot/openrocket/trunk@721 180e2498-e6e9-4542-8430-84ac67f01cd8

core/resources/l10n/messages.properties
core/src/net/sf/openrocket/gui/print/AbstractPrintable.java [new file with mode: 0644]
core/src/net/sf/openrocket/gui/print/AbstractPrintableTransition.java [deleted file]
core/src/net/sf/openrocket/gui/print/OpenRocketPrintable.java
core/src/net/sf/openrocket/gui/print/PrintController.java
core/src/net/sf/openrocket/gui/print/PrintableCenteringRing.java [new file with mode: 0644]
core/src/net/sf/openrocket/gui/print/PrintableNoseCone.java
core/src/net/sf/openrocket/gui/print/PrintableTransition.java
core/src/net/sf/openrocket/gui/print/visitor/CenteringRingStrategy.java [new file with mode: 0644]
core/src/net/sf/openrocket/gui/print/visitor/TransitionStrategy.java

index 5b44f44b8552db11e2880ea5a2169dd9f62eb66f..c7a472bbb4caa4d1fa44ff253e4a59c475f273cf 100644 (file)
@@ -1356,6 +1356,7 @@ OpenRocketPrintable.Transitiontemplates = Transition templates
 OpenRocketPrintable.Noseconetemplates = Nose Cone templates
 OpenRocketPrintable.Finmarkingguide = Fin marking guide
 OpenRocketPrintable.DesignReport = Design Report
+OpenRocketPrintable.Centeringringtemplates = Centering Ring templates
 
 OpenRocketDocument.Redo = Redo
 OpenRocketDocument.Undo = Undo
diff --git a/core/src/net/sf/openrocket/gui/print/AbstractPrintable.java b/core/src/net/sf/openrocket/gui/print/AbstractPrintable.java
new file mode 100644 (file)
index 0000000..739a7d9
--- /dev/null
@@ -0,0 +1,87 @@
+package net.sf.openrocket.gui.print;
+
+import java.awt.*;
+import java.awt.image.BufferedImage;
+
+public abstract class AbstractPrintable<T> extends PrintableComponent {
+    /**
+     * A thin stroke.
+     */
+    public final static BasicStroke thinStroke = new BasicStroke(1.0f);
+
+    /**
+     * A thick stroke.
+     */
+    public final static BasicStroke thickStroke = new BasicStroke(4.0f);
+
+    /**
+     * The X margin.
+     */
+    protected int marginX = (int) PrintUnit.INCHES.toPoints(0.25f);
+
+    /**
+     * The Y margin.
+     */
+    protected int marginY = (int) PrintUnit.INCHES.toPoints(0.25f);
+
+    /**
+     * Constructor. Initialize this printable with the component to be printed.
+     *
+     * @param isDoubleBuffered  a boolean, true for double-buffering
+     * @param transition  the component to be printed
+     */
+    public AbstractPrintable(boolean isDoubleBuffered, T transition) {
+        init(transition);
+    }
+
+    /**
+     * Compute the basic values of each arc of the transition/shroud.  This is adapted from
+     * <a href="http://www.rocketshoppe.com/info/Transitions.pdf">The Properties of
+     * Model Rocket Body Tube Transitions, by J.R. Brohm</a>
+     *
+     * @param component the transition component
+     */
+    protected abstract void init(T component);
+
+    /**
+     * Draw the component onto the graphics context.
+     *
+     * @param g2 the graphics context
+     */
+    protected abstract void draw(Graphics2D g2);
+
+    /**
+     * Returns a generated image of the transition.  May then be used wherever AWT images can be used, or converted to
+     * another image/picture format and used accordingly.
+     *
+     * @return an awt image of the transition
+     */
+    public Image createImage() {
+        int width = getWidth() + marginX;
+        int height = getHeight() + marginY;
+        // Create a buffered image in which to draw
+        BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
+        // Create a graphics contents on the buffered image
+        Graphics2D g2d = bufferedImage.createGraphics();
+        // Draw graphics
+        g2d.setBackground(Color.white);
+        g2d.clearRect(0, 0, width, height);
+        paintComponent(g2d);
+        // Graphics context no longer needed so dispose it
+        g2d.dispose();
+        return bufferedImage;
+    }
+
+    @Override
+    public void paintComponent(Graphics g) {
+        Graphics2D g2 = (Graphics2D) g;
+        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+                RenderingHints.VALUE_ANTIALIAS_ON);
+
+        g2.setColor(Color.BLACK);
+        g2.setStroke(thinStroke);
+               g2.translate(getOffsetX(), getOffsetY());
+
+        draw(g2);
+    }
+}
diff --git a/core/src/net/sf/openrocket/gui/print/AbstractPrintableTransition.java b/core/src/net/sf/openrocket/gui/print/AbstractPrintableTransition.java
deleted file mode 100644 (file)
index bb1d124..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-package net.sf.openrocket.gui.print;
-
-import net.sf.openrocket.rocketcomponent.Transition;
-
-import javax.swing.*;
-import java.awt.*;
-import java.awt.image.BufferedImage;
-
-public abstract class AbstractPrintableTransition extends PrintableComponent {
-    /**
-     * The stroke of the transition arc.
-     */
-    private final static BasicStroke thinStroke = new BasicStroke(1.0f);
-
-    /**
-     * The X margin.
-     */
-    protected int marginX = (int) PrintUnit.INCHES.toPoints(0.25f);
-
-    /**
-     * The Y margin.
-     */
-    protected int marginY = (int) PrintUnit.INCHES.toPoints(0.25f);
-    
-    /**
-     * Constructor. Initialize this printable with the component to be printed.
-     *
-     * @param isDoubleBuffered  a boolean, true for double-buffering
-     * @param transition  the component to be printed
-     */
-    public AbstractPrintableTransition(boolean isDoubleBuffered, Transition transition) {
-        init(transition);
-    }
-
-    /**
-     * Compute the basic values of each arc of the transition/shroud.  This is adapted from
-     * <a href="http://www.rocketshoppe.com/info/Transitions.pdf">The Properties of
-     * Model Rocket Body Tube Transitions, by J.R. Brohm</a>
-     *
-     * @param component the transition component
-     */
-    protected abstract void init(Transition component);
-
-    /**
-     * Draw the component onto the graphics context.
-     *
-     * @param g2 the graphics context
-     */
-    protected abstract void draw(Graphics2D g2);
-    
-    /**
-     * Returns a generated image of the transition.  May then be used wherever AWT images can be used, or converted to
-     * another image/picture format and used accordingly.
-     *
-     * @return an awt image of the fin set
-     */
-    public Image createImage() {
-        int width = getWidth() + marginX;
-        int height = getHeight() + marginY;
-        // Create a buffered image in which to draw
-        BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
-        // Create a graphics contents on the buffered image
-        Graphics2D g2d = bufferedImage.createGraphics();
-        // Draw graphics
-        g2d.setBackground(Color.white);
-        g2d.clearRect(0, 0, width, height);
-        paintComponent(g2d);
-        // Graphics context no longer needed so dispose it
-        g2d.dispose();
-        return bufferedImage;
-    }
-
-    @Override
-    public void paintComponent(Graphics g) {
-        Graphics2D g2 = (Graphics2D) g;
-        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
-                RenderingHints.VALUE_ANTIALIAS_ON);
-
-        g2.setColor(Color.BLACK);
-        g2.setStroke(thinStroke);
-               g2.translate(getOffsetX(), getOffsetY());
-
-        draw(g2);
-    }
-}
index 456495f384e3cc910d9f6798d795fb11405f2875..5bfd924c81b159689794b134180c0a282015854d 100644 (file)
@@ -22,29 +22,31 @@ public enum OpenRocketPrintable {
        NOSE_CONE_TEMPLATE("OpenRocketPrintable.Noseconetemplates", false, 3),
        // Transition Templates
        TRANSITION_TEMPLATE("OpenRocketPrintable.Transitiontemplates", false, 4),
+       // Centering Ring Templates
+       CENTERING_RING_TEMPLATE("OpenRocketPrintable.Centeringringtemplates", false, 5),
        // Finset shape
-       FIN_TEMPLATE("OpenRocketPrintable.Fintemplates", true, 5),
+       FIN_TEMPLATE("OpenRocketPrintable.Fintemplates", true, 6),
        // Fin marking guide.
-       FIN_MARKING_GUIDE("OpenRocketPrintable.Finmarkingguide", false, 6);
-       
+       FIN_MARKING_GUIDE("OpenRocketPrintable.Finmarkingguide", false, 7);
+
 
        private static final Translator trans = Application.getTranslator();
-       
+
        /**
         * The description - will be displayed in the JTree.
         */
        private String description;
-       
+
        /**
         * Flag that indicates if the enum value is different depending upon stage.
         */
        private boolean stageSpecific;
-       
+
        /**
         * The order of the item as it appears in the printed document.
         */
        private int order;
-       
+
        /**
         * Constructor.
         *
@@ -57,7 +59,7 @@ public enum OpenRocketPrintable {
                stageSpecific = staged;
                order = idx;
        }
-       
+
        /**
         * Get the description of this printable.
         *
@@ -66,7 +68,7 @@ public enum OpenRocketPrintable {
        public String getDescription() {
                return trans.get(description);
        }
-       
+
        /**
         * Answers if this enum value has different meaning depending upon the stage.
         *
@@ -75,7 +77,7 @@ public enum OpenRocketPrintable {
        public boolean isStageSpecific() {
                return stageSpecific;
        }
-       
+
        /**
         * Answer the print order.  This is relative to other enum values.  No two enum values will have the same print
         * order value.
@@ -85,7 +87,7 @@ public enum OpenRocketPrintable {
        public int getPrintOrder() {
                return order;
        }
-       
+
        /**
         * Look up an enum value based on the description.
         *
@@ -102,7 +104,7 @@ public enum OpenRocketPrintable {
                }
                return null;
        }
-       
+
        /**
         * Get a list of ordered enum values that do not have stage affinity.
         *
index 64d2b4d7628065f4a654d7f51b58ba8093b47056..4088de702de62fc79969f7a86195956abf75a2e9 100644 (file)
@@ -12,9 +12,10 @@ import com.itextpdf.text.pdf.PdfBoolean;
 import com.itextpdf.text.pdf.PdfName;
 import com.itextpdf.text.pdf.PdfWriter;
 import net.sf.openrocket.document.OpenRocketDocument;
-import net.sf.openrocket.gui.print.visitor.PageFitPrintStrategy;
+import net.sf.openrocket.gui.print.visitor.CenteringRingStrategy;
 import net.sf.openrocket.gui.print.visitor.FinMarkingGuideStrategy;
 import net.sf.openrocket.gui.print.visitor.FinSetPrintStrategy;
+import net.sf.openrocket.gui.print.visitor.PageFitPrintStrategy;
 import net.sf.openrocket.gui.print.visitor.PartsDetailVisitorStrategy;
 import net.sf.openrocket.gui.print.visitor.TransitionStrategy;
 
@@ -28,108 +29,121 @@ import java.util.Set;
  * file.
  */
 public class PrintController {
-       
-       /**
-        * Print the selected components to a PDF document.
-        *
-        * @param doc         the OR document
-        * @param toBePrinted the user chosen items to print
-        * @param outputFile  the file being written to
-        * @param settings    the print settings
+
+    /**
+     * Print the selected components to a PDF document.
+     *
+     * @param doc         the OR document
+     * @param toBePrinted the user chosen items to print
+     * @param outputFile  the file being written to
+     * @param settings    the print settings
      * @param rotation    the angle the rocket figure is rotated
-        */
-       public void print(OpenRocketDocument doc, Iterator<PrintableContext> toBePrinted, OutputStream outputFile,
-                                               PrintSettings settings, double rotation) {
-               
-               Document idoc = new Document(getSize(settings));
-               PdfWriter writer = null;
-               try {
-                       writer = PdfWriter.getInstance(idoc, outputFile);
-                       writer.setStrictImageSequence(true);
-                       
-                       writer.addViewerPreference(PdfName.PRINTSCALING, PdfName.NONE);
-                       writer.addViewerPreference(PdfName.PICKTRAYBYPDFSIZE, PdfBoolean.PDFTRUE);
-                       try {
-                               idoc.open();
-                               Thread.sleep(1000);
-                       } catch (InterruptedException e) {
-                       }
-                       
-                       // Used to combine multiple components onto fewer sheets of paper
-                       PageFitPrintStrategy pageFitPrint = new PageFitPrintStrategy(idoc, writer);
-                       
-                       while (toBePrinted.hasNext()) {
-                               PrintableContext printableContext = toBePrinted.next();
-                               
-                               Set<Integer> stages = printableContext.getStageNumber();
-                               
-                               switch (printableContext.getPrintable()) {
-                               case DESIGN_REPORT:
-                                       DesignReport dp = new DesignReport(doc, idoc, rotation);
-                                       dp.writeToDocument(writer);
-                                       idoc.newPage();
-                                       break;
-                               case FIN_TEMPLATE:
-                                       final FinSetPrintStrategy finWriter = new FinSetPrintStrategy(idoc, writer, stages, pageFitPrint);
-                    finWriter.writeToDocument(doc.getRocket());
-                    break;
-                case PARTS_DETAIL:
-                                       final PartsDetailVisitorStrategy detailVisitor = new PartsDetailVisitorStrategy(idoc, writer, stages);
-                    detailVisitor.writeToDocument(doc.getRocket());
-                    detailVisitor.close();
-                    idoc.newPage();
-                                       break;
-                case TRANSITION_TEMPLATE:
-                    final TransitionStrategy tranWriter = new TransitionStrategy(idoc, writer, stages, pageFitPrint);
-                    tranWriter.writeToDocument(doc.getRocket(), false);
-                    idoc.newPage();
-                    break;
-
-                case NOSE_CONE_TEMPLATE:
-                    final TransitionStrategy coneWriter = new TransitionStrategy(idoc, writer, stages, pageFitPrint);
-                    coneWriter.writeToDocument(doc.getRocket(), true);
-                    idoc.newPage();
-                    break;
-
-                case FIN_MARKING_GUIDE:
-                    final FinMarkingGuideStrategy fmg = new FinMarkingGuideStrategy(idoc, writer);
-                    fmg.writeToDocument(doc.getRocket());
-                    idoc.newPage();
-                    break;
+     */
+    public void print(OpenRocketDocument doc, Iterator<PrintableContext> toBePrinted, OutputStream outputFile,
+                      PrintSettings settings, double rotation) {
+
+        Document idoc = new Document(getSize(settings));
+        PdfWriter writer = null;
+        try {
+            writer = PdfWriter.getInstance(idoc, outputFile);
+            writer.setStrictImageSequence(true);
+
+            writer.addViewerPreference(PdfName.PRINTSCALING, PdfName.NONE);
+            writer.addViewerPreference(PdfName.PICKTRAYBYPDFSIZE, PdfBoolean.PDFTRUE);
+            try {
+                idoc.open();
+                Thread.sleep(1000);
+            }
+            catch (InterruptedException e) {
+            }
+
+            // Used to combine multiple components onto fewer sheets of paper
+            PageFitPrintStrategy pageFitPrint = new PageFitPrintStrategy(idoc, writer);
+
+            while (toBePrinted.hasNext()) {
+                PrintableContext printableContext = toBePrinted.next();
+
+                Set<Integer> stages = printableContext.getStageNumber();
+
+                switch (printableContext.getPrintable()) {
+                    case DESIGN_REPORT:
+                        DesignReport dp = new DesignReport(doc, idoc, rotation);
+                        dp.writeToDocument(writer);
+                        idoc.newPage();
+                        break;
+                    case FIN_TEMPLATE:
+                        final FinSetPrintStrategy finWriter = new FinSetPrintStrategy(idoc, writer, stages, pageFitPrint);
+                        finWriter.writeToDocument(doc.getRocket());
+                        break;
+                    case PARTS_DETAIL:
+                        final PartsDetailVisitorStrategy detailVisitor = new PartsDetailVisitorStrategy(idoc, writer, stages);
+                        detailVisitor.writeToDocument(doc.getRocket());
+                        detailVisitor.close();
+                        idoc.newPage();
+                        break;
+                    case TRANSITION_TEMPLATE:
+                        final TransitionStrategy tranWriter = new TransitionStrategy(idoc, writer, stages, pageFitPrint);
+                        tranWriter.writeToDocument(doc.getRocket(), false);
+                        idoc.newPage();
+                        break;
+
+                    case NOSE_CONE_TEMPLATE:
+                        final TransitionStrategy coneWriter = new TransitionStrategy(idoc, writer, stages, pageFitPrint);
+                        coneWriter.writeToDocument(doc.getRocket(), true);
+                        idoc.newPage();
+                        break;
+
+                    case CENTERING_RING_TEMPLATE:
+                        final CenteringRingStrategy crWriter = new CenteringRingStrategy(idoc, writer, stages,
+                                pageFitPrint);
+                        crWriter.writeToDocument(doc.getRocket());
+                        idoc.newPage();
+                        break;
+
+                    case FIN_MARKING_GUIDE:
+                        final FinMarkingGuideStrategy fmg = new FinMarkingGuideStrategy(idoc, writer);
+                        fmg.writeToDocument(doc.getRocket());
+                        idoc.newPage();
+                        break;
+                }
+            }
+            // Write out parts that we are going to combine onto single sheets of paper
+            pageFitPrint.writeToDocument(doc.getRocket());
+            idoc.newPage();
+
+            //Stupid iText throws a really nasty exception if there is no data when close is called.
+            if (writer.getCurrentDocumentSize() <= 140) {
+                writer.setPageEmpty(false);
+            }
+            writer.close();
+            idoc.close();
+        }
+        catch (DocumentException e) {
+        }
+        catch (ExceptionConverter ec) {
+        }
+        finally {
+            if (outputFile != null) {
+                try {
+                    outputFile.close();
+                }
+                catch (IOException e) {
                 }
-                       }
-                       // Write out parts that we are going to combine onto single sheets of paper
-                       pageFitPrint.writeToDocument(doc.getRocket());
-                       idoc.newPage();
-                       
-                       //Stupid iText throws a really nasty exception if there is no data when close is called.
-                       if (writer.getCurrentDocumentSize() <= 140) {
-                               writer.setPageEmpty(false);
-                       }
-                       writer.close();
-                       idoc.close();
-               } catch (DocumentException e) {
-               } catch (ExceptionConverter ec) {
-               } finally {
-                       if (outputFile != null) {
-                               try {
-                                       outputFile.close();
-                               } catch (IOException e) {
-                               }
-                       }
-               }
-       }
-       
-       /**
-        * Get the correct paper size from the print settings.
-        * 
-        * @param settings      the print settings
-        * @return                      the paper size
-        */
-       private Rectangle getSize(PrintSettings settings) {
-               PaperSize size = settings.getPaperSize();
-               PaperOrientation orientation = settings.getPaperOrientation();
-               return orientation.orient(size.getSize());
-       }
-       
+            }
+        }
+    }
+
+    /**
+     * Get the correct paper size from the print settings.
+     *
+     * @param settings the print settings
+     *
+     * @return the paper size
+     */
+    private Rectangle getSize(PrintSettings settings) {
+        PaperSize size = settings.getPaperSize();
+        PaperOrientation orientation = settings.getPaperOrientation();
+        return orientation.orient(size.getSize());
+    }
+
 }
diff --git a/core/src/net/sf/openrocket/gui/print/PrintableCenteringRing.java b/core/src/net/sf/openrocket/gui/print/PrintableCenteringRing.java
new file mode 100644 (file)
index 0000000..08d3f12
--- /dev/null
@@ -0,0 +1,104 @@
+package net.sf.openrocket.gui.print;
+
+import net.sf.openrocket.rocketcomponent.CenteringRing;
+
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Shape;
+import java.awt.geom.Ellipse2D;
+
+/**
+ * This class creates a renderable centering ring.  It depends only on AWT/Swing and can be called from other
+ * actors (like iText handlers) to render the centering ring on different graphics contexts.
+ */
+public class PrintableCenteringRing extends AbstractPrintable<CenteringRing> {
+    /**
+     * If the component to be drawn is a centering ring, save a reference to it.
+     */
+    private CenteringRing target;
+
+    /**
+     * The X margin.
+     */
+    protected int marginX = (int) PrintUnit.INCHES.toPoints(0.25f);
+
+    /**
+     * The Y margin.
+     */
+    protected int marginY = (int) PrintUnit.INCHES.toPoints(0.25f);
+
+    /**
+     * The line length of the cross hairs.
+     */
+    private final int lineLength = 10;
+
+    /**
+     * Construct a printable nose cone.
+     *
+     * @param theRing the component to print
+     */
+    public PrintableCenteringRing(CenteringRing theRing) {
+        super(false, theRing);
+    }
+
+    /**
+     * @param component the centering ring component
+     */
+    @Override
+    protected void init(final CenteringRing component) {
+
+        target = component;
+
+        double radius = target.getOuterRadius();
+        setSize((int) PrintUnit.METERS.toPoints(2 * radius) + marginX,
+                (int) PrintUnit.METERS.toPoints(2 * radius) + marginY);
+    }
+
+    /**
+     * Draw a centering ring.
+     *
+     * @param g2 the graphics context
+     */
+    @Override
+    protected void draw(Graphics2D g2) {
+        double radius = PrintUnit.METERS.toPoints(target.getOuterRadius());
+
+        Color original = g2.getBackground();
+        double x = marginX;
+        double y = marginY;
+        Shape outerCircle = new Ellipse2D.Double(x, y, radius * 2, radius * 2);
+        g2.setColor(Color.lightGray);
+        g2.fill(outerCircle);
+        g2.setColor(Color.black);
+        g2.draw(outerCircle);
+        x += radius;
+        y += radius;
+
+        double innerRadius = PrintUnit.METERS.toPoints(target.getInnerRadius());
+        Shape innerCircle = new Ellipse2D.Double(x - innerRadius, y - innerRadius, innerRadius * 2, innerRadius * 2);
+        g2.setColor(original);
+        g2.fill(innerCircle);
+        g2.setColor(Color.black);
+        g2.draw(innerCircle);
+
+        drawCross(g2, (int) x, (int) y, lineLength, lineLength);
+    }
+
+    /**
+     * Draw the center cross-hair.
+     *
+     * @param g  the graphics context
+     * @param x  the x coordinate of the center point
+     * @param y  the y coordinate of the center point
+     * @param width the width in pixels of the horizontal hair
+     * @param height the width in pixels of the vertical hair
+     */
+    private void drawCross(Graphics g, int x, int y, int width, int height) {
+        g.setColor(Color.black);
+        ((Graphics2D) g).setStroke(thinStroke);
+        g.drawLine(x - width / 2, y, x + width / 2, y);
+        g.drawLine(x, y - height / 2, x, y + height / 2);
+    }
+
+}
index 614aa35d77719c2a78f9d7fd9e2d307924e2cea3..17f072308e9890215dd392adca4548c872b934ae 100644 (file)
@@ -1,38 +1,33 @@
 package net.sf.openrocket.gui.print;
 
-import java.awt.Graphics;
+import net.sf.openrocket.gui.rocketfigure.TransitionShapes;
+import net.sf.openrocket.rocketcomponent.NoseCone;
+import net.sf.openrocket.util.Transformation;
+
 import java.awt.Graphics2D;
 import java.awt.Rectangle;
 import java.awt.Shape;
-import java.awt.print.PageFormat;
-import java.awt.print.Printable;
-import java.awt.print.PrinterException;
 
-import net.sf.openrocket.gui.rocketfigure.TransitionShapes;
-import net.sf.openrocket.rocketcomponent.NoseCone;
-import net.sf.openrocket.rocketcomponent.Transition;
-import net.sf.openrocket.util.Transformation;
+public class PrintableNoseCone extends AbstractPrintable<NoseCone> {
 
-public class PrintableNoseCone extends AbstractPrintableTransition {
-       
        /**
         * If the component to be drawn is a nose cone, save a reference to it.
         */
        private NoseCone target;
-       
+
        /**
         * Construct a printable nose cone.
         *
         * @param noseCone the component to print
         */
-       public PrintableNoseCone(Transition noseCone) {
+       public PrintableNoseCone(NoseCone noseCone) {
                super(false, noseCone);
        }
-       
+
        @Override
-       protected void init(Transition component) {
-               
-               target = (NoseCone) component;
+       protected void init(NoseCone component) {
+
+               target = component;
                double radius = target.getForeRadius();
                if (radius < target.getAftRadius()) {
                        radius = target.getAftRadius();
@@ -40,7 +35,7 @@ public class PrintableNoseCone extends AbstractPrintableTransition {
                setSize((int) PrintUnit.METERS.toPoints(2 * radius) + marginX,
                                (int) PrintUnit.METERS.toPoints(target.getLength() + target.getAftShoulderLength()) + marginY);
        }
-       
+
        /**
         * Draw a nose cone.
         *
@@ -49,7 +44,7 @@ public class PrintableNoseCone extends AbstractPrintableTransition {
        @Override
        protected void draw(Graphics2D g2) {
                Shape[] shapes = TransitionShapes.getShapesSide(target, Transformation.rotate_x(0d), PrintUnit.METERS.toPoints(1));
-               
+
                if (shapes != null && shapes.length > 0) {
                        Rectangle r = shapes[0].getBounds();
                        g2.translate(marginX + r.getHeight() / 2 + getOffsetX(), marginY + getOffsetY());
index fbe67692290a51f18bf6c494c80e23dc75b7f423..4a2d6d8135fa0e9d0dda87338c50cf2118e99623 100644 (file)
@@ -1,18 +1,14 @@
 package net.sf.openrocket.gui.print;
 
+import net.sf.openrocket.rocketcomponent.Transition;
+
 import java.awt.BasicStroke;
-import java.awt.Graphics;
 import java.awt.Graphics2D;
 import java.awt.geom.Arc2D;
 import java.awt.geom.GeneralPath;
 import java.awt.geom.Line2D;
 import java.awt.geom.Path2D;
 import java.awt.geom.Point2D;
-import java.awt.print.PageFormat;
-import java.awt.print.Printable;
-import java.awt.print.PrinterException;
-
-import net.sf.openrocket.rocketcomponent.Transition;
 
 /**
  * This class allows for a Transition to be printable.  It does so by decorating an existing transition (which will not be
@@ -22,8 +18,8 @@ import net.sf.openrocket.rocketcomponent.Transition;
  * Note: Currently nose cones are only supported by drawing the 2D projection of the profile.  A more useful approach
  * may be to draw a myriahedral projection that can be cut out and bent to form the shape.
  */
-public class PrintableTransition extends AbstractPrintableTransition {
-       
+public class PrintableTransition extends AbstractPrintable<Transition> {
+
        /**
         * Dashed array value.
         */
@@ -35,38 +31,38 @@ public class PrintableTransition extends AbstractPrintableTransition {
                        BasicStroke.CAP_BUTT,
                        BasicStroke.JOIN_MITER,
                        10.0f, dash1, 0.0f);
-       
+
        /**
         * The layout is an outer arc, an inner arc, and two lines one either endpoints that connect the arcs.
         * Most of the math involves transposing geometric cartesian coordinates to the Java AWT coordinate system.
         */
        private Path2D gp;
-       
+
        /**
         * The glue tab.
         */
        private Path2D glueTab1;
-       
+
        /**
         * The alignment marks.
         */
        private Line2D tick1, tick2;
-       
+
        /**
         * The x coordinates for the two ticks drawn at theta degrees.
         */
        private int tick3X, tick4X;
-       
+
        /**
         * The angle, in degrees.
         */
        private float theta;
-       
+
        /**
         * The x,y coordinates for where the virtual circle center is located.
         */
        private int circleCenterX, circleCenterY;
-       
+
        /**
         * Constructor.
         *
@@ -75,13 +71,13 @@ public class PrintableTransition extends AbstractPrintableTransition {
        public PrintableTransition(Transition transition) {
                super(false, transition);
        }
-       
+
        @Override
        protected void init(Transition component) {
-               
+
                double r1 = component.getAftRadius();
                double r2 = component.getForeRadius();
-               
+
                //Regardless of orientation, we have the convention of R1 as the smaller radius.  Flip if different.
                if (r1 > r2) {
                        r1 = r2;
@@ -91,19 +87,19 @@ public class PrintableTransition extends AbstractPrintableTransition {
                double v = r2 - r1;
                double tmp = Math.sqrt(v * v + len * len);
                double factor = tmp / v;
-               
+
                theta = (float) (360d * v / tmp);
-               
+
                int r1InPoints = (int) PrintUnit.METERS.toPoints(r1 * factor);
                int r2InPoints = (int) PrintUnit.METERS.toPoints(r2 * factor);
-               
+
                int x = marginX;
                int tabOffset = 35;
                int y = tabOffset + marginY;
-               
+
                Arc2D.Double outerArc = new Arc2D.Double();
                Arc2D.Double innerArc = new Arc2D.Double();
-               
+
                //If the arcs are more than 3/4 of a circle, then assume the height (y) is the same as the radius of the bigger arc.
                if (theta >= 270) {
                        y += r2InPoints;
@@ -114,23 +110,23 @@ public class PrintableTransition extends AbstractPrintableTransition {
                        double thetaRads = Math.toRadians(theta - 180);
                        y += (int) ((Math.cos(thetaRads) * r2InPoints) * Math.tan(thetaRads));
                }
-               
+
                circleCenterY = y;
                circleCenterX = r2InPoints + x;
-               
+
                //Create the larger arc.
                outerArc.setArcByCenter(circleCenterX, circleCenterY, r2InPoints, 180, theta, Arc2D.OPEN);
-               
+
                //Create the smaller arc.
                innerArc.setArcByCenter(circleCenterX, circleCenterY, r1InPoints, 180, theta, Arc2D.OPEN);
-               
+
                //Create the line between the start of the larger arc and the start of the smaller arc.
                Path2D.Double line = new Path2D.Double();
                line.setWindingRule(Path2D.WIND_NON_ZERO);
                line.moveTo(x, y);
                final int width = r2InPoints - r1InPoints;
                line.lineTo(width + x, y);
-               
+
                //Create the line between the endpoint of the larger arc and the endpoint of the smaller arc.
                Path2D.Double closingLine = new Path2D.Double();
                closingLine.setWindingRule(Path2D.WIND_NON_ZERO);
@@ -138,21 +134,21 @@ public class PrintableTransition extends AbstractPrintableTransition {
                closingLine.moveTo(innerArcEndPoint.getX(), innerArcEndPoint.getY());
                Point2D outerArcEndPoint = outerArc.getEndPoint();
                closingLine.lineTo(outerArcEndPoint.getX(), outerArcEndPoint.getY());
-               
+
                //Add all shapes to the polygon path.
                gp = new Path2D.Float(GeneralPath.WIND_EVEN_ODD, 4);
                gp.append(line, false);
                gp.append(outerArc, false);
                gp.append(closingLine, false);
                gp.append(innerArc, false);
-               
+
                //Create the glue tab.
                glueTab1 = new Path2D.Float(GeneralPath.WIND_EVEN_ODD, 4);
                glueTab1.moveTo(x, y);
                glueTab1.lineTo(x + tabOffset, y - tabOffset);
                glueTab1.lineTo(width + x - tabOffset, y - tabOffset);
                glueTab1.lineTo(width + x, y);
-               
+
                //Create tick marks for alignment, 1/4 of the width in from either edge
                int fromEdge = width / 4;
                final int tickLength = 8;
@@ -160,13 +156,13 @@ public class PrintableTransition extends AbstractPrintableTransition {
                tick1 = new Line2D.Float(x + fromEdge, y, x + fromEdge, y + tickLength);
                //Upper right
                tick2 = new Line2D.Float(x + width - fromEdge, y, x + width - fromEdge, y + tickLength);
-               
+
                tick3X = r2InPoints - fromEdge;
                tick4X = r1InPoints + fromEdge;
-               
+
                setSize(gp.getBounds().width, gp.getBounds().height + tabOffset);
        }
-       
+
        /**
         * Draw alignment marks on an angle.
         *
@@ -183,7 +179,7 @@ public class PrintableTransition extends AbstractPrintableTransition {
                g2.rotate(Math.toRadians(theta));
                g2.translate(-x, -y);
        }
-       
+
        /**
         * Draw a transition.
         *
@@ -203,9 +199,9 @@ public class PrintableTransition extends AbstractPrintableTransition {
                                circleCenterY,
                                new Line2D.Float(-tick4X, 0, -tick4X, -8),
                                theta);
-               
+
                g2.setStroke(dashed);
                g2.draw(glueTab1);
        }
-       
+
 }
diff --git a/core/src/net/sf/openrocket/gui/print/visitor/CenteringRingStrategy.java b/core/src/net/sf/openrocket/gui/print/visitor/CenteringRingStrategy.java
new file mode 100644 (file)
index 0000000..5241c22
--- /dev/null
@@ -0,0 +1,188 @@
+package net.sf.openrocket.gui.print.visitor;
+
+import com.itextpdf.text.Document;
+import com.itextpdf.text.DocumentException;
+import com.itextpdf.text.Rectangle;
+import com.itextpdf.text.pdf.PdfWriter;
+import net.sf.openrocket.gui.print.AbstractPrintable;
+import net.sf.openrocket.gui.print.ITextHelper;
+import net.sf.openrocket.gui.print.PrintableCenteringRing;
+import net.sf.openrocket.logging.LogHelper;
+import net.sf.openrocket.rocketcomponent.CenteringRing;
+import net.sf.openrocket.rocketcomponent.RocketComponent;
+import net.sf.openrocket.startup.Application;
+
+import java.awt.image.BufferedImage;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * A strategy for printing a centering ring to iText.
+ */
+public class CenteringRingStrategy {
+
+    /**
+     * The logger.
+     */
+    private static final LogHelper log = Application.getLogger();
+
+    /**
+     * The iText document.
+     */
+    protected Document document;
+
+    /**
+     * The direct iText writer.
+     */
+    protected PdfWriter writer;
+
+    /**
+     * The stages selected.
+     */
+    protected Set<Integer> stages;
+
+    /**
+     * Strategy for fitting multiple components onto a page.
+     */
+    protected PageFitPrintStrategy pageFitPrint;
+
+    /**
+     * Constructor.
+     *
+     * @param doc              The iText document
+     * @param theWriter        The direct iText writer
+     * @param theStagesToVisit The stages to be visited by this strategy
+     */
+    public CenteringRingStrategy(Document doc, PdfWriter theWriter, Set<Integer> theStagesToVisit, PageFitPrintStrategy pageFit) {
+        document = doc;
+        writer = theWriter;
+        stages = theStagesToVisit;
+        pageFitPrint = pageFit;
+    }
+
+    /**
+     * Recurse through the given rocket component.
+     *
+     * @param root the root component; all children will be visited recursively
+     */
+    public void writeToDocument(final RocketComponent root) {
+        List<RocketComponent> rc = root.getChildren();
+        goDeep(rc);
+    }
+
+
+    /**
+     * Recurse through the given rocket component.
+     *
+     * @param theRc an array of rocket components; all children will be visited recursively
+     */
+    protected void goDeep(final List<RocketComponent> theRc) {
+        for (RocketComponent rocketComponent : theRc) {
+            if (rocketComponent instanceof CenteringRing) {
+                render((CenteringRing) rocketComponent);
+            }
+            else if (rocketComponent.getChildCount() > 0) {
+                goDeep(rocketComponent.getChildren());
+            }
+        }
+    }
+
+    /**
+     * The core behavior of this visitor.
+     *
+     * @param component the object to extract info about; a graphical image of the centering ring shape is drawn to the
+     *                  document
+     */
+    private void render(final CenteringRing component) {
+        try {
+            AbstractPrintable pfs;
+            pfs = new PrintableCenteringRing(component);
+
+            java.awt.Dimension size = pfs.getSize();
+            final Dimension pageSize = getPageSize();
+            if (fitsOnOnePage(pageSize, size.getWidth(), size.getHeight())) {
+                pageFitPrint.addComponent(pfs);
+            }
+            else {
+                BufferedImage image = (BufferedImage) pfs.createImage();
+                ITextHelper.renderImageAcrossPages(new Rectangle(pageSize.getWidth(), pageSize.getHeight()),
+                        document, writer, image);
+            }
+        }
+        catch (DocumentException e) {
+            log.error("Could not render the centering ring.", e);
+        }
+    }
+
+    /**
+     * Determine if the image will fit on the given page.
+     *
+     * @param pageSize the page size
+     * @param wImage   the width of the thing to be printed
+     * @param hImage   the height of the thing to be printed
+     *
+     * @return true if the thing to be printed will fit on a single page
+     */
+    private boolean fitsOnOnePage(Dimension pageSize, double wImage, double hImage) {
+        double wPage = pageSize.getWidth();
+        double hPage = pageSize.getHeight();
+
+        int wRatio = (int) Math.ceil(wImage / wPage);
+        int hRatio = (int) Math.ceil(hImage / hPage);
+
+        return wRatio <= 1.0d && hRatio <= 1.0d;
+    }
+
+    /**
+     * Get the dimensions of the paper page.
+     *
+     * @return an internal Dimension
+     */
+    protected Dimension getPageSize() {
+        return new Dimension(document.getPageSize().getWidth(),
+                document.getPageSize().getHeight());
+    }
+
+    /**
+     * Convenience class to model a dimension.
+     */
+    class Dimension {
+        /**
+         * Width, in points.
+         */
+        public float width;
+        /**
+         * Height, in points.
+         */
+        public float height;
+
+        /**
+         * Constructor.
+         *
+         * @param w width
+         * @param h height
+         */
+        public Dimension(float w, float h) {
+            width = w;
+            height = h;
+        }
+
+        /**
+         * Get the width.
+         *
+         * @return the width
+         */
+        public float getWidth() {
+            return width;
+        }
+
+        /**
+         * Get the height.
+         *
+         * @return the height
+         */
+        public float getHeight() {
+            return height;
+        }
+    }
+}
index bd45045587e9780361591ad8dc2d8ccd425b3343..4752b3a7782c8ba681af3072dfb9d33e166ec874 100644 (file)
@@ -3,9 +3,8 @@ package net.sf.openrocket.gui.print.visitor;
 import com.itextpdf.text.Document;
 import com.itextpdf.text.DocumentException;
 import com.itextpdf.text.Rectangle;
-import com.itextpdf.text.pdf.PdfContentByte;
 import com.itextpdf.text.pdf.PdfWriter;
-import net.sf.openrocket.gui.print.AbstractPrintableTransition;
+import net.sf.openrocket.gui.print.AbstractPrintable;
 import net.sf.openrocket.gui.print.ITextHelper;
 import net.sf.openrocket.gui.print.PrintableNoseCone;
 import net.sf.openrocket.gui.print.PrintableTransition;
@@ -15,7 +14,6 @@ import net.sf.openrocket.rocketcomponent.RocketComponent;
 import net.sf.openrocket.rocketcomponent.Transition;
 import net.sf.openrocket.startup.Application;
 
-import java.awt.*;
 import java.awt.image.BufferedImage;
 import java.util.List;
 import java.util.Set;
@@ -103,9 +101,9 @@ public class TransitionStrategy {
      */
     private void render(final Transition component) {
         try {
-            AbstractPrintableTransition pfs;
+            AbstractPrintable pfs;
             if (component instanceof NoseCone) {
-                pfs = new PrintableNoseCone(component);
+                pfs = new PrintableNoseCone((NoseCone)component);
             } else {
                 pfs = new PrintableTransition(component);
             }
@@ -143,20 +141,6 @@ public class TransitionStrategy {
         return wRatio <= 1.0d && hRatio <= 1.0d;
     }
 
-    /**
-     * Print the transition.
-     *
-     * @param theTransition the printable transition
-     */
-    /*private void printOnOnePage(final AbstractPrintableTransition theTransition) {
-        Dimension d = getPageSize();
-        PdfContentByte cb = writer.getDirectContent();
-        Graphics2D g2 = cb.createGraphics(d.width, d.height);
-        theTransition.print(g2);
-        g2.dispose();
-        document.newPage();
-    }*/
-
     /**
      * Get the dimensions of the paper page.
      *