X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=core%2Fsrc%2Fnet%2Fsf%2Fopenrocket%2Fgui%2Fprint%2Fvisitor%2FPageFitPrintStrategy.java;fp=core%2Fsrc%2Fnet%2Fsf%2Fopenrocket%2Fgui%2Fprint%2Fvisitor%2FPageFitPrintStrategy.java;h=10ca735160b258701136c3a4ded05e3502a11514;hb=9349577cdfdff682b2aabd6daa24fdc3a7449b58;hp=0000000000000000000000000000000000000000;hpb=30ba0a882f0c061176ba14dbf86d3d6fad096c02;p=debian%2Fopenrocket diff --git a/core/src/net/sf/openrocket/gui/print/visitor/PageFitPrintStrategy.java b/core/src/net/sf/openrocket/gui/print/visitor/PageFitPrintStrategy.java new file mode 100644 index 00000000..10ca7351 --- /dev/null +++ b/core/src/net/sf/openrocket/gui/print/visitor/PageFitPrintStrategy.java @@ -0,0 +1,175 @@ +/* + * PageFitPrintStrategy.java + */ +package net.sf.openrocket.gui.print.visitor; + +import com.itextpdf.text.Document; +import com.itextpdf.text.pdf.PdfContentByte; +import com.itextpdf.text.pdf.PdfWriter; +import net.sf.openrocket.gui.print.PrintUnit; +import net.sf.openrocket.gui.print.PrintableComponent; +import net.sf.openrocket.logging.LogHelper; +import net.sf.openrocket.rocketcomponent.RocketComponent; +import net.sf.openrocket.startup.Application; + +import java.awt.Graphics2D; +import java.util.ArrayList; +import java.util.Collections; +import java.util.ListIterator; +import java.util.Set; + +/** + * A strategy for drawing multiple rocket components onto as few pages as possible. + * + * @author Jason Blood + */ +public class PageFitPrintStrategy { + + /** + * 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 stages; + + protected ArrayList componentToPrint; + + /** + * Constructor. + * + * @param doc The iText document + * @param theWriter The direct iText writer + */ + public PageFitPrintStrategy(Document doc, PdfWriter theWriter) { + document = doc; + writer = theWriter; + componentToPrint = new ArrayList(); + } + + /** + * Add a component we want to print. + * + * @param component The component to add for printing + */ + public void addComponent(PrintableComponent component) { + componentToPrint.add(component); + } + + /** + * Recurse through the given rocket component. + * + * @param root the root component; all children will be printed recursively + */ + public void writeToDocument (final RocketComponent root) { + fitPrintComponents(); + } + + /** + * Iterate through the components to print fitting them onto pages as best possible. + */ + private void fitPrintComponents() { + final Dimension pageSize = getPageSize(); + double wPage = pageSize.getWidth(); + double hPage = pageSize.getHeight(); + int marginX = (int)(PrintUnit.POINTS_PER_INCH * 0.3f); + int marginY = (int)(PrintUnit.POINTS_PER_INCH * 0.3f); + PdfContentByte cb = writer.getDirectContent(); + + Collections.sort(componentToPrint); + + while (componentToPrint.size() > 0) { + int pageY = marginY; + Boolean anyAddedToRow; + + Graphics2D g2 = cb.createGraphics(pageSize.width, pageSize.height); + + do { + // Fill the row + int rowX = marginX; + int rowY = pageY; + ListIterator entry = componentToPrint.listIterator(); + anyAddedToRow = false; + + while (entry.hasNext()) { + PrintableComponent component = entry.next(); + java.awt.Dimension dim = component.getSize(); + if ((rowX + dim.width + marginX < wPage) && (rowY + dim.height + marginY < hPage)) { + component.setPrintOffset(rowX, rowY); + rowX += dim.width + marginX; + if (rowY + dim.height + marginY > pageY) { + pageY = rowY + dim.height + marginY; + } + entry.remove(); + component.print(g2); + anyAddedToRow = true; + } + } + pageY += marginY; + } while (anyAddedToRow); + + g2.dispose(); + document.newPage(); + } + } + + /** + * 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; + } + } +}