Package org.geomajas.plugin.printing.document

Source Code of org.geomajas.plugin.printing.document.SinglePageDocument

/*
* This is part of Geomajas, a GIS framework, http://www.geomajas.org/.
*
* Copyright 2008-2011 Geosparc nv, http://www.geosparc.com/, Belgium.
*
* The program is available in open source according to the GNU Affero
* General Public License. All contributions in this program are covered
* by the Geomajas Contributors License Agreement. For full licensing
* details, see LICENSE.txt in the project root.
*/
package org.geomajas.plugin.printing.document;

import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;

import javax.imageio.ImageIO;

import org.geomajas.plugin.printing.PrintingException;
import org.geomajas.plugin.printing.component.MapComponent;
import org.geomajas.plugin.printing.component.PageComponent;
import org.geomajas.plugin.printing.component.PdfContext;
import org.geomajas.plugin.printing.component.PrintComponent;
import org.jpedal.PdfDecoder;
import org.jpedal.exception.PdfException;

import com.lowagie.text.Document;
import com.lowagie.text.DocumentException;
import com.lowagie.text.Rectangle;
import com.lowagie.text.pdf.PdfWriter;

/**
* Single page document for printing.
*
* @author Jan De Moerloose
*/
public class SinglePageDocument extends AbstractDocument {

  /**
   * the page to render
   */
  protected PageComponent page;

  /**
   * filters to apply to layers
   */
  protected Map<String, String> filters;

  /**
   * In-memory output stream to know content length.
   */
  private ByteArrayOutputStream baos;

  /**
   * Constructs a document with the specified dimensions.
   *
   * @param page page
   * @param filters filters
   */
  public SinglePageDocument(PageComponent page, Map<String, String> filters) {
    this.page = page;
    this.filters = (filters == null ? new HashMap<String, String>() : filters);

    // set filters
    for (PrintComponent comp : getPage().getChildren()) {
      if (comp instanceof MapComponent) {
        ((MapComponent) comp).setFilter(filters);
      }
    }
  }

  /**
   * Renders the document to the specified output stream.
   */
  public void render(OutputStream outputStream, Format format) throws PrintingException {
    try {
      doRender(outputStream, format);
    } catch (Exception e) {
      throw new PrintingException(e, PrintingException.DOCUMENT_RENDER_PROBLEM);
    }
  }

  /**
   * Re-calculates the layout and renders to internal memory stream. Always call this method before calling render()
   * to make sure that the latest document changes have been taken into account for rendering.
   *
   * @param format format
   * @throws PrintingException oops
   */
  public void layout(Format format) throws PrintingException {
    try {
      doRender(null, format);
    } catch (Exception e) {
      throw new PrintingException(e, PrintingException.DOCUMENT_LAYOUT_PROBLEM);
    }
  }

  /**
   * Prepare the document before rendering.
   *
   * @param outputStream output stream to render to, null if only for layout
   * @param format format
   * @throws DocumentException oops
   * @throws IOException oops
   * @throws PrintingException oops
   */
  private void doRender(OutputStream outputStream, Format format) throws IOException, DocumentException,
      PrintingException {
    // first render or re-render for different layout
    if (outputStream == null || baos == null || null != format) {
      if (baos == null) {
        baos = new ByteArrayOutputStream(10 * 1024);
      }
      baos.reset();
      boolean resize = false;
      if (page.getBounds().getWidth() == 0 || page.getBounds().getHeight() == 0) {
        resize = true;
      }
      // Create a document in the requested ISO scale.
      Document document = new Document(page.getBounds(), 0, 0, 0, 0);
      PdfWriter writer;
      writer = PdfWriter.getInstance(document, baos);

      // Render in correct colors for transparent rasters
      writer.setRgbTransparencyBlending(true);

      // The mapView is not scaled to the document, we assume the mapView
      // has the right ratio.

      // Write document title and metadata
      document.open();
      PdfContext context = new PdfContext(writer);
      context.initSize(page.getBounds());
      // first pass of all children to calculate size
      page.calculateSize(context);
      if (resize) {
        // we now know the bounds of the document
        // round 'm up and restart with a new document
        int width = (int) Math.ceil(page.getBounds().getWidth());
        int height = (int) Math.ceil(page.getBounds().getHeight());
        page.getConstraint().setWidth(width);
        page.getConstraint().setHeight(height);
        document = new Document(new Rectangle(width, height), 0, 0, 0, 0);
        writer = PdfWriter.getInstance(document, baos);
        // Render in correct colors for transparent rasters
        writer.setRgbTransparencyBlending(true);
        document.open();
        baos.reset();
        context = new PdfContext(writer);
        context.initSize(page.getBounds());
      }
      // Actual drawing
      document.addTitle("Geomajas");
      // second pass to layout
      page.layout(context);
      // finally render
      page.render(context);
      document.add(context.getImage());
      // Now close the document
      document.close();
      // convert to non-pdf format
      switch (format) {
        case PDF:
          break;
        case PNG:
        case JPG:
          /** instance of PdfDecoder to convert PDF into image */
          PdfDecoder decodePdf = new PdfDecoder(true);

          /** set mappings for non-embedded fonts to use */
          PdfDecoder.setFontReplacements(decodePdf);
          decodePdf.useHiResScreenDisplay(true);
          decodePdf.getDPIFactory().setDpi(2 * 72);
          decodePdf.setPageParameters(1, 1);
          try {
            decodePdf.openPdfArray(baos.toByteArray());
            /** get page 1 as an image */
            BufferedImage img = decodePdf.getPageAsImage(1);

            /** close the pdf file */
            decodePdf.closePdfFile();
            baos.reset();
            ImageIO.write(img, format.getExtension(), baos);
          } catch (PdfException e) {
            throw new PrintingException(e, PrintingException.DOCUMENT_RENDER_PROBLEM);
          }
          break;
        default:
          throw new IllegalStateException(
              "Oops, software error, need to support extra format at end of render" + format);
      }
      if (outputStream != null) {
        baos.writeTo(outputStream);
      }
    } else {
      baos.writeTo(outputStream);
    }
  }

  public PageComponent getPage() {
    return page;
  }

  public int getContentLength() {
    return baos == null ? 0 : baos.size();
  }

}
TOP

Related Classes of org.geomajas.plugin.printing.document.SinglePageDocument

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.