/**
* NanoDoA - File based document archive
*
* Copyright (C) 2011-2012 Christian Packenius, christian.packenius@googlemail.com
*
* This program 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
* any later version.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.chris_soft.utilities.pdf;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.geom.Rectangle2D;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import com.sun.pdfview.PDFFile;
import com.sun.pdfview.PDFPage;
import de.chris_soft.utilities.LogUtils;
/**
* Holding and rendering of PDF pages.
* @author Christian Packenius.
*/
public class PdfPageRenderUtility implements PdfViewConstants {
private final PDFFile pdfFileContent;
/**
* Number of pages in the pdf file.
*/
public final int pageCount;
/**
* File object of the PDF file to render here.
*/
public final File pdfFile;
/**
* Constructor.
* @param pdfFile2view PDF file to render.
* @throws IOException
*/
public PdfPageRenderUtility(File pdfFile2view) throws IOException {
try {
pdfFile = pdfFile2view;
RandomAccessFile raf = new RandomAccessFile(pdfFile2view, "r");
FileChannel fc = raf.getChannel();
ByteBuffer buf = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
pdfFileContent = new PDFFile(buf);
raf.close();
pageCount = pdfFileContent.getNumPages();
}
catch (IOException ioe) {
LogUtils.log(ioe);
throw ioe;
}
}
/**
* Render a thumbnail of the given page to the wanted size.
* @param pageID Page number to render.
* @param size Max size of the result thumbnail image.
* @return Thumbnail image.
*/
public synchronized Image getPage(int pageID, double size) {
if (pageID < 1 || pageID > pageCount) {
return null;
}
PDFPage page = pdfFileContent.getPage(pageID);
Rectangle2D r2d = page.getBBox();
final double width, height;
if (r2d.getWidth() > r2d.getHeight()) {
width = size;
height = (int) (size / (r2d.getWidth() / r2d.getHeight()));
}
else {
width = (int) (size / (r2d.getHeight() / r2d.getWidth()));
height = size;
}
return page.getImage((int) width, (int) height, r2d, null, true, true);
}
/**
* Render a thumbnail of the given page to the wanted size.
* @param pageID Page number to render.
* @param rect Size of the component to view the PDF page.
* @param viewMode View mode {@link PdfViewConstants}.
* @return Thumbnail image.
*/
public synchronized Image getPage(int pageID, Rectangle rect, int viewMode) {
if (pageID < 1 || pageID > pageCount) {
return null;
}
PDFPage page = pdfFileContent.getPage(pageID);
Rectangle2D r2d = page.getBBox();
double width = r2d.getWidth();
double height = r2d.getHeight();
width /= 72.0;
height /= 72.0;
int res = Toolkit.getDefaultToolkit().getScreenResolution();
width *= res;
height *= res;
double f = getSizeFactorFromViewMode(width, height, rect, viewMode);
width /= f;
height /= f;
return page.getImage((int) width, (int) height, r2d, null, true, true);
}
private double getSizeFactorFromViewMode(double width, double height, Rectangle rect, int viewMode) {
double f = 1.0;
double labelHeight, labelWidth;
switch (viewMode) {
case VIEW_MODE_FIT_TO_HEIGHT:
labelHeight = rect.getHeight();
f = height / labelHeight;
break;
case VIEW_MODE_FIT_TO_WIDTH:
labelWidth = rect.getWidth();
f = width / labelWidth;
break;
case VIEW_MODE_FIT_TO_SIZE:
labelHeight = rect.getHeight();
labelWidth = rect.getWidth();
double f1 = width / labelWidth;
double f2 = height / labelHeight;
f = Math.max(f1, f2);
break;
case VIEW_MODE_ORIGINAL_SIZE:
f = 1.0;
break;
default:
if (viewMode > 0) {
return 100.0 / viewMode;
}
break;
}
return f;
}
/**
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "[PDF renderer for " + pdfFile + "]";
}
}