Merge commit '42b2e5ca519766e37ce6941ba4faecc9691cc403' into upstream
[debian/openrocket] / core / src / net / sf / openrocket / gui / print / visitor / TransitionStrategy.java
index 1988ab8a31a67ca409b5501c8f454426170971e1..b6f1ee04265a7dc63492f79175edc21a6a100e2e 100644 (file)
@@ -3,10 +3,10 @@ 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.PrintUnit;
 import net.sf.openrocket.gui.print.PrintableNoseCone;
 import net.sf.openrocket.gui.print.PrintableTransition;
 import net.sf.openrocket.logging.LogHelper;
@@ -15,7 +15,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;
@@ -45,6 +44,11 @@ public class TransitionStrategy {
      */
     protected Set<Integer> stages;
 
+    /**
+     * Strategy for fitting multiple components onto a page.
+     */
+    protected PageFitPrintStrategy pageFitPrint;
+
     /**
      * Constructor.
      *
@@ -52,10 +56,11 @@ public class TransitionStrategy {
      * @param theWriter        The direct iText writer
      * @param theStagesToVisit The stages to be visited by this strategy
      */
-    public TransitionStrategy(Document doc, PdfWriter theWriter, Set<Integer> theStagesToVisit) {
+    public TransitionStrategy(Document doc, PdfWriter theWriter, Set<Integer> theStagesToVisit, PageFitPrintStrategy pageFit) {
         document = doc;
         writer = theWriter;
         stages = theStagesToVisit;
+        pageFitPrint = pageFit;
     }
 
     /**
@@ -63,10 +68,12 @@ public class TransitionStrategy {
      *
      * @param root      the root component; all children will be visited recursively
      * @param noseCones nose cones are a special form of a transition; if true, then print nose cones
+     *
+     * @return true if a transition/nosecone was rendered
      */
-    public void writeToDocument(final RocketComponent root, boolean noseCones) {
+    public boolean writeToDocument(final RocketComponent root, boolean noseCones) {
         List<RocketComponent> rc = root.getChildren();
-        goDeep(rc, noseCones);
+        return goDeep(rc, noseCones);
     }
 
 
@@ -75,47 +82,62 @@ public class TransitionStrategy {
      *
      * @param theRc     an array of rocket components; all children will be visited recursively
      * @param noseCones nose cones are a special form of a transition; if true, then print nose cones
+     *
+     * @return true if a transition/nosecone was rendered
      */
-    protected void goDeep(final List<RocketComponent> theRc, boolean noseCones) {
+    protected boolean goDeep(final List<RocketComponent> theRc, boolean noseCones) {
         for (RocketComponent rocketComponent : theRc) {
             if (rocketComponent instanceof NoseCone) {
                 if (noseCones) {
-                    render((Transition) rocketComponent);
+                    return render((Transition) rocketComponent);
                 }
-            } else if (rocketComponent instanceof Transition && !noseCones) {
-                render((Transition) rocketComponent);
-            } else if (rocketComponent.getChildCount() > 0) {
-                goDeep(rocketComponent.getChildren(), noseCones);
+            }
+            else if (rocketComponent instanceof Transition && !noseCones) {
+                return render((Transition) rocketComponent);
+            }
+            else if (rocketComponent.getChildCount() > 0) {
+                return goDeep(rocketComponent.getChildren(), noseCones);
             }
         }
+        return false;
     }
 
     /**
      * The core behavior of this visitor.
      *
-     * @param component the object to extract info about; a graphical image of the transition shape is drawn to the document
+     * @param component the object to extract info about; a graphical image of the transition shape is drawn to the
+     *                  document
+     *
+     * @return true, always
      */
-    private void render(final Transition component) {
+    private boolean render(final Transition component) {
         try {
-            AbstractPrintableTransition pfs;
+            AbstractPrintable pfs;
             if (component instanceof NoseCone) {
-                pfs = new PrintableNoseCone(component);
-            } else {
+                pfs = new PrintableNoseCone((NoseCone) component);
+            }
+            else {
                 pfs = new PrintableTransition(component);
             }
 
             java.awt.Dimension size = pfs.getSize();
             final Dimension pageSize = getPageSize();
             if (fitsOnOnePage(pageSize, size.getWidth(), size.getHeight())) {
-                printOnOnePage(pfs);
-            } else {
+                pageFitPrint.addComponent(pfs);
+            }
+            else {
+                int off = (int) (PrintUnit.POINTS_PER_INCH * 0.3f);
+                pfs.setPrintOffset(off, off);
                 BufferedImage image = (BufferedImage) pfs.createImage();
                 ITextHelper.renderImageAcrossPages(new Rectangle(pageSize.getWidth(), pageSize.getHeight()),
                         document, writer, image);
+                document.newPage();
             }
-        } catch (DocumentException e) {
+        }
+        catch (DocumentException e) {
             log.error("Could not render the transition.", e);
         }
+        return true;
     }
 
     /**
@@ -124,6 +146,7 @@ public class TransitionStrategy {
      * @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) {
@@ -136,20 +159,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.
      *