x/y scaling of barcodes, add paragraph and drawable cells

This commit is contained in:
Jörg Prante 2021-12-09 18:20:57 +01:00
parent 6711aa9cec
commit 10a401731f
62 changed files with 1028 additions and 479 deletions

View file

@ -643,7 +643,6 @@ public abstract class AbstractSymbol implements Symbol {
encodeInfo.append("Encoding in Shift-JIS character set\n");
return;
}
/* default */
qmarksAfter = eciEncode("UTF8");
eciMode = 26;
@ -902,8 +901,7 @@ public abstract class AbstractSymbol implements Symbol {
errorLatch = 2;
break;
}
if (
((aiValue[i] >= 100) && (aiValue[i] <= 179))
if (((aiValue[i] >= 100) && (aiValue[i] <= 179))
|| ((aiValue[i] >= 1000) && (aiValue[i] <= 1799))
|| ((aiValue[i] >= 200) && (aiValue[i] <= 229))
|| ((aiValue[i] >= 2000) && (aiValue[i] <= 2299))
@ -916,8 +914,7 @@ public abstract class AbstractSymbol implements Symbol {
if ((aiValue[i] >= 3100) && (aiValue[i] <= 3699) && dataLength[i] != 6) {
errorLatch = 1;
}
if (
((aiValue[i] >= 370) && (aiValue[i] <= 379))
if (((aiValue[i] >= 370) && (aiValue[i] <= 379))
|| ((aiValue[i] >= 3700) && (aiValue[i] <= 3799))) {
errorLatch = 2;
}
@ -926,8 +923,7 @@ public abstract class AbstractSymbol implements Symbol {
errorLatch = 1;
}
}
if (
((aiValue[i] >= 4100) && (aiValue[i] <= 4199))
if (((aiValue[i] >= 4100) && (aiValue[i] <= 4199))
|| ((aiValue[i] >= 700) && (aiValue[i] <= 703))
|| ((aiValue[i] >= 800) && (aiValue[i] <= 810))
|| ((aiValue[i] >= 900) && (aiValue[i] <= 999))
@ -945,7 +941,6 @@ public abstract class AbstractSymbol implements Symbol {
return "";
}
}
aiLatch = false;
for (i = 0; i < srcLen; i++) {
if ((source.charAt(i) != '[') && (source.charAt(i) != ']')) {
reduced.append(source.charAt(i));

View file

@ -130,7 +130,7 @@ public class Code3Of9 extends AbstractSymbol {
}
pattern = new String[]{dest.toString()};
rowCount = 1;
rowHeight = new int[]{-1};
rowHeight = new int[]{defaultHeight};
plotSymbol();
return true;
}

View file

@ -42,21 +42,17 @@ public class Code3Of9Extended extends AbstractSymbol {
int l = content.length();
int asciicode;
Code3Of9 c = new Code3Of9();
if (checkOption == CheckDigit.MOD43) {
c.setCheckDigit(Code3Of9.CheckDigit.MOD43);
}
if (!content.matches("[\u0000-\u007F]+")) {
errorMsg.append("Invalid characters in input data");
return false;
}
for (int i = 0; i < l; i++) {
asciicode = content.charAt(i);
buffer.append(ECode39[asciicode]);
}
try {
c.setContent(buffer.toString());
} catch (Exception e) {
@ -68,7 +64,7 @@ public class Code3Of9Extended extends AbstractSymbol {
pattern[0] = c.pattern[0];
rowCount = 1;
rowHeight = new int[1];
rowHeight[0] = -1;
rowHeight[0] = defaultHeight;
plotSymbol();
return true;
}

View file

@ -457,7 +457,7 @@ public class Pdf417 extends AbstractSymbol {
* Creates a new PDF417 symbol instance.
*/
public Pdf417() {
setBarHeight(3);
defaultHeight = 3;
}
private static EncodingMode chooseMode(int codeascii) {
@ -589,16 +589,6 @@ public class Pdf417 extends AbstractSymbol {
}
}
/**
* Sets the default bar height (height of a single row) for this symbol (default value is <code>3</code>).
*
* @param barHeight the default bar height for this symbol
*/
@Override
public void setBarHeight(int barHeight) {
super.setBarHeight(barHeight);
}
/**
* Returns the number of data columns used by this symbol, or {@code null}
* if the number of data columns has not been set.

View file

@ -31,9 +31,14 @@ public class BarcodeGraphicsRenderer {
private final Rectangle rectangle;
/**
* The scaling factor.
* The scaling factor for X dimension.
*/
private final double scalingFactor;
private final double scalingFactorX;
/**
* The scaling factor for Y dimension.
*/
private final double scalingFactorY;
/**
* The paper (background) color.
@ -54,7 +59,8 @@ public class BarcodeGraphicsRenderer {
*
* @param g2d the graphics to render to
* @param rectangle the visible rectangle
* @param scalingFactor the scaling factor to apply
* @param scalingFactorX the scaling factor to apply for x dimension
* @param scalingFactorY the scaling factor to apply for y dimension
* @param background the paper (background) color
* @param foreground the ink (foreground) color
* @param antialias if true give anti alias hint
@ -62,14 +68,16 @@ public class BarcodeGraphicsRenderer {
*/
public BarcodeGraphicsRenderer(Graphics2D g2d,
Rectangle rectangle,
double scalingFactor,
double scalingFactorX,
double scalingFactorY,
Color background,
Color foreground,
boolean antialias,
boolean transparentBackground) {
this.g2d = g2d;
this.rectangle = rectangle;
this.scalingFactor = scalingFactor;
this.scalingFactorX = scalingFactorX;
this.scalingFactorY = scalingFactorY;
this.background = background;
this.foreground = foreground;
this.antialias = antialias;
@ -85,8 +93,8 @@ public class BarcodeGraphicsRenderer {
} else {
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
}
double marginX = symbol.getQuietZoneHorizontal() * scalingFactor;
double marginY = symbol.getQuietZoneVertical() * scalingFactor;
double marginX = symbol.getQuietZoneHorizontal() * scalingFactorX;
double marginY = symbol.getQuietZoneVertical() * scalingFactorY;
g2d.setBackground(background);
if (!transparentBackground) {
g2d.setColor(background);
@ -96,10 +104,10 @@ public class BarcodeGraphicsRenderer {
g2d.setColor(foreground);
}
for (Rectangle2D.Double rect : symbol.getRectangles()) {
double x = rect.x * scalingFactor + marginX;
double y = rect.y * scalingFactor + marginY;
double w = rect.width * scalingFactor;
double h = rect.height * scalingFactor;
double x = rect.x * scalingFactorX + marginX;
double y = rect.y * scalingFactorY + marginY;
double w = rect.width * scalingFactorX;
double h = rect.height * scalingFactorY;
Path2D path = new Path2D.Double();
path.moveTo(x, y);
path.lineTo(x + w, y);
@ -111,24 +119,24 @@ public class BarcodeGraphicsRenderer {
if (symbol.getHumanReadableLocation() != HumanReadableLocation.NONE) {
Map<TextAttribute, Object> attributes = new HashMap<>();
attributes.put(TextAttribute.TRACKING, 0);
Font f = new Font(symbol.getFontName(), Font.PLAIN, (int) (symbol.getFontSize() * scalingFactor)).deriveFont(attributes);
Font f = new Font(symbol.getFontName(), Font.PLAIN, (int) (symbol.getFontSize() * Math.min(scalingFactorX, scalingFactorY))).deriveFont(attributes);
Font oldFont = g2d.getFont();
g2d.setFont(f);
FontMetrics fm = g2d.getFontMetrics();
for (TextBox text : symbol.getTexts()) {
Rectangle2D bounds = fm.getStringBounds(text.text, g2d);
double x = (text.x * scalingFactor) - (bounds.getWidth() / 2) + marginX;
double y = (text.y * scalingFactor) + marginY;
double x = (text.x * scalingFactorX) - (bounds.getWidth() / 2) + marginX;
double y = (text.y * scalingFactorY) + marginY;
g2d.drawString(text.text, (float) x, (float) y);
}
g2d.setFont(oldFont);
}
for (Hexagon hexagon : symbol.getHexagons()) {
Path2D path = new Path2D.Double();
path.moveTo(hexagon.pointX[0] * scalingFactor + marginX, hexagon.pointY[0] * scalingFactor + marginY);
path.moveTo(hexagon.pointX[0] * scalingFactorX + marginX, hexagon.pointY[0] * scalingFactorY + marginY);
for(int i = 1; i < 6; ++i) {
double x = hexagon.pointX[i] * scalingFactor + marginX;
double y = hexagon.pointY[i] * scalingFactor + marginY;
double x = hexagon.pointX[i] * scalingFactorX + marginX;
double y = hexagon.pointY[i] * scalingFactorY + marginY;
path.lineTo(x, y);
}
path.closePath();
@ -137,10 +145,10 @@ public class BarcodeGraphicsRenderer {
List<Ellipse2D.Double> targets = symbol.getTarget();
for (int i = 0; i < targets.size(); i++) {
Ellipse2D.Double ellipse = targets.get(i);
double x = ellipse.x * scalingFactor + marginX;
double y = ellipse.y * scalingFactor + marginY;
double w = ellipse.width * scalingFactor;
double h = ellipse.height * scalingFactor;
double x = ellipse.x * scalingFactorX + marginX;
double y = ellipse.y * scalingFactorY + marginY;
double w = ellipse.width * scalingFactorX;
double h = ellipse.height * scalingFactorY;
if ((i & 1) == 0) {
g2d.setColor(foreground);
} else {

View file

@ -219,7 +219,7 @@ public class SymbolTest {
// make sure the barcode images match
if (pngFile.exists()) {
BufferedImage expected = ImageIO.read(pngFile);
BufferedImage actual = draw(symbol, 10.0d);
BufferedImage actual = draw(symbol, 10.0d, 10.0d);
if (expected != null && actual != null) {
assertEqualImage(pngFile.getName(), expected, actual);
}
@ -358,7 +358,6 @@ public class SymbolTest {
* @throws IOException if there is any I/O error
*/
private void generateCodewordsExpectationFile(AbstractSymbol symbol) throws IOException {
//if (!codewordsFile.exists()) {
PrintWriter writer = new PrintWriter(codewordsFile);
try {
int[] codewords = symbol.getCodewords();
@ -371,7 +370,6 @@ public class SymbolTest {
}
}
writer.close();
//}
}
/**
@ -381,7 +379,7 @@ public class SymbolTest {
* @throws IOException if there is any I/O error
*/
private void generatePngExpectationFile(AbstractSymbol symbol) throws IOException {
BufferedImage img = draw(symbol, 10.0d);
BufferedImage img = draw(symbol, 10.0d, 10.0d);
if (img != null) {
ImageIO.write(img, "png", pngFile);
}
@ -408,15 +406,15 @@ public class SymbolTest {
* @param symbol the symbol to draw
* @return the resultant image
*/
private static BufferedImage draw(AbstractSymbol symbol, double scalingFactor) {
int width = (int) (symbol.getWidth() * scalingFactor);
int height = (int) (symbol.getHeight() * scalingFactor);
private static BufferedImage draw(AbstractSymbol symbol, double scalingFactorX, double scalingFactorY) {
int width = (int) (symbol.getWidth() * scalingFactorX);
int height = (int) (symbol.getHeight() * scalingFactorY);
if (width > 0 && height > 0) {
BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
Rectangle rectangle = new Rectangle(0, 0, img.getWidth(), img.getHeight());
Graphics2D g2d = img.createGraphics();
BarcodeGraphicsRenderer renderer = new BarcodeGraphicsRenderer(g2d, rectangle,
scalingFactor, Color.WHITE, Color.BLACK, true, false);
scalingFactorX, scalingFactorY, Color.WHITE, Color.BLACK, true, false);
renderer.render(symbol);
g2d.dispose();
return img;

View file

@ -21,12 +21,11 @@ public class Code39Test {
Code3Of9 code3Of9 = new Code3Of9();
code3Of9.setContent("20180123456");
code3Of9.setHumanReadableLocation(HumanReadableLocation.BOTTOM);
// pixels = (mm * dpi) / 25.4
double scalingFactor = (1.0d * 72.0d) / 25.4;
double scalingFactor = 3.0d;
int width = (int) (code3Of9.getWidth() * scalingFactor);
int height = (int) (code3Of9.getHeight() * scalingFactor);
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
BarcodeGraphicsRenderer renderer = createRenderer(bufferedImage, scalingFactor);
BarcodeGraphicsRenderer renderer = createRenderer(bufferedImage, scalingFactor, scalingFactor);
renderer.render(code3Of9);
renderer.close();
OutputStream outputStream = Files.newOutputStream(Paths.get("build/barcode1.png"));
@ -36,13 +35,15 @@ public class Code39Test {
@Test
public void createBarcode2() throws IOException {
int width = 512;
int height = 150;
Code3Of9 code3Of9 = new Code3Of9();
//code3Of9.setContent("20180123456");
code3Of9.setContent("11111111111");
code3Of9.setContent("20180123456");
code3Of9.setHumanReadableLocation(HumanReadableLocation.BOTTOM);
double scalingFactorX = 6.0d;
double scalingFactorY = 3.0d;
int width = (int) (code3Of9.getWidth() * scalingFactorX);
int height = (int) (code3Of9.getHeight() * scalingFactorY);
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
BarcodeGraphicsRenderer renderer = createRenderer(bufferedImage, 3.0d);
BarcodeGraphicsRenderer renderer = createRenderer(bufferedImage, scalingFactorX, scalingFactorY);
renderer.render(code3Of9);
renderer.close();
OutputStream outputStream = Files.newOutputStream(Paths.get("build/barcode2.png"));
@ -50,9 +51,26 @@ public class Code39Test {
outputStream.close();
}
private BarcodeGraphicsRenderer createRenderer(BufferedImage bufferedImage, double scalingFactor) {
@Test
public void createBarcode3() throws IOException {
int width = 512;
int height = 150;
Code3Of9 code3Of9 = new Code3Of9();
code3Of9.setContent("11111111111");
double scalingFactor = 3.0d;
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
BarcodeGraphicsRenderer renderer = createRenderer(bufferedImage, scalingFactor, scalingFactor);
renderer.render(code3Of9);
renderer.close();
OutputStream outputStream = Files.newOutputStream(Paths.get("build/barcode3.png"));
ImageIO.write(bufferedImage, "png", outputStream);
outputStream.close();
}
private BarcodeGraphicsRenderer createRenderer(BufferedImage bufferedImage, double scalingFactorX, double scalingFactorY) {
Graphics2D g2d = bufferedImage.createGraphics();
Rectangle rectangle = new Rectangle(0, 0, bufferedImage.getWidth(), bufferedImage.getHeight());
return new BarcodeGraphicsRenderer(g2d, rectangle, scalingFactor, Color.WHITE, Color.BLACK, false, false);
return new BarcodeGraphicsRenderer(g2d, rectangle, scalingFactorX, scalingFactorY,
Color.WHITE, Color.BLACK, false, false);
}
}

View file

@ -87,20 +87,20 @@ public class EPSRendererTest {
}
private void test(AbstractSymbol symbol,
double magnification,
double scale,
Color paper,
Color ink,
int margin,
String expectationFile) throws IOException {
symbol.setQuietZoneHorizontal(margin);
symbol.setQuietZoneVertical(margin);
int width = (int) (symbol.getWidth() * magnification);
int height = (int) (symbol.getHeight() * magnification);
int width = (int) (symbol.getWidth() * scale);
int height = (int) (symbol.getHeight() * scale);
Rectangle rectangle = new Rectangle(0, 0, width, height);
EPSGraphics2D epsGraphics2D = new EPSGraphics2D(rectangle);
epsGraphics2D.setFont(Font.decode("Dialog"));
BarcodeGraphicsRenderer barcodeGraphicsRenderer = new BarcodeGraphicsRenderer(epsGraphics2D, rectangle,
magnification, paper, ink, false, false);
scale, scale, paper, ink, false, false);
barcodeGraphicsRenderer.render(symbol);
barcodeGraphicsRenderer.close();
byte[] actualBytes = epsGraphics2D.getBytes();

View file

@ -87,20 +87,20 @@ public class PDFRendererTest {
}
private void test(AbstractSymbol symbol,
double magnification,
double scale,
Color paper,
Color ink,
int margin,
String expectationFile) throws IOException {
symbol.setQuietZoneHorizontal(margin);
symbol.setQuietZoneVertical(margin);
int width = (int) (symbol.getWidth() * magnification);
int height = (int) (symbol.getHeight() * magnification);
int width = (int) (symbol.getWidth() * scale);
int height = (int) (symbol.getHeight() * scale);
Rectangle rectangle = new Rectangle(0, 0, width, height);
PDFGraphics2D pdfGraphics2D = new PDFGraphics2D(rectangle);
pdfGraphics2D.setFont(Font.decode("Dialog")); // Helvetica
BarcodeGraphicsRenderer barcodeGraphicsRenderer = new BarcodeGraphicsRenderer(pdfGraphics2D,
rectangle, magnification, paper, ink, false, false);
rectangle, scale, scale, paper, ink, false, false);
barcodeGraphicsRenderer.render(symbol);
barcodeGraphicsRenderer.close();
byte[] actualBytes = pdfGraphics2D.getBytes();

View file

@ -87,20 +87,20 @@ public class SVGRendererTest {
}
private void test(AbstractSymbol symbol,
double magnification,
double scale,
Color paper,
Color ink,
int margin,
String expectationFile) throws IOException {
symbol.setQuietZoneHorizontal(margin);
symbol.setQuietZoneVertical(margin);
int width = (int) (symbol.getWidth() * magnification);
int height = (int) (symbol.getHeight() * magnification);
int width = (int) (symbol.getWidth() * scale);
int height = (int) (symbol.getHeight() * scale);
Rectangle rectangle = new Rectangle(0, 0, width, height);
SVGGraphics2D svgGraphics2D = new SVGGraphics2D(rectangle);
svgGraphics2D.setFont(Font.decode("Dialog"));
BarcodeGraphicsRenderer barcodeGraphicsRenderer = new BarcodeGraphicsRenderer(svgGraphics2D,
rectangle, magnification, paper, ink, false, false);
rectangle, scale, scale, paper, ink, false, false);
barcodeGraphicsRenderer.render(symbol);
barcodeGraphicsRenderer.close();
byte[] actualBytes = svgGraphics2D.getBytes();

View file

@ -17,31 +17,40 @@ public class BarcodeElement implements Element, Drawable, Dividable, WidthRespec
private final Symbol symbol;
private float width;
private Float width;
private float height;
private Float height;
private float scale;
private float scaleX = 1.0f;
private float scaleY = 1.0f;
private float maxWidth = -1;
private Position absolutePosition;
private Color color = Color.BLACK;
private Color backgroundColor = Color.WHITE;
public BarcodeElement(Symbol symbol) {
this.symbol = symbol;
setWidth(symbol.getWidth());
setHeight(symbol.getHeight());
setScale(1.0f);
}
public void setScale(float scale) {
this.scale = scale;
setWidth(width * scale);
setHeight(height * scale);
public void setScaleX(float scaleX) {
this.scaleX = scaleX;
}
public float getScale() {
return scale;
public float getScaleX() {
return scaleX;
}
public void setScaleY(float scaleY) {
this.scaleY = scaleY;
}
public float getScaleY() {
return scaleY;
}
public void setWidth(float width) {
@ -50,7 +59,7 @@ public class BarcodeElement implements Element, Drawable, Dividable, WidthRespec
@Override
public float getWidth() throws IOException {
return width;
return width != null ? width * scaleX : symbol.getWidth() * scaleX;
}
public void setHeight(float height) {
@ -59,7 +68,7 @@ public class BarcodeElement implements Element, Drawable, Dividable, WidthRespec
@Override
public float getHeight() throws IOException {
return height;
return height != null ? height * scaleY : symbol.getHeight() * scaleY;
}
@Override
@ -95,14 +104,22 @@ public class BarcodeElement implements Element, Drawable, Dividable, WidthRespec
this.absolutePosition = absolutePosition;
}
public void setColor(Color color) {
this.color = color;
}
public void setBackgroundColor(Color backgroundColor) {
this.backgroundColor = backgroundColor;
}
@Override
public void draw(PDDocument pdDocument, PDPageContentStream contentStream,
Position upperLeft, DrawListener drawListener) throws IOException {
float x = upperLeft.getX();
float y = upperLeft.getY() - height;
PdfBoxGraphics2D pdfBoxGraphics2D = new PdfBoxGraphics2D(pdDocument, width, height);
BarcodeGraphicsRenderer renderer = new BarcodeGraphicsRenderer(pdfBoxGraphics2D, null, 1.0d,
Color.WHITE, Color.BLACK, false, false);
float y = upperLeft.getY() - getHeight();
PdfBoxGraphics2D pdfBoxGraphics2D = new PdfBoxGraphics2D(pdDocument, getWidth(), getHeight());
BarcodeGraphicsRenderer renderer = new BarcodeGraphicsRenderer(pdfBoxGraphics2D, null, scaleX, scaleY,
backgroundColor, color, false, false);
renderer.render(symbol);
renderer.close();
PDFormXObject xFormObject = pdfBoxGraphics2D.getXFormObject();

View file

@ -35,7 +35,7 @@ public class Document implements Element, Closeable, RenderListener {
private final List<RenderListener> renderListener = new ArrayList<>();
private final PageFormat pageFormat;
private PageFormat pageFormat;
private final PDDocument pdDocument;
@ -58,13 +58,6 @@ public class Document implements Element, Closeable, RenderListener {
this(pageFormat, true);
}
public Document(PageFormat pageFormat, boolean memory) {
this.pageFormat = pageFormat;
this.pdDocument = new PDDocument(memory ?
MemoryUsageSetting.setupMainMemoryOnly() : MemoryUsageSetting.setupTempFileOnly());
this.pdDocumentInformation = new PDDocumentInformation();
}
/**
* Creates a Document in A4 with orientation portrait and the given margins.
* By default, a {@link VerticalLayout} is used.
@ -88,6 +81,16 @@ public class Document implements Element, Closeable, RenderListener {
this(PageFormat.builder().margins(marginLeft, marginRight, marginTop, marginBottom).build(), memory);
}
public Document(PageFormat pageFormat, boolean memory) {
this.pdDocument = new PDDocument(memory ? MemoryUsageSetting.setupMainMemoryOnly() : MemoryUsageSetting.setupTempFileOnly());
this.pdDocumentInformation = new PDDocumentInformation();
setPageFormat(pageFormat);
}
public void setPageFormat(PageFormat pageFormat) {
this.pageFormat = pageFormat;
}
public PDDocument getPdDocument() {
return pdDocument;
}
@ -153,8 +156,9 @@ public class Document implements Element, Closeable, RenderListener {
* @param element the element to add
* @param layoutHint the hint for the {@link Layout}.
*/
public void add(Element element, LayoutHint layoutHint) {
public Element add(Element element, LayoutHint layoutHint) {
elements.add(Map.entry(element, layoutHint));
return this;
}
/**

View file

@ -1,5 +1,7 @@
package org.xbib.graphics.pdfbox.layout.elements;
import org.xbib.graphics.pdfbox.layout.elements.render.LayoutHint;
/**
* Base (tagging) interface for elements in a {@link Document}.
*/
@ -8,4 +10,8 @@ public interface Element {
default Element add(Element element) {
throw new UnsupportedOperationException();
}
default Element add(Element element, LayoutHint layoutHint) {
throw new UnsupportedOperationException();
}
}

View file

@ -6,13 +6,13 @@ import org.xbib.graphics.pdfbox.layout.elements.render.VerticalLayout;
import java.util.Locale;
import java.util.Objects;
import static org.xbib.graphics.pdfbox.layout.util.PdfUtil.MM_TO_UNITS;
/**
* Defines the size and orientation of a page. The default is A4 portrait without margins.
*/
public class PageFormat implements Element {
public static final float MM_TO_UNITS = 1.0f / 25.4f * 72.0f;
public static final PDRectangle A0 = new PDRectangle(Math.round(841f * MM_TO_UNITS), Math.round(1189f * MM_TO_UNITS));
public static final PDRectangle A1 = new PDRectangle(Math.round(594f * MM_TO_UNITS), Math.round(841f * MM_TO_UNITS));

View file

@ -6,7 +6,7 @@ import org.xbib.graphics.pdfbox.layout.text.Alignment;
import org.xbib.graphics.pdfbox.layout.text.DrawListener;
import org.xbib.graphics.pdfbox.layout.text.Position;
import org.xbib.graphics.pdfbox.layout.text.TextFlow;
import org.xbib.graphics.pdfbox.layout.text.TextSequenceUtil;
import org.xbib.graphics.pdfbox.layout.util.TextSequenceUtil;
import org.xbib.graphics.pdfbox.layout.text.WidthRespecting;
/**

View file

@ -29,6 +29,9 @@ public class TableElement implements Element, Drawable, Dividable {
if (element instanceof Row.Builder) {
Row row = ((Row.Builder) element).build();
table.addRow(row);
} else if (element instanceof HorizontalRuler) {
Row row = Row.builder().add(element).build();
table.addRow(row);
} else {
throw new UnsupportedOperationException();
}

View file

@ -13,20 +13,22 @@ import java.io.IOException;
*/
public class ColumnLayout extends VerticalLayout {
private final int columnCount;
private int columnCount = 1;
private final float columnSpacing;
private float columnSpacing = 0f;
private int columnIndex = 0;
private Float offsetY = null;
public ColumnLayout(int columnCount) {
this(columnCount, 0);
public ColumnLayout setColumnCount(int columnCount) {
this.columnCount = columnCount;
return this;
}
public ColumnLayout(int columnCount, float columnSpacing) {
this.columnCount = columnCount;
public ColumnLayout setColumnSpacing(float columnSpacing) {
this.columnSpacing = columnSpacing;
return this;
}
@Override
@ -36,26 +38,24 @@ public class ColumnLayout extends VerticalLayout {
}
/**
* Flips to the next column
* Flips to the next column.
* @param renderContext render context
*/
@Override
protected void turnPage(final RenderContext renderContext)
throws IOException {
protected void turnPage(RenderContext renderContext) throws IOException {
if (++columnIndex >= columnCount) {
renderContext.newPage();
columnIndex = 0;
offsetY = 0f;
} else {
float nextColumnX = (getTargetWidth(renderContext) + columnSpacing)
* columnIndex;
float nextColumnX = (getTargetWidth(renderContext) + columnSpacing) * columnIndex;
renderContext.resetPositionToUpperLeft();
renderContext.movePositionBy(nextColumnX, -offsetY);
}
}
@Override
public boolean render(RenderContext renderContext, Element element,
LayoutHint layoutHint) throws IOException {
public boolean render(RenderContext renderContext, Element element, LayoutHint layoutHint) throws IOException {
if (element == ControlElement.NEWPAGE) {
renderContext.newPage();
return true;
@ -68,8 +68,7 @@ public class ColumnLayout extends VerticalLayout {
}
@Override
public void render(RenderContext renderContext, Drawable drawable,
LayoutHint layoutHint) throws IOException {
public void render(RenderContext renderContext, Drawable drawable, LayoutHint layoutHint) throws IOException {
if (offsetY == null) {
offsetY = renderContext.getUpperLeft().getY() - renderContext.getCurrentPosition().getY();
}
@ -84,5 +83,4 @@ public class ColumnLayout extends VerticalLayout {
}
return renderContext.getCurrentPosition().getY() == topPosition;
}
}

View file

@ -8,18 +8,17 @@ import org.xbib.graphics.pdfbox.layout.text.Alignment;
*/
public class ColumnLayoutHint extends VerticalLayoutHint {
public final static ColumnLayoutHint LEFT = new ColumnLayoutHint(
Alignment.LEFT);
public final static ColumnLayoutHint CENTER = new ColumnLayoutHint(
Alignment.CENTER);
public final static ColumnLayoutHint RIGHT = new ColumnLayoutHint(
Alignment.RIGHT);
public final static ColumnLayoutHint LEFT = new ColumnLayoutHint(Alignment.LEFT);
public final static ColumnLayoutHint CENTER = new ColumnLayoutHint(Alignment.CENTER);
public final static ColumnLayoutHint RIGHT = new ColumnLayoutHint(Alignment.RIGHT);
/**
* Creates a layout hint with {@link Alignment#LEFT left alignment}.
*/
public ColumnLayoutHint() {
super();
super(Alignment.LEFT);
}
/**
@ -40,8 +39,7 @@ public class ColumnLayoutHint extends VerticalLayoutHint {
* @param marginTop the top alignment.
* @param marginBottom the bottom alignment.
*/
public ColumnLayoutHint(Alignment alignment, float marginLeft,
float marginRight, float marginTop, float marginBottom) {
public ColumnLayoutHint(Alignment alignment, float marginLeft, float marginRight, float marginTop, float marginBottom) {
super(alignment, marginLeft, marginRight, marginTop, marginBottom);
}
@ -56,14 +54,11 @@ public class ColumnLayoutHint extends VerticalLayoutHint {
* @param resetY if <code>true</code>, the y coordinate will be reset to the
* point before layouting the element.
*/
public ColumnLayoutHint(Alignment alignment, float marginLeft,
float marginRight, float marginTop, float marginBottom,
public ColumnLayoutHint(Alignment alignment, float marginLeft, float marginRight, float marginTop, float marginBottom,
boolean resetY) {
super(alignment, marginLeft, marginRight, marginTop, marginBottom,
resetY);
super(alignment, marginLeft, marginRight, marginTop, marginBottom, resetY);
}
/**
* @return a {@link VerticalLayoutHintBuilder} for creating a
* {@link VerticalLayoutHint} using a fluent API.

View file

@ -4,11 +4,9 @@ import org.xbib.graphics.pdfbox.layout.elements.Document;
import org.xbib.graphics.pdfbox.layout.elements.Element;
/**
* Each element in a document is
* {@link Document#add(Element, LayoutHint)
* accompanied} by a hint, which gives some notes to the current layout on how
* Each element in a document {@link Document#add(Element, LayoutHint)}
* is accompanied by a hint, which gives some notes to the current layout on how
* to layout the element.
*/
public interface LayoutHint {
}

View file

@ -0,0 +1,14 @@
package org.xbib.graphics.pdfbox.layout.elements.render;
public enum Layouts {
VERTICAL,
COLUMN;
public Layout getLayout() {
switch (name()) {
case "VERTICAL": return new VerticalLayout();
case "COLUMN": return new ColumnLayout();
}
throw new IllegalArgumentException();
}
}

View file

@ -100,8 +100,7 @@ public class RenderContext implements Renderer, Closeable, DrawContext, DrawList
* {@link Document document} margins.
*/
public Position getUpperLeft() {
return new Position(getPageFormat().getMarginLeft(), getPageHeight()
- getPageFormat().getMarginTop());
return new Position(getPageFormat().getMarginLeft(), getPageHeight() - getPageFormat().getMarginTop());
}
/**
@ -109,8 +108,7 @@ public class RenderContext implements Renderer, Closeable, DrawContext, DrawList
* {@link Document document} margins.
*/
public Position getLowerRight() {
return new Position(getPageWidth() - getPageFormat().getMarginRight(),
getPageFormat().getMarginBottom());
return new Position(getPageWidth() - getPageFormat().getMarginRight(), getPageFormat().getMarginBottom());
}
/**

View file

@ -13,20 +13,22 @@ import org.xbib.graphics.pdfbox.layout.text.Alignment;
*/
public class VerticalLayoutHint implements LayoutHint {
public final static VerticalLayoutHint LEFT = new VerticalLayoutHint(
Alignment.LEFT);
public final static VerticalLayoutHint LEFT = new VerticalLayoutHint(Alignment.LEFT);
public final static VerticalLayoutHint CENTER = new VerticalLayoutHint(
Alignment.CENTER);
public final static VerticalLayoutHint CENTER = new VerticalLayoutHint(Alignment.CENTER);
public final static VerticalLayoutHint RIGHT = new VerticalLayoutHint(
Alignment.RIGHT);
public final static VerticalLayoutHint RIGHT = new VerticalLayoutHint(Alignment.RIGHT);
private final Alignment alignment;
private final float marginLeft;
private final float marginRight;
private final float marginTop;
private final float marginBottom;
private final boolean resetY;
/**
@ -54,8 +56,7 @@ public class VerticalLayoutHint implements LayoutHint {
* @param marginTop the top alignment.
* @param marginBottom the bottom alignment.
*/
public VerticalLayoutHint(Alignment alignment, float marginLeft,
float marginRight, float marginTop, float marginBottom) {
public VerticalLayoutHint(Alignment alignment, float marginLeft, float marginRight, float marginTop, float marginBottom) {
this(alignment, marginLeft, marginRight, marginTop, marginBottom, false);
}
@ -70,8 +71,7 @@ public class VerticalLayoutHint implements LayoutHint {
* @param resetY if <code>true</code>, the y coordinate will be reset to the
* point before layouting the element.
*/
public VerticalLayoutHint(Alignment alignment, float marginLeft,
float marginRight, float marginTop, float marginBottom,
public VerticalLayoutHint(Alignment alignment, float marginLeft, float marginRight, float marginTop, float marginBottom,
boolean resetY) {
this.alignment = alignment;
this.marginLeft = marginLeft;
@ -126,40 +126,45 @@ public class VerticalLayoutHint implements LayoutHint {
* {@link VerticalLayoutHint} using a fluent API.
*/
public static class VerticalLayoutHintBuilder {
protected Alignment alignment = Alignment.LEFT;
protected float marginLeft = 0;
protected float marginRight = 0;
protected float marginTop = 0;
protected float marginBottom = 0;
protected float marginLeft = 0f;
protected float marginRight = 0f;
protected float marginTop = 0f;
protected float marginBottom = 0f;
protected boolean resetY = false;
public VerticalLayoutHintBuilder alignment(final Alignment alignment) {
public VerticalLayoutHintBuilder alignment(Alignment alignment) {
this.alignment = alignment;
return this;
}
public VerticalLayoutHintBuilder marginLeft(final float marginLeft) {
public VerticalLayoutHintBuilder marginLeft(float marginLeft) {
this.marginLeft = marginLeft;
return this;
}
public VerticalLayoutHintBuilder marginRight(final float marginRight) {
public VerticalLayoutHintBuilder marginRight(float marginRight) {
this.marginRight = marginRight;
return this;
}
public VerticalLayoutHintBuilder marginTop(final float marginTop) {
public VerticalLayoutHintBuilder marginTop(float marginTop) {
this.marginTop = marginTop;
return this;
}
public VerticalLayoutHintBuilder marginBottom(final float marginBottom) {
public VerticalLayoutHintBuilder marginBottom(float marginBottom) {
this.marginBottom = marginBottom;
return this;
}
public VerticalLayoutHintBuilder margins(float marginLeft,
float marginRight, float marginTop, float marginBottom) {
public VerticalLayoutHintBuilder margins(float marginLeft, float marginRight, float marginTop, float marginBottom) {
this.marginLeft = marginLeft;
this.marginRight = marginRight;
this.marginTop = marginTop;
@ -167,16 +172,13 @@ public class VerticalLayoutHint implements LayoutHint {
return this;
}
public VerticalLayoutHintBuilder resetY(final boolean resetY) {
public VerticalLayoutHintBuilder resetY(boolean resetY) {
this.resetY = resetY;
return this;
}
public VerticalLayoutHint build() {
return new VerticalLayoutHint(alignment, marginLeft, marginRight,
marginTop, marginBottom, resetY);
return new VerticalLayoutHint(alignment, marginLeft, marginRight, marginTop, marginBottom, resetY);
}
}
}

View file

@ -4,14 +4,18 @@ import org.xbib.graphics.barcode.HumanReadableLocation;
import org.xbib.graphics.barcode.Symbol;
import org.xbib.graphics.barcode.Symbols;
import org.xbib.graphics.pdfbox.layout.elements.BarcodeElement;
import org.xbib.graphics.pdfbox.layout.elements.render.VerticalLayoutHint;
import org.xbib.graphics.pdfbox.layout.script.Engine;
import org.xbib.graphics.pdfbox.layout.script.State;
import org.xbib.graphics.pdfbox.layout.text.Alignment;
import org.xbib.graphics.pdfbox.layout.text.Position;
import org.xbib.settings.Settings;
import java.io.IOException;
import java.util.Locale;
import static org.xbib.graphics.pdfbox.layout.util.PdfUtil.mmToPt;
public class BarcodeCommand implements Command {
@Override
@ -27,17 +31,28 @@ public class BarcodeCommand implements Command {
throw new IOException(e);
}
if (settings.containsSetting("x") && settings.containsSetting("y")) {
element.setAbsolutePosition(new Position(settings.getAsFloat("x", 0f), settings.getAsFloat("y", 0f)));
element.setAbsolutePosition(new Position(mmToPt(settings.getAsFloat("x", 0f)), mmToPt(settings.getAsFloat("y", 0f))));
}
if (settings.containsSetting("width")) {
element.setWidth(settings.getAsFloat("width", element.getWidth()));
}
if (settings.containsSetting("height")) {
element.setWidth(settings.getAsFloat("height", element.getHeight()));
element.setHeight(settings.getAsFloat("height", element.getHeight()));
}
if (settings.containsSetting("scale")) {
element.setScale(settings.getAsFloat("scale", element.getScale()));
if (settings.containsSetting("scalex")) {
element.setScaleX(settings.getAsFloat("scalex", element.getScaleX()));
}
state.elements.peek().add(element);
if (settings.containsSetting("scaley")) {
element.setScaleY(settings.getAsFloat("scaley", element.getScaleY()));
}
Alignment alignment = Alignment.valueOf(settings.get("alignment", "left").toUpperCase(Locale.ROOT));
String margin = settings.get("margin", "0 0 0 0");
String[] margins = margin.split(" ");
float marginleft = Float.parseFloat(margins[0]);
float marginright = Float.parseFloat(margins[1]);
float margintop = Float.parseFloat(margins[2]);
float marginbottom = Float.parseFloat(margins[3]);
VerticalLayoutHint verticalLayoutHint = new VerticalLayoutHint(alignment, marginleft, marginright, margintop, marginbottom, true);
state.elements.peek().add(element, verticalLayoutHint);
}
}

View file

@ -2,30 +2,40 @@ package org.xbib.graphics.pdfbox.layout.script.command;
import org.xbib.graphics.pdfbox.layout.color.ColorFactory;
import org.xbib.graphics.pdfbox.layout.elements.Document;
import org.xbib.graphics.pdfbox.layout.elements.Paragraph;
import org.xbib.graphics.pdfbox.layout.font.Font;
import org.xbib.graphics.pdfbox.layout.font.Fonts;
import org.xbib.graphics.pdfbox.layout.script.Engine;
import org.xbib.graphics.pdfbox.layout.script.State;
import org.xbib.graphics.pdfbox.layout.table.BorderStyle;
import org.xbib.graphics.pdfbox.layout.table.BorderStyleInterface;
import org.xbib.graphics.pdfbox.layout.table.HorizontalAlignment;
import org.xbib.graphics.pdfbox.layout.table.Markup;
import org.xbib.graphics.pdfbox.layout.table.ParagraphCell;
import org.xbib.graphics.pdfbox.layout.table.TextCell;
import org.xbib.graphics.pdfbox.layout.table.VerticalAlignment;
import org.xbib.graphics.pdfbox.layout.text.Alignment;
import org.xbib.graphics.pdfbox.layout.text.Position;
import org.xbib.settings.Settings;
import java.awt.Color;
import java.io.IOException;
import java.util.Locale;
import static org.xbib.graphics.pdfbox.layout.util.PdfUtil.mmToPt;
public class CellCommand implements Command {
@Override
public void execute(Engine engine, State state, Settings settings) throws IOException {
if (settings.containsSetting("value")) {
TextCell.Builder cell = TextCell.builder();
cell.padding(settings.getAsFloat("padding", 0f));
cell.text(settings.get("value"));
cell.fontSize(settings.getAsFloat("size", 11.0f));
cell.fontSize(settings.getAsFloat("fontsize", 11.0f));
Document document = state.getDocument();
Font font = Fonts.valueOf(settings.get("font", "helvetica").toUpperCase(Locale.ROOT)).getFont(document);
cell.font(font);
cell.padding(settings.getAsFloat("padding", 0f));
Color color = ColorFactory.web(settings.get("color", "black"));
cell.textColor(color);
if (settings.containsSetting("backgroundcolor")) {
@ -39,8 +49,36 @@ public class CellCommand implements Command {
cell.borderWidth(settings.getAsFloat("borderwidth", 0f));
BorderStyleInterface styleInterface = BorderStyle.valueOf(settings.get("borderstyle", "solid").toUpperCase(Locale.ROOT));
cell.borderStyle(styleInterface);
if (settings.containsSetting("horizontalalignment")) {
cell.horizontalAlignment(HorizontalAlignment.valueOf(settings.get("horizontalalignment", "left").toUpperCase(Locale.ROOT)));
}
if (settings.containsSetting("verticalalignment")) {
cell.verticalAlignment(VerticalAlignment.valueOf(settings.get("verticalalignment", "left").toUpperCase(Locale.ROOT)));
}
cell.colSpan(settings.getAsInt("colspan", 1));
cell.rowSpan(settings.getAsInt("rowspan", 1));
state.elements.peek().add(cell.build());
} else if (settings.containsSetting("markup")) {
ParagraphCell.Builder cell = ParagraphCell.builder();
cell.colSpan(settings.getAsInt("colspan", 1));
cell.rowSpan(settings.getAsInt("rowspan", 1));
Paragraph paragraph = new Paragraph();
if (settings.containsSetting("x") && settings.containsSetting("y")) {
paragraph.setAbsolutePosition(new Position(mmToPt(settings.getAsFloat("x", 0f)), mmToPt(settings.getAsFloat("y", 0f))));
}
if (settings.containsSetting("width")) {
paragraph.setMaxWidth(settings.getAsFloat("width", 0f));
}
if (settings.containsSetting("alignment")) {
paragraph.setAlignment(Alignment.valueOf(settings.get("alignment", "left").toUpperCase(Locale.ROOT)));
}
cell.paragraph(paragraph);
String value = settings.get("markup");
float size = settings.getAsFloat("fontsize", 11.0f);
Document document = state.getDocument();
Font font = Fonts.valueOf(settings.get("font", "helvetica").toUpperCase(Locale.ROOT)).getFont(document);
cell.add(new Markup().setValue(value).setFont(font).setFontSize(size));
state.elements.peek().add(cell.build());
}
}
}

View file

@ -11,7 +11,9 @@ public class ColumnlayoutCommand implements Command {
@Override
public void execute(Engine engine, State state, Settings settings) throws IOException {
ColumnLayout columnLayout = new ColumnLayout(settings.getAsInt("columns", 2), settings.getAsFloat("spacing", 10f));
ColumnLayout columnLayout = new ColumnLayout();
columnLayout.setColumnCount(settings.getAsInt("columns", 2));
columnLayout.setColumnSpacing(settings.getAsFloat("spacing", 10f));
state.elements.peek().add(columnLayout);
}
}

View file

@ -11,18 +11,20 @@ import org.xbib.settings.Settings;
import java.io.IOException;
import java.util.Locale;
import static org.xbib.graphics.pdfbox.layout.util.PdfUtil.mmToPt;
public class ImageCommand implements Command {
@Override
public void execute(Engine engine, State state, Settings settings) throws IOException {
ImageElement imageElement = new ImageElement(settings.get("value"));
if (settings.containsSetting("x") && settings.containsSetting("y")) {
imageElement.setAbsolutePosition(new Position(settings.getAsFloat("x", 0f), settings.getAsFloat("y", 0f)));
imageElement.setAbsolutePosition(new Position(mmToPt(settings.getAsFloat("x", 0f)), mmToPt(settings.getAsFloat("y", 0f))));
}
if (settings.containsSetting("width")) {
imageElement.setWidth(settings.getAsFloat("width", imageElement.getWidth()));
}
if (settings.containsSetting("height")) {
imageElement.setWidth(settings.getAsFloat("height", imageElement.getHeight()));
imageElement.setHeight(settings.getAsFloat("height", imageElement.getHeight()));
}
if (settings.containsSetting("scale")) {
imageElement.setScale(settings.getAsFloat("scale", imageElement.getScale()));
@ -35,6 +37,6 @@ public class ImageCommand implements Command {
float margintop = Float.parseFloat(margins[2]);
float marginbottom = Float.parseFloat(margins[3]);
VerticalLayoutHint verticalLayoutHint = new VerticalLayoutHint(alignment, marginleft, marginright, margintop, marginbottom, true);
state.elements.peek().add(imageElement);
state.elements.peek().add(imageElement, verticalLayoutHint);
}
}

View file

@ -0,0 +1,16 @@
package org.xbib.graphics.pdfbox.layout.script.command;
import org.xbib.graphics.pdfbox.layout.script.Engine;
import org.xbib.graphics.pdfbox.layout.script.State;
import org.xbib.settings.Settings;
import java.io.IOException;
import java.util.Locale;
public class LayoutCommand implements Command {
@Override
public void execute(Engine engine, State state, Settings settings) throws IOException {
String layout = settings.get("layout", "vertical").toUpperCase(Locale.ROOT);
}
}

View file

@ -1,6 +1,7 @@
package org.xbib.graphics.pdfbox.layout.script.command;
import org.xbib.graphics.pdfbox.layout.elements.Paragraph;
import org.xbib.graphics.pdfbox.layout.elements.render.VerticalLayoutHint;
import org.xbib.graphics.pdfbox.layout.script.Engine;
import org.xbib.graphics.pdfbox.layout.script.State;
import org.xbib.graphics.pdfbox.layout.text.Alignment;
@ -10,13 +11,15 @@ import org.xbib.settings.Settings;
import java.io.IOException;
import java.util.Locale;
import static org.xbib.graphics.pdfbox.layout.util.PdfUtil.mmToPt;
public class ParagraphCommand implements Command {
@Override
public void execute(Engine engine, State state, Settings settings) throws IOException {
Paragraph paragraph = new Paragraph();
if (settings.containsSetting("x") && settings.containsSetting("y")) {
paragraph.setAbsolutePosition(new Position(settings.getAsFloat("x", 0f), settings.getAsFloat("y", 0f)));
paragraph.setAbsolutePosition(new Position(mmToPt(settings.getAsFloat("x", 0f)), mmToPt(settings.getAsFloat("y", 0f))));
}
if (settings.containsSetting("width")) {
paragraph.setMaxWidth(settings.getAsFloat("width", 0f));
@ -27,6 +30,15 @@ public class ParagraphCommand implements Command {
state.elements.push(paragraph);
engine.executeElements(settings);
state.elements.pop();
state.elements.peek().add(paragraph);
Alignment alignment = Alignment.valueOf(settings.get("layout.alignment", "left").toUpperCase(Locale.ROOT));
String margin = settings.get("layout.margin", "0 0 0 0");
String[] margins = margin.split(" ");
float marginleft = Float.parseFloat(margins[0]);
float marginright = Float.parseFloat(margins[1]);
float margintop = Float.parseFloat(margins[2]);
float marginbottom = Float.parseFloat(margins[3]);
boolean resetY = settings.getAsBoolean("layout.resety", false);
VerticalLayoutHint verticalLayoutHint = new VerticalLayoutHint(alignment, marginleft, marginright, margintop, marginbottom, resetY);
state.elements.peek().add(paragraph, verticalLayoutHint);
}
}

View file

@ -1,11 +1,20 @@
package org.xbib.graphics.pdfbox.layout.script.command;
import org.xbib.graphics.pdfbox.layout.color.ColorFactory;
import org.xbib.graphics.pdfbox.layout.elements.Document;
import org.xbib.graphics.pdfbox.layout.font.Fonts;
import org.xbib.graphics.pdfbox.layout.script.Engine;
import org.xbib.graphics.pdfbox.layout.script.State;
import org.xbib.graphics.pdfbox.layout.table.BorderStyle;
import org.xbib.graphics.pdfbox.layout.table.BorderStyleInterface;
import org.xbib.graphics.pdfbox.layout.table.HorizontalAlignment;
import org.xbib.graphics.pdfbox.layout.table.Row;
import org.xbib.graphics.pdfbox.layout.table.VerticalAlignment;
import org.xbib.settings.Settings;
import java.awt.Color;
import java.io.IOException;
import java.util.Locale;
public class RowCommand implements Command {
@ -13,6 +22,28 @@ public class RowCommand implements Command {
public void execute(Engine engine, State state, Settings settings) throws IOException {
Row.Builder row = Row.builder();
row.padding(settings.getAsFloat("padding", 0f));
row.fontSize(settings.getAsFloat("fontsize", 11.0f));
Document document = state.getDocument();
row.font(Fonts.valueOf(settings.get("font", "helvetica").toUpperCase(Locale.ROOT)).getFont(document));
Color color = ColorFactory.web(settings.get("color", "black"));
row.textColor(color);
if (settings.containsSetting("backgroundcolor")) {
Color backgroundColor = ColorFactory.web(settings.get("backgroundcolor", "black"));
row.backgroundColor(backgroundColor);
}
if (settings.containsSetting("bordercolor")) {
Color borderColor = ColorFactory.web(settings.get("bordercolor", "black"));
row.borderColor(borderColor);
}
row.borderWidth(settings.getAsFloat("borderwidth", 0f));
BorderStyleInterface styleInterface = BorderStyle.valueOf(settings.get("borderstyle", "solid").toUpperCase(Locale.ROOT));
row.borderStyle(styleInterface);
if (settings.containsSetting("horizontalalignment")) {
row.horizontalAlignment(HorizontalAlignment.valueOf(settings.get("horizontalalignment", "left").toUpperCase(Locale.ROOT)));
}
if (settings.containsSetting("verticalalignment")) {
row.verticalAlignment(VerticalAlignment.valueOf(settings.get("verticalalignment", "left").toUpperCase(Locale.ROOT)));
}
state.elements.push(row);
engine.executeElements(settings);
state.elements.pop();

View file

@ -3,21 +3,29 @@ package org.xbib.graphics.pdfbox.layout.script.command;
import org.xbib.graphics.pdfbox.layout.elements.TableElement;
import org.xbib.graphics.pdfbox.layout.script.Engine;
import org.xbib.graphics.pdfbox.layout.script.State;
import org.xbib.graphics.pdfbox.layout.text.Position;
import org.xbib.settings.Settings;
import java.io.IOException;
import static org.xbib.graphics.pdfbox.layout.util.PdfUtil.mmToPt;
public class TableCommand implements Command {
@Override
public void execute(Engine engine, State state, Settings settings) throws IOException {
TableElement tableElement = new TableElement();
if (settings.containsSetting("columnwidths")) {
String columnWidths = settings.get("columnwidths");
for (String columnWidth : columnWidths.split(" ")) {
tableElement.addColumnOfWidth(Float.parseFloat(columnWidth));
String columnwidths = settings.get("columnwidths");
String[] widths = columnwidths.split(" ");
for (String width : widths) {
tableElement.addColumnOfWidth(mmToPt(Float.parseFloat(width)));
}
}
if (settings.containsSetting("x") && settings.containsSetting("y")) {
tableElement.setAbsolutePosition(new Position(mmToPt(settings.getAsFloat("x", 0f)), mmToPt(settings.getAsFloat("y", 0f))));
}
state.elements.push(tableElement);
engine.executeElements(settings);
state.elements.pop();

View file

@ -1,23 +1,55 @@
package org.xbib.graphics.pdfbox.layout.script.command;
import org.xbib.graphics.pdfbox.layout.elements.Document;
import org.xbib.graphics.pdfbox.layout.elements.Element;
import org.xbib.graphics.pdfbox.layout.elements.Paragraph;
import org.xbib.graphics.pdfbox.layout.elements.TextElement;
import org.xbib.graphics.pdfbox.layout.elements.render.VerticalLayoutHint;
import org.xbib.graphics.pdfbox.layout.font.Font;
import org.xbib.graphics.pdfbox.layout.font.Fonts;
import org.xbib.graphics.pdfbox.layout.script.Engine;
import org.xbib.graphics.pdfbox.layout.script.State;
import org.xbib.graphics.pdfbox.layout.text.Alignment;
import org.xbib.graphics.pdfbox.layout.text.Position;
import org.xbib.settings.Settings;
import java.util.Locale;
import static org.xbib.graphics.pdfbox.layout.util.PdfUtil.mmToPt;
public class TextCommand implements Command {
@Override
public void execute(Engine engine, State state, Settings settings) {
String value = settings.get("value");
float size = settings.getAsFloat("size", 11.0f);
float size = settings.getAsFloat("fontsize", 11.0f);
Document document = state.getDocument();
Font font = Fonts.valueOf(settings.get("font", "helvetica").toUpperCase(Locale.ROOT)).getFont(document);
state.elements.peek().add(new TextElement(value, font, size));
Element element = state.elements.peek();
if (element instanceof Paragraph) {
element.add(new TextElement(value, font, size));
} else if (element instanceof Document) {
Paragraph paragraph = new Paragraph();
if (settings.containsSetting("x") && settings.containsSetting("y")) {
paragraph.setAbsolutePosition(new Position(mmToPt(settings.getAsFloat("x", 0f)), mmToPt(settings.getAsFloat("y", 0f))));
}
if (settings.containsSetting("width")) {
paragraph.setMaxWidth(settings.getAsFloat("width", 0f));
}
if (settings.containsSetting("alignment")) {
paragraph.setAlignment(Alignment.valueOf(settings.get("alignment", "left").toUpperCase(Locale.ROOT)));
}
paragraph.add(new TextElement(value, font, size));
Alignment alignment = Alignment.valueOf(settings.get("layout.alignment", "left").toUpperCase(Locale.ROOT));
String margin = settings.get("layout.margin", "0 0 0 0");
String[] margins = margin.split(" ");
float marginleft = Float.parseFloat(margins[0]);
float marginright = Float.parseFloat(margins[1]);
float margintop = Float.parseFloat(margins[2]);
float marginbottom = Float.parseFloat(margins[3]);
boolean resetY = settings.getAsBoolean("layout.resety", false);
VerticalLayoutHint verticalLayoutHint = new VerticalLayoutHint(alignment, marginleft, marginright, margintop, marginbottom, resetY);
element.add(paragraph, verticalLayoutHint);
}
}
}

View file

@ -1,11 +1,10 @@
package org.xbib.graphics.pdfbox.layout.table;
import org.xbib.graphics.pdfbox.layout.elements.Element;
import org.xbib.graphics.pdfbox.layout.table.render.AbstractCellRenderer;
import org.xbib.graphics.pdfbox.layout.table.render.Renderer;
import java.awt.Color;
public abstract class AbstractCell implements Element {
public abstract class AbstractCell implements Cell {
private static final float DEFAULT_MIN_HEIGHT = 10f;
@ -13,7 +12,7 @@ public abstract class AbstractCell implements Element {
private int rowSpan = 1;
protected AbstractCellRenderer<AbstractCell> drawer;
protected AbstractCellRenderer<Cell> renderer;
private Row row;
@ -29,26 +28,90 @@ public abstract class AbstractCell implements Element {
this.colSpan = colSpan;
}
@Override
public int getColSpan() {
return colSpan;
}
public void setRowSpan(int rowSpan) {
this.rowSpan = rowSpan;
}
public float getPaddingBottom() {
return parameters.getPaddingBottom();
@Override
public int getRowSpan() {
return rowSpan;
}
@Override
public void setColumn(Column column) {
this.column = column;
}
public float getPaddingTop() {
return parameters.getPaddingTop();
public Column getColumn() {
return column;
}
@Override
public void setRow(Row row) {
this.row = row;
}
public Row getRow() {
return row;
}
@Override
public void setWidth(float width) {
this.width = width;
}
public float getWidth() {
return width;
}
public void setMinHeight(float minHeight) {
this.minHeight = minHeight;
}
@Override
public float getMinHeight() {
return minHeight;
}
@Override
public float getHeight() {
assertIsRendered();
return getRowSpan() > 1 ? calculateHeightForRowSpan() : getMinHeight();
}
public void setParameters(Parameters parameters) {
this.parameters = parameters;
}
@Override
public Parameters getParameters() {
return parameters;
}
@Override
public float getPaddingLeft() {
return parameters.getPaddingLeft();
}
@Override
public float getPaddingRight() {
return parameters.getPaddingRight();
}
@Override
public float getPaddingTop() {
return parameters.getPaddingTop();
}
@Override
public float getPaddingBottom() {
return parameters.getPaddingBottom();
}
public float getHorizontalPadding() {
return parameters.getPaddingLeft() + parameters.getPaddingRight();
}
@ -57,137 +120,105 @@ public abstract class AbstractCell implements Element {
return parameters.getPaddingTop() + parameters.getPaddingBottom();
}
@Override
public float getBorderWidthTop() {
return hasBorderTop() ? parameters.getBorderWidthTop() : 0;
}
@Override
public boolean hasBorderTop() {
return parameters.getBorderWidthTop() != null && parameters.getBorderWidthTop() > 0;
}
@Override
public float getBorderWidthBottom() {
return hasBorderBottom() ? parameters.getBorderWidthBottom() : 0;
}
@Override
public boolean hasBorderBottom() {
return parameters.getBorderWidthBottom() != null && parameters.getBorderWidthBottom() > 0;
}
@Override
public float getBorderWidthLeft() {
return hasBorderLeft() ? parameters.getBorderWidthLeft() : 0;
}
@Override
public boolean hasBorderLeft() {
return parameters.getBorderWidthLeft() != null && parameters.getBorderWidthLeft() > 0;
}
@Override
public float getBorderWidthRight() {
return hasBorderRight() ? parameters.getBorderWidthRight() : 0;
}
@Override
public boolean hasBorderRight() {
return parameters.getBorderWidthRight() != null && parameters.getBorderWidthRight() > 0;
}
@Override
public BorderStyleInterface getBorderStyleTop() {
return parameters.getBorderStyleTop();
}
@Override
public BorderStyleInterface getBorderStyleBottom() {
return parameters.getBorderStyleBottom();
}
@Override
public BorderStyleInterface getBorderStyleLeft() {
return parameters.getBorderStyleLeft();
}
@Override
public BorderStyleInterface getBorderStyleRight() {
return parameters.getBorderStyleRight();
}
@Override
public boolean hasBackgroundColor() {
return parameters.getBackgroundColor() != null;
}
@Override
public Color getBackgroundColor() {
return parameters.getBackgroundColor();
}
@Override
public Color getBorderColor() {
return parameters.getBorderColor();
}
@Override
public boolean isHorizontallyAligned(HorizontalAlignment alignment) {
return parameters.getHorizontalAlignment() == alignment;
}
@Override
public boolean isVerticallyAligned(VerticalAlignment alignment) {
return parameters.getVerticalAlignment() == alignment;
}
public boolean isWordBreak() {
return parameters.isWordBreak();
}
public Column getColumn() {
return column;
public void setRenderer(AbstractCellRenderer<Cell> renderer) {
this.renderer = renderer;
}
public static float getDefaultMinHeight() {
return DEFAULT_MIN_HEIGHT;
@Override
public Renderer getRenderer() {
return this.renderer != null ? this.renderer.withCell(this) : createDefaultRenderer();
}
public float getMinHeight() {
return minHeight;
}
public float getWidth() {
return width;
}
public int getColSpan() {
return colSpan;
}
public int getRowSpan() {
return rowSpan;
}
public Row getRow() {
return row;
}
public Parameters getParameters() {
return parameters;
}
public void setColumn(Column column) {
this.column = column;
}
public void setDrawer(AbstractCellRenderer<AbstractCell> drawer) {
this.drawer = drawer;
}
public void setMinHeight(float minHeight) {
this.minHeight = minHeight;
}
public void setRow(Row row) {
this.row = row;
}
public void setParameters(Parameters parameters) {
this.parameters = parameters;
}
public void setWidth(float width) {
this.width = width;
}
public float getHeight() {
assertIsRendered();
return getRowSpan() > 1 ? calculateHeightForRowSpan() : getMinHeight();
}
public Renderer getDrawer() {
return this.drawer != null ? this.drawer.withCell(this) : createDefaultDrawer();
}
protected abstract Renderer createDefaultDrawer();
@Override
public float calculateHeightForRowSpan() {
Row currentRow = row;
float result = currentRow.getHeight();
@ -204,11 +235,5 @@ public abstract class AbstractCell implements Element {
}
}
public boolean isHorizontallyAligned(HorizontalAlignment alignment) {
return getParameters().getHorizontalAlignment() == alignment;
}
public boolean isVerticallyAligned(VerticalAlignment alignment) {
return getParameters().getVerticalAlignment() == alignment;
}
protected abstract Renderer createDefaultRenderer();
}

View file

@ -9,7 +9,14 @@ import java.util.List;
public abstract class AbstractTextCell extends AbstractCell {
protected float lineSpacing = 1f;
private Float textHeight;
private float lineSpacing = 1f;
@Override
public float getMinHeight() {
return Math.max((getVerticalPadding() + getTextHeight()), super.getMinHeight());
}
public Font getFont() {
return parameters.getFont();
@ -23,19 +30,16 @@ public abstract class AbstractTextCell extends AbstractCell {
return parameters.getTextColor();
}
private Float textHeight;
public abstract String getText();
public void setLineSpacing(float lineSpacing) {
this.lineSpacing = lineSpacing;
}
public float getLineSpacing() {
return lineSpacing;
}
@Override
public float getMinHeight() {
return Math.max((getVerticalPadding() + getTextHeight()), super.getMinHeight());
}
public float getTextHeight() {
if (this.textHeight != null) {
return this.textHeight;
@ -66,7 +70,7 @@ public abstract class AbstractTextCell extends AbstractCell {
private float getMaxWidthOfText() {
float columnsWidth = getColumn().getWidth();
if (getColSpan() > 1) {
if (getColSpan() > 0) {
Column currentColumn = getColumn();
for (int i = 1; i < getColSpan(); i++) {
columnsWidth += currentColumn.getNext().getWidth();

View file

@ -0,0 +1,78 @@
package org.xbib.graphics.pdfbox.layout.table;
import org.xbib.graphics.pdfbox.layout.elements.Element;
import org.xbib.graphics.pdfbox.layout.table.render.Renderer;
import java.awt.Color;
public interface Cell extends Element {
int getRowSpan();
int getColSpan();
void setRow(Row row);
Row getRow();
void setColumn(Column column);
Column getColumn();
void setWidth(float width);
Parameters getParameters();
float getMinHeight();
float getWidth();
float getHeight();
Renderer getRenderer();
boolean hasBackgroundColor();
Color getBackgroundColor();
Color getBorderColor();
float getPaddingLeft();
float getPaddingRight();
float getPaddingTop();
float getPaddingBottom();
boolean hasBorderLeft();
boolean hasBorderRight();
boolean hasBorderTop();
boolean hasBorderBottom();
float getBorderWidthLeft();
float getBorderWidthRight();
float getBorderWidthTop();
float getBorderWidthBottom();
BorderStyleInterface getBorderStyleLeft();
BorderStyleInterface getBorderStyleRight();
BorderStyleInterface getBorderStyleTop();
BorderStyleInterface getBorderStyleBottom();
float calculateHeightForRowSpan();
boolean isHorizontallyAligned(HorizontalAlignment alignment);
boolean isVerticallyAligned(VerticalAlignment alignment);
}

View file

@ -0,0 +1,73 @@
package org.xbib.graphics.pdfbox.layout.table;
import org.xbib.graphics.pdfbox.layout.elements.Drawable;
import org.xbib.graphics.pdfbox.layout.table.render.DrawableCellRenderer;
import org.xbib.graphics.pdfbox.layout.table.render.Renderer;
public class DrawableCell extends AbstractCell {
private Drawable drawable;
public DrawableCell() {
}
public void setDrawable(Drawable drawable) {
this.drawable = drawable;
}
public Drawable getDrawable() {
return drawable;
}
@Override
protected Renderer createDefaultRenderer() {
return new DrawableCellRenderer(this);
}
public static Builder builder() {
return new Builder();
}
public static class Builder {
private Drawable drawable;
private final Parameters parameters;
private int colSpan;
private int rowSpan;
private Builder() {
this.parameters = new Parameters();
}
public Builder drawable(Drawable drawable) {
this.drawable = drawable;
return this;
}
public Builder colSpan(int colSpan) {
this.colSpan = colSpan;
return this;
}
public Builder rowSpan(int rowSpan) {
this.rowSpan = rowSpan;
return this;
}
public DrawableCell build() {
DrawableCell cell = new DrawableCell();
cell.setDrawable(drawable);
cell.setParameters(parameters);
if (colSpan > 0) {
cell.setColSpan(colSpan);
}
if (rowSpan > 0) {
cell.setRowSpan(rowSpan);
}
return cell;
}
}
}

View file

@ -40,7 +40,7 @@ public class ImageCell extends AbstractCell {
}
@Override
protected Renderer createDefaultDrawer() {
protected Renderer createDefaultRenderer() {
return new ImageCellRenderer(this);
}
@ -49,21 +49,16 @@ public class ImageCell extends AbstractCell {
float scaledWidth = image.getWidth() * getScale();
float scaledHeight = image.getHeight() * getScale();
final float resultingWidth = getWidth() - getHorizontalPadding();
// maybe reduce the image to fit in column
if (scaledWidth > resultingWidth) {
scaledHeight = (resultingWidth / scaledWidth) * scaledHeight;
scaledWidth = resultingWidth;
}
if (maxHeight > 0.0f && scaledHeight > maxHeight) {
scaledWidth = (maxHeight / scaledHeight) * scaledWidth;
scaledHeight = maxHeight;
}
sizes.x = scaledWidth;
sizes.y = scaledHeight;
return sizes;
}

View file

@ -3,34 +3,35 @@ package org.xbib.graphics.pdfbox.layout.table;
import org.xbib.graphics.pdfbox.layout.elements.Paragraph;
import org.xbib.graphics.pdfbox.layout.font.Font;
import java.io.IOException;
public class Markup implements ParagraphProcessor {
private String markup;
private String value;
private Font font;
private Float fontSize;
public void setMarkup(String markup) {
this.markup = markup;
public Markup setValue(String value) {
this.value = value;
return this;
}
public String getMarkup() {
return markup;
public String getValue() {
return value;
}
public void setFont(Font font) {
public Markup setFont(Font font) {
this.font = font;
return this;
}
public Font getFont() {
return font;
}
public void setFontSize(Float fontSize) {
public Markup setFontSize(Float fontSize) {
this.fontSize = fontSize;
return this;
}
public Float getFontSize() {
@ -40,7 +41,7 @@ public class Markup implements ParagraphProcessor {
@Override
public void process(Paragraph paragraph, Parameters parameters) {
float fontSize = getFontSize() != null ? getFontSize() : parameters.getFontSize();
paragraph.addMarkup(getMarkup(), fontSize, font);
paragraph.addMarkup(getValue(), fontSize, font);
}
}

View file

@ -1,17 +1,19 @@
package org.xbib.graphics.pdfbox.layout.table;
import org.xbib.graphics.pdfbox.layout.elements.Paragraph;
import org.xbib.graphics.pdfbox.layout.table.render.Renderer;
import org.xbib.graphics.pdfbox.layout.table.render.ParagraphCellRenderer;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.util.ArrayList;
import java.util.List;
public class ParagraphCell extends AbstractCell {
protected float lineSpacing = 1f;
private Paragraph paragraph;
private CellParagraph cellParagraph;
public void setLineSpacing(float lineSpacing) {
this.lineSpacing = lineSpacing;
@ -21,60 +23,111 @@ public class ParagraphCell extends AbstractCell {
return lineSpacing;
}
public void setParagraph(Paragraph paragraph) {
this.paragraph = paragraph;
public void setCellParagraph(CellParagraph cellParagraph) {
this.cellParagraph = cellParagraph;
}
public Paragraph getParagraph() {
return paragraph;
public CellParagraph getCellParagraph() {
return cellParagraph;
}
@Override
public void setWidth(float width) {
super.setWidth(width);
while (getParagraph().getWrappedParagraph().removeLast() != null) {
}
for (ParagraphProcessor p : getParagraph().getProcessables()) {
//while (getCellParagraph().getParagraph().removeLast() != null) {
//}
for (ParagraphProcessor p : getCellParagraph().getParagraphProcessors()) {
try {
p.process(getParagraph().getWrappedParagraph(), getParameters());
p.process(getCellParagraph().getParagraph(), getParameters());
} catch (IOException exception) {
throw new UncheckedIOException(exception);
}
}
org.xbib.graphics.pdfbox.layout.elements.Paragraph wrappedParagraph = paragraph.getWrappedParagraph();
wrappedParagraph.setLineSpacing(getLineSpacing());
wrappedParagraph.setApplyLineSpacingToFirstLine(false);
wrappedParagraph.setMaxWidth(width - getHorizontalPadding());
Paragraph paragraph = cellParagraph.getParagraph();
paragraph.setLineSpacing(getLineSpacing());
paragraph.setApplyLineSpacingToFirstLine(false);
paragraph.setMaxWidth(width - getHorizontalPadding());
}
@Override
protected Renderer createDefaultDrawer() {
protected Renderer createDefaultRenderer() {
return new ParagraphCellRenderer(this);
}
@Override
public float getMinHeight() {
float height = paragraph.getWrappedParagraph().getHeight() + getVerticalPadding();
float height = cellParagraph.getParagraph().getHeight() + getVerticalPadding();
return Math.max(height, super.getMinHeight());
}
public static class Paragraph {
public static class CellParagraph {
private final List<ParagraphProcessor> processables;
private final Paragraph paragraph;
private final org.xbib.graphics.pdfbox.layout.elements.Paragraph wrappedParagraph =
new org.xbib.graphics.pdfbox.layout.elements.Paragraph();
private final List<ParagraphProcessor> paragraphProcessors;
public Paragraph(List<ParagraphProcessor> processables) {
this.processables = processables;
public CellParagraph(Paragraph paragraph, List<ParagraphProcessor> processables) {
this.paragraph = paragraph;
this.paragraphProcessors = processables;
}
public List<ParagraphProcessor> getProcessables() {
return processables;
public List<ParagraphProcessor> getParagraphProcessors() {
return paragraphProcessors;
}
public org.xbib.graphics.pdfbox.layout.elements.Paragraph getWrappedParagraph() {
return wrappedParagraph;
public Paragraph getParagraph() {
return paragraph;
}
}
public static Builder builder() {
return new Builder();
}
public static class Builder {
private final Parameters parameters;
private int colSpan;
private int rowSpan;
private Paragraph paragraph;
private final List<ParagraphProcessor> processors;
private Builder() {
this.parameters = new Parameters();
this.processors = new ArrayList<>();
}
public Builder colSpan(int colSpan) {
this.colSpan = colSpan;
return this;
}
public Builder rowSpan(int rowSpan) {
this.rowSpan = rowSpan;
return this;
}
public Builder paragraph(Paragraph paragraph) {
this.paragraph = paragraph;
return this;
}
public Builder add(ParagraphProcessor processor) {
this.processors.add(processor);
return this;
}
public ParagraphCell build() {
ParagraphCell cell = new ParagraphCell();
cell.setParameters(parameters);
cell.setColSpan(colSpan);
cell.setRowSpan(rowSpan);
cell.setCellParagraph(new CellParagraph(paragraph, processors));
return cell;
}
}
}

View file

@ -1,6 +1,8 @@
package org.xbib.graphics.pdfbox.layout.table;
import org.xbib.graphics.pdfbox.layout.elements.Drawable;
import org.xbib.graphics.pdfbox.layout.elements.Element;
import org.xbib.graphics.pdfbox.layout.elements.HorizontalRuler;
import org.xbib.graphics.pdfbox.layout.font.Font;
import java.awt.Color;
@ -15,7 +17,7 @@ public class Row {
private Table table;
private List<AbstractCell> cells;
private List<Cell> cells;
private Parameters parameters;
@ -23,7 +25,7 @@ public class Row {
private Row next;
private Row(List<AbstractCell> cells) {
private Row(List<Cell> cells) {
this.cells = cells;
}
@ -43,15 +45,19 @@ public class Row {
return DEFAULT_HEIGHT;
}
public List<AbstractCell> getCells() {
public List<Cell> getCells() {
return cells;
}
public void setTable(Table table) {
this.table = table;
}
public Table getTable() {
return table;
}
public void setCells(List<AbstractCell> cells) {
public void setCells(List<Cell> cells) {
this.cells = cells;
}
@ -63,10 +69,6 @@ public class Row {
this.next = next;
}
public void setTable(Table table) {
this.table = table;
}
public float getHeight() {
if (table == null) {
throw new TableNotYetBuiltException();
@ -74,7 +76,7 @@ public class Row {
if (height == null) {
this.height = getCells().stream()
.filter(cell -> cell.getRowSpan() == 1)
.map(AbstractCell::getHeight)
.map(Cell::getHeight)
.max(naturalOrder())
.orElse(DEFAULT_HEIGHT);
}
@ -92,7 +94,7 @@ public class Row {
public static class Builder implements Element {
private final List<AbstractCell> cells = new ArrayList<>();
private final List<Cell> cells = new ArrayList<>();
private final Parameters parameters = new Parameters();
@ -101,7 +103,14 @@ public class Row {
@Override
public Builder add(Element element) {
cells.add((AbstractCell) element);
if (element instanceof Cell) {
cells.add((Cell) element);
} else if (element instanceof HorizontalRuler) {
Cell cell = DrawableCell.builder()
.drawable((Drawable) element)
.build();
cells.add(cell);
}
return this;
}

View file

@ -162,12 +162,10 @@ public class Table {
// Store how many cells can or better have to be omitted in the next rows
// due to cells in this row that declare row spanning
updateRowSpanCellsSet(row.getCells());
if (!rows.isEmpty()) {
rows.get(rows.size() - 1).setNext(row);
}
rows.add(row);
return this;
}
@ -183,19 +181,14 @@ public class Table {
// Put every cell coordinate in the set which needs to be skipped because it is
// "contained" in another cell due to row spanning.
// The coordinates are those of the table how it would look like without any spanning.
private void updateRowSpanCellsSet(List<AbstractCell> cells) {
private void updateRowSpanCellsSet(List<Cell> cells) {
int currentColumn = 0;
for (AbstractCell cell : cells) {
for (Cell cell : cells) {
while (rowSpanCells.contains(new Point(rows.size(), currentColumn))) {
currentColumn++;
}
if (cell.getRowSpan() > 1) {
for (int rowsToSpan = 0; rowsToSpan < cell.getRowSpan(); rowsToSpan++) {
// Skip first row's cell, because that is a regular cell
if (rowsToSpan >= 1) {
for (int colSpan = 0; colSpan < cell.getColSpan(); colSpan++) {
@ -204,7 +197,6 @@ public class Table {
}
}
}
currentColumn += cell.getColSpan();
}
}
@ -310,7 +302,7 @@ public class Table {
row.getParameters().fillingMergeBy(table.getSettings());
}
int columnIndex = 0;
for (AbstractCell cell : row.getCells()) {
for (Cell cell : row.getCells()) {
cell.getParameters().fillingMergeBy(row.getParameters());
cell.setRow(row);
while (table.isRowSpanAt(rowIndex, columnIndex)) {
@ -333,9 +325,9 @@ public class Table {
private void correctHeightOfCellsDueToRowSpanningIfNecessaryFor(Table table) {
for (int i = 0; i < table.getRows().size(); i++) {
final Optional<AbstractCell> highestSpanningCell = rows.get(i).getCells().stream()
final Optional<Cell> highestSpanningCell = rows.get(i).getCells().stream()
.filter(x -> x.getRowSpan() > 1)
.max(Comparator.comparing(AbstractCell::getMinHeight));
.max(Comparator.comparing(Cell::getMinHeight));
if (highestSpanningCell.isPresent()) {
final float heightOfHighestCell = highestSpanningCell.get().getMinHeight();
float regularHeightOfRows = 0;

View file

@ -162,12 +162,12 @@ public class TableRenderer {
protected void drawRow(Point2D.Float start, Row row, int rowIndex, BiConsumer<Renderer, RenderContext> consumer) {
float x = start.x;
int columnCounter = 0;
for (AbstractCell cell : row.getCells()) {
for (Cell cell : row.getCells()) {
while (table.isRowSpanAt(rowIndex, columnCounter)) {
x += table.getColumns().get(columnCounter).getWidth();
columnCounter++;
}
consumer.accept(cell.getDrawer(), new RenderContext(pdDocument, contentStream, page, new Point2D.Float(x, start.y)));
consumer.accept(cell.getRenderer(), new RenderContext(pdDocument, contentStream, page, new Point2D.Float(x, start.y)));
x += cell.getWidth();
columnCounter += cell.getColSpan();
}
@ -179,7 +179,7 @@ public class TableRenderer {
private Float getHighestCellOf(Row row) {
return row.getCells().stream()
.map(AbstractCell::getHeight)
.map(Cell::getHeight)
.max(Comparator.naturalOrder())
.orElse(row.getHeight());
}

View file

@ -9,7 +9,8 @@ public class TextCell extends AbstractTextCell {
protected String text;
protected Renderer createDefaultDrawer() {
@Override
protected Renderer createDefaultRenderer() {
return new TextCellRenderer<>(this);
}

View file

@ -7,7 +7,7 @@ public class VerticalTextCell extends AbstractTextCell {
private String text;
protected Renderer createDefaultDrawer() {
protected Renderer createDefaultRenderer() {
return new VerticalTextCellRenderer(this);
}

View file

@ -3,12 +3,13 @@ package org.xbib.graphics.pdfbox.layout.table.render;
import static org.xbib.graphics.pdfbox.layout.table.VerticalAlignment.BOTTOM;
import static org.xbib.graphics.pdfbox.layout.table.VerticalAlignment.MIDDLE;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.xbib.graphics.pdfbox.layout.table.AbstractCell;
import org.xbib.graphics.pdfbox.layout.table.Cell;
import org.xbib.graphics.pdfbox.layout.util.RenderUtil;
import java.awt.Color;
import java.awt.geom.Point2D;
public abstract class AbstractCellRenderer<T extends AbstractCell> implements Renderer {
public abstract class AbstractCellRenderer<T extends Cell> implements Renderer {
protected T cell;

View file

@ -0,0 +1,38 @@
package org.xbib.graphics.pdfbox.layout.table.render;
import org.xbib.graphics.pdfbox.layout.elements.Drawable;
import org.xbib.graphics.pdfbox.layout.table.DrawableCell;
import org.xbib.graphics.pdfbox.layout.text.Position;
import org.xbib.graphics.pdfbox.layout.text.WidthRespecting;
import java.io.IOException;
import java.io.UncheckedIOException;
public class DrawableCellRenderer extends AbstractCellRenderer<DrawableCell> {
public DrawableCellRenderer(DrawableCell cell) {
this.cell = cell;
}
@Override
public void renderContent(RenderContext renderContext) {
Drawable drawable = cell.getDrawable();
if (drawable instanceof WidthRespecting) {
WidthRespecting widthRespecting = (WidthRespecting) drawable;
widthRespecting.setMaxWidth(cell.getWidth());
}
float x = renderContext.getStartingPoint().x + cell.getPaddingLeft();
float y = renderContext.getStartingPoint().y + getAdaptionForVerticalAlignment();
Position position = new Position(x, y);
try {
drawable.draw(renderContext.getPdDocument(), renderContext.getContentStream(), position,null);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
@Override
protected float calculateInnerHeight() {
return 0;
}
}

View file

@ -3,7 +3,6 @@ package org.xbib.graphics.pdfbox.layout.table.render;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotation;
import org.xbib.graphics.pdfbox.layout.elements.Paragraph;
import org.xbib.graphics.pdfbox.layout.table.HorizontalAlignment;
import org.xbib.graphics.pdfbox.layout.table.ParagraphCell;
@ -12,8 +11,6 @@ import org.xbib.graphics.pdfbox.layout.text.DrawContext;
import org.xbib.graphics.pdfbox.layout.text.Position;
import org.xbib.graphics.pdfbox.layout.text.annotations.AnnotationDrawListener;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.util.EnumMap;
import java.util.Map;
@ -33,30 +30,20 @@ public class ParagraphCellRenderer extends AbstractCellRenderer<ParagraphCell> {
@Override
public void renderContent(RenderContext renderContext) {
if (renderContext.getPage() == null) {
throw new PageNotSetException("Page is not set in drawing context. Please ensure the page is set on table drawer.");
}
Paragraph paragraph = cell.getParagraph().getWrappedParagraph();
AnnotationDrawListener annotationDrawListener = createAndGetAnnotationDrawListenerWith(renderContext);
Paragraph paragraph = cell.getCellParagraph().getParagraph();
float x = renderContext.getStartingPoint().x + cell.getPaddingLeft();
float y = renderContext.getStartingPoint().y + getAdaptionForVerticalAlignment();
AnnotationDrawListener annotationDrawListener = createAndGetAnnotationDrawListenerWith(renderContext);
paragraph.drawText(renderContext.getContentStream(),
new Position(x, y),
ALIGNMENT_MAP.getOrDefault(cell.getParameters().getHorizontalAlignment(), Alignment.LEFT),
annotationDrawListener
);
annotationDrawListener.afterPage(null);
annotationDrawListener.afterRender();
try {
renderContext.getPage().getAnnotations().forEach(PDAnnotation::constructAppearances);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
@Override
protected float calculateInnerHeight() {
return cell.getParagraph().getWrappedParagraph().getHeight();
return cell.getCellParagraph().getParagraph().getHeight();
}
private AnnotationDrawListener createAndGetAnnotationDrawListenerWith(RenderContext renderContext) {

View file

@ -6,6 +6,7 @@ import static org.xbib.graphics.pdfbox.layout.table.HorizontalAlignment.RIGHT;
import org.xbib.graphics.pdfbox.layout.font.Font;
import org.xbib.graphics.pdfbox.layout.table.AbstractTextCell;
import org.xbib.graphics.pdfbox.layout.util.PdfUtil;
import org.xbib.graphics.pdfbox.layout.util.RenderUtil;
import java.awt.Color;
import java.io.IOException;
@ -43,9 +44,9 @@ public class TextCellRenderer<T extends AbstractTextCell> extends AbstractCellRe
throw new UncheckedIOException(exception);
}
}
PositionedStyledText text = new PositionedStyledText(xOffset, yOffset,
line, currentFont, currentFontSize, currentTextColor);
drawText(renderContext, text);
PositionedStyledText positionedStyledText = new PositionedStyledText(xOffset, yOffset, line,
currentFont, currentFontSize, currentTextColor);
RenderUtil.drawText(renderContext.getContentStream(), positionedStyledText);
}
}
@ -54,17 +55,16 @@ public class TextCellRenderer<T extends AbstractTextCell> extends AbstractCellRe
return cell.getTextHeight();
}
private float calculateYOffset(Font currentFont, float currentFontSize, int lineIndex) {
return PdfUtil.getFontHeight(currentFont, currentFontSize) +
(lineIndex > 0 ? PdfUtil.getFontHeight(currentFont, currentFontSize) * cell.getLineSpacing() : 0f);
}
static boolean isNotLastLine(List<String> lines, int i) {
private static boolean isNotLastLine(List<String> lines, int i) {
return i != lines.size() - 1;
}
protected float calculateCharSpacingFor(String line) {
private float calculateCharSpacingFor(String line) {
float charSpacing = 0;
if (line.length() > 1) {
float size = PdfUtil.getStringWidth(line, cell.getFont(), cell.getFontSize());
@ -76,13 +76,9 @@ public class TextCellRenderer<T extends AbstractTextCell> extends AbstractCellRe
return charSpacing;
}
protected List<String> calculateAndGetLines(Font currentFont, float currentFontSize, float maxWidth) {
private List<String> calculateAndGetLines(Font currentFont, float currentFontSize, float maxWidth) {
return cell.isWordBreak()
? PdfUtil.getOptimalTextBreakLines(cell.getText(), currentFont, currentFontSize, maxWidth)
: Collections.singletonList(cell.getText());
}
protected void drawText(RenderContext renderContext, PositionedStyledText positionedStyledText) {
RenderUtil.drawText(renderContext.getContentStream(), positionedStyledText);
}
}

View file

@ -3,6 +3,8 @@ package org.xbib.graphics.pdfbox.layout.text;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.xbib.graphics.pdfbox.layout.font.Font;
import org.xbib.graphics.pdfbox.layout.font.FontDescriptor;
import org.xbib.graphics.pdfbox.layout.util.TextSequenceUtil;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
@ -223,9 +225,8 @@ public class TextFlow implements TextSequence, WidthRespecting {
@Override
public void drawText(PDPageContentStream contentStream, Position upperLeft,
Alignment alignment, DrawListener drawListener) {
TextSequenceUtil.drawText(this, contentStream, upperLeft, drawListener, alignment,
getMaxWidth(), getLineSpacing(),
isApplyLineSpacingToFirstLine());
TextSequenceUtil.drawText(this, contentStream, upperLeft, drawListener,
alignment, getMaxWidth(), getLineSpacing(), isApplyLineSpacingToFirstLine());
}
public void drawTextRightAligned(PDPageContentStream contentStream,

View file

@ -3,6 +3,8 @@ package org.xbib.graphics.pdfbox.layout.text;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.util.Matrix;
import org.xbib.graphics.pdfbox.layout.font.FontDescriptor;
import org.xbib.graphics.pdfbox.layout.util.TextSequenceUtil;
import java.awt.Color;
import java.io.IOException;
import java.io.UncheckedIOException;

View file

@ -19,6 +19,12 @@ public final class PdfUtil {
public static final String NEW_LINE_REGEX = "\\r?\\n";
public static final float MM_TO_UNITS = 1.0f / 25.4f * 72.0f;
public static float mmToPt(float number) {
return number * MM_TO_UNITS;
}
/**
* Computes the width of a String (in points).
*

View file

@ -1,7 +1,10 @@
package org.xbib.graphics.pdfbox.layout.table.render;
package org.xbib.graphics.pdfbox.layout.util;
import static org.xbib.graphics.pdfbox.layout.table.BorderStyle.SOLID;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.xbib.graphics.pdfbox.layout.table.render.PositionedLine;
import org.xbib.graphics.pdfbox.layout.table.render.PositionedRectangle;
import org.xbib.graphics.pdfbox.layout.table.render.PositionedStyledText;
import java.awt.Color;
import java.io.IOException;

View file

@ -1,11 +1,21 @@
package org.xbib.graphics.pdfbox.layout.text;
package org.xbib.graphics.pdfbox.layout.util;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.xbib.graphics.pdfbox.layout.elements.Dividable.Divided;
import org.xbib.graphics.pdfbox.layout.elements.Paragraph;
import org.xbib.graphics.pdfbox.layout.font.FontDescriptor;
import org.xbib.graphics.pdfbox.layout.util.Pair;
import org.xbib.graphics.pdfbox.layout.util.WordBreakerFactory;
import org.xbib.graphics.pdfbox.layout.text.Alignment;
import org.xbib.graphics.pdfbox.layout.text.DrawListener;
import org.xbib.graphics.pdfbox.layout.text.Indent;
import org.xbib.graphics.pdfbox.layout.text.NewLine;
import org.xbib.graphics.pdfbox.layout.text.Position;
import org.xbib.graphics.pdfbox.layout.text.ReplacedWhitespace;
import org.xbib.graphics.pdfbox.layout.text.StyledText;
import org.xbib.graphics.pdfbox.layout.text.TextFlow;
import org.xbib.graphics.pdfbox.layout.text.TextFragment;
import org.xbib.graphics.pdfbox.layout.text.TextLine;
import org.xbib.graphics.pdfbox.layout.text.TextSequence;
import org.xbib.graphics.pdfbox.layout.text.WrappingNewLine;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.util.ArrayList;
@ -134,71 +144,47 @@ public class TextSequenceUtil {
return result;
}
private static WordWrapContext wordWrap(final WordWrapContext context,
final float maxWidth, final TextFlow result) {
private static WordWrapContext wordWrap(WordWrapContext context, float maxWidth, TextFlow result) {
TextFragment word = context.getWord();
TextFragment moreToWrap = null;
float indentation = context.getIndentation();
float lineLength = context.getLineLength();
boolean isWrappedLine = context.isWrappedLine();
if (isWrappedLine && lineLength == indentation) {
// start of line, replace leading blanks if
TextFragment[] replaceLeadingBlanks = replaceLeadingBlanks(word);
word = replaceLeadingBlanks[0];
if (replaceLeadingBlanks.length > 1) {
result.add(replaceLeadingBlanks[1]);
}
}
FontDescriptor fontDescriptor = word.getFontDescriptor();
float length = word.getWidth();
if (maxWidth > 0 && lineLength + length > maxWidth) {
// word exceeds max width, so create new line
// break hard, if the text does not fit in a full (next) line
boolean breakHard = indentation + length > maxWidth;
Pair<TextFragment> brokenWord = breakWord(word, length, maxWidth
- lineLength, maxWidth - indentation, breakHard);
if (brokenWord != null) {
// word is broken
word = brokenWord.getFirst();
length = word.getWidth();
moreToWrap = brokenWord.getSecond();
result.add(word);
if (length > 0) {
lineLength += length;
}
} else {
if (lineLength == indentation) {
// Begin of line and word could now be broke...
// Well, so we have to use it as it is,
// it won't get any better in the next line
result.add(word);
if (length > 0) {
lineLength += length;
}
} else {
// give it another try in a new line, there
// will be more space.
moreToWrap = word;
if (result.getLast() != null) {
// since the current word is not used, take
// font descriptor of last line. Otherwise
// the line break might be to high
fontDescriptor = result.getLast().getFontDescriptor();
}
}
}
// wrap line only if not empty
if (lineLength > indentation) {
// and terminate it with a new line
result.add(new WrappingNewLine(fontDescriptor));
isWrappedLine = true;
if (indentation > 0) {
@ -206,24 +192,20 @@ public class TextSequenceUtil {
}
lineLength = indentation;
}
} else {
// word fits, so just add it
result.add(word);
if (length > 0) {
lineLength += length;
}
}
return new WordWrapContext(moreToWrap, lineLength, indentation,
isWrappedLine);
return new WordWrapContext(moreToWrap, lineLength, indentation, isWrappedLine);
}
/**
* Replaces leading whitespace by {@link ReplacedWhitespace}.
*
* @param word the fragment to replace
* @return
* @return text fragments
*/
private static TextFragment[] replaceLeadingBlanks(final TextFragment word) {
String text = word.getText();
@ -232,7 +214,6 @@ public class TextSequenceUtil {
&& Character.isWhitespace(text.charAt(splitIndex))) {
++splitIndex;
}
if (splitIndex == 0) {
return new TextFragment[]{word};
} else {
@ -257,7 +238,7 @@ public class TextSequenceUtil {
* @param text the text to de-wrap.
* @return the de-wrapped text.
*/
public static TextFlow deWrap(final TextSequence text) {
public static TextFlow deWrap(TextSequence text) {
TextFlow result = new TextFlow();
for (TextFragment fragment : text) {
if (fragment instanceof WrappingNewLine) {
@ -268,7 +249,6 @@ public class TextSequenceUtil {
result.add(fragment);
}
}
if (text instanceof TextFlow) {
result.setLineSpacing(((TextFlow) text).getLineSpacing());
}
@ -283,8 +263,7 @@ public class TextSequenceUtil {
* @param maxWidth the max width to fit.
* @return the word-wrapped text lines.
*/
public static List<TextLine> wordWrapToLines(final TextSequence text,
final float maxWidth) {
public static List<TextLine> wordWrapToLines(TextSequence text, float maxWidth) {
return getLines(wordWrap(text, maxWidth));
}
@ -305,11 +284,9 @@ public class TextSequenceUtil {
leftMargin = ((StyledText) text).getLeftMargin();
rightMargin = ((StyledText) text).getRightMargin();
}
String[] words = text.getText().split(" ", -1);
for (int index = 0; index < words.length; ++index) {
String newWord = index == 0 ? words[index] : " " + words[index];
float currentLeftMargin = 0;
float currentRightMargin = 0;
if (index == 0) {
@ -336,15 +313,13 @@ public class TextSequenceUtil {
* @param rightMargin the new right margin.
* @return the derived text fragment.
*/
protected static TextFragment deriveFromExisting(
final TextFragment toDeriveFrom, final String text,
final float leftMargin, final float rightMargin) {
protected static TextFragment deriveFromExisting(TextFragment toDeriveFrom, String text, float leftMargin,
float rightMargin) {
if (toDeriveFrom instanceof StyledText) {
return ((StyledText) toDeriveFrom).inheritAttributes(text,
leftMargin, rightMargin);
}
return new StyledText(text, toDeriveFrom.getFontDescriptor(),
toDeriveFrom.getColor(), 0, leftMargin, rightMargin);
return new StyledText(text, toDeriveFrom.getFontDescriptor(), toDeriveFrom.getColor(), 0, leftMargin, rightMargin);
}
private static Pair<TextFragment> breakWord(TextFragment word,

View file

@ -1,7 +1,7 @@
package org.xbib.graphics.pdfbox.layout.util;
import org.xbib.graphics.pdfbox.layout.font.FontDescriptor;
import org.xbib.graphics.pdfbox.layout.text.TextSequenceUtil;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

View file

@ -8,7 +8,6 @@ import org.xbib.graphics.pdfbox.layout.elements.render.ColumnLayout;
import org.xbib.graphics.pdfbox.layout.elements.render.VerticalLayoutHint;
import org.xbib.graphics.pdfbox.layout.font.BaseFont;
import java.io.FileOutputStream;
import java.io.OutputStream;
public class ColumnsTest {
@ -33,27 +32,20 @@ public class ColumnsTest {
+ "gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.\n";
Document document = new Document(40, 50, 40, 60);
Paragraph title = new Paragraph();
title.addMarkup("*This Text is organized in Colums*", 20, BaseFont.TIMES);
document.add(title, VerticalLayoutHint.CENTER);
document.add(new VerticalSpacer(5));
// use column layout from now on
document.add(new ColumnLayout(2, 10));
document.add(new ColumnLayout().setColumnCount(2).setColumnSpacing(10f));
Paragraph paragraph1 = new Paragraph();
paragraph1.addMarkup(text1, 11, BaseFont.TIMES);
document.add(paragraph1);
Paragraph paragraph2 = new Paragraph();
paragraph2.addMarkup(text2, 12, BaseFont.HELVETICA);
document.add(paragraph2);
Paragraph paragraph3 = new Paragraph();
paragraph3.addMarkup(text1, 8, BaseFont.COURIER);
document.add(paragraph3);
document.add(paragraph1);
document.add(paragraph3);
document.add(paragraph1);

View file

@ -18,7 +18,7 @@ import org.xbib.graphics.pdfbox.layout.font.BaseFont;
import org.xbib.graphics.pdfbox.layout.text.Position;
import org.xbib.graphics.pdfbox.layout.text.TextFlow;
import org.xbib.graphics.pdfbox.layout.text.TextFlowUtil;
import org.xbib.graphics.pdfbox.layout.text.TextSequenceUtil;
import org.xbib.graphics.pdfbox.layout.util.TextSequenceUtil;
import java.awt.Color;
import java.io.FileOutputStream;
import java.io.IOException;

View file

@ -49,11 +49,9 @@ public class LandscapeTest {
PageFormat a5_landscape = PageFormat.builder().A5().landscape().margins(10, 50, 0, 30).build();
PageFormat a4_portrait = PageFormat.builder().margins(40, 50, 40, 60).build();
Document document = new Document(a4_portrait);
document.add(titleA4, VerticalLayoutHint.CENTER);
document.add(new VerticalSpacer(5));
document.add(new ColumnLayout(2, 10));
document.add(new ColumnLayout().setColumnCount(2).setColumnSpacing(10f));
document.add(paragraph2);
document.add(paragraph1);
document.add(paragraph1);
@ -68,7 +66,7 @@ public class LandscapeTest {
document.add(new VerticalLayout());
document.add(titleA5, VerticalLayoutHint.CENTER);
document.add(new VerticalSpacer(5));
document.add(new ColumnLayout(2, 10));
document.add(new ColumnLayout().setColumnCount(2).setColumnSpacing(10f));
document.add(paragraph1);
document.add(paragraph3);
@ -80,7 +78,7 @@ public class LandscapeTest {
document.add(new VerticalLayout());
document.add(titleA4, VerticalLayoutHint.CENTER);
document.add(new VerticalSpacer(5));
document.add(new ColumnLayout(2, 10));
document.add(new ColumnLayout().setColumnCount(2).setColumnSpacing(10f));
document.add(paragraph2);
document.add(paragraph1);
@ -96,7 +94,7 @@ public class LandscapeTest {
document.add(new VerticalLayout());
document.add(titleA5, VerticalLayoutHint.CENTER);
document.add(new VerticalSpacer(5));
document.add(new ColumnLayout(2, 10));
document.add(new ColumnLayout().setColumnCount(2).setColumnSpacing(10f));
document.add(paragraph1);
document.add(paragraph3);

View file

@ -22,7 +22,7 @@ public class LineSpacingTest {
// create document without margins
Document document = new Document();
document.add(new ColumnLayout(2, 5));
document.add(new ColumnLayout().setColumnCount(2).setColumnSpacing(5f));
Paragraph left = new Paragraph();
// no line spacing for the first line

View file

@ -11,7 +11,7 @@ import org.xbib.graphics.pdfbox.layout.font.BaseFont;
import org.xbib.graphics.pdfbox.layout.text.Position;
import org.xbib.graphics.pdfbox.layout.text.TextFlow;
import org.xbib.graphics.pdfbox.layout.text.TextFlowUtil;
import org.xbib.graphics.pdfbox.layout.text.TextSequenceUtil;
import org.xbib.graphics.pdfbox.layout.util.TextSequenceUtil;
import java.io.FileOutputStream;
public class ListenerTest {

View file

@ -15,7 +15,7 @@ import org.xbib.graphics.pdfbox.layout.text.DrawContext;
import org.xbib.graphics.pdfbox.layout.text.Position;
import org.xbib.graphics.pdfbox.layout.text.TextFlow;
import org.xbib.graphics.pdfbox.layout.text.TextFlowUtil;
import org.xbib.graphics.pdfbox.layout.text.TextSequenceUtil;
import org.xbib.graphics.pdfbox.layout.util.TextSequenceUtil;
import org.xbib.graphics.pdfbox.layout.text.annotations.AnnotationDrawListener;
import java.awt.Color;
import java.io.FileOutputStream;

View file

@ -53,7 +53,7 @@ public class RotationTest {
document.add(titleA4, VerticalLayoutHint.CENTER);
document.add(new VerticalSpacer(5));
document.add(new ColumnLayout(2, 10));
document.add(new ColumnLayout().setColumnCount(2).setColumnSpacing(10f));
document.add(paragraph2);
document.add(paragraph1);
@ -68,7 +68,7 @@ public class RotationTest {
document.add(new VerticalLayout());
document.add(titleA5, VerticalLayoutHint.CENTER);
document.add(new VerticalSpacer(5));
document.add(new ColumnLayout(2, 10));
document.add(new ColumnLayout().setColumnCount(2).setColumnSpacing(10f));
document.add(paragraph2);
document.add(paragraph1);
@ -83,7 +83,7 @@ public class RotationTest {
document.add(new VerticalLayout());
document.add(titleA4, VerticalLayoutHint.CENTER);
document.add(new VerticalSpacer(5));
document.add(new ColumnLayout(2, 10));
document.add(new ColumnLayout().setColumnCount(2).setColumnSpacing(10f));
document.add(paragraph2);
document.add(paragraph1);
@ -98,7 +98,7 @@ public class RotationTest {
document.add(new VerticalLayout());
document.add(titleA5, VerticalLayoutHint.CENTER);
document.add(new VerticalSpacer(5));
document.add(new ColumnLayout(2, 10));
document.add(new ColumnLayout().setColumnCount(2).setColumnSpacing(10f));
document.add(paragraph2);
document.add(paragraph1);

View file

@ -22,4 +22,19 @@ public class ScriptTest {
}
engine.close();
}
@Test
public void deckblatt() throws Exception {
Settings settings = Settings.settingsBuilder()
.loadFromResource("json", getClass().getResourceAsStream("deckblatt.json"))
.build();
Engine engine = new Engine();
engine.execute(settings);
int i = 0;
for (Document document : engine.getState().getDocuments()) {
document.render().save(new FileOutputStream("build/deckblatt" + (i++) + ".pdf")).close();
}
engine.close();
}
}

View file

@ -0,0 +1,108 @@
{
"type": "document",
"margin": "10 10 10 10",
"author": "Jörg Prante",
"creator": "org.xbib.graphics.pdfbox.layout",
"elements": [
{
"type": "image",
"x": 10,
"y": 290,
"scale": 0.25,
"value": "iVBORw0KGgoAAAANSUhEUgAAAfQAAAC0AQMAAABYN0wRAAAABlBMVEUAAAD///+l2Z/dAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH1gsEDjEFTKgt4wAAAi5JREFUaN7t2s1ygyAQAOClHLiVHnvojI/io+mj+Sg+Qo4eGKmwgPkfdjfTNC05ZEblm+BmxQUFL/ocoPnmhX6Fy0/zzf+kN8L8fXl/Fr8Z9O/wACq1nQAs1S9Q/Mabb/6v+qOd0+O82/3C8eFYvn6X++evrno/lwNr88033/zr+Vlnv8BA99vIOSQ/nvahzs+x58G7OBynglnX+jGO78EfIHSF6FfIv2rDoZ7qHRb0wY/xJkT0odPYawvxVkX0M+RevyMj+rANXWj2BTEURD8W/4lzG6KPjWPUPjhen/uB5t/gJOpbKGkeHu07jteP85bsp+K/ON644uMsas0hqfT9mrPWhG2TvK31g8/ebgJrxYXg/TYCoe+CMzjybRt1Xu2+9zEUuL+v9DrsEniz+zgK6dRoqPR29774Ma5x0L2n+654tXvcYHnly2lU+b547fGvlHuHaVTlhys+TWaI3hz7rtb7K/4g9BgWkR8kfhJ6TF+qt0deiTzUe3XF56tY4I3EO6HPc3muT+nL81rkY+RT+rN9St+n+ZT+PG/2VdWf92sqxfRtn8rOOz6nL8O78C31ZSmL7pdUBHUXfj5dAbztO4mPNKc/w0ea05fhJ6EfA40zIhxHiH5N5SjXu1hEcT2Enpf5H8MjcyKvhd482Vuh74R+EHov80rotdBboe+F3nM9TqU133vMnguPzylVzdPO81Y0f+/9i6d7/vP35ptvvvnmX9i/8PuHzf9f/w3g1VrR1Tf4UwAAAABJRU5ErkJggg=="
},
{
"type": "text",
"x": 70,
"y": 290,
"value": "*Aufsatzbestellung*",
"fontsize": 24
},
{
"type": "barcode",
"x": 70,
"y": 280,
"symbol": "Code3Of9Extended",
"value": "1234567890",
"scalex": 2.0,
"scaley": 1.0
},
{
"type": "table",
"x": 10,
"y": 260,
"columnwidths": "40 150",
"elements": [
{
"type": "row",
"elements": [
{
"type": "cell",
"markup": "*This* is markup"
},
{
"type": "cell",
"value": "Hello World"
}
]
},
{
"type": "row",
"elements": [
{
"type": "cell",
"markup": "*This* is markup",
"fontsize": 12
},
{
"type": "cell",
"markup": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.",
"fontsize": 12
}
]
},
{
"type": "row",
"elements": [
{
"type": "horizontalruler",
"linewidth": 0.5
},
{
"type": "horizontalruler",
"linewidth": 0.5
}
]
},
{
"type": "row",
"elements": [
{
"type": "cell",
"markup": "*This* is markup"
},
{
"type": "cell",
"value": "Hello World",
"fontsize": 20
}
]
},
{
"type": "row",
"elements": [
{
"type": "cell",
"markup": "*This* is markup"
},
{
"type": "cell",
"value": "Hello World",
"fontsize": 36
}
]
}
]
}
]
}