/*

* 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 this 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 );