Added ruler graphic to printed output; improvements to layout and margins in printing; bug fix in PrintUnit; other
minor printing related cleanup.
This commit is contained in:
parent
905c7f740a
commit
eb0cfe141e
@ -1,6 +1,11 @@
|
|||||||
package net.sf.openrocket.gui.print;
|
package net.sf.openrocket.gui.print;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.BasicStroke;
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Graphics;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.Image;
|
||||||
|
import java.awt.RenderingHints;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
|
|
||||||
public abstract class AbstractPrintable<T> extends PrintableComponent {
|
public abstract class AbstractPrintable<T> extends PrintableComponent {
|
||||||
@ -14,16 +19,6 @@ public abstract class AbstractPrintable<T> extends PrintableComponent {
|
|||||||
*/
|
*/
|
||||||
public final static BasicStroke thickStroke = new BasicStroke(4.0f);
|
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.
|
* Constructor. Initialize this printable with the component to be printed.
|
||||||
*
|
*
|
||||||
@ -35,11 +30,9 @@ public abstract class AbstractPrintable<T> extends PrintableComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compute the basic values of each arc of the transition/shroud. This is adapted from
|
* Initialize the printable.
|
||||||
* <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
|
* @param component the component
|
||||||
*/
|
*/
|
||||||
protected abstract void init(T component);
|
protected abstract void init(T component);
|
||||||
|
|
||||||
@ -51,14 +44,14 @@ public abstract class AbstractPrintable<T> extends PrintableComponent {
|
|||||||
protected abstract void draw(Graphics2D g2);
|
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
|
* Returns a generated image of the component. May then be used wherever AWT images can be used, or converted to
|
||||||
* another image/picture format and used accordingly.
|
* another image/picture format and used accordingly.
|
||||||
*
|
*
|
||||||
* @return an awt image of the transition
|
* @return an awt image of the printable component
|
||||||
*/
|
*/
|
||||||
public Image createImage() {
|
public Image createImage() {
|
||||||
int width = getWidth() + marginX;
|
int width = getWidth() + getOffsetX();
|
||||||
int height = getHeight() + marginY;
|
int height = getHeight() + getOffsetY();
|
||||||
// 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
|
||||||
|
@ -12,6 +12,7 @@ import com.itextpdf.text.pdf.PdfBoolean;
|
|||||||
import com.itextpdf.text.pdf.PdfName;
|
import com.itextpdf.text.pdf.PdfName;
|
||||||
import com.itextpdf.text.pdf.PdfWriter;
|
import com.itextpdf.text.pdf.PdfWriter;
|
||||||
import net.sf.openrocket.document.OpenRocketDocument;
|
import net.sf.openrocket.document.OpenRocketDocument;
|
||||||
|
import net.sf.openrocket.gui.print.components.Rule;
|
||||||
import net.sf.openrocket.gui.print.visitor.CenteringRingStrategy;
|
import net.sf.openrocket.gui.print.visitor.CenteringRingStrategy;
|
||||||
import net.sf.openrocket.gui.print.visitor.FinMarkingGuideStrategy;
|
import net.sf.openrocket.gui.print.visitor.FinMarkingGuideStrategy;
|
||||||
import net.sf.openrocket.gui.print.visitor.FinSetPrintStrategy;
|
import net.sf.openrocket.gui.print.visitor.FinSetPrintStrategy;
|
||||||
@ -60,6 +61,8 @@ public class PrintController {
|
|||||||
// Used to combine multiple components onto fewer sheets of paper
|
// Used to combine multiple components onto fewer sheets of paper
|
||||||
PageFitPrintStrategy pageFitPrint = new PageFitPrintStrategy(idoc, writer);
|
PageFitPrintStrategy pageFitPrint = new PageFitPrintStrategy(idoc, writer);
|
||||||
|
|
||||||
|
boolean addRule = false;
|
||||||
|
|
||||||
while (toBePrinted.hasNext()) {
|
while (toBePrinted.hasNext()) {
|
||||||
PrintableContext printableContext = toBePrinted.next();
|
PrintableContext printableContext = toBePrinted.next();
|
||||||
|
|
||||||
@ -71,42 +74,55 @@ public class PrintController {
|
|||||||
dp.writeToDocument(writer);
|
dp.writeToDocument(writer);
|
||||||
idoc.newPage();
|
idoc.newPage();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FIN_TEMPLATE:
|
case FIN_TEMPLATE:
|
||||||
final FinSetPrintStrategy finWriter = new FinSetPrintStrategy(idoc, writer, stages, pageFitPrint);
|
final FinSetPrintStrategy finWriter = new FinSetPrintStrategy(idoc, writer, stages, pageFitPrint);
|
||||||
finWriter.writeToDocument(doc.getRocket());
|
finWriter.writeToDocument(doc.getRocket());
|
||||||
|
addRule = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PARTS_DETAIL:
|
case PARTS_DETAIL:
|
||||||
final PartsDetailVisitorStrategy detailVisitor = new PartsDetailVisitorStrategy(idoc, writer, stages);
|
final PartsDetailVisitorStrategy detailVisitor = new PartsDetailVisitorStrategy(idoc, writer, stages);
|
||||||
detailVisitor.writeToDocument(doc.getRocket());
|
detailVisitor.writeToDocument(doc.getRocket());
|
||||||
detailVisitor.close();
|
detailVisitor.close();
|
||||||
idoc.newPage();
|
idoc.newPage();
|
||||||
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);
|
||||||
tranWriter.writeToDocument(doc.getRocket(), false);
|
if (tranWriter.writeToDocument(doc.getRocket(), false)) {
|
||||||
idoc.newPage();
|
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);
|
||||||
coneWriter.writeToDocument(doc.getRocket(), true);
|
if (coneWriter.writeToDocument(doc.getRocket(), true)) {
|
||||||
idoc.newPage();
|
addRule = true;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CENTERING_RING_TEMPLATE:
|
case CENTERING_RING_TEMPLATE:
|
||||||
final CenteringRingStrategy crWriter = new CenteringRingStrategy(idoc, writer, stages,
|
final CenteringRingStrategy crWriter = new CenteringRingStrategy(idoc, writer, stages,
|
||||||
pageFitPrint);
|
pageFitPrint);
|
||||||
crWriter.writeToDocument(doc.getRocket());
|
crWriter.writeToDocument(doc.getRocket());
|
||||||
idoc.newPage();
|
addRule = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FIN_MARKING_GUIDE:
|
case FIN_MARKING_GUIDE:
|
||||||
final FinMarkingGuideStrategy fmg = new FinMarkingGuideStrategy(idoc, writer);
|
final FinMarkingGuideStrategy fmg = new FinMarkingGuideStrategy(idoc, writer);
|
||||||
fmg.writeToDocument(doc.getRocket());
|
fmg.writeToDocument(doc.getRocket());
|
||||||
idoc.newPage();
|
idoc.newPage();
|
||||||
|
addRule = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (addRule) {
|
||||||
|
//Add a ruler to the output.
|
||||||
|
pageFitPrint.addComponent(new Rule(Rule.Orientation.BOTTOM));
|
||||||
|
}
|
||||||
|
|
||||||
// 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(doc.getRocket());
|
||||||
idoc.newPage();
|
idoc.newPage();
|
||||||
|
@ -12,7 +12,7 @@ public enum PrintUnit {
|
|||||||
public double toMillis(double d) { return d/FEET_PER_MM; }
|
public double toMillis(double d) { return d/FEET_PER_MM; }
|
||||||
public double toCentis(double d) { return d/(FEET_PER_MM*TEN); }
|
public double toCentis(double d) { return d/(FEET_PER_MM*TEN); }
|
||||||
public double toMeters(double d) { return d/(FEET_PER_MM*TEN*TEN*TEN); }
|
public double toMeters(double d) { return d/(FEET_PER_MM*TEN*TEN*TEN); }
|
||||||
public long toPoints(double d) { return (long)(d * POINTS_PER_INCH * 12); }
|
public double toPoints(double d) { return (d * POINTS_PER_INCH * 12); }
|
||||||
public double convert(double d, PrintUnit u) { return u.toInches(d)/12; }
|
public double convert(double d, PrintUnit u) { return u.toInches(d)/12; }
|
||||||
},
|
},
|
||||||
INCHES {
|
INCHES {
|
||||||
@ -20,7 +20,7 @@ public enum PrintUnit {
|
|||||||
public double toMillis(double d) { return d/INCHES_PER_MM; }
|
public double toMillis(double d) { return d/INCHES_PER_MM; }
|
||||||
public double toCentis(double d) { return d/(INCHES_PER_MM*TEN); }
|
public double toCentis(double d) { return d/(INCHES_PER_MM*TEN); }
|
||||||
public double toMeters(double d) { return d/(INCHES_PER_MM*TEN*TEN*TEN); }
|
public double toMeters(double d) { return d/(INCHES_PER_MM*TEN*TEN*TEN); }
|
||||||
public long toPoints(double d) { return (long)(d * POINTS_PER_INCH); }
|
public double toPoints(double d) { return (d * POINTS_PER_INCH); }
|
||||||
public double convert(double d, PrintUnit u) { return u.toInches(d); }
|
public double convert(double d, PrintUnit u) { return u.toInches(d); }
|
||||||
},
|
},
|
||||||
MILLIMETERS {
|
MILLIMETERS {
|
||||||
@ -28,7 +28,7 @@ public enum PrintUnit {
|
|||||||
public double toMillis(double d) { return d; }
|
public double toMillis(double d) { return d; }
|
||||||
public double toCentis(double d) { return d/TEN; }
|
public double toCentis(double d) { return d/TEN; }
|
||||||
public double toMeters(double d) { return d/(TEN*TEN*TEN); }
|
public double toMeters(double d) { return d/(TEN*TEN*TEN); }
|
||||||
public long toPoints(double d) { return INCHES.toPoints(toInches(d)); }
|
public double toPoints(double d) { return INCHES.toPoints(toInches(d)); }
|
||||||
public double convert(double d, PrintUnit u) { return u.toMillis(d); }
|
public double convert(double d, PrintUnit u) { return u.toMillis(d); }
|
||||||
},
|
},
|
||||||
CENTIMETERS {
|
CENTIMETERS {
|
||||||
@ -36,7 +36,7 @@ public enum PrintUnit {
|
|||||||
public double toMillis(double d) { return d * TEN; }
|
public double toMillis(double d) { return d * TEN; }
|
||||||
public double toCentis(double d) { return d; }
|
public double toCentis(double d) { return d; }
|
||||||
public double toMeters(double d) { return d/(TEN*TEN); }
|
public double toMeters(double d) { return d/(TEN*TEN); }
|
||||||
public long toPoints(double d) { return INCHES.toPoints(toInches(d)); }
|
public double toPoints(double d) { return INCHES.toPoints(toInches(d)); }
|
||||||
public double convert(double d, PrintUnit u) { return u.toCentis(d); }
|
public double convert(double d, PrintUnit u) { return u.toCentis(d); }
|
||||||
},
|
},
|
||||||
METERS {
|
METERS {
|
||||||
@ -44,7 +44,7 @@ public enum PrintUnit {
|
|||||||
public double toMillis(double d) { return d * TEN * TEN * TEN; }
|
public double toMillis(double d) { return d * TEN * TEN * TEN; }
|
||||||
public double toCentis(double d) { return d * TEN * TEN; }
|
public double toCentis(double d) { return d * TEN * TEN; }
|
||||||
public double toMeters(double d) { return d; }
|
public double toMeters(double d) { return d; }
|
||||||
public long toPoints(double d) { return INCHES.toPoints(toInches(d)); }
|
public double toPoints(double d) { return INCHES.toPoints(toInches(d)); }
|
||||||
public double convert(double d, PrintUnit u) { return u.toMeters(d); }
|
public double convert(double d, PrintUnit u) { return u.toMeters(d); }
|
||||||
},
|
},
|
||||||
POINTS {
|
POINTS {
|
||||||
@ -52,7 +52,7 @@ public enum PrintUnit {
|
|||||||
public double toMillis(double d) { return d/(POINTS_PER_INCH * INCHES_PER_MM); }
|
public double toMillis(double d) { return d/(POINTS_PER_INCH * INCHES_PER_MM); }
|
||||||
public double toCentis(double d) { return toMillis(d)/TEN; }
|
public double toCentis(double d) { return toMillis(d)/TEN; }
|
||||||
public double toMeters(double d) { return toMillis(d)/(TEN*TEN*TEN); }
|
public double toMeters(double d) { return toMillis(d)/(TEN*TEN*TEN); }
|
||||||
public long toPoints(double d) { return (long)d; }
|
public double toPoints(double d) { return d; }
|
||||||
public double convert(double d, PrintUnit u) { return u.toPoints(d); }
|
public double convert(double d, PrintUnit u) { return u.toPoints(d); }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -160,7 +160,7 @@ public enum PrintUnit {
|
|||||||
* overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
|
* overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
|
||||||
* @see #convert
|
* @see #convert
|
||||||
*/
|
*/
|
||||||
public long toPoints(double length) {
|
public double toPoints(double length) {
|
||||||
throw new AbstractMethodError();
|
throw new AbstractMethodError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,16 +18,6 @@ public class PrintableCenteringRing extends AbstractPrintable<CenteringRing> {
|
|||||||
*/
|
*/
|
||||||
private CenteringRing target;
|
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.
|
* The line length of the cross hairs.
|
||||||
*/
|
*/
|
||||||
@ -51,8 +41,8 @@ public class PrintableCenteringRing extends AbstractPrintable<CenteringRing> {
|
|||||||
target = component;
|
target = component;
|
||||||
|
|
||||||
double radius = target.getOuterRadius();
|
double radius = target.getOuterRadius();
|
||||||
setSize((int) PrintUnit.METERS.toPoints(2 * radius) + marginX,
|
setSize((int) PrintUnit.METERS.toPoints(2 * radius),
|
||||||
(int) PrintUnit.METERS.toPoints(2 * radius) + marginY);
|
(int) PrintUnit.METERS.toPoints(2 * radius));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -65,8 +55,8 @@ public class PrintableCenteringRing extends AbstractPrintable<CenteringRing> {
|
|||||||
double radius = PrintUnit.METERS.toPoints(target.getOuterRadius());
|
double radius = PrintUnit.METERS.toPoints(target.getOuterRadius());
|
||||||
|
|
||||||
Color original = g2.getBackground();
|
Color original = g2.getBackground();
|
||||||
double x = marginX;
|
double x = 0;
|
||||||
double y = marginY;
|
double y = 0;
|
||||||
Shape outerCircle = new Ellipse2D.Double(x, y, radius * 2, radius * 2);
|
Shape outerCircle = new Ellipse2D.Double(x, y, radius * 2, radius * 2);
|
||||||
g2.setColor(Color.lightGray);
|
g2.setColor(Color.lightGray);
|
||||||
g2.fill(outerCircle);
|
g2.fill(outerCircle);
|
||||||
|
@ -3,23 +3,22 @@
|
|||||||
*/
|
*/
|
||||||
package net.sf.openrocket.gui.print;
|
package net.sf.openrocket.gui.print;
|
||||||
|
|
||||||
|
import javax.swing.JPanel;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
import java.awt.print.PageFormat;
|
import java.awt.print.PageFormat;
|
||||||
import java.awt.print.Printable;
|
import java.awt.print.Printable;
|
||||||
import java.awt.print.PrinterException;
|
import java.awt.print.PrinterException;
|
||||||
|
|
||||||
import javax.swing.JPanel;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Common interface for components we want to print. Used by PageFitPrintStrategy
|
* Common interface for components we want to print. Used by PageFitPrintStrategy
|
||||||
*
|
*
|
||||||
* @author Jason Blood <dyster2000@gmail.com>
|
* @author Jason Blood <dyster2000@gmail.com>
|
||||||
*/
|
*/
|
||||||
public class PrintableComponent extends JPanel implements Printable {
|
public class PrintableComponent extends JPanel implements Printable, Comparable<PrintableComponent> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The printing offsets
|
* The printing offsets.
|
||||||
*/
|
*/
|
||||||
private int offsetX = 0;
|
private int offsetX = 0;
|
||||||
private int offsetY = 0;
|
private int offsetY = 0;
|
||||||
@ -68,7 +67,7 @@ public class PrintableComponent extends JPanel implements Printable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the offset this component will be printed to the page
|
* Set the offset this component will be printed to the page.
|
||||||
* @param x X offset to print at.
|
* @param x X offset to print at.
|
||||||
* @param y Y offset to print at.
|
* @param y Y offset to print at.
|
||||||
*/
|
*/
|
||||||
@ -78,7 +77,7 @@ public class PrintableComponent extends JPanel implements Printable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the X offset this component will be printed to the page
|
* Get the X offset this component will be printed to the page.
|
||||||
* @return X offset to print at.
|
* @return X offset to print at.
|
||||||
*/
|
*/
|
||||||
public int getOffsetX() {
|
public int getOffsetX() {
|
||||||
@ -86,10 +85,38 @@ public class PrintableComponent extends JPanel implements Printable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the Y offset this component will be printed to the page
|
* Get the Y offset this component will be printed to the page.
|
||||||
* @return Y offset to print at.
|
* @return Y offset to print at.
|
||||||
*/
|
*/
|
||||||
public int getOffsetY() {
|
public int getOffsetY() {
|
||||||
return offsetY;
|
return offsetY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* Bin packing theory says that trying to fit the biggest items first may have a better outcome. So this is sorted
|
||||||
|
* in size descending order, with width taking precedence over height.
|
||||||
|
*
|
||||||
|
* @param other the object to be compared.
|
||||||
|
*
|
||||||
|
* @return a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the
|
||||||
|
* specified object.
|
||||||
|
*
|
||||||
|
* @throws NullPointerException if the specified object is null
|
||||||
|
* @throws ClassCastException if the specified object's type prevents it from being compared to this object.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int compareTo(final PrintableComponent other) {
|
||||||
|
int widthDiff = other.getWidth() - getWidth();
|
||||||
|
if (widthDiff > 0) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else if (widthDiff < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return other.getHeight() - getHeight();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,13 +6,12 @@ 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 javax.swing.*;
|
import java.awt.Color;
|
||||||
import java.awt.*;
|
import java.awt.Graphics;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.Image;
|
||||||
import java.awt.geom.GeneralPath;
|
import java.awt.geom.GeneralPath;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.awt.print.PageFormat;
|
|
||||||
import java.awt.print.Printable;
|
|
||||||
import java.awt.print.PrinterException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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
|
||||||
@ -26,14 +25,6 @@ public class PrintableFinSet extends PrintableComponent {
|
|||||||
*/
|
*/
|
||||||
protected GeneralPath polygon = null;
|
protected GeneralPath polygon = null;
|
||||||
|
|
||||||
/**
|
|
||||||
* The X margin.
|
|
||||||
*/
|
|
||||||
private final int marginX = (int)(PrintUnit.POINTS_PER_INCH * 0.3f);
|
|
||||||
/**
|
|
||||||
* The Y margin.
|
|
||||||
*/
|
|
||||||
private final int marginY = (int)(PrintUnit.POINTS_PER_INCH * 0.3f);
|
|
||||||
/**
|
/**
|
||||||
* The minimum X coordinate.
|
* The minimum X coordinate.
|
||||||
*/
|
*/
|
||||||
@ -58,9 +49,7 @@ public class PrintableFinSet extends PrintableComponent {
|
|||||||
* @param points an array of points.
|
* @param points an array of points.
|
||||||
*/
|
*/
|
||||||
public PrintableFinSet (Coordinate[] points) {
|
public PrintableFinSet (Coordinate[] points) {
|
||||||
//super(false);
|
|
||||||
init(points);
|
init(points);
|
||||||
//setBackground(Color.white);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -77,8 +66,8 @@ public class PrintableFinSet extends PrintableComponent {
|
|||||||
int maxY = 0;
|
int maxY = 0;
|
||||||
|
|
||||||
for (Coordinate point : points) {
|
for (Coordinate point : points) {
|
||||||
final long x = PrintUnit.METERS.toPoints(point.x);
|
final long x = (long)PrintUnit.METERS.toPoints(point.x);
|
||||||
final long y = PrintUnit.METERS.toPoints(point.y);
|
final long y = (long)PrintUnit.METERS.toPoints(point.y);
|
||||||
minX = (int) Math.min(x, minX);
|
minX = (int) Math.min(x, minX);
|
||||||
minY = (int) Math.min(y, minY);
|
minY = (int) Math.min(y, minY);
|
||||||
maxX = (int) Math.max(x, maxX);
|
maxX = (int) Math.max(x, maxX);
|
||||||
@ -90,24 +79,6 @@ public class PrintableFinSet extends PrintableComponent {
|
|||||||
setSize(maxX - minX, maxY - minY);
|
setSize(maxX - minX, maxY - minY);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the X-axis margin value.
|
|
||||||
*
|
|
||||||
* @return margin, in points
|
|
||||||
*/
|
|
||||||
protected double getMarginX () {
|
|
||||||
return marginX;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the Y-axis margin value.
|
|
||||||
*
|
|
||||||
* @return margin, in points
|
|
||||||
*/
|
|
||||||
protected double getMarginY () {
|
|
||||||
return marginY;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a generated image of the fin set. May then be used wherever AWT images can be used, or converted to
|
* 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.
|
* another image/picture format and used accordingly.
|
||||||
@ -115,8 +86,8 @@ public class PrintableFinSet extends PrintableComponent {
|
|||||||
* @return an awt image of the fin set
|
* @return an awt image of the fin set
|
||||||
*/
|
*/
|
||||||
public Image createImage () {
|
public Image createImage () {
|
||||||
int width = getWidth() + marginX;
|
int width = getWidth();
|
||||||
int height = getHeight() + marginY;
|
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
|
||||||
@ -144,6 +115,9 @@ public class PrintableFinSet extends PrintableComponent {
|
|||||||
int x = 0;
|
int x = 0;
|
||||||
int y = 0;
|
int y = 0;
|
||||||
|
|
||||||
|
int marginX = this.getOffsetX();
|
||||||
|
int marginY = this.getOffsetY();
|
||||||
|
|
||||||
// The minimum X/Y can be negative (primarily only Y due to fin tabs; rarely (never) X, but protect both anyway).
|
// The minimum X/Y can be negative (primarily only Y due to fin tabs; rarely (never) X, but protect both anyway).
|
||||||
if (minX < marginX) {
|
if (minX < marginX) {
|
||||||
x = marginX + Math.abs(minX);
|
x = marginX + Math.abs(minX);
|
||||||
@ -152,7 +126,7 @@ public class PrintableFinSet extends PrintableComponent {
|
|||||||
y = marginY + Math.abs(minY);
|
y = marginY + Math.abs(minY);
|
||||||
}
|
}
|
||||||
// Reset the origin.
|
// Reset the origin.
|
||||||
g2d.translate(x + getOffsetX(), y + getOffsetY());
|
g2d.translate(x, y);
|
||||||
g2d.setPaint(TemplateProperties.getFillColor());
|
g2d.setPaint(TemplateProperties.getFillColor());
|
||||||
g2d.fill(polygon);
|
g2d.fill(polygon);
|
||||||
g2d.setPaint(TemplateProperties.getLineColor());
|
g2d.setPaint(TemplateProperties.getLineColor());
|
||||||
|
@ -32,12 +32,13 @@ public class PrintableNoseCone extends AbstractPrintable<NoseCone> {
|
|||||||
if (radius < target.getAftRadius()) {
|
if (radius < target.getAftRadius()) {
|
||||||
radius = target.getAftRadius();
|
radius = target.getAftRadius();
|
||||||
}
|
}
|
||||||
setSize((int) PrintUnit.METERS.toPoints(2 * radius) + marginX,
|
setSize((int) PrintUnit.METERS.toPoints(2 * radius) + 4,
|
||||||
(int) PrintUnit.METERS.toPoints(target.getLength() + target.getAftShoulderLength()) + marginY);
|
(int) PrintUnit.METERS.toPoints(target.getLength() + target.getAftShoulderLength()) + 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Draw a nose cone.
|
* Draw a nose cone. Presumes that the graphics context has already had the x/y position translated based on
|
||||||
|
* where it should be drawn.
|
||||||
*
|
*
|
||||||
* @param g2 the graphics context
|
* @param g2 the graphics context
|
||||||
*/
|
*/
|
||||||
@ -47,7 +48,7 @@ public class PrintableNoseCone extends AbstractPrintable<NoseCone> {
|
|||||||
|
|
||||||
if (shapes != null && shapes.length > 0) {
|
if (shapes != null && shapes.length > 0) {
|
||||||
Rectangle r = shapes[0].getBounds();
|
Rectangle r = shapes[0].getBounds();
|
||||||
g2.translate(marginX + r.getHeight() / 2 + getOffsetX(), marginY + getOffsetY());
|
g2.translate(r.getHeight() / 2, 0);
|
||||||
g2.rotate(Math.PI / 2);
|
g2.rotate(Math.PI / 2);
|
||||||
for (Shape shape : shapes) {
|
for (Shape shape : shapes) {
|
||||||
g2.draw(shape);
|
g2.draw(shape);
|
||||||
|
@ -72,6 +72,13 @@ public class PrintableTransition extends AbstractPrintable<Transition> {
|
|||||||
super(false, transition);
|
super(false, 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 component
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void init(Transition component) {
|
protected void init(Transition component) {
|
||||||
|
|
||||||
@ -93,9 +100,9 @@ public class PrintableTransition extends AbstractPrintable<Transition> {
|
|||||||
int r1InPoints = (int) PrintUnit.METERS.toPoints(r1 * factor);
|
int r1InPoints = (int) PrintUnit.METERS.toPoints(r1 * factor);
|
||||||
int r2InPoints = (int) PrintUnit.METERS.toPoints(r2 * factor);
|
int r2InPoints = (int) PrintUnit.METERS.toPoints(r2 * factor);
|
||||||
|
|
||||||
int x = marginX;
|
int x = 0;
|
||||||
int tabOffset = 35;
|
int tabOffset = 35;
|
||||||
int y = tabOffset + marginY;
|
int y = tabOffset;
|
||||||
|
|
||||||
Arc2D.Double outerArc = new Arc2D.Double();
|
Arc2D.Double outerArc = new Arc2D.Double();
|
||||||
Arc2D.Double innerArc = new Arc2D.Double();
|
Arc2D.Double innerArc = new Arc2D.Double();
|
||||||
|
273
core/src/net/sf/openrocket/gui/print/components/Rule.java
Normal file
273
core/src/net/sf/openrocket/gui/print/components/Rule.java
Normal file
@ -0,0 +1,273 @@
|
|||||||
|
package net.sf.openrocket.gui.print.components;
|
||||||
|
|
||||||
|
import net.sf.openrocket.gui.print.PrintUnit;
|
||||||
|
import net.sf.openrocket.gui.print.PrintableComponent;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Font;
|
||||||
|
import java.awt.Graphics;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class creates a Swing ruler. The ruler has both vertical and horizontal rules, as well as divisions for both
|
||||||
|
* inches and centimeters.
|
||||||
|
*/
|
||||||
|
public class Rule extends PrintableComponent {
|
||||||
|
|
||||||
|
public static enum Orientation {
|
||||||
|
TOP,
|
||||||
|
BOTTOM
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final int TINIEST_TICK_LENGTH = 3;
|
||||||
|
public static final int MINOR_TICK_LENGTH = 6;
|
||||||
|
public static final int MID_MAJOR_TICK_LENGTH = 9;
|
||||||
|
public static final int MAJOR_TICK_LENGTH = 14;
|
||||||
|
|
||||||
|
private Orientation orientation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param theOrientation defines if the horizontal ruler should be on the top or bottom; the vertical is always
|
||||||
|
* left justified
|
||||||
|
*/
|
||||||
|
public Rule(Orientation theOrientation) {
|
||||||
|
orientation = theOrientation;
|
||||||
|
int dim = (int) PrintUnit.INCHES.toPoints(2) + 32;
|
||||||
|
setSize(dim, dim);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render the component onto a graphics context.
|
||||||
|
*
|
||||||
|
* @param g the opaque graphics context
|
||||||
|
*/
|
||||||
|
public void paintComponent(Graphics g) {
|
||||||
|
Graphics2D g2 = (Graphics2D) g;
|
||||||
|
|
||||||
|
double div = PrintUnit.INCHES.toPoints(1) / 8; //1/8 inch increment
|
||||||
|
final int width = (int) PrintUnit.INCHES.toPoints(2);
|
||||||
|
int x = 20;
|
||||||
|
int y = x + 20;
|
||||||
|
boolean inchOutSide = true;
|
||||||
|
|
||||||
|
g2.translate(getOffsetX(), getOffsetY());
|
||||||
|
|
||||||
|
if (orientation == Orientation.TOP) {
|
||||||
|
Font f = g.getFont();
|
||||||
|
g.setFont(f.deriveFont(f.getSize() - 2f));
|
||||||
|
g.drawString("in cm", x - MAJOR_TICK_LENGTH, y + width + 20);
|
||||||
|
g.drawString("in", x + width + 4, y + 4);
|
||||||
|
g.drawString("cm", x + width + 4, y + 18);
|
||||||
|
y += 6;
|
||||||
|
|
||||||
|
drawVerticalRule(g2, true, inchOutSide, x, y, width, 0, div * 2, div * 4, div * 8);
|
||||||
|
drawHorizontalRule(g2, true, !inchOutSide, x, y, width, 0, div * 2, div * 4, div * 8);
|
||||||
|
div = PrintUnit.MILLIMETERS.toPoints(1); //mm increment
|
||||||
|
drawVerticalRule(g2, true, !inchOutSide, x, y, width, 0, 0, div * 5, div * 10);
|
||||||
|
drawHorizontalRule(g2, true, inchOutSide, x, y, width, 0, 0, div * 5, div * 10);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Font f = g.getFont();
|
||||||
|
g.setFont(f.deriveFont(f.getSize() - 2f));
|
||||||
|
g.drawString("in cm", x - MAJOR_TICK_LENGTH, y);
|
||||||
|
g.drawString("cm", x + width + 6, y + width + 4);
|
||||||
|
g.drawString("in", x + width + 6, y + width + 18);
|
||||||
|
y += 6;
|
||||||
|
|
||||||
|
//Draw Inches first.
|
||||||
|
drawVerticalRule(g2, false, inchOutSide, x, y, width, 0, div * 2, div * 4, div * 8);
|
||||||
|
drawHorizontalRule(g2, true, inchOutSide, x, y + width, width, 0, div * 2, div * 4, div * 8);
|
||||||
|
div = PrintUnit.MILLIMETERS.toPoints(1); //mm increment
|
||||||
|
drawVerticalRule(g2, false, !inchOutSide, x, y, width, 0, 0, div * 5, div * 10);
|
||||||
|
drawHorizontalRule(g2, true, !inchOutSide, x, y + width, width, 0, 0, div * 5, div * 10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draw a horizontal ruler.
|
||||||
|
*
|
||||||
|
* @param g the graphics context
|
||||||
|
* @param vertexAtLeft true if the horizontal/vertical vertex is oriented to the top
|
||||||
|
* @param drawTicksDown true if the ruler should draw interval tick marks to the underside of the solid ruler line
|
||||||
|
* @param x starting x position of the ruler
|
||||||
|
* @param y starting y position of the rule
|
||||||
|
* @param length the number of points in length to extend the vertical ruler
|
||||||
|
* @param tinyEveryX the number of points for each tiny division tick line; if zero or negative tiny will not be
|
||||||
|
* drawn
|
||||||
|
* @param minorEveryX the number of points for each minor division tick line; if zero or negative minor will not
|
||||||
|
* be drawn
|
||||||
|
* @param midMajorEveryX the number of points for each mid-major division tick line
|
||||||
|
* @param majorEveryX the number of points for each major division tick line (this is typically the inch or cm
|
||||||
|
* distance in points).
|
||||||
|
*/
|
||||||
|
private void drawHorizontalRule(Graphics2D g,
|
||||||
|
boolean vertexAtLeft,
|
||||||
|
boolean drawTicksDown,
|
||||||
|
int x, int y, int length,
|
||||||
|
double tinyEveryX,
|
||||||
|
double minorEveryX,
|
||||||
|
double midMajorEveryX,
|
||||||
|
double majorEveryX) {
|
||||||
|
|
||||||
|
//Draw solid horizontal line
|
||||||
|
g.setColor(Color.black);
|
||||||
|
g.drawLine(x, y, x + length, y);
|
||||||
|
|
||||||
|
int tiniest = drawTicksDown ? TINIEST_TICK_LENGTH : -1 * TINIEST_TICK_LENGTH;
|
||||||
|
int minor = drawTicksDown ? MINOR_TICK_LENGTH : -1 * MINOR_TICK_LENGTH;
|
||||||
|
int mid = drawTicksDown ? MID_MAJOR_TICK_LENGTH : -1 * MID_MAJOR_TICK_LENGTH;
|
||||||
|
int major = drawTicksDown ? MAJOR_TICK_LENGTH : -1 * MAJOR_TICK_LENGTH;
|
||||||
|
|
||||||
|
//Draw vertical rule ticks for the horizontal ruler
|
||||||
|
//Draw minor ticks
|
||||||
|
int initial = x;
|
||||||
|
int end = initial + length;
|
||||||
|
double increment = tinyEveryX;
|
||||||
|
boolean lessThanEqual = true;
|
||||||
|
if (!vertexAtLeft) {
|
||||||
|
initial = x + length;
|
||||||
|
end = x;
|
||||||
|
lessThanEqual = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tinyEveryX > 0) {
|
||||||
|
if (!vertexAtLeft) {
|
||||||
|
increment = -1 * increment;
|
||||||
|
}
|
||||||
|
for (double xtick = initial; lessThanEqual ? (xtick <= end) : (xtick >= end); xtick += increment) {
|
||||||
|
g.drawLine((int) xtick, y, (int) xtick, y + tiniest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//Draw minor ticks
|
||||||
|
if (minorEveryX > 0) {
|
||||||
|
if (!vertexAtLeft) {
|
||||||
|
increment = -1 * minorEveryX;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
increment = minorEveryX;
|
||||||
|
}
|
||||||
|
for (double xtick = initial; lessThanEqual ? (xtick <= end) : (xtick >= end); xtick += increment) {
|
||||||
|
g.drawLine((int) xtick, y, (int) xtick, y + minor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Draw mid-major ticks
|
||||||
|
if (midMajorEveryX > 0) {
|
||||||
|
if (!vertexAtLeft) {
|
||||||
|
increment = -1 * midMajorEveryX;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
increment = midMajorEveryX;
|
||||||
|
}
|
||||||
|
for (double xtick = initial; lessThanEqual ? (xtick <= end) : (xtick >= end); xtick += increment) {
|
||||||
|
g.drawLine((int) xtick, y, (int) xtick, y + mid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!vertexAtLeft) {
|
||||||
|
increment = -1 * majorEveryX;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
increment = majorEveryX;
|
||||||
|
}
|
||||||
|
//Draw major ticks
|
||||||
|
for (double xtick = initial; lessThanEqual ? (xtick <= end) : (xtick >= end); xtick += increment) {
|
||||||
|
g.drawLine((int) xtick, y, (int) xtick, y + major);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draw a vertical ruler.
|
||||||
|
*
|
||||||
|
* @param g the graphics context
|
||||||
|
* @param vertexAtTop true if the horizontal/vertical vertex is oriented to the top
|
||||||
|
* @param drawTicksRight true if the ruler should draw interval tick marks to the right side of the solid ruler
|
||||||
|
* line
|
||||||
|
* @param x starting x position of the ruler
|
||||||
|
* @param y starting y position of the rule
|
||||||
|
* @param length the number of points in length to extend the vertical ruler
|
||||||
|
* @param tinyEveryY the number of points for each tiny division tick line; if zero or negative tiny will not be
|
||||||
|
* drawn
|
||||||
|
* @param minorEveryY the number of points for each minor division tick line; if zero or negative minor will not
|
||||||
|
* be drawn
|
||||||
|
* @param midMajorEveryY the number of points for each mid-major division tick line
|
||||||
|
* @param majorEveryY the number of points for each major division tick line (this is typically the inch or cm
|
||||||
|
* distance in points).
|
||||||
|
*/
|
||||||
|
private void drawVerticalRule(Graphics2D g,
|
||||||
|
boolean vertexAtTop,
|
||||||
|
boolean drawTicksRight, int x, int y, int length,
|
||||||
|
double tinyEveryY,
|
||||||
|
double minorEveryY,
|
||||||
|
double midMajorEveryY,
|
||||||
|
double majorEveryY) {
|
||||||
|
|
||||||
|
int tiniest = drawTicksRight ? TINIEST_TICK_LENGTH : -1 * TINIEST_TICK_LENGTH;
|
||||||
|
int minor = drawTicksRight ? MINOR_TICK_LENGTH : -1 * MINOR_TICK_LENGTH;
|
||||||
|
int mid = drawTicksRight ? MID_MAJOR_TICK_LENGTH : -1 * MID_MAJOR_TICK_LENGTH;
|
||||||
|
int major = drawTicksRight ? MAJOR_TICK_LENGTH : -1 * MAJOR_TICK_LENGTH;
|
||||||
|
|
||||||
|
//Draw solid vertical line
|
||||||
|
g.setColor(Color.black);
|
||||||
|
g.drawLine(x, y, x, y + length);
|
||||||
|
|
||||||
|
//Draw horizontal rule ticks for the vertical ruler
|
||||||
|
//Draw tiny ticks
|
||||||
|
int initial = y;
|
||||||
|
int end = initial + length;
|
||||||
|
double increment = tinyEveryY;
|
||||||
|
boolean lessThanEqual = true;
|
||||||
|
if (!vertexAtTop) {
|
||||||
|
initial = y + length;
|
||||||
|
end = y;
|
||||||
|
lessThanEqual = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tinyEveryY > 0) {
|
||||||
|
if (!vertexAtTop) {
|
||||||
|
increment = -1 * increment;
|
||||||
|
}
|
||||||
|
for (double tick = initial; lessThanEqual ? (tick <= end) : (tick >= end); tick += increment) {
|
||||||
|
g.drawLine(x, (int) tick, x - tiniest, (int) tick);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Draw minor ticks
|
||||||
|
if (minorEveryY > 0) {
|
||||||
|
if (!vertexAtTop) {
|
||||||
|
increment = -1 * minorEveryY;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
increment = minorEveryY;
|
||||||
|
}
|
||||||
|
for (double tick = initial; lessThanEqual ? (tick <= end) : (tick >= end); tick += increment) {
|
||||||
|
g.drawLine(x, (int) tick, x - minor, (int) tick);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Draw mid-major ticks
|
||||||
|
if (!vertexAtTop) {
|
||||||
|
increment = -1 * midMajorEveryY;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
increment = midMajorEveryY;
|
||||||
|
}
|
||||||
|
for (double tick = initial; lessThanEqual ? (tick <= end) : (tick >= end); tick += increment) {
|
||||||
|
g.drawLine(x, (int) tick, x - mid, (int) tick);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Draw major ticks
|
||||||
|
if (!vertexAtTop) {
|
||||||
|
increment = -1 * majorEveryY;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
increment = majorEveryY;
|
||||||
|
}
|
||||||
|
for (double tick = initial; lessThanEqual ? (tick <= end) : (tick >= end); tick += increment) {
|
||||||
|
g.drawLine(x, (int) tick, x - major, (int) tick);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -6,6 +6,7 @@ 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.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.logging.LogHelper;
|
||||||
import net.sf.openrocket.rocketcomponent.CenteringRing;
|
import net.sf.openrocket.rocketcomponent.CenteringRing;
|
||||||
@ -104,9 +105,12 @@ public class CenteringRingStrategy {
|
|||||||
pageFitPrint.addComponent(pfs);
|
pageFitPrint.addComponent(pfs);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
int off = (int) (PrintUnit.POINTS_PER_INCH * 0.3f);
|
||||||
|
pfs.setPrintOffset(off, off);
|
||||||
BufferedImage image = (BufferedImage) pfs.createImage();
|
BufferedImage image = (BufferedImage) pfs.createImage();
|
||||||
ITextHelper.renderImageAcrossPages(new Rectangle(pageSize.getWidth(), pageSize.getHeight()),
|
ITextHelper.renderImageAcrossPages(new Rectangle(pageSize.getWidth(), pageSize.getHeight()),
|
||||||
document, writer, image);
|
document, writer, image);
|
||||||
|
document.newPage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (DocumentException e) {
|
catch (DocumentException e) {
|
||||||
|
@ -6,7 +6,6 @@ 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.Rectangle;
|
||||||
import com.itextpdf.text.pdf.PdfContentByte;
|
|
||||||
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.ITextHelper;
|
||||||
import net.sf.openrocket.gui.print.PrintUnit;
|
import net.sf.openrocket.gui.print.PrintUnit;
|
||||||
@ -16,11 +15,8 @@ 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 net.sf.openrocket.startup.Application;
|
||||||
|
|
||||||
import java.awt.*;
|
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.ListIterator;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -110,6 +106,8 @@ public class FinSetPrintStrategy {
|
|||||||
pageFitPrint.addComponent(pfs);
|
pageFitPrint.addComponent(pfs);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
int off = (int)(PrintUnit.POINTS_PER_INCH * 0.3f);
|
||||||
|
pfs.setPrintOffset(off, off);
|
||||||
BufferedImage image = (BufferedImage) pfs.createImage();
|
BufferedImage image = (BufferedImage) pfs.createImage();
|
||||||
ITextHelper.renderImageAcrossPages(new Rectangle(pageSize.getWidth(), pageSize.getHeight()),
|
ITextHelper.renderImageAcrossPages(new Rectangle(pageSize.getWidth(), pageSize.getHeight()),
|
||||||
document, writer, image);
|
document, writer, image);
|
||||||
|
@ -12,8 +12,9 @@ import net.sf.openrocket.logging.LogHelper;
|
|||||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||||
import net.sf.openrocket.startup.Application;
|
import net.sf.openrocket.startup.Application;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.Graphics2D;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.ListIterator;
|
import java.util.ListIterator;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
@ -51,7 +52,6 @@ public class PageFitPrintStrategy {
|
|||||||
*
|
*
|
||||||
* @param doc The iText document
|
* @param doc The iText document
|
||||||
* @param theWriter The direct iText writer
|
* @param theWriter The direct iText writer
|
||||||
* @param theStages The stages to be printed by this strategy
|
|
||||||
*/
|
*/
|
||||||
public PageFitPrintStrategy(Document doc, PdfWriter theWriter) {
|
public PageFitPrintStrategy(Document doc, PdfWriter theWriter) {
|
||||||
document = doc;
|
document = doc;
|
||||||
@ -88,15 +88,17 @@ public class PageFitPrintStrategy {
|
|||||||
int marginY = (int)(PrintUnit.POINTS_PER_INCH * 0.3f);
|
int marginY = (int)(PrintUnit.POINTS_PER_INCH * 0.3f);
|
||||||
PdfContentByte cb = writer.getDirectContent();
|
PdfContentByte cb = writer.getDirectContent();
|
||||||
|
|
||||||
|
Collections.sort(componentToPrint);
|
||||||
|
|
||||||
while (componentToPrint.size() > 0) {
|
while (componentToPrint.size() > 0) {
|
||||||
int pageY = 0;
|
int pageY = marginY;
|
||||||
Boolean anyAddedToRow;
|
Boolean anyAddedToRow;
|
||||||
|
|
||||||
Graphics2D g2 = cb.createGraphics(pageSize.width, pageSize.height);
|
Graphics2D g2 = cb.createGraphics(pageSize.width, pageSize.height);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
// Fill the row
|
// Fill the row
|
||||||
int rowX = 0;
|
int rowX = marginX;
|
||||||
int rowY = pageY;
|
int rowY = pageY;
|
||||||
ListIterator<PrintableComponent> entry = componentToPrint.listIterator();
|
ListIterator<PrintableComponent> entry = componentToPrint.listIterator();
|
||||||
anyAddedToRow = false;
|
anyAddedToRow = false;
|
||||||
@ -104,16 +106,18 @@ 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 < wPage) && (rowY + dim.height < hPage)) {
|
if ((rowX + dim.width + marginX < wPage) && (rowY + dim.height + marginY < hPage)) {
|
||||||
component.setPrintOffset(rowX, rowY);
|
component.setPrintOffset(rowX, rowY);
|
||||||
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pageY += marginY;
|
||||||
} while (anyAddedToRow);
|
} while (anyAddedToRow);
|
||||||
|
|
||||||
g2.dispose();
|
g2.dispose();
|
||||||
|
@ -6,6 +6,7 @@ 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.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.logging.LogHelper;
|
||||||
@ -46,7 +47,7 @@ public class TransitionStrategy {
|
|||||||
/**
|
/**
|
||||||
* Strategy for fitting multiple components onto a page.
|
* Strategy for fitting multiple components onto a page.
|
||||||
*/
|
*/
|
||||||
protected PageFitPrintStrategy pageFitPrint;
|
protected PageFitPrintStrategy pageFitPrint;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
@ -67,10 +68,12 @@ public class TransitionStrategy {
|
|||||||
*
|
*
|
||||||
* @param root the root component; all children will be visited recursively
|
* @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
|
* @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();
|
List<RocketComponent> rc = root.getChildren();
|
||||||
goDeep(rc, noseCones);
|
return goDeep(rc, noseCones);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -79,48 +82,62 @@ public class TransitionStrategy {
|
|||||||
*
|
*
|
||||||
* @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
|
* @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) {
|
for (RocketComponent rocketComponent : theRc) {
|
||||||
if (rocketComponent instanceof NoseCone) {
|
if (rocketComponent instanceof NoseCone) {
|
||||||
if (noseCones) {
|
if (noseCones) {
|
||||||
render((Transition) rocketComponent);
|
return render((Transition) rocketComponent);
|
||||||
}
|
}
|
||||||
} else if (rocketComponent instanceof Transition && !noseCones) {
|
}
|
||||||
render((Transition) rocketComponent);
|
else if (rocketComponent instanceof Transition && !noseCones) {
|
||||||
} else if (rocketComponent.getChildCount() > 0) {
|
return render((Transition) rocketComponent);
|
||||||
goDeep(rocketComponent.getChildren(), noseCones);
|
}
|
||||||
|
else if (rocketComponent.getChildCount() > 0) {
|
||||||
|
return goDeep(rocketComponent.getChildren(), noseCones);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The core behavior of this visitor.
|
* 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 {
|
try {
|
||||||
AbstractPrintable pfs;
|
AbstractPrintable pfs;
|
||||||
if (component instanceof NoseCone) {
|
if (component instanceof NoseCone) {
|
||||||
pfs = new PrintableNoseCone((NoseCone)component);
|
pfs = new PrintableNoseCone((NoseCone) component);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
pfs = new PrintableTransition(component);
|
pfs = new PrintableTransition(component);
|
||||||
}
|
}
|
||||||
|
|
||||||
java.awt.Dimension size = pfs.getSize();
|
java.awt.Dimension size = pfs.getSize();
|
||||||
final Dimension pageSize = getPageSize();
|
final Dimension pageSize = getPageSize();
|
||||||
if (fitsOnOnePage(pageSize, size.getWidth(), size.getHeight())) {
|
if (fitsOnOnePage(pageSize, size.getWidth(), size.getHeight())) {
|
||||||
pageFitPrint.addComponent(pfs);
|
pageFitPrint.addComponent(pfs);
|
||||||
//printOnOnePage(pfs);
|
}
|
||||||
} else {
|
else {
|
||||||
|
int off = (int) (PrintUnit.POINTS_PER_INCH * 0.3f);
|
||||||
|
pfs.setPrintOffset(off, off);
|
||||||
BufferedImage image = (BufferedImage) pfs.createImage();
|
BufferedImage image = (BufferedImage) pfs.createImage();
|
||||||
ITextHelper.renderImageAcrossPages(new Rectangle(pageSize.getWidth(), pageSize.getHeight()),
|
ITextHelper.renderImageAcrossPages(new Rectangle(pageSize.getWidth(), pageSize.getHeight()),
|
||||||
document, writer, image);
|
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);
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -129,6 +146,7 @@ public class TransitionStrategy {
|
|||||||
* @param pageSize the page size
|
* @param pageSize the page size
|
||||||
* @param wImage the width of the thing to be printed
|
* @param wImage the width of the thing to be printed
|
||||||
* @param hImage the height 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
|
* @return true if the thing to be printed will fit on a single page
|
||||||
*/
|
*/
|
||||||
private boolean fitsOnOnePage(Dimension pageSize, double wImage, double hImage) {
|
private boolean fitsOnOnePage(Dimension pageSize, double wImage, double hImage) {
|
||||||
|
49
core/test/net/sf/openrocket/gui/print/PrintUnitTest.java
Normal file
49
core/test/net/sf/openrocket/gui/print/PrintUnitTest.java
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
package net.sf.openrocket.gui.print;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PrintUnit Tester.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class PrintUnitTest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Method: toMillis(double length)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testToMillis() throws Exception {
|
||||||
|
Assert.assertEquals(25.400000, PrintUnit.INCHES.toMillis(1), 0.00001);
|
||||||
|
Assert.assertEquals(1, PrintUnit.MILLIMETERS.toInches(PrintUnit.INCHES.toMillis(1)), 0.000001);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Method: toCentis(double length)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testToCentis() throws Exception {
|
||||||
|
Assert.assertEquals(4, PrintUnit.CENTIMETERS.toMeters(PrintUnit.METERS.toCentis(4)), 0.000001);
|
||||||
|
Assert.assertEquals(4, PrintUnit.CENTIMETERS.toPoints(PrintUnit.POINTS.toCentis(4)), 0.000001);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Method: toPoints(double length)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testToPoints() throws Exception {
|
||||||
|
Assert.assertEquals(1, PrintUnit.POINTS.toInches(72), 0.00001);
|
||||||
|
Assert.assertEquals(25.4, PrintUnit.POINTS.toMillis(72), 0.00001);
|
||||||
|
Assert.assertEquals(1, PrintUnit.MILLIMETERS.toPoints(PrintUnit.POINTS.toMillis(1)), 0.000001);
|
||||||
|
|
||||||
|
Assert.assertEquals(28.3464567, PrintUnit.CENTIMETERS.toPoints(1), 0.000001d);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user