All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.sf.nervalreports.generators.PDFTableCell Maven / Gradle / Ivy

Go to download

This is the PDF generator package of NervalReports (a lightweight report creation library), used to generate a report directly to a .pdf file.

The newest version!
/** This file is part of nervalreports.
 *
 * nervalreports is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * nervalreports 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 Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with nervalreports.  If not, see . */
package net.sf.nervalreports.generators;

import java.io.IOException;
import java.util.ArrayList;

import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;

import net.sf.nervalreports.core.ReportColor;
import net.sf.nervalreports.core.ReportTextAlignment;
import net.sf.nervalreports.generators.PDFTextSentence.PDFTextSentenceType;

/** Cell information for table construction on {@link PDFReportGenerator}.
 * @author farrer */
/* default */ class PDFTableCell {
	
	/** Current needed height (y) for cell's content. */
	private float neededHeight;
	
	/** If recalculation of needed height is needed. */
	private boolean heightChanged;
	
	/** Current columns to span with this cell (default: 1). */
	private int colspan;
	
	/** Left corner of the table cell coordinate. */
	private final float initialX;
	
	/** Maximum width of the cell. */
	private final float maxWidth;
	
	/** Lines of text of the cell. */
	private final ArrayList lines;
	
	/** If the cell contains a table inside it. */
	private boolean containsTable;
	
	/** Default constructor.
	 * @param initialX X coordinate where the cell should init.
	 * @param maxWidth maximum cell's width. */
	PDFTableCell(float initialX, float maxWidth) {
		this.maxWidth = maxWidth;
		lines = new ArrayList();
		heightChanged = false;
		containsTable = false;
		this.initialX = initialX;
		neededHeight = 0;
		setColspan(1);
	}
	
	/** Reset the current values of the cell, so we can reuse it in another context, 
	 * without the need to reallocate it. */
	void reset() {
		lines.clear();
		heightChanged = false;
		neededHeight = 0;
		containsTable = false;
		setColspan(1);
	}
	
	/** @return {{@link #maxWidth}. */
	float getMaxWidth() {
		return maxWidth;
	}
	
	/** Force the {@link #neededHeight} of a cell to a value. 
	 * @param neededHeight {@link #neededHeight} value. */
	void setNeededHeight(float neededHeight) {
		this.neededHeight = neededHeight;
		heightChanged = false;
	}

	/** @return {@link #neededHeight}. */
	float getNeededHeight() {
		if (heightChanged) {
			/* recalculate the height */
			neededHeight = 0;
			for (PDFLine line : lines) {
				neededHeight += line.getNeededHeight();
			}
			heightChanged = false;
		}
		return neededHeight;
	}
	
	/** Add an image to the cell, breaking lines if needed. 
	 * @param image image to be used as sentence.
	 * @param width desired width to render the image at the sentence.
	 * @param height desired height to render the image at the sentence.
	 * @param spanedColsWidth width of all columns the current one expands into.
	 * @param textAlignment alignment to use. */
	void addToSentenceImage(PDImageXObject image, float width, float height, float spanedColsWidth,
			ReportTextAlignment textAlignment) {
		heightChanged = true;
		
		PDFLine curLine;
		float curWidth;
		
		if (lines.size() == 0) {
			/* Must create the first line */
			curLine = new PDFLine(textAlignment, maxWidth + spanedColsWidth);
			lines.add(curLine);
			curWidth = 0.0f;
		} else {
			/* Current width must be equal to of the current line. */
			curLine = lines.get(lines.size() - 1);
			curWidth = curLine.getWidth();
		}
		
		/* Check if image fits current line. */
		if ( (curWidth + width > maxWidth + spanedColsWidth) || (!curLine.getTextAlignment().equals(textAlignment))) {
			/* Image is too wide for current line or with distinct alignment, must create a new one */
			curLine = new PDFLine(textAlignment, maxWidth + spanedColsWidth);
			lines.add(curLine);
		} 
		curLine.addSentenceImage(image, width, height);
	}
	
	/** Add a line break to the cell. */
	void addLineBreak() {
		if(lines.size() > 0) {
			PDFLine curLine = lines.get(lines.size() - 1);
			lines.add(new PDFLine(curLine.getTextAlignment(), curLine.getMaxWidth()));
		}
	}
	
	/** Add text to the cell, breaking lines if needed.
	 * @param type type of the textual sentence to add.
	 * @param text text of the sentence.
	 * @param color color to use.
	 * @param font font to use.
	 * @param fontSize size of the font. 
	 * @param spanedColsWidth width of all columns the current one expands into.
	 * @param textAlignment alignment to use.
	 * @throws IOException in failure to determine width. */
	void addText(PDFTextSentenceType type, String text, ReportColor color, PDFFontInfo font, int fontSize, 
			float spanedColsWidth, ReportTextAlignment textAlignment) throws IOException {
		
		heightChanged = true;
		
		PDFLine curLine;
		float curWidth;
		float spaceWidth = font.getSpaceWidth(fontSize);
		
		if (lines.size() == 0) {
			/* Must create the first line */
			curLine = new PDFLine(textAlignment, maxWidth + spanedColsWidth);
			lines.add(curLine);
			curWidth = 0.0f;
		} else {
			/* Current width must be equal to of the current line. */
			curLine = lines.get(lines.size() - 1);
			curWidth = curLine.getWidth();
			
			/* Check if same alignment */
			if(!curLine.getTextAlignment().equals(textAlignment)) {
				/* Distinct, must use a new line. */
				curLine = new PDFLine(textAlignment, maxWidth + spanedColsWidth);
				lines.add(curLine);
				curWidth = 0.0f;
			}
		}

		/* Split the text in words, and try to insert them one by one, breaking lines when needed. */
		String[] words = text.split(" ");
		
		for (int curWord = 0; curWord < words.length; curWord++) {
			String word = words[curWord];
			float wordWidth = font.getStringWidth(fontSize, word);
			
			/* Only insert with space after if not the last word. 
			 * Or contains the ' ' character at the end of the text. */
			if ((curWord != words.length - 1) || (text.charAt(text.length() - 1) == ' ')) {
				wordWidth += spaceWidth;
			}
			curWidth += wordWidth;
			
			if (curWidth > maxWidth + spanedColsWidth) {
				/* Word is too wide for current line: must break the line to insert it. */
				curLine = new PDFLine(textAlignment, maxWidth + spanedColsWidth);
				lines.add(curLine);
				curWidth = wordWidth;
			} 

			/* Finally, add or append the text. */
			curLine.addToOrAppendToNewSentence(type, word, color, font, fontSize, wordWidth);
		}
	}
	
	/** Add an already created line to the table cell.
	 * @param line line to add. */
	void addLine(PDFLine line) {
		heightChanged = true;
		lines.add(line);
	}
	
	/** @return {@link #lines} */
	ArrayList getLines() {
		return lines;
	}

	/** @return {@link #initialX} */
	float getInitialX() {
		return initialX;
	}

	/** @return {@link #colspan} */
	int getColspan() {
		return colspan;
	}

	/** Define {@link #colspan}.
	 * @param colspan number of columns to span (default: 1). */
	void setColspan(int colspan) {
		this.colspan = colspan;
	}
	
	/** Define that the current cell contains a table inside it. */
	void setContainsTable() {
		containsTable = true;
	}
	
	/** @return {@link #containsTable}. */
	boolean containsTable() {
		return containsTable;
	}
	
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy