/*
* SwingOSC proves very powerful in providing a bridge to any other third party java library.
*
* Here we demonstrate how to utilize the iText PDF library to export a drawing designed
* for JPen as a PDF document
*/
// first download iText from here: http://www.lowagie.com/iText/download.html
// --> the plain compiled iText core "iText-2.1.2u.jar" should be sufficent
// add the library to the classpath
// (do this only once after booting SwingOSC)
// (make sure to use the correct URL!)
SwingOSC.default.addClasses( "file:///Users/rutz/Desktop/iText-2.1.2u.jar" );
// paper size
h = 595; v = 842; // this is A4 with 72 dpi (iText standard)
// define a JPen function
(
~func = {
// the translate / scale / rotate don't seem to work ATM ;-C
// JPen.translate( h / 2, v / 2 );
thisThread.randSeed = 0; // so we can really compare the screen and pdf
500.do {
JPen.color = Color.green( rrand( 0.0, 1 ), rrand( 0.0, 0.5 ));
JPen.addAnnularWedge(
(h/2).rand @ (v/2).rand,
rrand( h/20, h/4 ),
rrand( h/4, h/2 ),
2pi.rand,
2pi.rand
);
JPen.perform([ \stroke, \fill ].choose );
};
JPen.font = JFont( "Helvetica", 36 );
JPen.fillColor = Color.white;
JPen.stringAtPoint( "PDF Example", (h/4) @ (v/4) );
};
)
// lets see the graphics in a regular window
(
w = JSCWindow( "Graphics", Rect( 400, 20, h, v ), resizable: false );
w.view.background_( Color.white );
w.drawHook = ~func;
w.front;
)
// a function that creates a pdf
(
~createPDF = { arg drawFunc, fileName, width = 595, height = 842;
var g, pageSize, doc, writerC, stream, writer, cb, tp, g2, pen;
g = SwingOSC.default;
pageSize = JavaObject( "com.lowagie.text.Rectangle", g, 0, 0, width, height );
doc = JavaObject( "com.lowagie.text.Document", g, pageSize, 80, 60, 60, 60 ); // margins don't matter
writerC = JavaObject.getClass( "com.lowagie.text.pdf.PdfWriter", g );
stream = JavaObject( "java.io.FileOutputStream", g, fileName );
writer = writerC.getInstance__( doc, stream );
doc.open;
cb = writer.getDirectContent__;
tp = cb.createTemplate__( width, height );
g2 = tp.createGraphics__( width, height );
pen = JavaObject( "de.sciss.swingosc.Pen", g, nil );
JPen.protRefresh( drawFunc, nil, g, pen.id );
pen.paintIcon( nil, g2, 0, 0 );
g2.dispose;
cb.addTemplate( tp, 0, 0 );
doc.close;
doc.destroy; cb.destroy; g2.destroy; pen.destroy; tp.destroy;
writer.destroy; stream.destroy; writerC.destroy; pageSize.destroy;
};
)
// this actually creates the file
// (make sure to use a proper file name!)
~createPDF.( ~func, "/Users/rutz/Desktop/test.pdf", h, v );
// here's another one
(
~func = {
JPen.width = 2;
80.do {
JPen.width = rrand(0,4) + 0.5;
JPen.moveTo(Point(h.rand, v.rand));
JPen.lineTo(Point(h.rand, v.rand));
JPen.stroke;
};
};
)
// you can also use iText to create a PDF screenshot from a window
// ; the quality depends however on the particular widgets used
// (pure vector graphics widgets will scale smoothly, while those
// using bitmap images will scale poorly)
(
~pdfScreenShot = { arg view, fileName, width = 595, height = 842;
var g, bounds, pageSize, doc, writerC, stream, writer, cb, tp, g2, viewJ;
g = view.server;
bounds = view.bounds;
pageSize = JavaObject( "com.lowagie.text.Rectangle", g, 0, 0, width, height );
doc = JavaObject( "com.lowagie.text.Document", g, pageSize, 80, 60, 60, 60 ); // margins don't matter
writerC = JavaObject.getClass( "com.lowagie.text.pdf.PdfWriter", g );
stream = JavaObject( "java.io.FileOutputStream", g, fileName );
writer = writerC.getInstance__( doc, stream );
doc.open;
cb = writer.getDirectContent__;
tp = cb.createTemplate__( bounds.width, bounds.height );
g2 = tp.createGraphics__( bounds.width, bounds.height );
viewJ = JavaObject.basicNew( view.id, g );
viewJ.paint( g2 );
g2.dispose;
cb.addTemplate( tp, (width - bounds.width) / 2, (height - bounds.height) / 2 ); // centered
doc.close;
doc.destroy; cb.destroy; g2.destroy; tp.destroy;
writer.destroy; stream.destroy; writerC.destroy; pageSize.destroy;
};
)
// some look-and-feels operate on the OS level and are not
// pure java (e.g. apple's aqua). they are not exported properly, so
// we ensure here that the default "metal" look-and-feel is used
~ui = JavaObject.getClass( "javax.swing.UIManager" );
~ui.setLookAndFeel( "javax.swing.plaf.metal.MetalLookAndFeel" );
JSCWindow.viewPalette;
~pdfScreenShot.( JSCWindow.allWindows.last.view, "/Users/rutz/Desktop/test2.pdf", h, v );
// the cool thing of this second approach is that the affine transforms seem
// to fully working this way:
(
w = JSCWindow.new.front;
w.view.background_( Color.white );
w.drawHook = {
var x1, y1, x2, y2, x1a, y1a, x2a, y2a, txr, tyr, rr;
thisThread.randSeed = 666;
JPen.translate( 200, 200 );
JPen.scale( 0.5, 0.5 );
x1 = 175.0.bilinrand;
x2 = 175.0.bilinrand;
y1 = 175.0.bilinrand;
y2 = 175.0.bilinrand;
x1a = 15.0.bilinrand;
x2a = 15.0.bilinrand;
y1a = 15.0.bilinrand;
y2a = 15.0.bilinrand;
txr = 2.0.bilinrand;
tyr = 2.0.bilinrand;
rr = 0.05pi.bilinrand;
JPen.moveTo( 175 @ 0 );
200.do { arg i;
JPen.translate( txr, tyr );
JPen.rotate( rr );
JPen.line( x1 @ y1, x2 @ y2 );
x1 = x1 + x1a;
x2 = x2 + x2a;
y1 = y1 + y1a;
y2 = y2 + y2a;
};
JPen.stroke;
};
)
~pdfScreenShot.( w.view, "/Users/rutz/Desktop/test3.pdf", h, v );