org.mapfish.print.PDFCustomBlocks Maven / Gradle / Ivy
/*
* Copyright (C) 2013 Camptocamp
*
* This file is part of MapFish Print
*
* MapFish Print is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* MapFish Print is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with MapFish Print. If not, see .
*/
package org.mapfish.print;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
import org.mapfish.print.config.layout.HeaderFooter;
import org.mapfish.print.utils.PJsonObject;
import com.itextpdf.text.BadElementException;
import com.itextpdf.text.Chunk;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Font;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.PdfAnnotation;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfImportedPage;
import com.itextpdf.text.pdf.PdfPageEventHelper;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfWriter;
/**
* Listen to events from the PDF document in order to render the
* custom {@link org.mapfish.print.ChunkDrawer}s, the header/footer and the background.
*/
public class PDFCustomBlocks extends PdfPageEventHelper {
public static final Logger LOGGER = Logger.getLogger(PDFCustomBlocks.class);
private ChunkDrawer last = null;
private final PdfWriter writer;
private final RenderingContext context;
private HeaderFooter header;
private PJsonObject headerParams;
private HeaderFooter footer;
private PJsonObject footerParams;
private String backgroundPdf;
private final List errors = Collections.synchronizedList(new ArrayList());
/**
* cache of background PDF pages
*/
private final Map backgroundPdfs = new HashMap();
/**
* block for rendering the totalpage number.
*/
private TotalPageNum totalPageNum = null;
public PDFCustomBlocks(PdfWriter writer, RenderingContext context) {
this.writer = writer;
this.context = context;
writer.setPageEvent(this);
}
public void onStartPage(PdfWriter writer, Document document) {
super.onStartPage(writer, document);
final PdfContentByte dc = writer.getDirectContent();
addBackground(writer, document, dc);
}
public void onEndPage(PdfWriter writer, Document document) {
final PdfContentByte dc = writer.getDirectContent();
addHeader(document, dc);
addFooter(document, dc);
addErrors(writer);
super.onEndPage(writer, document);
}
public void onCloseDocument(PdfWriter writer, Document document) {
if (totalPageNum != null) {
totalPageNum.render(writer);
}
super.onCloseDocument(writer, document);
}
private void addBackground(PdfWriter writer, Document document, PdfContentByte dc) {
if (backgroundPdf != null) {
try {
PdfImportedPage page = backgroundPdfs.get(backgroundPdf);
if (page == null) {
PdfReader reader = new PdfReader(backgroundPdf);
page = writer.getImportedPage(reader, 1);
backgroundPdfs.put(backgroundPdf, page);
}
final Rectangle pageSize = document.getPageSize();
final boolean rotate = (page.getWidth() < page.getHeight()) ^ (pageSize.getWidth() < pageSize.getHeight());
if (rotate) {
dc.addTemplate(page, 0, -1, 1, 0, 0, pageSize.getHeight());
} else {
dc.addTemplate(page, 0, 0);
}
} catch (IOException e) {
addError(e);
}
}
}
private void addHeader(Document document, PdfContentByte dc) {
if (header != null) {
Rectangle rectangle = new Rectangle(document.left(), document.top(),
document.right(), document.top() + header.getHeight());
header.render(rectangle, dc, headerParams, context);
}
}
private void addFooter(Document document, PdfContentByte dc) {
if (footer != null) {
Rectangle rectangle = new Rectangle(document.left(), document.bottom() - footer.getHeight(), document.right(), document.bottom());
footer.render(rectangle, dc, footerParams, context);
}
}
private void addErrors(PdfWriter writer) {
if (errors.size() > 0) {
StringBuilder errorTxt = new StringBuilder();
for (int i = 0; i < errors.size(); i++) {
Exception exception = errors.get(i);
errorTxt.append(exception).append("\n");
}
errors.clear();
final Rectangle rect = new Rectangle(20f, 40f, 40f, 60f);
final PdfAnnotation annotation = PdfAnnotation.createText(writer, rect, "Error", errorTxt.toString(), false, "Note");
writer.addAnnotation(annotation);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Added an annotation for errors");
}
}
}
/**
* Register a custom drawer.
*/
public void addChunkDrawer(ChunkDrawer chunkDrawer) {
last = chunkDrawer;
}
/**
* Called when a custom drawer has been rendered.
*/
public void blockRendered(ChunkDrawer chunkDrawer) {
if (last == chunkDrawer) {
last = null;
}
}
/**
* Schedule a absolute block (like a !columns or a !map).
*/
public void addAbsoluteDrawer(AbsoluteDrawer chunkDrawer) throws DocumentException {
if (last != null) {
//a chunk drawer is scheduled, need to draw oneself after it.
last.addAbsoluteDrawer(chunkDrawer);
} else {
//no chunk drawer is scheduled. We can draw it right away.
chunkDrawer.render(writer.getDirectContent());
}
}
public void setHeader(HeaderFooter header, PJsonObject params) {
this.header = header;
this.headerParams = params;
}
public void setFooter(HeaderFooter footer, PJsonObject params) {
this.footer = footer;
this.footerParams = params;
}
public void setBackgroundPdf(String backgroundPdf) {
this.backgroundPdf = backgroundPdf;
}
public void addError(Exception e) {
errors.add(e);
if (LOGGER.isDebugEnabled()) {
LOGGER.error("Error while adding a PDF element", e);
} else {
LOGGER.error("Error while adding a PDF element" + e.toString());
}
}
public Chunk getOrCreateTotalPagesBlock(Font font) throws BadElementException {
if (totalPageNum == null) {
totalPageNum = new TotalPageNum(writer, font);
}
return totalPageNum.createPlaceHolder();
}
/**
* Base class for the absolute drawers
*/
public static abstract class AbsoluteDrawer {
public abstract void render(PdfContentByte dc) throws DocumentException;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy