]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.export.core/src/org/simantics/export/core/pdf/PageNumbering.java
Fonts are now embedded in diagram, wiki, etc PDF exports.
[simantics/platform.git] / bundles / org.simantics.export.core / src / org / simantics / export / core / pdf / PageNumbering.java
diff --git a/bundles/org.simantics.export.core/src/org/simantics/export/core/pdf/PageNumbering.java b/bundles/org.simantics.export.core/src/org/simantics/export/core/pdf/PageNumbering.java
new file mode 100644 (file)
index 0000000..edf4e72
--- /dev/null
@@ -0,0 +1,168 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Semantum Oy - initial API and implementation
+ *******************************************************************************/
+package org.simantics.export.core.pdf;
+
+import java.awt.geom.Point2D;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.SubMonitor;
+
+import com.lowagie.text.Document;
+import com.lowagie.text.DocumentException;
+import com.lowagie.text.Element;
+import com.lowagie.text.Font;
+import com.lowagie.text.Phrase;
+import com.lowagie.text.Rectangle;
+import com.lowagie.text.pdf.BadPdfFormatException;
+import com.lowagie.text.pdf.ColumnText;
+import com.lowagie.text.pdf.PdfContentByte;
+import com.lowagie.text.pdf.PdfCopy;
+import com.lowagie.text.pdf.PdfImportedPage;
+import com.lowagie.text.pdf.PdfReader;
+import com.lowagie.text.pdf.PdfWriter;
+
+/**
+ * PDF page numbering related post-processing utilities using iText.
+ * 
+ * @author Tuukka Lehtonen
+ * @since 1.28.0
+ */
+public class PageNumbering {
+
+       public static enum NumberingFormat {
+               PAGE_SLASH_TOTAL_PAGES
+       }
+
+       public static enum Position {
+               BOTTOM_LEFT,
+               BOTTOM_RIGHT,
+               TOP_LEFT,
+               TOP_RIGHT,
+       }
+
+       private static int pageNumberAlignment(Position positioning) {
+               switch (positioning) {
+               case BOTTOM_LEFT:
+               case TOP_LEFT:  return Element.ALIGN_LEFT;
+
+               case BOTTOM_RIGHT:
+               case TOP_RIGHT:
+               default: return Element.ALIGN_RIGHT;
+               }
+       }
+
+       private static Point2D.Float pageNumberPosition(Position positioning, Rectangle pageSize, Font font) {
+               switch (positioning) {
+               case TOP_LEFT:
+                       return new Point2D.Float(12, pageSize.getHeight() - 12 - font.getCalculatedSize()*0.8f);
+               case TOP_RIGHT:
+                       return new Point2D.Float(pageSize.getWidth() - 12, pageSize.getHeight() - 12 - font.getCalculatedSize()*0.8f);
+               case BOTTOM_LEFT:
+                       return new Point2D.Float(12, 12);
+               case BOTTOM_RIGHT: 
+               default:
+                       return new Point2D.Float(pageSize.getWidth() - 12, 12);
+               }
+       }
+
+       public static String formatPageNumber(NumberingFormat format, int pageNumber, int totalPages) {
+               switch (format) {
+               case PAGE_SLASH_TOTAL_PAGES: return String.format("%d / %d", pageNumber, totalPages);
+               default:
+                       throw new UnsupportedOperationException("Unsupported numbering format: " + format);
+               }
+       }
+
+       public static void addPageNumber(
+                       PdfCopy pdfCopy,
+                       PdfReader sourceReader,
+                       int sourcePageNumber,
+                       int currentPageNumber,
+                       int totalPages,
+                       Font font,
+                       Position positioning,
+                       NumberingFormat format)
+                                       throws IOException, BadPdfFormatException
+       {
+               Rectangle pageSize = sourceReader.getPageSizeWithRotation(sourcePageNumber);
+               PdfImportedPage imp = pdfCopy.getImportedPage(sourceReader, sourcePageNumber);
+               PdfCopy.PageStamp ps = pdfCopy.createPageStamp(imp);
+               PdfContentByte over = ps.getOverContent();
+               String text = formatPageNumber(format, currentPageNumber, totalPages);
+               Point2D.Float pos = pageNumberPosition(positioning, pageSize, font);
+               int alignment = pageNumberAlignment(positioning);
+               ColumnText.showTextAligned(over, alignment, new Phrase(text, font), pos.x, pos.y, 0);
+               ps.alterContents();
+               pdfCopy.addPage(imp);
+       }
+
+       public static void addPageNumbers(
+                       IProgressMonitor monitor,
+                       Path inputFile,
+                       Path outputFile,
+                       Position positioning,
+                       NumberingFormat format,
+                       Font pageNumberFont)
+                                       throws IOException, DocumentException
+       {
+               PdfReader reader = null;
+               try {
+                       reader = new PdfReader(inputFile.toString());
+                       int totalPages = reader.getNumberOfPages();
+                       int currentPage = 1;
+
+                       SubMonitor mon = SubMonitor.convert(monitor, totalPages);
+
+                       try (OutputStream fos = Files.newOutputStream(outputFile)) {
+                               Document document = new Document();
+                               PdfCopy pdfCopy = new PdfCopy(document, fos); 
+                               pdfCopy.setPdfVersion(PdfWriter.PDF_VERSION_1_7);
+                               document.open();
+                               try {
+                                       for (int i = 1; i <= totalPages; ++i) {
+                                               mon.subTask(i + "/" + totalPages);
+                                               PageNumbering.addPageNumber(pdfCopy, reader, i,
+                                                               currentPage++, totalPages,
+                                                               pageNumberFont,
+                                                               positioning,
+                                                               format);
+                                       }
+                               } finally {
+                                       if (document != null && document.isOpen())
+                                               document.close();
+                                       if (pdfCopy != null)
+                                               pdfCopy.close();
+                               }
+                       }
+               } finally {
+                       if (reader != null)
+                               reader.close();
+               }
+
+       }
+
+       public static void addPageNumbers(
+                       IProgressMonitor monitor,
+                       Path inputFile,
+                       Path outputFile,
+                       Position positioning,
+                       NumberingFormat format)
+                                       throws IOException, DocumentException
+       {
+               addPageNumbers(monitor, inputFile, outputFile, positioning, format, new Font(Font.HELVETICA, 8));
+       }
+
+}
\ No newline at end of file