Merge pull request #30 from rodinia814/printing
Printing fixes; added Save As file to MRU
This commit is contained in:
commit
e31f94ed99
@ -1,63 +1,5 @@
|
|||||||
package net.sf.openrocket.gui.main;
|
package net.sf.openrocket.gui.main;
|
||||||
|
|
||||||
import java.awt.Dimension;
|
|
||||||
import java.awt.Font;
|
|
||||||
import java.awt.Toolkit;
|
|
||||||
import java.awt.Window;
|
|
||||||
import java.awt.event.ActionEvent;
|
|
||||||
import java.awt.event.ActionListener;
|
|
||||||
import java.awt.event.KeyEvent;
|
|
||||||
import java.awt.event.MouseAdapter;
|
|
||||||
import java.awt.event.MouseEvent;
|
|
||||||
import java.awt.event.MouseListener;
|
|
||||||
import java.awt.event.WindowAdapter;
|
|
||||||
import java.awt.event.WindowEvent;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
import java.net.URI;
|
|
||||||
import java.net.URISyntaxException;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.net.URLDecoder;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
|
|
||||||
import javax.swing.Action;
|
|
||||||
import javax.swing.BorderFactory;
|
|
||||||
import javax.swing.InputMap;
|
|
||||||
import javax.swing.JButton;
|
|
||||||
import javax.swing.JComponent;
|
|
||||||
import javax.swing.JDialog;
|
|
||||||
import javax.swing.JFileChooser;
|
|
||||||
import javax.swing.JFrame;
|
|
||||||
import javax.swing.JMenu;
|
|
||||||
import javax.swing.JMenuBar;
|
|
||||||
import javax.swing.JMenuItem;
|
|
||||||
import javax.swing.JOptionPane;
|
|
||||||
import javax.swing.JPanel;
|
|
||||||
import javax.swing.JPopupMenu;
|
|
||||||
import javax.swing.JScrollPane;
|
|
||||||
import javax.swing.JSpinner;
|
|
||||||
import javax.swing.JSplitPane;
|
|
||||||
import javax.swing.JTabbedPane;
|
|
||||||
import javax.swing.JTextField;
|
|
||||||
import javax.swing.KeyStroke;
|
|
||||||
import javax.swing.ListSelectionModel;
|
|
||||||
import javax.swing.ScrollPaneConstants;
|
|
||||||
import javax.swing.SwingUtilities;
|
|
||||||
import javax.swing.border.BevelBorder;
|
|
||||||
import javax.swing.border.TitledBorder;
|
|
||||||
import javax.swing.event.TreeSelectionEvent;
|
|
||||||
import javax.swing.event.TreeSelectionListener;
|
|
||||||
import javax.swing.tree.DefaultTreeSelectionModel;
|
|
||||||
import javax.swing.tree.TreePath;
|
|
||||||
import javax.swing.tree.TreeSelectionModel;
|
|
||||||
|
|
||||||
import net.miginfocom.swing.MigLayout;
|
import net.miginfocom.swing.MigLayout;
|
||||||
import net.sf.openrocket.aerodynamics.WarningSet;
|
import net.sf.openrocket.aerodynamics.WarningSet;
|
||||||
import net.sf.openrocket.document.OpenRocketDocument;
|
import net.sf.openrocket.document.OpenRocketDocument;
|
||||||
@ -107,6 +49,63 @@ import net.sf.openrocket.util.MemoryManagement.MemoryData;
|
|||||||
import net.sf.openrocket.util.Reflection;
|
import net.sf.openrocket.util.Reflection;
|
||||||
import net.sf.openrocket.util.TestRockets;
|
import net.sf.openrocket.util.TestRockets;
|
||||||
|
|
||||||
|
import javax.swing.Action;
|
||||||
|
import javax.swing.BorderFactory;
|
||||||
|
import javax.swing.InputMap;
|
||||||
|
import javax.swing.JButton;
|
||||||
|
import javax.swing.JComponent;
|
||||||
|
import javax.swing.JDialog;
|
||||||
|
import javax.swing.JFileChooser;
|
||||||
|
import javax.swing.JFrame;
|
||||||
|
import javax.swing.JMenu;
|
||||||
|
import javax.swing.JMenuBar;
|
||||||
|
import javax.swing.JMenuItem;
|
||||||
|
import javax.swing.JOptionPane;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.JPopupMenu;
|
||||||
|
import javax.swing.JScrollPane;
|
||||||
|
import javax.swing.JSpinner;
|
||||||
|
import javax.swing.JSplitPane;
|
||||||
|
import javax.swing.JTabbedPane;
|
||||||
|
import javax.swing.JTextField;
|
||||||
|
import javax.swing.KeyStroke;
|
||||||
|
import javax.swing.ListSelectionModel;
|
||||||
|
import javax.swing.ScrollPaneConstants;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
|
import javax.swing.border.BevelBorder;
|
||||||
|
import javax.swing.border.TitledBorder;
|
||||||
|
import javax.swing.event.TreeSelectionEvent;
|
||||||
|
import javax.swing.event.TreeSelectionListener;
|
||||||
|
import javax.swing.tree.DefaultTreeSelectionModel;
|
||||||
|
import javax.swing.tree.TreePath;
|
||||||
|
import javax.swing.tree.TreeSelectionModel;
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.Font;
|
||||||
|
import java.awt.Toolkit;
|
||||||
|
import java.awt.Window;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
import java.awt.event.KeyEvent;
|
||||||
|
import java.awt.event.MouseAdapter;
|
||||||
|
import java.awt.event.MouseEvent;
|
||||||
|
import java.awt.event.MouseListener;
|
||||||
|
import java.awt.event.WindowAdapter;
|
||||||
|
import java.awt.event.WindowEvent;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLDecoder;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
|
||||||
public class BasicFrame extends JFrame {
|
public class BasicFrame extends JFrame {
|
||||||
private static final LogHelper log = Application.getLogger();
|
private static final LogHelper log = Application.getLogger();
|
||||||
|
|
||||||
@ -1329,7 +1328,12 @@ public class BasicFrame extends JFrame {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
file = FileHelper.forceExtension(file, "ork");
|
file = FileHelper.forceExtension(file, "ork");
|
||||||
return FileHelper.confirmWrite(file, this) && saveAs(file);
|
boolean result = FileHelper.confirmWrite(file, this) && saveAs(file);
|
||||||
|
if (result) {
|
||||||
|
MRUDesignFile opts = MRUDesignFile.getInstance();
|
||||||
|
opts.addFile(file.getAbsolutePath());
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,11 +22,10 @@ public abstract class AbstractPrintable<T> extends PrintableComponent {
|
|||||||
/**
|
/**
|
||||||
* Constructor. Initialize this printable with the component to be printed.
|
* Constructor. Initialize this printable with the component to be printed.
|
||||||
*
|
*
|
||||||
* @param isDoubleBuffered a boolean, true for double-buffering
|
* @param component the component to be printed
|
||||||
* @param transition the component to be printed
|
|
||||||
*/
|
*/
|
||||||
public AbstractPrintable(boolean isDoubleBuffered, T transition) {
|
public AbstractPrintable(T component) {
|
||||||
init(transition);
|
init(component);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -50,8 +49,8 @@ public abstract class AbstractPrintable<T> extends PrintableComponent {
|
|||||||
* @return an awt image of the printable component
|
* @return an awt image of the printable component
|
||||||
*/
|
*/
|
||||||
public Image createImage() {
|
public Image createImage() {
|
||||||
int width = getWidth() + getOffsetX();
|
int width = getWidth();
|
||||||
int height = getHeight() + getOffsetY();
|
int height = getHeight();
|
||||||
// Create a buffered image in which to draw
|
// Create a buffered image in which to draw
|
||||||
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
|
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
|
||||||
// Create a graphics contents on the buffered image
|
// Create a graphics contents on the buffered image
|
||||||
@ -73,8 +72,12 @@ public abstract class AbstractPrintable<T> extends PrintableComponent {
|
|||||||
|
|
||||||
g2.setColor(Color.BLACK);
|
g2.setColor(Color.BLACK);
|
||||||
g2.setStroke(thinStroke);
|
g2.setStroke(thinStroke);
|
||||||
g2.translate(getOffsetX(), getOffsetY());
|
translate(g2);
|
||||||
|
|
||||||
draw(g2);
|
draw(g2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void translate(final Graphics2D theG2) {
|
||||||
|
theG2.translate(getOffsetX(), getOffsetY());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,9 +3,6 @@
|
|||||||
*/
|
*/
|
||||||
package net.sf.openrocket.gui.print;
|
package net.sf.openrocket.gui.print;
|
||||||
|
|
||||||
import java.awt.Graphics2D;
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
|
|
||||||
import com.itextpdf.text.Chunk;
|
import com.itextpdf.text.Chunk;
|
||||||
import com.itextpdf.text.Document;
|
import com.itextpdf.text.Document;
|
||||||
import com.itextpdf.text.DocumentException;
|
import com.itextpdf.text.DocumentException;
|
||||||
@ -19,24 +16,29 @@ import com.itextpdf.text.pdf.PdfPCell;
|
|||||||
import com.itextpdf.text.pdf.PdfPTable;
|
import com.itextpdf.text.pdf.PdfPTable;
|
||||||
import com.itextpdf.text.pdf.PdfWriter;
|
import com.itextpdf.text.pdf.PdfWriter;
|
||||||
|
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A bunch of helper methods for creating iText components.
|
* A bunch of helper methods for creating iText components.
|
||||||
*/
|
*/
|
||||||
public final class ITextHelper {
|
public final class ITextHelper {
|
||||||
|
|
||||||
public static BaseFont getBaseFont(){
|
public static BaseFont getBaseFont() {
|
||||||
try {
|
try {
|
||||||
return BaseFont.createFont("/dejavu-font/DejaVuSerif.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
|
return BaseFont.createFont("/dejavu-font/DejaVuSerif.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
|
||||||
} catch (Exception ex ) {
|
}
|
||||||
throw new RuntimeException(ex);
|
catch (Exception ex) {
|
||||||
}
|
throw new RuntimeException(ex);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a cell for an iText table.
|
* Create a cell for an iText table.
|
||||||
*
|
*
|
||||||
* @return a cell with bottom border
|
* @return a cell with bottom border
|
||||||
*/
|
*/
|
||||||
public static PdfPCell createCell () {
|
public static PdfPCell createCell() {
|
||||||
return createCell(Rectangle.BOTTOM);
|
return createCell(Rectangle.BOTTOM);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,7 +49,7 @@ public final class ITextHelper {
|
|||||||
*
|
*
|
||||||
* @return a cell with given border
|
* @return a cell with given border
|
||||||
*/
|
*/
|
||||||
public static PdfPCell createCell (int border) {
|
public static PdfPCell createCell(int border) {
|
||||||
PdfPCell result = new PdfPCell();
|
PdfPCell result = new PdfPCell();
|
||||||
result.setBorder(border);
|
result.setBorder(border);
|
||||||
|
|
||||||
@ -61,7 +63,7 @@ public final class ITextHelper {
|
|||||||
*
|
*
|
||||||
* @return the cell containing a table
|
* @return the cell containing a table
|
||||||
*/
|
*/
|
||||||
public static PdfPCell createCell (PdfPTable table) {
|
public static PdfPCell createCell(PdfPTable table) {
|
||||||
PdfPCell result = new PdfPCell();
|
PdfPCell result = new PdfPCell();
|
||||||
result.setBorder(PdfPCell.NO_BORDER);
|
result.setBorder(PdfPCell.NO_BORDER);
|
||||||
result.addElement(table);
|
result.addElement(table);
|
||||||
@ -76,7 +78,7 @@ public final class ITextHelper {
|
|||||||
*
|
*
|
||||||
* @return the cell containing the text
|
* @return the cell containing the text
|
||||||
*/
|
*/
|
||||||
public static PdfPCell createCell (String v) {
|
public static PdfPCell createCell(String v) {
|
||||||
return createCell(v, Rectangle.NO_BORDER, PrintUtilities.NORMAL);
|
return createCell(v, Rectangle.NO_BORDER, PrintUtilities.NORMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,7 +90,7 @@ public final class ITextHelper {
|
|||||||
*
|
*
|
||||||
* @return the cell containing the text
|
* @return the cell containing the text
|
||||||
*/
|
*/
|
||||||
public static PdfPCell createCell (String v, Font font) {
|
public static PdfPCell createCell(String v, Font font) {
|
||||||
return createCell(v, Rectangle.NO_BORDER, font);
|
return createCell(v, Rectangle.NO_BORDER, font);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,7 +103,7 @@ public final class ITextHelper {
|
|||||||
*
|
*
|
||||||
* @return the cell containing the text
|
* @return the cell containing the text
|
||||||
*/
|
*/
|
||||||
public static PdfPCell createCell (String v, int leftPad, int rightPad) {
|
public static PdfPCell createCell(String v, int leftPad, int rightPad) {
|
||||||
PdfPCell c = createCell(v, Rectangle.NO_BORDER, PrintUtilities.NORMAL);
|
PdfPCell c = createCell(v, Rectangle.NO_BORDER, PrintUtilities.NORMAL);
|
||||||
c.setPaddingLeft(leftPad);
|
c.setPaddingLeft(leftPad);
|
||||||
c.setPaddingRight(rightPad);
|
c.setPaddingRight(rightPad);
|
||||||
@ -116,13 +118,12 @@ public final class ITextHelper {
|
|||||||
*
|
*
|
||||||
* @return the cell containing the text
|
* @return the cell containing the text
|
||||||
*/
|
*/
|
||||||
public static PdfPCell createCell (String v, int border) {
|
public static PdfPCell createCell(String v, int border) {
|
||||||
return createCell(v, border, PrintUtilities.NORMAL);
|
return createCell(v, border, PrintUtilities.NORMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Complete create cell - fully qualified. Create a cell whose contents are the given string with the given border
|
* Complete create cell - fully qualified. Create a cell whose contents are the given string with the given border and font.
|
||||||
* and font.
|
|
||||||
*
|
*
|
||||||
* @param v the text of the cell
|
* @param v the text of the cell
|
||||||
* @param border the border type
|
* @param border the border type
|
||||||
@ -130,7 +131,7 @@ public final class ITextHelper {
|
|||||||
*
|
*
|
||||||
* @return the cell containing the text
|
* @return the cell containing the text
|
||||||
*/
|
*/
|
||||||
public static PdfPCell createCell (String v, int border, Font font) {
|
public static PdfPCell createCell(String v, int border, Font font) {
|
||||||
PdfPCell result = new PdfPCell();
|
PdfPCell result = new PdfPCell();
|
||||||
result.setBorder(border);
|
result.setBorder(border);
|
||||||
Chunk c = new Chunk();
|
Chunk c = new Chunk();
|
||||||
@ -148,7 +149,7 @@ public final class ITextHelper {
|
|||||||
*
|
*
|
||||||
* @return an iText phrase
|
* @return an iText phrase
|
||||||
*/
|
*/
|
||||||
public static Phrase createPhrase (String text, Font font) {
|
public static Phrase createPhrase(String text, Font font) {
|
||||||
Phrase p = new Phrase();
|
Phrase p = new Phrase();
|
||||||
final Chunk chunk = new Chunk(text);
|
final Chunk chunk = new Chunk(text);
|
||||||
chunk.setFont(font);
|
chunk.setFont(font);
|
||||||
@ -163,7 +164,7 @@ public final class ITextHelper {
|
|||||||
*
|
*
|
||||||
* @return an iText phrase
|
* @return an iText phrase
|
||||||
*/
|
*/
|
||||||
public static Phrase createPhrase (String text) {
|
public static Phrase createPhrase(String text) {
|
||||||
return createPhrase(text, PrintUtilities.NORMAL);
|
return createPhrase(text, PrintUtilities.NORMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,7 +176,7 @@ public final class ITextHelper {
|
|||||||
*
|
*
|
||||||
* @return an iText paragraph
|
* @return an iText paragraph
|
||||||
*/
|
*/
|
||||||
public static Paragraph createParagraph (String text, Font font) {
|
public static Paragraph createParagraph(String text, Font font) {
|
||||||
Paragraph p = new Paragraph();
|
Paragraph p = new Paragraph();
|
||||||
final Chunk chunk = new Chunk(text);
|
final Chunk chunk = new Chunk(text);
|
||||||
chunk.setFont(font);
|
chunk.setFont(font);
|
||||||
@ -190,14 +191,13 @@ public final class ITextHelper {
|
|||||||
*
|
*
|
||||||
* @return an iText paragraph
|
* @return an iText paragraph
|
||||||
*/
|
*/
|
||||||
public static Paragraph createParagraph (String text) {
|
public static Paragraph createParagraph(String text) {
|
||||||
return createParagraph(text, PrintUtilities.NORMAL);
|
return createParagraph(text, PrintUtilities.NORMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Break a large image up into page-size pieces and output each page in order to an iText document. The image is
|
* Break a large image up into page-size pieces and output each page in order to an iText document. The image is overlayed with an matrix of pages
|
||||||
* overlayed with an matrix of pages running from left to right until the right side of the image is reached. Then
|
* running from left to right until the right side of the image is reached. Then the next 'row' of pages is output from left to right, and so on.
|
||||||
* the next 'row' of pages is output from left to right, and so on.
|
|
||||||
*
|
*
|
||||||
* @param pageSize a rectangle that defines the bounds of the page size
|
* @param pageSize a rectangle that defines the bounds of the page size
|
||||||
* @param doc the iText document
|
* @param doc the iText document
|
||||||
@ -206,9 +206,9 @@ public final class ITextHelper {
|
|||||||
*
|
*
|
||||||
* @throws DocumentException thrown if the document could not be written
|
* @throws DocumentException thrown if the document could not be written
|
||||||
*/
|
*/
|
||||||
public static void renderImageAcrossPages (Rectangle pageSize, Document doc, PdfWriter writer, java.awt.Image image)
|
public static void renderImageAcrossPages(Rectangle pageSize, Document doc, PdfWriter writer, java.awt.Image image)
|
||||||
throws DocumentException {
|
throws DocumentException {
|
||||||
final int margin = (int)Math.min(doc.topMargin(), PrintUnit.POINTS_PER_INCH * 0.3f);
|
final int margin = (int) Math.min(doc.topMargin(), PrintUnit.POINTS_PER_INCH * 0.3f);
|
||||||
float wPage = pageSize.getWidth() - 2 * margin;
|
float wPage = pageSize.getWidth() - 2 * margin;
|
||||||
float hPage = pageSize.getHeight() - 2 * margin;
|
float hPage = pageSize.getHeight() - 2 * margin;
|
||||||
|
|
||||||
@ -218,7 +218,7 @@ public final class ITextHelper {
|
|||||||
hImage));
|
hImage));
|
||||||
PdfContentByte content = writer.getDirectContent();
|
PdfContentByte content = writer.getDirectContent();
|
||||||
|
|
||||||
int ymargin = 0;
|
int ymargin = margin;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
BufferedImage subImage = ((BufferedImage) image).getSubimage((int) crop.getX(), (int) crop.getY(),
|
BufferedImage subImage = ((BufferedImage) image).getSubimage((int) crop.getX(), (int) crop.getY(),
|
||||||
@ -228,20 +228,21 @@ public final class ITextHelper {
|
|||||||
g2.drawImage(subImage, margin, ymargin, null);
|
g2.drawImage(subImage, margin, ymargin, null);
|
||||||
g2.dispose();
|
g2.dispose();
|
||||||
|
|
||||||
// After the first page, the y-margin needs to be set.
|
final int newImageX = (int) (crop.getWidth() + crop.getX());
|
||||||
ymargin = margin;
|
|
||||||
|
|
||||||
final int newX = (int) (crop.getWidth() + crop.getX());
|
if (newImageX < wImage) {
|
||||||
if (newX < wImage) {
|
//Spans multiple pages horizontally
|
||||||
double adjust = Math.min(wImage - newX, wPage);
|
double subImageWidth = Math.min(wImage - newImageX, wPage);
|
||||||
crop = new java.awt.Rectangle(newX, (int) crop.getY(), (int) adjust,
|
crop = new java.awt.Rectangle(newImageX, (int) crop.getY(), (int) subImageWidth,
|
||||||
(int) crop.getHeight());
|
(int) crop.getHeight());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
final int newY = (int) (crop.getHeight() + crop.getY());
|
//Spans multiple pages vertically
|
||||||
if (newY < hImage) {
|
final int newImageY = (int) (crop.getHeight() + crop.getY());
|
||||||
double adjust = Math.min(hImage - newY, hPage);
|
|
||||||
crop = new java.awt.Rectangle(0, newY, (int) Math.min(wPage, wImage), (int) adjust);
|
if (newImageY < hImage) {
|
||||||
|
double subImageHeight = Math.min(hImage - newImageY, hPage);
|
||||||
|
crop = new java.awt.Rectangle(0, newImageY, (int) Math.min(wPage, wImage), (int) subImageHeight);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
break;
|
break;
|
||||||
|
@ -89,15 +89,15 @@ public class PrintController {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case TRANSITION_TEMPLATE:
|
case TRANSITION_TEMPLATE:
|
||||||
final TransitionStrategy tranWriter = new TransitionStrategy(idoc, writer, stages, pageFitPrint);
|
final TransitionStrategy tranWriter = new TransitionStrategy(idoc, writer, stages, pageFitPrint, false);
|
||||||
if (tranWriter.writeToDocument(doc.getRocket(), false)) {
|
if (tranWriter.writeToDocument(doc.getRocket())) {
|
||||||
addRule = true;
|
addRule = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NOSE_CONE_TEMPLATE:
|
case NOSE_CONE_TEMPLATE:
|
||||||
final TransitionStrategy coneWriter = new TransitionStrategy(idoc, writer, stages, pageFitPrint);
|
final TransitionStrategy coneWriter = new TransitionStrategy(idoc, writer, stages, pageFitPrint, true);
|
||||||
if (coneWriter.writeToDocument(doc.getRocket(), true)) {
|
if (coneWriter.writeToDocument(doc.getRocket())) {
|
||||||
addRule = true;
|
addRule = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -124,7 +124,7 @@ public class PrintController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Write out parts that we are going to combine onto single sheets of paper
|
// Write out parts that we are going to combine onto single sheets of paper
|
||||||
pageFitPrint.writeToDocument(doc.getRocket());
|
pageFitPrint.writeToDocument();
|
||||||
idoc.newPage();
|
idoc.newPage();
|
||||||
|
|
||||||
//Stupid iText throws a really nasty exception if there is no data when close is called.
|
//Stupid iText throws a really nasty exception if there is no data when close is called.
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package net.sf.openrocket.gui.print;
|
package net.sf.openrocket.gui.print;
|
||||||
|
|
||||||
import net.sf.openrocket.gui.print.visitor.CenteringRingStrategy;
|
import net.sf.openrocket.gui.print.visitor.Dimension;
|
||||||
import net.sf.openrocket.rocketcomponent.CenteringRing;
|
import net.sf.openrocket.rocketcomponent.CenteringRing;
|
||||||
import net.sf.openrocket.rocketcomponent.ClusterConfiguration;
|
import net.sf.openrocket.rocketcomponent.ClusterConfiguration;
|
||||||
import net.sf.openrocket.rocketcomponent.InnerTube;
|
import net.sf.openrocket.rocketcomponent.InnerTube;
|
||||||
@ -34,7 +34,7 @@ public class PrintableCenteringRing extends AbstractPrintable<CenteringRing> {
|
|||||||
/**
|
/**
|
||||||
* A set of the inner 'holes'. At least one, but will have many if clustered.
|
* A set of the inner 'holes'. At least one, but will have many if clustered.
|
||||||
*/
|
*/
|
||||||
private Set<CenteringRingStrategy.Dimension> innerCenterPoints = new HashSet<CenteringRingStrategy.Dimension>();
|
private Set<Dimension> innerCenterPoints = new HashSet<Dimension>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a simple, non-clustered, printable centering ring, or if the motor mount represents a clustered
|
* Construct a simple, non-clustered, printable centering ring, or if the motor mount represents a clustered
|
||||||
@ -44,12 +44,12 @@ public class PrintableCenteringRing extends AbstractPrintable<CenteringRing> {
|
|||||||
* @param theMotorMount the motor mount if clustered, else null
|
* @param theMotorMount the motor mount if clustered, else null
|
||||||
*/
|
*/
|
||||||
private PrintableCenteringRing(CenteringRing theRing, InnerTube theMotorMount) {
|
private PrintableCenteringRing(CenteringRing theRing, InnerTube theMotorMount) {
|
||||||
super(false, theRing);
|
super(theRing);
|
||||||
if (theMotorMount == null || theMotorMount.getClusterConfiguration().equals(ClusterConfiguration.SINGLE)) {
|
if (theMotorMount == null || theMotorMount.getClusterConfiguration().equals(ClusterConfiguration.SINGLE)) {
|
||||||
//Single motor.
|
//Single motor.
|
||||||
final float v = (float) PrintUnit.METERS.toPoints(target.getOuterRadius());
|
final float v = (float) PrintUnit.METERS.toPoints(target.getOuterRadius());
|
||||||
innerCenterPoints.add(
|
innerCenterPoints.add(
|
||||||
new CenteringRingStrategy.Dimension(v, v,
|
new Dimension(v, v,
|
||||||
(float) PrintUnit.METERS.toPoints((target.getInnerRadius()))));
|
(float) PrintUnit.METERS.toPoints((target.getInnerRadius()))));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -70,7 +70,7 @@ public class PrintableCenteringRing extends AbstractPrintable<CenteringRing> {
|
|||||||
* @param theMotorMounts a list of the motor mount tubes that are physically supported by the centering ring
|
* @param theMotorMounts a list of the motor mount tubes that are physically supported by the centering ring
|
||||||
*/
|
*/
|
||||||
private PrintableCenteringRing(CenteringRing theRing, List<InnerTube> theMotorMounts) {
|
private PrintableCenteringRing(CenteringRing theRing, List<InnerTube> theMotorMounts) {
|
||||||
super(false, theRing);
|
super(theRing);
|
||||||
List<Coordinate> points = new ArrayList<Coordinate>();
|
List<Coordinate> points = new ArrayList<Coordinate>();
|
||||||
//Transform the radial positions of the tubes.
|
//Transform the radial positions of the tubes.
|
||||||
for (InnerTube it : theMotorMounts) {
|
for (InnerTube it : theMotorMounts) {
|
||||||
@ -117,7 +117,7 @@ public class PrintableCenteringRing extends AbstractPrintable<CenteringRing> {
|
|||||||
private void populateCenterPoints(final List<Coordinate> theCoords) {
|
private void populateCenterPoints(final List<Coordinate> theCoords) {
|
||||||
float radius = (float) PrintUnit.METERS.toPoints(target.getOuterRadius());
|
float radius = (float) PrintUnit.METERS.toPoints(target.getOuterRadius());
|
||||||
for (Coordinate coordinate : theCoords) {
|
for (Coordinate coordinate : theCoords) {
|
||||||
innerCenterPoints.add(new CenteringRingStrategy.Dimension(
|
innerCenterPoints.add(new Dimension(
|
||||||
(float) PrintUnit.METERS.toPoints(coordinate.y) + radius, //center point x
|
(float) PrintUnit.METERS.toPoints(coordinate.y) + radius, //center point x
|
||||||
(float) PrintUnit.METERS.toPoints(coordinate.z) + radius, //center point y
|
(float) PrintUnit.METERS.toPoints(coordinate.z) + radius, //center point y
|
||||||
(float) PrintUnit.METERS.toPoints(coordinate.x))); //radius of motor mount
|
(float) PrintUnit.METERS.toPoints(coordinate.x))); //radius of motor mount
|
||||||
@ -153,7 +153,7 @@ public class PrintableCenteringRing extends AbstractPrintable<CenteringRing> {
|
|||||||
g2.setColor(Color.black);
|
g2.setColor(Color.black);
|
||||||
g2.draw(outerCircle);
|
g2.draw(outerCircle);
|
||||||
|
|
||||||
for (CenteringRingStrategy.Dimension next : innerCenterPoints) {
|
for (Dimension next : innerCenterPoints) {
|
||||||
drawInnerCircle(g2, next.getWidth(), next.getHeight(), next.getBreadth());
|
drawInnerCircle(g2, next.getWidth(), next.getHeight(), next.getBreadth());
|
||||||
}
|
}
|
||||||
g2.setColor(original);
|
g2.setColor(original);
|
||||||
|
@ -92,7 +92,6 @@ public class PrintableComponent extends JPanel implements Printable, Comparable<
|
|||||||
return offsetY;
|
return offsetY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compares this object with the specified object for order. Returns a negative integer, zero, or a positive integer
|
* Compares this object with the specified object for order. Returns a negative integer, zero, or a positive integer
|
||||||
* as this object is less than, equal to, or greater than the specified object.
|
* as this object is less than, equal to, or greater than the specified object.
|
||||||
|
@ -6,33 +6,29 @@ package net.sf.openrocket.gui.print;
|
|||||||
import net.sf.openrocket.rocketcomponent.FinSet;
|
import net.sf.openrocket.rocketcomponent.FinSet;
|
||||||
import net.sf.openrocket.util.Coordinate;
|
import net.sf.openrocket.util.Coordinate;
|
||||||
|
|
||||||
import java.awt.Color;
|
|
||||||
import java.awt.Graphics;
|
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
import java.awt.Image;
|
|
||||||
import java.awt.geom.GeneralPath;
|
import java.awt.geom.GeneralPath;
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class allows for a FinSet to be printable. It does so by decorating an existing finset (which will not be
|
* This class allows for a FinSet to be printable. It does so by decorating an existing finset (which will not be
|
||||||
* modified) and rendering it within a JPanel. The JPanel is not actually visualized on a display, but instead renders
|
* modified) and rendering it within a JPanel. The JPanel is not actually visualized on a display, but instead renders
|
||||||
* it to a print device.
|
* it to a print device.
|
||||||
*/
|
*/
|
||||||
public class PrintableFinSet extends PrintableComponent {
|
public class PrintableFinSet extends AbstractPrintable<FinSet> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The object that represents the shape (outline) of the fin. This gets drawn onto the Swing component.
|
* The object that represents the shape (outline) of the fin. This gets drawn onto the Swing component.
|
||||||
*/
|
*/
|
||||||
protected GeneralPath polygon = null;
|
protected GeneralPath polygon;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The minimum X coordinate.
|
* The minimum X coordinate.
|
||||||
*/
|
*/
|
||||||
private int minX = 0;
|
private int minX;
|
||||||
/**
|
/**
|
||||||
* The minimum Y coordinate.
|
* The minimum Y coordinate.
|
||||||
*/
|
*/
|
||||||
private int minY = 0;
|
private int minY;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
@ -40,28 +36,23 @@ public class PrintableFinSet extends PrintableComponent {
|
|||||||
* @param fs the finset to print
|
* @param fs the finset to print
|
||||||
*/
|
*/
|
||||||
public PrintableFinSet (FinSet fs) {
|
public PrintableFinSet (FinSet fs) {
|
||||||
this(fs.getFinPointsWithTab());
|
super(fs);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Construct a fin set from a set of points.
|
|
||||||
*
|
|
||||||
* @param points an array of points.
|
|
||||||
*/
|
|
||||||
public PrintableFinSet (Coordinate[] points) {
|
|
||||||
init(points);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the fin set polygon and set the size of the component.
|
* Initialize the fin set polygon and set the size of the component.
|
||||||
*
|
*
|
||||||
* @param points an array of points.
|
* @param component the fin set
|
||||||
*/
|
*/
|
||||||
private void init (Coordinate[] points) {
|
protected void init (FinSet component) {
|
||||||
|
|
||||||
|
Coordinate[] points = component.getFinPointsWithTab();
|
||||||
|
|
||||||
polygon = new GeneralPath(GeneralPath.WIND_EVEN_ODD, points.length);
|
polygon = new GeneralPath(GeneralPath.WIND_EVEN_ODD, points.length);
|
||||||
polygon.moveTo(0, 0);
|
polygon.moveTo(0, 0);
|
||||||
|
|
||||||
|
minX = 0;
|
||||||
|
minY = 0;
|
||||||
int maxX = 0;
|
int maxX = 0;
|
||||||
int maxY = 0;
|
int maxY = 0;
|
||||||
|
|
||||||
@ -76,29 +67,7 @@ public class PrintableFinSet extends PrintableComponent {
|
|||||||
}
|
}
|
||||||
polygon.closePath();
|
polygon.closePath();
|
||||||
|
|
||||||
setSize(maxX - minX, maxY - minY);
|
setSize(maxX - minX + 1, maxY - minY + 1);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a generated image of the fin set. 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();
|
|
||||||
int height = getHeight();
|
|
||||||
// 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -106,12 +75,9 @@ public class PrintableFinSet extends PrintableComponent {
|
|||||||
* outline of the fin set coordinates to create a polygon, which is then drawn onto the graphics context.
|
* outline of the fin set coordinates to create a polygon, which is then drawn onto the graphics context.
|
||||||
* Through-the-wall fin tabs are supported if they are present.
|
* Through-the-wall fin tabs are supported if they are present.
|
||||||
*
|
*
|
||||||
* @param g the Java2D graphics context
|
* @param g2d the Java2D graphics context
|
||||||
*/
|
*/
|
||||||
@Override
|
protected void draw(Graphics2D g2d) {
|
||||||
public void paintComponent(Graphics g) {
|
|
||||||
Graphics2D g2d = (Graphics2D) g;
|
|
||||||
|
|
||||||
int x = 0;
|
int x = 0;
|
||||||
int y = 0;
|
int y = 0;
|
||||||
|
|
||||||
@ -132,4 +98,13 @@ public class PrintableFinSet extends PrintableComponent {
|
|||||||
g2d.setPaint(TemplateProperties.getLineColor());
|
g2d.setPaint(TemplateProperties.getLineColor());
|
||||||
g2d.draw(polygon);
|
g2d.draw(polygon);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Don't let super class translate the coordinates - we'll do that ourselves in the draw method.
|
||||||
|
*
|
||||||
|
* @param theG2 the graphics context
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void translate(final Graphics2D theG2) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package net.sf.openrocket.gui.print;
|
package net.sf.openrocket.gui.print;
|
||||||
|
|
||||||
|
import net.sf.openrocket.gui.print.visitor.PageFitPrintStrategy;
|
||||||
import net.sf.openrocket.gui.rocketfigure.TransitionShapes;
|
import net.sf.openrocket.gui.rocketfigure.TransitionShapes;
|
||||||
import net.sf.openrocket.rocketcomponent.NoseCone;
|
import net.sf.openrocket.rocketcomponent.NoseCone;
|
||||||
import net.sf.openrocket.util.Transformation;
|
import net.sf.openrocket.util.Transformation;
|
||||||
@ -10,50 +11,71 @@ import java.awt.Shape;
|
|||||||
|
|
||||||
public class PrintableNoseCone extends AbstractPrintable<NoseCone> {
|
public class PrintableNoseCone extends AbstractPrintable<NoseCone> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the component to be drawn is a nose cone, save a reference to it.
|
* If the component to be drawn is a nose cone, save a reference to it.
|
||||||
*/
|
*/
|
||||||
private NoseCone target;
|
private NoseCone target;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a printable nose cone.
|
* Offset for shoulder radius edge case.
|
||||||
*
|
*/
|
||||||
* @param noseCone the component to print
|
private int xOffset;
|
||||||
*/
|
|
||||||
public PrintableNoseCone(NoseCone noseCone) {
|
|
||||||
super(false, noseCone);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
protected void init(NoseCone component) {
|
* Construct a printable nose cone.
|
||||||
|
*
|
||||||
|
* @param noseCone the component to print
|
||||||
|
*/
|
||||||
|
public PrintableNoseCone(NoseCone noseCone) {
|
||||||
|
super(noseCone);
|
||||||
|
}
|
||||||
|
|
||||||
target = component;
|
@Override
|
||||||
double radius = target.getForeRadius();
|
protected void init(NoseCone component) {
|
||||||
if (radius < target.getAftRadius()) {
|
|
||||||
radius = target.getAftRadius();
|
|
||||||
}
|
|
||||||
setSize((int) PrintUnit.METERS.toPoints(2 * radius) + 4,
|
|
||||||
(int) PrintUnit.METERS.toPoints(target.getLength() + target.getAftShoulderLength()) + 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
target = component;
|
||||||
* Draw a nose cone. Presumes that the graphics context has already had the x/y position translated based on
|
xOffset = 0;
|
||||||
* where it should be drawn.
|
double radius = target.getForeRadius();
|
||||||
*
|
if (radius < target.getAftRadius()) {
|
||||||
* @param g2 the graphics context
|
radius = target.getAftRadius();
|
||||||
*/
|
}
|
||||||
@Override
|
//Really odd edge case where the shoulder radius exceeds the radius of the nose cone.
|
||||||
protected void draw(Graphics2D g2) {
|
if (radius < target.getAftShoulderRadius()) {
|
||||||
Shape[] shapes = TransitionShapes.getShapesSide(target, Transformation.rotate_x(0d), PrintUnit.METERS.toPoints(1));
|
double tmp = radius;
|
||||||
|
radius = target.getAftShoulderRadius();
|
||||||
|
xOffset = (int) PrintUnit.METERS.toPoints(radius - tmp) + PageFitPrintStrategy.MARGIN;
|
||||||
|
}
|
||||||
|
setSize((int) PrintUnit.METERS.toPoints(2 * radius) + 4,
|
||||||
|
(int) PrintUnit.METERS.toPoints(target.getLength() + target.getAftShoulderLength()) + 4);
|
||||||
|
}
|
||||||
|
|
||||||
if (shapes != null && shapes.length > 0) {
|
/**
|
||||||
Rectangle r = shapes[0].getBounds();
|
* Draw a nose cone. Presumes that the graphics context has already had the x/y position translated based on where it should be drawn.
|
||||||
g2.translate(r.getHeight() / 2, 0);
|
*
|
||||||
g2.rotate(Math.PI / 2);
|
* @param g2 the graphics context
|
||||||
for (Shape shape : shapes) {
|
*/
|
||||||
g2.draw(shape);
|
@Override
|
||||||
}
|
protected void draw(Graphics2D g2) {
|
||||||
g2.rotate(-Math.PI / 2);
|
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(r.getHeight() / 2, 0);
|
||||||
|
g2.rotate(Math.PI / 2);
|
||||||
|
for (Shape shape : shapes) {
|
||||||
|
g2.draw(shape);
|
||||||
|
}
|
||||||
|
g2.rotate(-Math.PI / 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void translate(final Graphics2D theG2) {
|
||||||
|
if (xOffset == 0) {
|
||||||
|
super.translate(theG2);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
theG2.translate(xOffset, getOffsetY());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -69,7 +69,7 @@ public class PrintableTransition extends AbstractPrintable<Transition> {
|
|||||||
* @param transition the transition to print
|
* @param transition the transition to print
|
||||||
*/
|
*/
|
||||||
public PrintableTransition(Transition transition) {
|
public PrintableTransition(Transition transition) {
|
||||||
super(false, transition);
|
super(transition);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -0,0 +1,137 @@
|
|||||||
|
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.logging.LogHelper;
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Common logic for printing strategies.
|
||||||
|
*/
|
||||||
|
public abstract class AbstractPrintStrategy<V> {
|
||||||
|
/**
|
||||||
|
* The logger.
|
||||||
|
*/
|
||||||
|
protected 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 document
|
||||||
|
* @param pageFit the page fitting strategy
|
||||||
|
* @param theWriter the pdf writer
|
||||||
|
* @param theStages the set of stages in the rocket
|
||||||
|
*/
|
||||||
|
public AbstractPrintStrategy(Document doc, PageFitPrintStrategy pageFit, PdfWriter theWriter,
|
||||||
|
Set<Integer> theStages) {
|
||||||
|
document = doc;
|
||||||
|
pageFitPrint = pageFit;
|
||||||
|
writer = theWriter;
|
||||||
|
stages = theStages;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recurse through the given rocket component.
|
||||||
|
*
|
||||||
|
* @param root the root component; all children will be printed recursively
|
||||||
|
*/
|
||||||
|
public V writeToDocument(final RocketComponent root) {
|
||||||
|
return goDeep(root.getChildren());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recurse through the given rocket component.
|
||||||
|
*
|
||||||
|
* @param theRc an array of rocket components; all children will be printed recursively
|
||||||
|
*/
|
||||||
|
protected abstract V goDeep(List<RocketComponent> theRc);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
protected boolean fitsOnOnePage(Dimension pageSize, double wImage, double hImage) {
|
||||||
|
double wPage = pageSize.getWidth() - PageFitPrintStrategy.MARGIN * 2;
|
||||||
|
double hPage = pageSize.getHeight() - PageFitPrintStrategy.MARGIN * 2;
|
||||||
|
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if the strategy's set of stage numbers (to print) contains the specified stage.
|
||||||
|
*
|
||||||
|
* @param stageNumber a stage number
|
||||||
|
*
|
||||||
|
* @return true if the strategy contains the stage number provided
|
||||||
|
*/
|
||||||
|
public boolean shouldPrintStage(int stageNumber) {
|
||||||
|
if (stages == null || stages.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (final Integer stage : stages) {
|
||||||
|
if (stage == stageNumber) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void render(final AbstractPrintable thePrintable) throws DocumentException {
|
||||||
|
java.awt.Dimension size = thePrintable.getSize();
|
||||||
|
final Dimension pageSize = getPageSize();
|
||||||
|
if (fitsOnOnePage(pageSize, size.getWidth(), size.getHeight())) {
|
||||||
|
pageFitPrint.addComponent(thePrintable);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
BufferedImage image = (BufferedImage) thePrintable.createImage();
|
||||||
|
ITextHelper.renderImageAcrossPages(new Rectangle(pageSize.getWidth(), pageSize.getHeight()),
|
||||||
|
document, writer, image);
|
||||||
|
document.newPage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2,52 +2,21 @@ package net.sf.openrocket.gui.print.visitor;
|
|||||||
|
|
||||||
import com.itextpdf.text.Document;
|
import com.itextpdf.text.Document;
|
||||||
import com.itextpdf.text.DocumentException;
|
import com.itextpdf.text.DocumentException;
|
||||||
import com.itextpdf.text.Rectangle;
|
|
||||||
import com.itextpdf.text.pdf.PdfWriter;
|
import com.itextpdf.text.pdf.PdfWriter;
|
||||||
import net.sf.openrocket.gui.print.AbstractPrintable;
|
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.PrintableCenteringRing;
|
import net.sf.openrocket.gui.print.PrintableCenteringRing;
|
||||||
import net.sf.openrocket.logging.LogHelper;
|
|
||||||
import net.sf.openrocket.rocketcomponent.CenteringRing;
|
import net.sf.openrocket.rocketcomponent.CenteringRing;
|
||||||
import net.sf.openrocket.rocketcomponent.InnerTube;
|
import net.sf.openrocket.rocketcomponent.InnerTube;
|
||||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||||
import net.sf.openrocket.startup.Application;
|
|
||||||
import net.sf.openrocket.util.ArrayList;
|
import net.sf.openrocket.util.ArrayList;
|
||||||
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A strategy for printing a centering ring to iText.
|
* A strategy for printing a centering ring to iText.
|
||||||
*/
|
*/
|
||||||
public class CenteringRingStrategy {
|
public class CenteringRingStrategy extends AbstractPrintStrategy<Void> {
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.
|
* Constructor.
|
||||||
@ -57,29 +26,19 @@ public class CenteringRingStrategy {
|
|||||||
* @param theStagesToVisit The stages to be visited by this strategy
|
* @param theStagesToVisit The stages to be visited by this strategy
|
||||||
*/
|
*/
|
||||||
public CenteringRingStrategy(Document doc, PdfWriter theWriter, Set<Integer> theStagesToVisit, PageFitPrintStrategy pageFit) {
|
public CenteringRingStrategy(Document doc, PdfWriter theWriter, Set<Integer> theStagesToVisit, PageFitPrintStrategy pageFit) {
|
||||||
|
super(doc, pageFit, theWriter, theStagesToVisit);
|
||||||
document = doc;
|
document = doc;
|
||||||
writer = theWriter;
|
writer = theWriter;
|
||||||
stages = theStagesToVisit;
|
stages = theStagesToVisit;
|
||||||
pageFitPrint = pageFit;
|
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.
|
* Recurse through the given rocket component.
|
||||||
*
|
*
|
||||||
* @param theRc an array of rocket components; all children will be visited recursively
|
* @param theRc an array of rocket components; all children will be visited recursively
|
||||||
*/
|
*/
|
||||||
protected void goDeep(final List<RocketComponent> theRc) {
|
protected Void goDeep(final List<RocketComponent> theRc) {
|
||||||
for (RocketComponent rocketComponent : theRc) {
|
for (RocketComponent rocketComponent : theRc) {
|
||||||
if (rocketComponent instanceof CenteringRing) {
|
if (rocketComponent instanceof CenteringRing) {
|
||||||
render((CenteringRing) rocketComponent);
|
render((CenteringRing) rocketComponent);
|
||||||
@ -88,6 +47,7 @@ public class CenteringRingStrategy {
|
|||||||
goDeep(rocketComponent.getChildren());
|
goDeep(rocketComponent.getChildren());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -141,130 +101,21 @@ public class CenteringRingStrategy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The core behavior of this visitor.
|
* The core behavior of this strategy.
|
||||||
*
|
*
|
||||||
* @param component the object to extract info about; a graphical image of the centering ring shape is drawn to the
|
* @param component the object to extract info about; a graphical image of the centering ring shape is drawn to the
|
||||||
* document
|
* document
|
||||||
*/
|
*/
|
||||||
private void render(final CenteringRing component) {
|
private void render(final CenteringRing component) {
|
||||||
try {
|
try {
|
||||||
AbstractPrintable<CenteringRing> pfs;
|
AbstractPrintable pfs;
|
||||||
pfs = PrintableCenteringRing.create(component, findMotorMount(component));
|
pfs = PrintableCenteringRing.create(component, findMotorMount(component));
|
||||||
|
|
||||||
java.awt.Dimension size = pfs.getSize();
|
render(pfs);
|
||||||
final Dimension pageSize = getPageSize();
|
|
||||||
if (fitsOnOnePage(pageSize, size.getWidth(), size.getHeight())) {
|
|
||||||
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 centering ring.", 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.
|
|
||||||
*/
|
|
||||||
public static class Dimension {
|
|
||||||
/**
|
|
||||||
* Width, in points.
|
|
||||||
*/
|
|
||||||
public float width;
|
|
||||||
/**
|
|
||||||
* Height, in points.
|
|
||||||
*/
|
|
||||||
public float height;
|
|
||||||
/**
|
|
||||||
* Breadth, in points.
|
|
||||||
*/
|
|
||||||
public float breadth = 0f;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor.
|
|
||||||
*
|
|
||||||
* @param w width
|
|
||||||
* @param h height
|
|
||||||
*/
|
|
||||||
public Dimension(float w, float h) {
|
|
||||||
width = w;
|
|
||||||
height = h;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor.
|
|
||||||
*
|
|
||||||
* @param w width
|
|
||||||
* @param h height
|
|
||||||
* @param b breadth; optionally used to represent radius
|
|
||||||
*/
|
|
||||||
public Dimension(float w, float h, float b) {
|
|
||||||
width = w;
|
|
||||||
height = h;
|
|
||||||
breadth = b;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the width.
|
|
||||||
*
|
|
||||||
* @return the width
|
|
||||||
*/
|
|
||||||
public float getWidth() {
|
|
||||||
return width;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the height.
|
|
||||||
*
|
|
||||||
* @return the height
|
|
||||||
*/
|
|
||||||
public float getHeight() {
|
|
||||||
return height;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the breadth.
|
|
||||||
*
|
|
||||||
* @return the breadth
|
|
||||||
*/
|
|
||||||
public float getBreadth() {
|
|
||||||
return breadth;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
70
core/src/net/sf/openrocket/gui/print/visitor/Dimension.java
Normal file
70
core/src/net/sf/openrocket/gui/print/visitor/Dimension.java
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
package net.sf.openrocket.gui.print.visitor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convenience class to model a dimension.
|
||||||
|
*/
|
||||||
|
public class Dimension {
|
||||||
|
/**
|
||||||
|
* Width, in points.
|
||||||
|
*/
|
||||||
|
public float width;
|
||||||
|
/**
|
||||||
|
* Height, in points.
|
||||||
|
*/
|
||||||
|
public float height;
|
||||||
|
/**
|
||||||
|
* Breadth, in points.
|
||||||
|
*/
|
||||||
|
public float breadth = 0f;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param w width
|
||||||
|
* @param h height
|
||||||
|
*/
|
||||||
|
public Dimension(float w, float h) {
|
||||||
|
width = w;
|
||||||
|
height = h;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param w width
|
||||||
|
* @param h height
|
||||||
|
* @param b breadth; optionally used to represent radius
|
||||||
|
*/
|
||||||
|
public Dimension(float w, float h, float b) {
|
||||||
|
width = w;
|
||||||
|
height = h;
|
||||||
|
breadth = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the width.
|
||||||
|
*
|
||||||
|
* @return the width
|
||||||
|
*/
|
||||||
|
public float getWidth() {
|
||||||
|
return width;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the height.
|
||||||
|
*
|
||||||
|
* @return the height
|
||||||
|
*/
|
||||||
|
public float getHeight() {
|
||||||
|
return height;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the breadth.
|
||||||
|
*
|
||||||
|
* @return the breadth
|
||||||
|
*/
|
||||||
|
public float getBreadth() {
|
||||||
|
return breadth;
|
||||||
|
}
|
||||||
|
}
|
@ -5,49 +5,19 @@ package net.sf.openrocket.gui.print.visitor;
|
|||||||
|
|
||||||
import com.itextpdf.text.Document;
|
import com.itextpdf.text.Document;
|
||||||
import com.itextpdf.text.DocumentException;
|
import com.itextpdf.text.DocumentException;
|
||||||
import com.itextpdf.text.Rectangle;
|
|
||||||
import com.itextpdf.text.pdf.PdfWriter;
|
import com.itextpdf.text.pdf.PdfWriter;
|
||||||
import net.sf.openrocket.gui.print.ITextHelper;
|
import net.sf.openrocket.gui.print.AbstractPrintable;
|
||||||
import net.sf.openrocket.gui.print.PrintUnit;
|
|
||||||
import net.sf.openrocket.gui.print.PrintableFinSet;
|
import net.sf.openrocket.gui.print.PrintableFinSet;
|
||||||
import net.sf.openrocket.logging.LogHelper;
|
|
||||||
import net.sf.openrocket.rocketcomponent.FinSet;
|
import net.sf.openrocket.rocketcomponent.FinSet;
|
||||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||||
import net.sf.openrocket.startup.Application;
|
|
||||||
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A strategy for drawing fin templates.
|
* A strategy for drawing fin templates.
|
||||||
*/
|
*/
|
||||||
public class FinSetPrintStrategy {
|
public class FinSetPrintStrategy extends AbstractPrintStrategy<Void> {
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.
|
* Constructor.
|
||||||
@ -57,37 +27,25 @@ public class FinSetPrintStrategy {
|
|||||||
* @param theStages The stages to be printed by this strategy
|
* @param theStages The stages to be printed by this strategy
|
||||||
*/
|
*/
|
||||||
public FinSetPrintStrategy(Document doc, PdfWriter theWriter, Set<Integer> theStages, PageFitPrintStrategy pageFit) {
|
public FinSetPrintStrategy(Document doc, PdfWriter theWriter, Set<Integer> theStages, PageFitPrintStrategy pageFit) {
|
||||||
document = doc;
|
super(doc, pageFit, theWriter, theStages);
|
||||||
writer = theWriter;
|
|
||||||
stages = theStages;
|
|
||||||
pageFitPrint = pageFit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Recurse through the given rocket component.
|
|
||||||
*
|
|
||||||
* @param root the root component; all children will be printed recursively
|
|
||||||
*/
|
|
||||||
public void writeToDocument (final RocketComponent root) {
|
|
||||||
List<RocketComponent> rc = root.getChildren();
|
|
||||||
goDeep(rc);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Recurse through the given rocket component.
|
* Recurse through the given rocket component.
|
||||||
*
|
*
|
||||||
* @param theRc an array of rocket components; all children will be printed recursively
|
* @param theRc an array of rocket components; all children will be printed recursively
|
||||||
*/
|
*/
|
||||||
protected void goDeep (final List<RocketComponent> theRc) {
|
@Override
|
||||||
|
protected Void goDeep (final List<RocketComponent> theRc) {
|
||||||
for (RocketComponent rocketComponent : theRc) {
|
for (RocketComponent rocketComponent : theRc) {
|
||||||
if (rocketComponent instanceof FinSet) {
|
if (rocketComponent instanceof FinSet) {
|
||||||
printFinSet((FinSet) rocketComponent);
|
render((FinSet) rocketComponent);
|
||||||
}
|
}
|
||||||
else if (rocketComponent.getChildCount() > 0) {
|
else if (rocketComponent.getChildCount() > 0) {
|
||||||
goDeep(rocketComponent.getChildren());
|
goDeep(rocketComponent.getChildren());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -95,24 +53,11 @@ public class FinSetPrintStrategy {
|
|||||||
*
|
*
|
||||||
* @param finSet the object to extract info about; a graphical image of the fin shape is drawn to the document
|
* @param finSet the object to extract info about; a graphical image of the fin shape is drawn to the document
|
||||||
*/
|
*/
|
||||||
private void printFinSet(final FinSet finSet) {
|
private void render(final FinSet finSet) {
|
||||||
if (shouldPrintStage(finSet.getStageNumber())) {
|
if (shouldPrintStage(finSet.getStageNumber())) {
|
||||||
try {
|
try {
|
||||||
PrintableFinSet pfs = new PrintableFinSet(finSet);
|
AbstractPrintable<FinSet> pfs = new PrintableFinSet(finSet);
|
||||||
|
render(pfs);
|
||||||
java.awt.Dimension finSize = pfs.getSize();
|
|
||||||
final Dimension pageSize = getPageSize();
|
|
||||||
if (fitsOnOnePage(pageSize, finSize.getWidth(), finSize.getHeight())) {
|
|
||||||
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 fin.", e);
|
log.error("Could not render fin.", e);
|
||||||
@ -120,91 +65,4 @@ public class FinSetPrintStrategy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine if the strategy's set of stage numbers (to print) contains the specified stage.
|
|
||||||
*
|
|
||||||
* @param stageNumber a stage number
|
|
||||||
*
|
|
||||||
* @return true if the strategy contains the stage number provided
|
|
||||||
*/
|
|
||||||
public boolean shouldPrintStage(int stageNumber) {
|
|
||||||
if (stages == null || stages.isEmpty()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (final Integer stage : stages) {
|
|
||||||
if (stage == stageNumber) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -8,7 +8,9 @@ import com.itextpdf.text.pdf.PdfContentByte;
|
|||||||
import com.itextpdf.text.pdf.PdfWriter;
|
import com.itextpdf.text.pdf.PdfWriter;
|
||||||
import net.sf.openrocket.gui.print.PrintUnit;
|
import net.sf.openrocket.gui.print.PrintUnit;
|
||||||
import net.sf.openrocket.gui.print.PrintableComponent;
|
import net.sf.openrocket.gui.print.PrintableComponent;
|
||||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
import net.sf.openrocket.logging.LogHelper;
|
||||||
|
import net.sf.openrocket.startup.Application;
|
||||||
|
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@ -22,6 +24,14 @@ import java.util.Set;
|
|||||||
*/
|
*/
|
||||||
public class PageFitPrintStrategy {
|
public class PageFitPrintStrategy {
|
||||||
|
|
||||||
|
/** The margin. */
|
||||||
|
public final static int MARGIN = (int)(PrintUnit.POINTS_PER_INCH * 0.3f);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The logger.
|
||||||
|
*/
|
||||||
|
private static final LogHelper log = Application.getLogger();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The iText document.
|
* The iText document.
|
||||||
*/
|
*/
|
||||||
@ -62,10 +72,8 @@ public class PageFitPrintStrategy {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Recurse through the given rocket component.
|
* Recurse through the given rocket component.
|
||||||
*
|
|
||||||
* @param root the root component; all children will be printed recursively
|
|
||||||
*/
|
*/
|
||||||
public void writeToDocument (final RocketComponent root) {
|
public void writeToDocument () {
|
||||||
fitPrintComponents();
|
fitPrintComponents();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,8 +84,8 @@ public class PageFitPrintStrategy {
|
|||||||
final Dimension pageSize = getPageSize();
|
final Dimension pageSize = getPageSize();
|
||||||
double wPage = pageSize.getWidth();
|
double wPage = pageSize.getWidth();
|
||||||
double hPage = pageSize.getHeight();
|
double hPage = pageSize.getHeight();
|
||||||
int marginX = (int)(PrintUnit.POINTS_PER_INCH * 0.3f);
|
int marginX = MARGIN;
|
||||||
int marginY = (int)(PrintUnit.POINTS_PER_INCH * 0.3f);
|
int marginY = MARGIN;
|
||||||
PdfContentByte cb = writer.getDirectContent();
|
PdfContentByte cb = writer.getDirectContent();
|
||||||
|
|
||||||
Collections.sort(componentToPrint);
|
Collections.sort(componentToPrint);
|
||||||
@ -86,7 +94,7 @@ public class PageFitPrintStrategy {
|
|||||||
int pageY = marginY;
|
int pageY = marginY;
|
||||||
Boolean anyAddedToRow;
|
Boolean anyAddedToRow;
|
||||||
|
|
||||||
Graphics2D g2 = cb.createGraphics(pageSize.width, pageSize.height);
|
Graphics2D g2 = createGraphics((float) wPage, (float) hPage, cb);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
// Fill the row
|
// Fill the row
|
||||||
@ -98,17 +106,19 @@ public class PageFitPrintStrategy {
|
|||||||
while (entry.hasNext()) {
|
while (entry.hasNext()) {
|
||||||
PrintableComponent component = entry.next();
|
PrintableComponent component = entry.next();
|
||||||
java.awt.Dimension dim = component.getSize();
|
java.awt.Dimension dim = component.getSize();
|
||||||
if ((rowX + dim.width + marginX < wPage) && (rowY + dim.height + marginY < hPage)) {
|
if ((rowX + dim.width + marginX <= wPage) && (rowY + dim.height + marginY <= hPage)) {
|
||||||
component.setPrintOffset(rowX, rowY);
|
component.setPrintOffset(rowX, rowY);
|
||||||
|
// Separate each component horizontally by a space equal to the margin
|
||||||
rowX += dim.width + marginX;
|
rowX += dim.width + marginX;
|
||||||
if (rowY + dim.height + marginY > pageY) {
|
if (rowY + dim.height + marginY > pageY) {
|
||||||
pageY = rowY + dim.height + marginY;
|
pageY = rowY + dim.height + marginY;
|
||||||
}
|
}
|
||||||
entry.remove();
|
entry.remove();
|
||||||
component.print(g2);
|
component.print(g2);
|
||||||
anyAddedToRow = true;
|
anyAddedToRow = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Separate each component vertically by a space equal to the margin
|
||||||
pageY += marginY;
|
pageY += marginY;
|
||||||
} while (anyAddedToRow);
|
} while (anyAddedToRow);
|
||||||
|
|
||||||
@ -117,6 +127,20 @@ public class PageFitPrintStrategy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a graphics context.
|
||||||
|
*
|
||||||
|
* @param theWPage the width of the physical page
|
||||||
|
* @param theHPage the height of the physical
|
||||||
|
*
|
||||||
|
* @param theCb the pdf content byte instance
|
||||||
|
*
|
||||||
|
* @return a Graphics2D instance
|
||||||
|
*/
|
||||||
|
Graphics2D createGraphics(final float theWPage, final float theHPage, final PdfContentByte theCb) {
|
||||||
|
return theCb.createGraphics(theWPage, theHPage);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the dimensions of the paper page.
|
* Get the dimensions of the paper page.
|
||||||
*
|
*
|
||||||
@ -126,42 +150,4 @@ public class PageFitPrintStrategy {
|
|||||||
return new Dimension(document.getPageSize().getWidth(),
|
return new Dimension(document.getPageSize().getWidth(),
|
||||||
document.getPageSize().getHeight());
|
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -2,52 +2,26 @@ package net.sf.openrocket.gui.print.visitor;
|
|||||||
|
|
||||||
import com.itextpdf.text.Document;
|
import com.itextpdf.text.Document;
|
||||||
import com.itextpdf.text.DocumentException;
|
import com.itextpdf.text.DocumentException;
|
||||||
import com.itextpdf.text.Rectangle;
|
|
||||||
import com.itextpdf.text.pdf.PdfWriter;
|
import com.itextpdf.text.pdf.PdfWriter;
|
||||||
import net.sf.openrocket.gui.print.AbstractPrintable;
|
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.PrintableNoseCone;
|
||||||
import net.sf.openrocket.gui.print.PrintableTransition;
|
import net.sf.openrocket.gui.print.PrintableTransition;
|
||||||
import net.sf.openrocket.logging.LogHelper;
|
|
||||||
import net.sf.openrocket.rocketcomponent.NoseCone;
|
import net.sf.openrocket.rocketcomponent.NoseCone;
|
||||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||||
import net.sf.openrocket.rocketcomponent.Transition;
|
import net.sf.openrocket.rocketcomponent.Transition;
|
||||||
import net.sf.openrocket.startup.Application;
|
|
||||||
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A strategy for drawing transition/shroud/nose cone templates.
|
* A strategy for drawing transition/shroud/nose cone templates.
|
||||||
*/
|
*/
|
||||||
public class TransitionStrategy {
|
public class TransitionStrategy extends AbstractPrintStrategy <Boolean> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The logger.
|
* Print nose cones?
|
||||||
*/
|
*/
|
||||||
private static final LogHelper log = Application.getLogger();
|
private boolean printNoseCones = false;
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.
|
* Constructor.
|
||||||
@ -55,65 +29,53 @@ public class TransitionStrategy {
|
|||||||
* @param doc The iText document
|
* @param doc The iText document
|
||||||
* @param theWriter The direct iText writer
|
* @param theWriter The direct iText writer
|
||||||
* @param theStagesToVisit The stages to be visited by this strategy
|
* @param theStagesToVisit The stages to be visited by this strategy
|
||||||
|
* @param pageFit the page fit strategy
|
||||||
|
* @param noseCones nose cones are a special form of a transition; if true, then print nose cones
|
||||||
*/
|
*/
|
||||||
public TransitionStrategy(Document doc, PdfWriter theWriter, Set<Integer> theStagesToVisit, PageFitPrintStrategy pageFit) {
|
public TransitionStrategy(Document doc, PdfWriter theWriter, Set<Integer> theStagesToVisit, PageFitPrintStrategy pageFit, boolean noseCones) {
|
||||||
|
super(doc, pageFit, theWriter, theStagesToVisit);
|
||||||
document = doc;
|
document = doc;
|
||||||
writer = theWriter;
|
writer = theWriter;
|
||||||
stages = theStagesToVisit;
|
stages = theStagesToVisit;
|
||||||
pageFitPrint = pageFit;
|
pageFitPrint = pageFit;
|
||||||
|
printNoseCones = noseCones;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Recurse through the given rocket component.
|
|
||||||
*
|
|
||||||
* @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 boolean writeToDocument(final RocketComponent root, boolean noseCones) {
|
|
||||||
List<RocketComponent> rc = root.getChildren();
|
|
||||||
return goDeep(rc, noseCones);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Recurse through the given rocket component.
|
* Recurse through the given rocket component.
|
||||||
*
|
*
|
||||||
* @param theRc an array of rocket components; all children will be visited recursively
|
* @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
|
* @return true if a transition/nosecone was rendered
|
||||||
*/
|
*/
|
||||||
protected boolean goDeep(final List<RocketComponent> theRc, boolean noseCones) {
|
protected Boolean goDeep(final List<RocketComponent> theRc) {
|
||||||
boolean result = false;
|
boolean result = false;
|
||||||
for (RocketComponent rocketComponent : theRc) {
|
for (RocketComponent rocketComponent : theRc) {
|
||||||
if (rocketComponent instanceof NoseCone) {
|
if (rocketComponent instanceof NoseCone) {
|
||||||
if (noseCones) {
|
if (printNoseCones) {
|
||||||
result |= render((Transition) rocketComponent);
|
result |= render((Transition) rocketComponent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (rocketComponent instanceof Transition && !noseCones) {
|
else if (rocketComponent instanceof Transition && !printNoseCones) {
|
||||||
result |= render((Transition) rocketComponent);
|
result |= render((Transition) rocketComponent);
|
||||||
}
|
}
|
||||||
else if (rocketComponent.getChildCount() > 0) {
|
else if (rocketComponent.getChildCount() > 0) {
|
||||||
result |= goDeep(rocketComponent.getChildren(), noseCones);
|
result |= goDeep(rocketComponent.getChildren());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The core behavior of this visitor.
|
* The core behavior of this strategy.
|
||||||
*
|
*
|
||||||
* @param component the object to extract info about; a graphical image of the transition shape is drawn to the
|
* @param component the object to extract info about; a graphical image of the transition shape is drawn to the document
|
||||||
* document
|
|
||||||
*
|
*
|
||||||
* @return true, always
|
* @return true, always
|
||||||
*/
|
*/
|
||||||
private boolean render(final Transition component) {
|
private boolean render(final Transition component) {
|
||||||
try {
|
try {
|
||||||
AbstractPrintable<?> pfs;
|
AbstractPrintable pfs;
|
||||||
if (component instanceof NoseCone) {
|
if (component instanceof NoseCone) {
|
||||||
pfs = new PrintableNoseCone((NoseCone) component);
|
pfs = new PrintableNoseCone((NoseCone) component);
|
||||||
}
|
}
|
||||||
@ -121,19 +83,7 @@ public class TransitionStrategy {
|
|||||||
pfs = new PrintableTransition(component);
|
pfs = new PrintableTransition(component);
|
||||||
}
|
}
|
||||||
|
|
||||||
java.awt.Dimension size = pfs.getSize();
|
render(pfs);
|
||||||
final Dimension pageSize = getPageSize();
|
|
||||||
if (fitsOnOnePage(pageSize, size.getWidth(), size.getHeight())) {
|
|
||||||
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);
|
log.error("Could not render the transition.", e);
|
||||||
@ -141,75 +91,4 @@ public class TransitionStrategy {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user