/*

 * 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://sourceforge.net/projects/itext/files/

// --> the plain compiled iText core "iText-5.0.4.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/Downloads/iText-5.0.4.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 = JSCFont( "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.itextpdf.text.Rectangle", g, 0, 0, width, height );

doc = JavaObject( "com.itextpdf.text.Document", g, pageSize, 0, 0, 0, 0 );

writerC = JavaObject.getClass( "com.itextpdf.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, false );

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, "~/Desktop/test.pdf".standardizePath, 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.itextpdf.text.Rectangle", g, 0, 0, width, height );

doc = JavaObject( "com.itextpdf.text.Document", g, pageSize, 0, 0, 0, 0 );

writerC = JavaObject.getClass( "com.itextpdf.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, "~/Desktop/test2.pdf".standardizePath, 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, "~/Desktop/test3.pdf".standardizePath, h, v );