org.jopendocument.renderer.ODTRenderer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jOpenDocument Show documentation
Show all versions of jOpenDocument Show documentation
jOpenDocument is a free library for developers looking to use
Open Document files without OpenOffice.org.
The newest version!
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2008-2013 jOpenDocument, by ILM Informatique. All rights reserved.
*
* The contents of this file are subject to the terms of the GNU
* General Public License Version 3 only ("GPL").
* You may not use this file except in compliance with the License.
* You can obtain a copy of the License at http://www.gnu.org/licenses/gpl-3.0.html
* See the License for the specific language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each file.
*
*/
package org.jopendocument.renderer;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.util.List;
import javax.swing.JPanel;
import org.jopendocument.model.OpenDocument;
import org.jopendocument.model.Page;
import org.jopendocument.model.PrintedPage;
import org.jopendocument.model.draw.DrawFrame;
import org.jopendocument.model.draw.DrawImage;
import org.jopendocument.model.office.OfficeBody;
import org.jopendocument.model.office.OfficeSpreadsheet;
import org.jopendocument.model.style.StyleStyle;
import org.jopendocument.model.style.StyleTableCellProperties;
import org.jopendocument.model.table.TableShapes;
import org.jopendocument.model.table.TableTable;
import org.jopendocument.model.table.TableTableCell;
import org.jopendocument.model.table.TableTableColumn;
import org.jopendocument.model.table.TableTableRow;
import org.jopendocument.util.ValueHelper;
@SuppressWarnings("unqualified-field-access")
public class ODTRenderer extends JPanel {
private static final long serialVersionUID = -4903349568929293597L;
private double resizeFactor;
private OfficeBody body;
private TableTable table;
private int printHeightPixel;
private int printWidthPixel;
private int printWidth;
private int printHeight;
private static final ODTCellBackgroundRenderer backgroundRenderer = new ODTCellBackgroundRenderer();
private static final ODTCellBorderRenderer borderRenderer = new ODTCellBorderRenderer();
private static final ODTCellTextRenderer textRenderer = new ODTCellTextRenderer();
private static final ODTCellImageRenderer imageRenderer = new ODTCellImageRenderer();
private static boolean debug = false;
private PrintedPage currentPage;
private boolean paintMaxResolution;
private boolean ignoreMargins;
private OpenDocument od;
private int currentPageIndex;
public ODTRenderer(OpenDocument doc) {
this.body = doc.getBody();
this.setBackground(Color.WHITE);
this.currentPageIndex = 0;
this.currentPage = (PrintedPage) doc.getPrintedPage(this.currentPageIndex);
setResizeFactor(360);
this.od = doc;
}
public void setCurrentPage(int i) {
this.currentPageIndex = i;
this.currentPage = (PrintedPage) od.getPrintedPage(i);
updateSize();
repaint();
}
private void updateSize() {
this.setSize(getPageWidthInPixel(), getPageHeightInPixel());
}
public double getPageHeight() {
return this.getPageHeightInPixel() * resizeFactor;
}
public int getPageHeightInPixel() {
int h = 0;
final TableTableRow[] rows = this.currentPage.getRows();
final int rowCount = rows.length;
for (int rowIndex = 0; rowIndex < rowCount; rowIndex++) {
final TableTableRow row = rows[rowIndex];
h += (int) (row.getHeight() / this.resizeFactor);
}
return h;
}
public double getPageWidth() {
return this.getPageWidthInPixel() * resizeFactor;
}
public int getPageWidthInPixel() {
final int printStartCol = table.getPrintStartCol();
final int printStopCol = table.getPrintStopCol();
final TableTableRow[] rows = this.currentPage.getRows();
final double currentResizeFactor = this.resizeFactor;
int marginLeft = table.getPageLayoutProperties().getMarginLeft();
if (ignoreMargins) {
marginLeft = 0;
}
int h = (int) (marginLeft / currentResizeFactor);
final TableTableColumn[] columns = table.getColumns().toArray(new TableTableColumn[0]);
for (int rowIndex = 0; rowIndex < 1; rowIndex++) {
final TableTableRow row = rows[rowIndex];
final TableTableCell[] cells = row.getCellsInRange(printStartCol, printStopCol);
final int cellsSize = cells.length;
// les cells repeated sont deja clonées
for (int i = 0; i < cellsSize; i++) {
final TableTableCell cell = cells[i];
if (cell == null) {
continue;
}
final TableTableColumn col = columns[printStartCol + i];
final StyleStyle style = cell.getStyle();
h += (int) (col.getWidth() / this.resizeFactor);
}
}
return h;
}
public int getPrintedPagesNumber() {
return this.od.getPrintedPageCount();
}
public synchronized void setResizeFactor(double resizeFactor) {
this.resizeFactor = resizeFactor;
final List l = this.body.getOfficeSpreadsheets();
final int spreadSheatCount = l.size();
for (int i = 0; i < spreadSheatCount; i++) {
final List tables = l.get(i).getTables();
final int size = tables.size();
for (int j = 0; j < size; j++) {
final TableTable t = tables.get(j);
this.table = t;
// FIXME here printWidth is the width of the whole sheet
printWidth = t.getPrintWidth() + t.getPageLayoutProperties().getMarginLeft() + t.getPageLayoutProperties().getMarginRight();
// FIXME here printHeight is the height of one page
printHeight = t.getPageLayoutProperties().getPageHeight();
if (ignoreMargins) {
// FIXME here of the whole sheet
printWidth = t.getPrintWidth();
printHeight = t.getPrintHeight();
}
printWidthPixel = (int) Math.ceil(printWidth / resizeFactor);
printHeightPixel = (int) Math.ceil(printHeight / resizeFactor);
setPreferredSize(new Dimension(printWidthPixel, printHeightPixel));
break;
}
}
updateSize();
repaint();
}
public int getPrintWidthInPixel() {
return printWidthPixel;
}
public int getPrintHeightInPixel() {
return printHeightPixel;
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
if (debug) {
printRendererInformation();
System.out.println("********************** RENDERING BACKGROUND *************");
}
drawODTBackground(g2);
if (debug) {
System.out.println("********************** RENDERING BORDERS *************");
}
drawODTBorders(g2);
if (debug) {
System.out.println("********************** RENDERING TEXTS *************");
}
drawODTText(g2);
if (debug) {
System.out.println("********************** RENDERING IMAGES *************");
}
drawODTImages(g2);
}
/**
* @param g2
*/
private final void drawODTImages(Graphics2D g2) {
if (!paintMaxResolution) {
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_SPEED);
} else {
g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
}
// Images in Cells
drawCells(g2, imageRenderer);
// Image in Page
final TableTable currentTable = this.table;
TableShapes shapes = currentTable.getTableShapes();
if (shapes == null) {
return;
}
List frames = shapes.getDrawFrames();
final double currentResizeFactor = this.resizeFactor;
int borderLeft = (int) (currentTable.getPageLayoutProperties().getMarginLeft() / currentResizeFactor);
int borderRight = (int) (currentTable.getPageLayoutProperties().getMarginRight() / currentResizeFactor);
int borderTop = (int) (currentTable.getPageLayoutProperties().getMarginTop() / currentResizeFactor);
int borderBottom = (int) (currentTable.getPageLayoutProperties().getMarginBottom() / currentResizeFactor);
if (this.ignoreMargins) {
borderLeft = 0;
borderRight = 0;
borderTop = 0;
borderBottom = 0;
}
for (DrawFrame frame : frames) {
DrawImage dIm = frame.getDrawImage();
if (dIm != null) {
final Rectangle frameRect = new Rectangle(ValueHelper.getLength(frame.getSvgX()), ValueHelper.getLength(frame.getSvgY()), ValueHelper.getLength(frame.getSvgWidth()),
ValueHelper.getLength(frame.getSvgHeight()));
// FIXME doesn't work since printHeight is wrong (see setResizeFactor())
// final int currentOrigin = this.currentPageIndex * this.printHeight;
// final Rectangle pageRect = new Rectangle(0, currentOrigin, this.printWidth,
// this.printHeight);
// if (frameRect.intersects(pageRect)) {
frameRect.x /= resizeFactor;
frameRect.y /= resizeFactor;
frameRect.width /= resizeFactor;
frameRect.height /= resizeFactor;
// after since already resized
frameRect.translate(borderLeft, borderTop);
Image im = null;
if (!paintMaxResolution) {
im = body.getDocument().getImage(dIm.getXlinkHref(), frameRect.width, frameRect.height);
g2.drawImage(im, frameRect.x, frameRect.y, null);
} else {
im = body.getDocument().getImage(dIm.getXlinkHref());
g2.drawImage(im, frameRect.x, frameRect.y, frameRect.width, frameRect.height, null);
}
// }
}
}
}
/**
* @param g2
*/
private final void drawODTText(Graphics2D g2) {
// Texts
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
drawCells(g2, textRenderer);
}
/**
* @param g2
*/
private final void drawODTBorders(Graphics2D g2) {
// Borders
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
drawCells(g2, borderRenderer);
}
/**
* @param g2
*/
private final void drawODTBackground(Graphics2D g2) {
// Background
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
drawCells(g2, backgroundRenderer);
}
private final void drawCells(final Graphics2D g, final ODTCellRenderer renderer) {
// Constants
final TableTable currentTable = this.table;
final int printStartCol = currentTable.getPrintStartCol();
final int printStopCol = currentTable.getPrintStopCol();
final TableTableRow[] rows = this.currentPage.getRows();
final int rowCount = rows.length;
final double currentResizeFactor = this.resizeFactor;
int marginLeft = currentTable.getPageLayoutProperties().getMarginLeft();
int marginTop = currentTable.getPageLayoutProperties().getMarginTop();
if (ignoreMargins) {
marginLeft = 0;
marginTop = 0;
}
final int borderLeft = (int) (marginLeft / currentResizeFactor);
final TableTableColumn[] columns = table.getColumns().toArray(new TableTableColumn[0]);
final double[] columnsWidth = new double[columns.length];
for (int i = 0; i < columns.length; i++) {
columnsWidth[i] = columns[i].getWidth() / currentResizeFactor;
}
int y = (int) (marginTop / currentResizeFactor);
for (int rowIndex = 0; rowIndex < rowCount; rowIndex++) {
final TableTableRow row = rows[rowIndex];
final int rowHeight = (int) (row.getHeight() / currentResizeFactor);
final TableTableCell[] cells = row.getCellsInRange(printStartCol, printStopCol);
final int cellsSize = cells.length;
int x = borderLeft;
// les cells repeated sont deja clonées
for (int i = 0; i < cellsSize; i++) {
final TableTableCell cell = cells[i];
if (cell == null) {
continue;
}
final StyleStyle style = cell.getStyle();
int cellWidth = (int) columnsWidth[printStartCol + i];
final StyleTableCellProperties cellProps = style.getStyleTableCellProperties();
int cellHeight = rowHeight;
if (cell.getTableNumberRowsSpanned() > 1) {
for (int repeat = 1; repeat < cell.getTableNumberRowsSpanned(); repeat++) {
cellHeight += rows[rowIndex + repeat].getHeight() / currentResizeFactor;
}
}
if (cell.getTableNumberColumnsSpanned() > 1) {
for (int repeat = 1; repeat < cell.getTableNumberColumnsSpanned(); repeat++) {
final int colIndex = printStartCol + i + repeat;
final double w = columnsWidth[colIndex];
cellWidth += w;
}
}
try {
if (!cell.isCovered()) {
renderer.draw(g, x, y, cellWidth, cellHeight, currentResizeFactor, cell, cellProps);
}
} catch (Exception e) {
// TODO: handle exception
System.err.println("Failed on x:" + x + " y:" + y + " Cell:" + cell);
e.printStackTrace();
}
x += columnsWidth[printStartCol + i];
}
y += rowHeight;
}
}
public double getPrintWidth() {
return this.printWidth;
}
public double getPrintHeight() {
return this.printHeight;
}
/**
* Set the image rendering policy
*
* @param b : true if you need an extra definition (ex for printing)
*/
public void setPaintMaxResolution(boolean b) {
this.paintMaxResolution = b;
imageRenderer.setPaintMaxResolution(b);
}
public void setIgnoreMargins(boolean b) {
this.ignoreMargins = b;
}
public void printRendererInformation() {
System.out.println("==== Spreadsheet Renderer ===");
System.out.println("Rendering file: " + this.od.getZipFile().getName());
System.out.println("Document margins ignored: " + this.ignoreMargins);
System.out.println("Max image quality: " + this.paintMaxResolution);
System.out.println("Current page: " + (this.currentPageIndex + 1) + " / " + this.getPrintedPagesNumber());
System.out.println("Width: " + (long) getPrintWidth() + " micrometers (" + getPrintWidth() / 10000 + " cms)");
System.out.println("Height: " + (long) getPrintHeight() + " micrometers (" + getPrintHeight() / 10000 + " cms)");
System.out.println("Size in pixels: " + this.getPrintWidthInPixel() + "x" + this.getPrintHeightInPixel());
System.out.println("Resize factor " + this.resizeFactor);
System.out.println("Page:" + this.currentPage.getRows().length + " rows ");
System.out.println();
}
public void setDebug(boolean b) {
debug = true;
}
public void printRow(int startRow, int stopRow, int startColumn, int stopColumn) {
final TableTableRow[] rows = this.currentPage.getRows();
for (int i = startRow; i < stopRow; i++) {
TableTableRow row = rows[i];
TableTableCell[] cells = row.getCellsInRange(startColumn, stopColumn);
System.out.println("======== Row:" + i);
for (int j = startColumn; j < stopColumn; j++) {
TableTableCell cell = cells[j];
// System.out.println("Cell" + j + ":" + cell + ":" + cell.getFullText() +
// " Spanned:" + cell.getTableNumberColumnsSpanned() + " Repeated:" +
// cell.getTableNumberColumnsRepeated()
// + " Covered:" + cell.isCovered());
}
}
}
}