Package ch.randelshofer.scorm

Source Code of ch.randelshofer.scorm.CourseModelPDFPrinter

/*
* @(#)CourseModelPDFPrinter.java  1.0.7  2008-12-16
*
* Copyright (c) 2007-2008 Werner Randelshofer
* Hausmatt 10, CH-6405 Immensee, Switzerland
* All rights reserved.
*
* The copyright of this software is owned by Werner Randelshofer.
* You may not use, copy or modify this software, except in 
* accordance with the license agreement you entered into with 
* Werner Randelshofer. For details see accompanying license terms.
*/
package ch.randelshofer.scorm;

import ch.randelshofer.gui.ProgressIndicator;
import ch.randelshofer.scorm.cam.*;
import ch.randelshofer.util.ResourceBundleUtil;
import com.lowagie.text.*;
import com.lowagie.text.pdf.*;
import java.awt.image.*;
import java.text.DateFormat;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.*;
import java.io.*;
import java.net.*;
import java.util.*;
import javax.xml.parsers.SAXParserFactory;
import org.ccil.cowan.tagsoup.Parser;
import org.ccil.cowan.tagsoup.jaxp.*;
import org.xhtmlrenderer.pdf.ITextOutputDevice;
import org.xhtmlrenderer.pdf.ITextRenderer;
import org.xhtmlrenderer.simple.*;
import org.xhtmlrenderer.util.XRLog;
import org.xml.sax.SAXException;

/**
* Prints a CourseModel as a PDF document.
*
* @author Werner Randelshofer
* @version 1.0.7 2008-12-16 Fixed encoding of baseURI.
* <br>1.0 6. August 2007 Created.
*/
public class CourseModelPDFPrinter {

    private CourseModel model;
    private URI baseURI;
    private File pdfFile;
    private ResourceBundleUtil labels;
    /**
     * If this is set to true, renders a page first as an image, and inserts
     * it into the PDF page.
     * <p>
     * If this is set to false, renders a page directly into PDF page.
     */
    private boolean isRenderAsImage = false;
    private String mediaType = "screen";

    /** Creates a new instance. */
    public CourseModelPDFPrinter(CourseModel model) {
        this.model = model;
        baseURI = model.getIMSManifestDocument().getManifestURI();
        labels = ResourceBundleUtil.getLAFBundle("ch.randelshofer.scorm.Labels");
    }

    public void setMediaType(String newValue) {
        mediaType = newValue;
    }

    public void setRenderAsImage(boolean newValue) {
        isRenderAsImage = newValue;
    }

    public void print(File pdfFile, ProgressIndicator p) throws IOException {
        if (isRenderAsImage) {
            printAsImage(pdfFile, p);
        } else {
            printAsText(pdfFile, p);
        }
    }

    public void printAsImage(File pdfFile, ProgressIndicator p) throws IOException {
        System.setProperty("xr.load.xml-reader", "org.ccil.cowan.tagsoup.Parser");
        XRLog.setLoggingEnabled(false);

        this.pdfFile = pdfFile;

        ArrayList pageList = model.createPageList(model.getSelectedOrganization());
        p.setMaximum(pageList.size());

        String printDate = DateFormat.getInstance().format(new Date());


        Document pdf = new Document(PageSize.A4, 50, 50, 50, 50);
        PdfWriter writer;
        try {
            writer = PdfWriter.getInstance(pdf, new FileOutputStream(pdfFile));


            // Print each page
            // -------------------------------------------
            for (int i = 0; i < pageList.size() && !p.isCanceled(); i++) {
                ItemElement item = (ItemElement) pageList.get(i);

                p.setProgress(i);
                p.setNote(item.getTitle());

                Enumeration enm = model.getIMSManifestDocument().getResourcesElement().preorderEnumeration();
                ResourceElement resource = null;
                while (enm.hasMoreElements()) {
                    Object o = enm.nextElement();
                    if (o instanceof ResourceElement) {
                        resource = (ResourceElement) o;
                        if (item.getIdentifierref().equals(resource.getIdentifier())) {
                            break;
                        }
                    }
                }

                Phrase phrase = new Phrase(model.getSelectedOrganization().getTitle());
                HeaderFooter header = new MyHeaderFooter(
                        new Phrase(model.getSelectedOrganization().getTitle()),
                        new Phrase(item.getTitle()));
                pdf.setHeader(header);
                HeaderFooter footer = new MyHeaderFooter(
                        new Phrase(printDate),
                        new Phrase(labels.getFormatted("pdf.pagina", Integer.toString(i + 1))));
                footer.setAlignment(HeaderFooter.ALIGN_RIGHT);
                pdf.setHeader(header);
                pdf.setFooter(footer);


                if (i == 0) {
                    pdf.open();
                } else {
                    pdf.newPage();
                }
                printPageAsImage(pdf, writer, baseURI.toURL(), resource.getHRef());
            }
            p.setProgress(pageList.size());

        } catch (DocumentException ex) {
            IOException ioe = new IOException(ex.getMessage());
            ioe.initCause(ex);
            throw ioe;
        } finally {
            try {
                pdf.close();
            } catch (Throwable e) {
            }
            p.close();
        }
    }

