package gutenberg.itext;
import com.google.common.base.Function;
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Document;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfPageEventHelper;
import com.itextpdf.text.pdf.PdfWriter;
import static com.itextpdf.text.pdf.ColumnText.showTextAligned;
import static org.apache.commons.lang3.StringUtils.defaultString;
/**
* @author <a href="http://twitter.com/aloyer">@aloyer</a>
*/
public class HeaderFooter extends PdfPageEventHelper {
public static Function<PageInfos, Phrase> none() {
return new Function<PageInfos, Phrase>() {
@Override
public Phrase apply(PageInfos pageInfos) {
return null;
}
};
}
public static Function<PageInfos, Phrase> create(final Styles styles,
final Object fontKey,
final String firstPageTemplate,
final String otherPageTemplate,
final Phrase otherPage) {
return new Function<PageInfos, Phrase>() {
@Override
public Phrase apply(PageInfos pageInfos) {
Font font = styles.getFontOrDefault(fontKey);
if (pageInfos.getRawPageNumber() == 1) {
if (firstPageTemplate != null) {
return new Phrase(firstPageTemplate, font);
}
} else {
if (otherPage != null)
return otherPage;
else if (otherPageTemplate != null) {
String text = otherPageTemplate;
text = text.replace("${chapterTitle}", defaultString(pageInfos.chapterTitle()));
text = text.replace("${sectionTitle}", defaultString(pageInfos.sectionTitle()));
return new Phrase(text, font);
}
}
return null;
}
};
}
public static final String HEADER_FONT = "header-font";
public static final String FOOTER_FONT = "footer-font";
public static final String HEADER_LINE_COLOR = "header-line-color";
private final PageNumber pageNumber;
private final Styles styles;
private final Function<PageInfos, Phrase> header;
private final Function<PageInfos, Phrase> footer;
private boolean footerOnFirstPage = false;
private Rectangle rect;
private boolean drawLine = true;
public HeaderFooter(PageNumber pageNumber,
Styles styles,
Function<PageInfos, Phrase> header,
Function<PageInfos, Phrase> footer) {
this.pageNumber = pageNumber;
this.styles = styles;
this.header = header;
this.footer = footer;
}
public HeaderFooter footerOnFirstPage(boolean footerOnFirstPage) {
this.footerOnFirstPage = footerOnFirstPage;
return this;
}
@Override
public void onEndPage(PdfWriter writer, Document document) {
if (rect == null)
rect = writer.getBoxSize("art");
PdfContentByte canvas = writer.getDirectContent();
PageInfos pageInfos = pageNumber.pageInfos();
drawHeader(canvas, pageInfos);
drawFooter(canvas, pageInfos);
}
public void drawHeader(PdfContentByte canvas, PageInfos pageInfos) {
float top = rect.getTop() + 20;
Phrase header = headerText(pageInfos);
if (header != null) {
showTextAligned(canvas, Element.ALIGN_CENTER, header, (rect.getLeft() + rect.getRight()) / 2, top, 0);
}
}
public void drawFooter(PdfContentByte canvas, PageInfos pageInfos) {
if (pageInfos.getRawPageNumber() == 1 && !footerOnFirstPage)
return;
if (drawLine) {
BaseColor lineColor = styles.getColorOrDefault(HEADER_LINE_COLOR);
canvas.saveState();
canvas.setColorStroke(lineColor);
canvas.setLineWidth(1.2f);
canvas.moveTo(rect.getLeft(), rect.getBottom() - 6);
canvas.lineTo(rect.getRight(), rect.getBottom() - 6);
canvas.stroke();
canvas.restoreState();
}
float bottom = rect.getBottom() - 20;
Phrase footer = footerText(pageInfos);
if (footer != null) {
showTextAligned(canvas, Element.ALIGN_LEFT, footer, rect.getLeft(), bottom, 0);
}
Font footerFont = styles.getFontOrDefault(FOOTER_FONT);
Phrase page = new Phrase(pageInfos.getFormattedPageNumber(), footerFont);
showTextAligned(canvas, Element.ALIGN_RIGHT, page, rect.getRight(), bottom, 0);
}
private Phrase headerText(PageInfos pageInfos) {
return header.apply(pageInfos);
}
private Phrase footerText(PageInfos pageInfos) {
return footer.apply(pageInfos);
}
}