    /**
     * Exports a document to pdf.
     * @param pdf The PDF output document
     * @param baseURI the base URL of the input document
     * @param href the relative URL of the input document.
     */
    private void printPageAsImage(Document pdf, PdfWriter writer, URL baseURL, String href) throws IOException, DocumentException {

        File outDir = pdfFile.getParentFile();
        File outFile = new File(outDir, href);
        URL url = new URL(baseURL, href);
        URI uri;
        try {
            uri = url.toURI();
        } catch (URISyntaxException ex) {
            IOException ioe = new IOException("Couldn't convert "+url+" to URI");
            ioe.initCause(ex);
            throw ioe;
        }

        if (isRenderAsImage) {
            // Width and height of an A4 page (210x297 mm) in 300 DPI;
            int width = (int) (210 * 300 / 254);
            int height = (int) (297 * 300 / 254);
            try {
                width = Integer.decode(model.getFramesetPageWidth());
            } catch (NumberFormatException ex) {
            //ex.printStackTrace();
            }
            try {
                height = Integer.decode(model.getFramesetPageHeight());
            } catch (NumberFormatException ex) {
            //ex.printStackTrace();
            }

            ImageRenderer renderer = new ImageRenderer();
            BufferedImage bufferedImg = renderer.renderToImage(
                    uri.toString(),
                    null,
                    width, height);
            //ImageIO.write(img, "PNG", new File(outFile.getPath()+".png"));

            com.lowagie.text.Image img = com.lowagie.text.Image.getInstance(
                    bufferedImg, null);
            float absWidth = pdf.getPageSize().getWidth() - pdf.leftMargin() - pdf.rightMargin();
            float absHeight = absWidth * bufferedImg.getHeight() / bufferedImg.getWidth();

            // if the image is too high, scale it down
            float oversizeFactor = (pdf.getPageSize().getHeight() -
                    pdf.leftMargin() -
                    pdf.rightMargin()) / absHeight;
            if (oversizeFactor < 1f) {
                absWidth *= oversizeFactor;
                absHeight *= oversizeFactor;
            }

            img.scaleAbsolute(absWidth, absHeight);
            img.setAbsolutePosition(
                    (pdf.getPageSize().getWidth() - absWidth) / 2f,
                    (pdf.getPageSize().getHeight() - absHeight) / 2f + pdf.bottomMargin());
            PdfContentByte cb = writer.getDirectContent();
            cb.addImage(img);
        } else {
            /* Unfortunately, the PDF Renderer only renders the text of an HTML page* /
            PDFRenderer renderer = new PDFRenderer();
            try {
            renderer.renderToPDF(url.toString(), outFile.getPath()+".pdf");
            } catch (DocumentException e) {
            IOException ioe = new IOException("Couldn't render "+url);
            ioe.initCause(e);
            throw ioe;
            }*/

            // This might work better:
            ITextRenderer renderer = new ITextRenderer();
            renderer.setDocument(url.toString());
            renderer.getSharedContext().setPrint(false); // Explicitly switch print mode off
            OutputStream os = null;
            try {
                os = new FileOutputStream(outFile.getPath() + ".pdf");
                renderer.layout();
                renderer.createPDF(os);

                os.close();
                os = null;
            } finally {
                if (os != null) {
                    try {
                        os.close();
                    } catch (IOException e) {
                    // ignore
                    }
                }
            }
        }
    }

    public void printAsText(File pdfFile, ProgressIndicator p) throws IOException {
        System.setProperty("xr.load.xml-reader", "org.ccil.cowan.tagsoup.Parser");
        XRLog.setLoggingEnabled(false);

        this.pdfFile = pdfFile;

        ArrayList pageList = model.createPageList(model.getSelectedOrganization());
        p.setMaximum(pageList.size());

        String printDate = DateFormat.getInstance().format(new Date());

        // Width and height of an A4 page (210x297 mm) in 72 DPI;
        int width = (int) (210 * 254 / 72);
        int height = (int) (297 * 254 / 72);
        try {
            width = Integer.decode(model.getFramesetPageWidth());
        } catch (NumberFormatException ex) {
        //ex.printStackTrace();
        }
        try {
            height = Integer.decode(model.getFramesetPageHeight());
        } catch (NumberFormatException ex) {
        //ex.printStackTrace();
        }
       
        float dpi = width / (190f / 25.4f * 3.5f);
        OutputStream os = null;
        try {
            os = new FileOutputStream(pdfFile);

            // ITextRenderer renderer = new ITextRenderer();
            // ITextRenderer renderer = new ITextRenderer(20f * 4f / 3f, 20);
            ITextRenderer renderer = new ITextRenderer(dpi, 20);
            renderer.getSharedContext().setMedia(mediaType);

            // Print each page
            // -------------------------------------------
            for (int i = 0; i < pageList.size() && !p.isCanceled(); i++) {
                ItemElement item = (ItemElement) pageList.get(i);

                p.setProgress(i);
                p.setNote(item.getTitle());

                Enumeration enm = model.getIMSManifestDocument().getResourcesElement().preorderEnumeration();
                ResourceElement resource = null;
                while (enm.hasMoreElements()) {
                    Object o = enm.nextElement();
                    if (o instanceof ResourceElement) {
                        resource = (ResourceElement) o;
                        if (item.getIdentifierref().equals(resource.getIdentifier())) {
                            break;
                        }
                    }
                }


                URL url = new URL(baseURI.toURL(), resource.getHRef());
                renderer.setDocument(url.toString());
                renderer.layout();
                if (i == 0) {
                    renderer.createPDF(os, false);
                } else {
                    renderer.writeNextDocument();
                }
            }

            renderer.finishPDF();

            os.close();
            os = null;
        } catch (DocumentException de) {
            IOException e = new IOException();
            e.initCause(de);
            throw e;
        } finally {
            if (os != null) {
                try {
                    os.close();
                } catch (IOException e) {
                // ignore
                }
            }
        }
    }

    public static class MyHeaderFooter extends HeaderFooter {

        public MyHeaderFooter(Phrase before, Phrase after) {
            super(before, after);
        }

        public Paragraph paragraph() {
            Paragraph paragraph = new Paragraph(getBefore().getLeading());
            paragraph.add(getBefore());
            paragraph.addSpecial(new Phrase(" – "));
            /*
            if (numbered) {
            paragraph.addSpecial(new Chunk(String.valueOf(pageN), before.font()));
            }*/
            if (getAfter() != null) {
                paragraph.addSpecial(getAfter());
            }
            paragraph.setAlignment(alignment());
            return paragraph;
        }
    }
}
TOP

Related Classes of ch.randelshofer.scorm.CourseModelPDFPrinter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.