adding TableElement, table commands, position commands

This commit is contained in:
Jörg Prante 2021-12-07 16:56:03 +01:00
parent 072d5e8727
commit 8056505e4d
55 changed files with 772 additions and 321 deletions

View file

@ -2,6 +2,8 @@ package org.xbib.graphics.pdfbox.layout.boxable;
import org.apache.pdfbox.pdmodel.font.PDFont; import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDType1Font; import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.xbib.graphics.pdfbox.layout.util.PDStreamUtils;
import java.awt.Color; import java.awt.Color;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;

View file

@ -7,6 +7,8 @@ import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDType0Font; import org.apache.pdfbox.pdmodel.font.PDType0Font;
import org.apache.pdfbox.pdmodel.interactive.documentnavigation.destination.PDPageXYZDestination; import org.apache.pdfbox.pdmodel.interactive.documentnavigation.destination.PDPageXYZDestination;
import org.apache.pdfbox.pdmodel.interactive.documentnavigation.outline.PDOutlineItem; import org.apache.pdfbox.pdmodel.interactive.documentnavigation.outline.PDOutlineItem;
import org.xbib.graphics.pdfbox.layout.util.PDStreamUtils;
import java.awt.Color; import java.awt.Color;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;

View file

@ -4,6 +4,8 @@ import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream; import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDFont; import org.apache.pdfbox.pdmodel.font.PDFont;
import org.xbib.graphics.pdfbox.layout.util.PDStreamUtils;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;

View file

@ -6,6 +6,7 @@ package org.xbib.graphics.pdfbox.layout.elements;
public class Dimension { public class Dimension {
private final float width; private final float width;
private final float height; private final float height;
public Dimension(float width, float height) { public Dimension(float width, float height) {

View file

@ -2,6 +2,7 @@ package org.xbib.graphics.pdfbox.layout.elements;
import org.apache.pdfbox.io.MemoryUsageSetting; import org.apache.pdfbox.io.MemoryUsageSetting;
import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDDocumentInformation;
import org.xbib.graphics.pdfbox.layout.elements.render.Layout; import org.xbib.graphics.pdfbox.layout.elements.render.Layout;
import org.xbib.graphics.pdfbox.layout.elements.render.LayoutHint; import org.xbib.graphics.pdfbox.layout.elements.render.LayoutHint;
import org.xbib.graphics.pdfbox.layout.elements.render.RenderContext; import org.xbib.graphics.pdfbox.layout.elements.render.RenderContext;
@ -12,7 +13,12 @@ import org.xbib.graphics.pdfbox.layout.elements.render.VerticalLayoutHint;
import java.io.Closeable; import java.io.Closeable;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -23,11 +29,6 @@ import java.util.Map.Entry;
*/ */
public class Document implements Closeable, RenderListener { public class Document implements Closeable, RenderListener {
/**
* A4 portrait without margins.
*/
public final static PageFormat DEFAULT_PAGE_FORMAT = new PageFormat();
private final List<Entry<Element, LayoutHint>> elements = new ArrayList<>(); private final List<Entry<Element, LayoutHint>> elements = new ArrayList<>();
private final List<Renderer> customRenderer = new ArrayList<>(); private final List<Renderer> customRenderer = new ArrayList<>();
@ -38,11 +39,30 @@ public class Document implements Closeable, RenderListener {
private final PDDocument pdDocument; private final PDDocument pdDocument;
private final PDDocumentInformation pdDocumentInformation;
/** /**
* Creates a Document using the {@link #DEFAULT_PAGE_FORMAT}. * Creates a Document.
*/ */
public Document() { public Document() {
this(DEFAULT_PAGE_FORMAT, true); this(PageFormats.A4_PORTRAIT, true);
}
/**
* Creates a Document based on the given page format. By default, a
* {@link VerticalLayout} is used.
*
* @param pageFormat the page format box to use.
*/
public Document(PageFormat pageFormat) {
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();
} }
/** /**
@ -68,26 +88,54 @@ public class Document implements Closeable, RenderListener {
this(PageFormat.builder().margins(marginLeft, marginRight, marginTop, marginBottom).build(), memory); this(PageFormat.builder().margins(marginLeft, marginRight, marginTop, marginBottom).build(), memory);
} }
/**
* Creates a Document based on the given page format. By default, a
* {@link VerticalLayout} is used.
*
* @param pageFormat the page format box to use.
*/
public Document(PageFormat pageFormat) {
this(pageFormat, true);
}
public Document(PageFormat pageFormat, boolean memory) {
this.pageFormat = pageFormat;
this.pdDocument = new PDDocument(memory ?
MemoryUsageSetting.setupMainMemoryOnly() : MemoryUsageSetting.setupTempFileOnly());
}
public PDDocument getPdDocument() { public PDDocument getPdDocument() {
return pdDocument; return pdDocument;
} }
public void setAuthor(String author) {
pdDocumentInformation.setAuthor(author);
}
public void setCreator(String creator) {
pdDocumentInformation.setCreator(creator);
}
public void setTitle(String title) {
pdDocumentInformation.setTitle(title);
}
public void setSubject(String subject) {
pdDocumentInformation.setSubject(subject);
}
public void setKeywords(String keywords) {
pdDocumentInformation.setKeywords(keywords);
}
public void setProducer(String producer) {
pdDocumentInformation.setProducer(producer);
}
public void setTrapped(String value) {
pdDocumentInformation.setTrapped(value);
}
public void setCreationDate(Instant instant) {
ZonedDateTime zdt = ZonedDateTime.ofInstant(instant, ZoneId.systemDefault());
Calendar calendar = GregorianCalendar.from(zdt);
pdDocumentInformation.setCreationDate(calendar);
}
public void setModificationDate(Instant instant) {
ZonedDateTime zdt = ZonedDateTime.ofInstant(instant, ZoneId.systemDefault());
Calendar calendar = GregorianCalendar.from(zdt);
pdDocumentInformation.setModificationDate(calendar);
}
public void setCustomMetadata(String key, String value) {
pdDocumentInformation.setCustomMetadataValue(key, value);
}
/** /**
* Adds an element to the document using a {@link VerticalLayoutHint}. * Adds an element to the document using a {@link VerticalLayoutHint}.
* *
@ -176,6 +224,7 @@ public class Document implements Closeable, RenderListener {
* @throws IOException by pdfbox * @throws IOException by pdfbox
*/ */
public Document render() throws IOException { public Document render() throws IOException {
pdDocument.setDocumentInformation(pdDocumentInformation);
RenderContext renderContext = new RenderContext(this, pdDocument); RenderContext renderContext = new RenderContext(this, pdDocument);
for (Entry<Element, LayoutHint> entry : elements) { for (Entry<Element, LayoutHint> entry : elements) {
Element element = entry.getKey(); Element element = entry.getKey();

View file

@ -4,33 +4,30 @@ import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.xbib.graphics.pdfbox.layout.elements.render.VerticalLayout; import org.xbib.graphics.pdfbox.layout.elements.render.VerticalLayout;
import java.util.Locale; import java.util.Locale;
import java.util.Objects;
/** /**
* Defines the size and orientation of a page. The default is A4 portrait without margins. * Defines the size and orientation of a page. The default is A4 portrait without margins.
*/ */
public class PageFormat implements Element { public class PageFormat implements Element {
public static final int DEFAULT_USER_SPACE_UNIT_DPI = 72; public static final float MM_TO_UNITS = 1.0f / 25.4f * 72.0f;
public static final float MM_TO_UNITS = 1 / (10 * 2.54f) * DEFAULT_USER_SPACE_UNIT_DPI; public static final PDRectangle A0 = new PDRectangle(Math.round(841f * MM_TO_UNITS), Math.round(1189f * MM_TO_UNITS));
public static final PDRectangle A0 = new PDRectangle(841 * MM_TO_UNITS, public static final PDRectangle A1 = new PDRectangle(Math.round(594f * MM_TO_UNITS), Math.round(841f * MM_TO_UNITS));
1189 * MM_TO_UNITS);
public static final PDRectangle A1 = new PDRectangle(594 * MM_TO_UNITS,
841 * MM_TO_UNITS);
public static final PDRectangle A2 = new PDRectangle(420 * MM_TO_UNITS,
594 * MM_TO_UNITS);
public static final PDRectangle A3 = new PDRectangle(297 * MM_TO_UNITS,
420 * MM_TO_UNITS);
public static final PDRectangle A4 = new PDRectangle(210 * MM_TO_UNITS,
297 * MM_TO_UNITS);
public static final PDRectangle A5 = new PDRectangle(148 * MM_TO_UNITS,
210 * MM_TO_UNITS);
public static final PDRectangle A6 = new PDRectangle(105 * MM_TO_UNITS,
148 * MM_TO_UNITS);
public static final PDRectangle Letter = new PDRectangle(215.9f * MM_TO_UNITS, public static final PDRectangle A2 = new PDRectangle(Math.round(420f * MM_TO_UNITS), Math.round(594f * MM_TO_UNITS));
279.4f * MM_TO_UNITS);
public static final PDRectangle A3 = new PDRectangle(Math.round(297f * MM_TO_UNITS), Math.round(420f * MM_TO_UNITS));
public static final PDRectangle A4 = new PDRectangle(Math.round(210f * MM_TO_UNITS), Math.round(297f * MM_TO_UNITS));
public static final PDRectangle A5 = new PDRectangle(Math.round(148f * MM_TO_UNITS), Math.round(210f * MM_TO_UNITS));
public static final PDRectangle A6 = new PDRectangle(Math.round(105f * MM_TO_UNITS), Math.round(148f * MM_TO_UNITS));
public static final PDRectangle Letter = new PDRectangle(Math.round(215.9f * MM_TO_UNITS), Math.round(279.4f * MM_TO_UNITS));
private final float marginLeft; private final float marginLeft;
@ -58,7 +55,7 @@ public class PageFormat implements Element {
* *
* @param mediaBox the size. * @param mediaBox the size.
*/ */
public PageFormat(final PDRectangle mediaBox) { public PageFormat(PDRectangle mediaBox) {
this(mediaBox, Orientation.PORTRAIT); this(mediaBox, Orientation.PORTRAIT);
} }
@ -68,7 +65,7 @@ public class PageFormat implements Element {
* @param mediaBox the size. * @param mediaBox the size.
* @param orientation the orientation. * @param orientation the orientation.
*/ */
public PageFormat(final PDRectangle mediaBox, final Orientation orientation) { public PageFormat(PDRectangle mediaBox, Orientation orientation) {
this(mediaBox, orientation, 0, 0, 0, 0); this(mediaBox, orientation, 0, 0, 0, 0);
} }
@ -84,8 +81,7 @@ public class PageFormat implements Element {
* @param marginBottom the bottom margin * @param marginBottom the bottom margin
*/ */
public PageFormat(PDRectangle mediaBox, Orientation orientation, public PageFormat(PDRectangle mediaBox, Orientation orientation,
float marginLeft, float marginRight, float marginTop, float marginLeft, float marginRight, float marginTop, float marginBottom) {
float marginBottom) {
this(mediaBox, orientation, 0, marginLeft, marginRight, marginTop, marginBottom); this(mediaBox, orientation, 0, marginLeft, marginRight, marginTop, marginBottom);
} }
@ -101,9 +97,8 @@ public class PageFormat implements Element {
* @param marginTop the top margin * @param marginTop the top margin
* @param marginBottom the bottom margin * @param marginBottom the bottom margin
*/ */
public PageFormat(PDRectangle mediaBox, Orientation orientation, public PageFormat(PDRectangle mediaBox, Orientation orientation, int rotation,
int rotation, float marginLeft, float marginRight, float marginLeft, float marginRight, float marginTop, float marginBottom) {
float marginTop, float marginBottom) {
this.mediaBox = mediaBox; this.mediaBox = mediaBox;
this.orientation = orientation; this.orientation = orientation;
this.rotation = rotation; this.rotation = rotation;
@ -113,8 +108,6 @@ public class PageFormat implements Element {
this.marginBottom = marginBottom; this.marginBottom = marginBottom;
} }
/** /**
* @return the orientation to use. * @return the orientation to use.
*/ */
@ -179,12 +172,19 @@ public class PageFormat implements Element {
} }
public static class PageFormatBuilder { public static class PageFormatBuilder {
private float marginLeft; private float marginLeft;
private float marginRight; private float marginRight;
private float marginTop; private float marginTop;
private float marginBottom; private float marginBottom;
private PDRectangle mediaBox = A4; private PDRectangle mediaBox = A4;
private Orientation orientation; private Orientation orientation;
private int rotation; private int rotation;
protected PageFormatBuilder() { protected PageFormatBuilder() {
@ -243,8 +243,7 @@ public class PageFormat implements Element {
* @param marginBottom the bottom margin to use. * @param marginBottom the bottom margin to use.
* @return the builder. * @return the builder.
*/ */
public PageFormatBuilder margins(float marginLeft, float marginRight, public PageFormatBuilder margins(float marginLeft, float marginRight, float marginTop, float marginBottom) {
float marginTop, float marginBottom) {
this.marginLeft = marginLeft; this.marginLeft = marginLeft;
this.marginRight = marginRight; this.marginRight = marginRight;
this.marginTop = marginTop; this.marginTop = marginTop;
@ -391,7 +390,8 @@ public class PageFormat implements Element {
} }
public PageFormatBuilder pageFormat(String format) { public PageFormatBuilder pageFormat(String format) {
switch (format.toLowerCase(Locale.ROOT)) { Objects.requireNonNull(format);
switch (format.toUpperCase(Locale.ROOT)) {
case "A0" : case "A0" :
A0(); A0();
break; break;
@ -426,8 +426,7 @@ public class PageFormat implements Element {
* @return the resulting PageFormat. * @return the resulting PageFormat.
*/ */
public PageFormat build() { public PageFormat build() {
return new PageFormat(mediaBox, orientation, rotation, marginLeft, return new PageFormat(mediaBox, orientation, rotation, marginLeft, marginRight, marginTop, marginBottom);
marginRight, marginTop, marginBottom);
} }
} }
} }

View file

@ -2,11 +2,15 @@ package org.xbib.graphics.pdfbox.layout.elements;
public interface PageFormats { public interface PageFormats {
PageFormat A4_PORTRAIT = new PageFormat(); PageFormat A4_PORTRAIT = new PageFormat(PageFormat.A4, Orientation.PORTRAIT);
PageFormat A4_LANDSCAPE = new PageFormat(PageFormat.A4, Orientation.LANDSCAPE); PageFormat A4_LANDSCAPE = new PageFormat(PageFormat.A4, Orientation.LANDSCAPE);
PageFormat A5_PORTRAIT = new PageFormat(PageFormat.A5, Orientation.PORTRAIT); PageFormat A5_PORTRAIT = new PageFormat(PageFormat.A5, Orientation.PORTRAIT);
PageFormat A5_LANDSCAPE = new PageFormat(PageFormat.A5, Orientation.LANDSCAPE); PageFormat A5_LANDSCAPE = new PageFormat(PageFormat.A5, Orientation.LANDSCAPE);
PageFormat LETTER_PORTRAIT = new PageFormat(PageFormat.Letter, Orientation.PORTRAIT);
PageFormat LETTER_LANDSCAPE = new PageFormat(PageFormat.Letter, Orientation.LANDSCAPE);
} }

View file

@ -6,12 +6,6 @@ package org.xbib.graphics.pdfbox.layout.elements;
*/ */
public class PositionControl extends ControlElement { public class PositionControl extends ControlElement {
/**
* Use this value in {@link #createSetPosition(Float, Float)} to reset
* either one or both coordinates to the marked position.
*/
public static final Float MARKED_POSITION = Float.NEGATIVE_INFINITY;
/** /**
* Add this element to a document to mark the current position. * Add this element to a document to mark the current position.
* *
@ -21,18 +15,25 @@ public class PositionControl extends ControlElement {
return new MarkPosition(); return new MarkPosition();
} }
/**
* Add this element to a document to reset to the marked position.
*
* @return the created element
*/
public static ResetPosition createResetPosition() {
return new ResetPosition();
}
/** /**
* Add this element to a document to manipulate the current layout position. * Add this element to a document to manipulate the current layout position.
* If <code>null</code>, the position won't be changed (useful if you want * If <code>null</code>, the position won't be changed (useful if you want
* to change only X or Y). If the value is {@link #MARKED_POSITION}, it wil * to change only X or Y).
* be (re-)set to the marked position.
* *
* @param newX the new X position. * @param newX the new X position.
* @param newY new new Y position. * @param newY new new Y position.
* @return the created element * @return the created element
*/ */
public static SetPosition createSetPosition(final Float newX, public static SetPosition createSetPosition(Float newX, Float newY) {
final Float newY) {
return new SetPosition(newX, newY); return new SetPosition(newX, newY);
} }
@ -45,22 +46,31 @@ public class PositionControl extends ControlElement {
* @param relativeY the value to change position in Y direction. * @param relativeY the value to change position in Y direction.
* @return the created element * @return the created element
*/ */
public static MovePosition createMovePosition(final float relativeX, public static MovePosition createMovePosition(float relativeX, float relativeY) {
final float relativeY) {
return new MovePosition(relativeX, relativeY); return new MovePosition(relativeX, relativeY);
} }
public static class MarkPosition extends PositionControl { public static class MarkPosition extends PositionControl {
private MarkPosition() { private MarkPosition() {
super("MARK_POSITION"); super("MARK_POSITION");
} }
} }
public static class ResetPosition extends PositionControl {
private ResetPosition() {
super("RESET_POSITION");
}
}
public static class SetPosition extends PositionControl { public static class SetPosition extends PositionControl {
private final Float newX; private final Float newX;
private final Float newY; private final Float newY;
private SetPosition(final Float newX, final Float newY) { private SetPosition(Float newX, Float newY) {
super(String.format("SET_POSITION x:%f, y%f", newX, newY)); super(String.format("SET_POSITION x:%f, y%f", newX, newY));
this.newX = newX; this.newX = newX;
this.newY = newY; this.newY = newY;
@ -73,15 +83,16 @@ public class PositionControl extends ControlElement {
public Float getY() { public Float getY() {
return newY; return newY;
} }
} }
public static class MovePosition extends PositionControl { public static class MovePosition extends PositionControl {
private final float relativeX; private final float relativeX;
private final float relativeY; private final float relativeY;
private MovePosition(final float relativeX, final float relativeY) { private MovePosition(float relativeX, float relativeY) {
super(String.format("SET_POSITION x:%f, y%f", relativeX, relativeY)); super(String.format("MOVE_POSITION x:%f, y%f", relativeX, relativeY));
this.relativeX = relativeX; this.relativeX = relativeX;
this.relativeY = relativeY; this.relativeY = relativeY;
} }
@ -93,11 +104,9 @@ public class PositionControl extends ControlElement {
public float getY() { public float getY() {
return relativeY; return relativeY;
} }
} }
private PositionControl(String name) { private PositionControl(String name) {
super(name); super(name);
} }
} }

View file

@ -6,6 +6,7 @@ package org.xbib.graphics.pdfbox.layout.elements;
public class Rectangle extends Dimension { public class Rectangle extends Dimension {
private final float x; private final float x;
private final float y; private final float y;
public Rectangle(float x, float y, float width, float height) { public Rectangle(float x, float y, float width, float height) {

View file

@ -0,0 +1,114 @@
package org.xbib.graphics.pdfbox.layout.elements;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
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.Table;
import org.xbib.graphics.pdfbox.layout.table.TableRenderer;
import org.xbib.graphics.pdfbox.layout.table.VerticalAlignment;
import org.xbib.graphics.pdfbox.layout.text.DrawListener;
import org.xbib.graphics.pdfbox.layout.text.Position;
import java.awt.Color;
import java.io.IOException;
public class TableElement implements Element, Drawable, Dividable {
private final Table.Builder table;
private Position absolutePosition;
public TableElement() {
this.table = Table.builder();
}
public void add(Row row) {
table.addRow(row);
}
public void addColumnOfWidth(float width) {
table.addColumnOfWidth(width);
}
public void padding(float padding) {
table.padding(padding);
}
public void textColor(Color color) {
table.textColor(color);
}
public void backgroundColor(Color color) {
table.backgroundColor(color);
}
public void borderColor(Color color) {
table.borderColor(color);
}
public void borderWidth(float borderWidth) {
table.borderWidth(borderWidth);
}
public void borderStyle(BorderStyleInterface style) {
table.borderStyle(style);
}
public void horizontalAlignment(HorizontalAlignment horizontalAlignment) {
table.horizontalAlignment(horizontalAlignment);
}
public void verticalAlignment(VerticalAlignment verticalAlignment) {
table.verticalAlignment(verticalAlignment);
}
@Override
public float getWidth() {
return table.build().getWidth();
}
@Override
public float getHeight() {
return table.build().getHeight();
}
@Override
public Divided divide(float remainingHeight, float nextPageHeight) throws IOException {
if (getHeight() <= nextPageHeight) {
return new Divided(new VerticalSpacer(remainingHeight), this);
}
return new Cutter(this).divide(remainingHeight, nextPageHeight);
}
@Override
public Position getAbsolutePosition() {
return absolutePosition;
}
public void setAbsolutePosition(Position absolutePosition) {
this.absolutePosition = absolutePosition;
}
@Override
public void draw(PDDocument pdDocument, PDPageContentStream contentStream,
Position upperLeft, DrawListener drawListener) throws IOException {
TableRenderer tableRenderer = TableRenderer.builder()
.table(table.build())
.document(pdDocument)
.contentStream(contentStream)
.startX(upperLeft.getX())
.startY(upperLeft.getY())
.build();
tableRenderer.draw();
if (drawListener != null) {
drawListener.drawn(this, upperLeft, getWidth(), getHeight());
}
}
@Override
public Drawable removeLeadingEmptyVerticalSpace() {
return this;
}
}

View file

@ -12,6 +12,7 @@ import org.xbib.graphics.pdfbox.layout.elements.PageFormat;
import org.xbib.graphics.pdfbox.layout.elements.PositionControl; import org.xbib.graphics.pdfbox.layout.elements.PositionControl;
import org.xbib.graphics.pdfbox.layout.elements.PositionControl.MarkPosition; import org.xbib.graphics.pdfbox.layout.elements.PositionControl.MarkPosition;
import org.xbib.graphics.pdfbox.layout.elements.PositionControl.MovePosition; import org.xbib.graphics.pdfbox.layout.elements.PositionControl.MovePosition;
import org.xbib.graphics.pdfbox.layout.elements.PositionControl.ResetPosition;
import org.xbib.graphics.pdfbox.layout.elements.PositionControl.SetPosition; import org.xbib.graphics.pdfbox.layout.elements.PositionControl.SetPosition;
import org.xbib.graphics.pdfbox.layout.text.DrawContext; import org.xbib.graphics.pdfbox.layout.text.DrawContext;
import org.xbib.graphics.pdfbox.layout.text.DrawListener; import org.xbib.graphics.pdfbox.layout.text.DrawListener;
@ -121,7 +122,7 @@ public class RenderContext implements Renderer, Closeable, DrawContext, DrawList
} }
/** /**
* @return the {@link PositionControl#MARKED_POSITION}. * @return the marked position.
*/ */
public Position getMarkedPosition() { public Position getMarkedPosition() {
return markedPosition; return markedPosition;
@ -301,23 +302,18 @@ public class RenderContext implements Renderer, Closeable, DrawContext, DrawList
setMarkedPosition(getCurrentPosition()); setMarkedPosition(getCurrentPosition());
return true; return true;
} }
if (positionControl instanceof ResetPosition) {
currentPosition = new Position(getMarkedPosition().getX(), getMarkedPosition().getY());
}
if (positionControl instanceof SetPosition) { if (positionControl instanceof SetPosition) {
SetPosition setPosition = (SetPosition) positionControl; SetPosition setPosition = (SetPosition) positionControl;
Float x = setPosition.getX(); Float x = setPosition.getX();
if (x == null) { if (x == null) {
x = getCurrentPosition().getX(); x = getCurrentPosition().getX();
} else {
if (x.equals(PositionControl.MARKED_POSITION)) {
x = getMarkedPosition().getX();
}
} }
Float y = setPosition.getY(); Float y = setPosition.getY();
if (y == null) { if (y == null) {
y = getCurrentPosition().getY(); y = getCurrentPosition().getY();
} else {
if (y.equals(PositionControl.MARKED_POSITION)) {
y = getMarkedPosition().getY();
}
} }
currentPosition = new Position(x, y); currentPosition = new Position(x, y);
return true; return true;
@ -390,8 +386,7 @@ public class RenderContext implements Renderer, Closeable, DrawContext, DrawList
} }
@Override @Override
public void drawn(Object drawnObject, Position upperLeft, float width, public void drawn(Object drawnObject, Position upperLeft, float width, float height) {
float height) {
updateMaxPositionOnPage(upperLeft, width, height); updateMaxPositionOnPage(upperLeft, width, height);
annotationDrawListener.drawn(drawnObject, upperLeft, width, height); annotationDrawListener.drawn(drawnObject, upperLeft, width, height);
} }
@ -399,12 +394,11 @@ public class RenderContext implements Renderer, Closeable, DrawContext, DrawList
/** /**
* Updates the maximum right resp. bottom position on the page. * Updates the maximum right resp. bottom position on the page.
* *
* @param upperLeft * @param upperLeft the upper left position
* @param width * @param width the width
* @param height * @param height the height
*/ */
protected void updateMaxPositionOnPage(Position upperLeft, float width, protected void updateMaxPositionOnPage(Position upperLeft, float width, float height) {
float height) {
maxPositionOnPage = new Position(Math.max(maxPositionOnPage.getX(), maxPositionOnPage = new Position(Math.max(maxPositionOnPage.getX(),
upperLeft.getX() + width), Math.min(maxPositionOnPage.getY(), upperLeft.getX() + width), Math.min(maxPositionOnPage.getY(),
upperLeft.getY() - height)); upperLeft.getY() - height));

View file

@ -19,6 +19,5 @@ public interface Renderer {
* @return <code>true</code> if the layout is able to render the element. * @return <code>true</code> if the layout is able to render the element.
* @throws IOException by pdfbox * @throws IOException by pdfbox
*/ */
boolean render(RenderContext renderContext, Element element, boolean render(RenderContext renderContext, Element element, LayoutHint layoutHint) throws IOException;
LayoutHint layoutHint) throws IOException;
} }

View file

@ -50,8 +50,7 @@ public class VerticalLayout implements Layout {
* @param renderContext the render context. * @param renderContext the render context.
* @throws IOException by pdfbox. * @throws IOException by pdfbox.
*/ */
protected void turnPage(final RenderContext renderContext) protected void turnPage(final RenderContext renderContext) throws IOException {
throws IOException {
renderContext.newPage(); renderContext.newPage();
} }
@ -60,8 +59,7 @@ public class VerticalLayout implements Layout {
* @return the target width to draw to. * @return the target width to draw to.
*/ */
protected float getTargetWidth(final RenderContext renderContext) { protected float getTargetWidth(final RenderContext renderContext) {
float targetWidth = renderContext.getWidth(); return renderContext.getWidth();
return targetWidth;
} }
@Override @Override
@ -75,12 +73,10 @@ public class VerticalLayout implements Layout {
turnPage(renderContext); turnPage(renderContext);
return true; return true;
} }
return false; return false;
} }
public void render(final RenderContext renderContext, Drawable drawable, public void render(RenderContext renderContext, Drawable drawable, LayoutHint layoutHint) throws IOException {
final LayoutHint layoutHint) throws IOException {
if (drawable.getAbsolutePosition() != null) { if (drawable.getAbsolutePosition() != null) {
renderAbsolute(renderContext, drawable, layoutHint, renderAbsolute(renderContext, drawable, layoutHint,
drawable.getAbsolutePosition()); drawable.getAbsolutePosition());
@ -98,11 +94,9 @@ public class VerticalLayout implements Layout {
* @param position the left upper position to start drawing at. * @param position the left upper position to start drawing at.
* @throws IOException by pdfbox * @throws IOException by pdfbox
*/ */
protected void renderAbsolute(final RenderContext renderContext, protected void renderAbsolute(RenderContext renderContext,
Drawable drawable, final LayoutHint layoutHint, Drawable drawable, LayoutHint layoutHint, Position position) throws IOException {
final Position position) throws IOException { drawable.draw(renderContext.getPdDocument(), renderContext.getContentStream(), position, renderContext);
drawable.draw(renderContext.getPdDocument(),
renderContext.getContentStream(), position, renderContext);
} }
/** /**
@ -117,8 +111,8 @@ public class VerticalLayout implements Layout {
* @param layoutHint the layout hint used to layout. * @param layoutHint the layout hint used to layout.
* @throws IOException by pdfbox * @throws IOException by pdfbox
*/ */
protected void renderReleative(final RenderContext renderContext, protected void renderReleative(RenderContext renderContext,
Drawable drawable, final LayoutHint layoutHint) throws IOException { Drawable drawable, LayoutHint layoutHint) throws IOException {
VerticalLayoutHint verticalLayoutHint = null; VerticalLayoutHint verticalLayoutHint = null;
if (layoutHint instanceof VerticalLayoutHint) { if (layoutHint instanceof VerticalLayoutHint) {
verticalLayoutHint = (VerticalLayoutHint) layoutHint; verticalLayoutHint = (VerticalLayoutHint) layoutHint;
@ -127,9 +121,7 @@ public class VerticalLayout implements Layout {
verticalLayoutHint.getMarginTop()), verticalLayoutHint); verticalLayoutHint.getMarginTop()), verticalLayoutHint);
} }
} }
layoutAndDrawReleative(renderContext, drawable, verticalLayoutHint); layoutAndDrawReleative(renderContext, drawable, verticalLayoutHint);
if (verticalLayoutHint != null) { if (verticalLayoutHint != null) {
if (verticalLayoutHint.getMarginBottom() > 0) { if (verticalLayoutHint.getMarginBottom() > 0) {
layoutAndDrawReleative(renderContext, new VerticalSpacer( layoutAndDrawReleative(renderContext, new VerticalSpacer(
@ -151,9 +143,8 @@ public class VerticalLayout implements Layout {
* @param layoutHint the layout hint used to layout. * @param layoutHint the layout hint used to layout.
* @throws IOException by pdfbox * @throws IOException by pdfbox
*/ */
protected void layoutAndDrawReleative(final RenderContext renderContext, protected void layoutAndDrawReleative(RenderContext renderContext,
Drawable drawable, final LayoutHint layoutHint) throws IOException { Drawable drawable, LayoutHint layoutHint) throws IOException {
float targetWidth = getTargetWidth(renderContext); float targetWidth = getTargetWidth(renderContext);
boolean movePosition = true; boolean movePosition = true;
VerticalLayoutHint verticalLayoutHint = null; VerticalLayoutHint verticalLayoutHint = null;
@ -163,7 +154,6 @@ public class VerticalLayout implements Layout {
targetWidth -= verticalLayoutHint.getMarginRight(); targetWidth -= verticalLayoutHint.getMarginRight();
movePosition = !verticalLayoutHint.isResetY(); movePosition = !verticalLayoutHint.isResetY();
} }
float oldMaxWidth = -1; float oldMaxWidth = -1;
if (drawable instanceof WidthRespecting) { if (drawable instanceof WidthRespecting) {
WidthRespecting flowing = (WidthRespecting) drawable; WidthRespecting flowing = (WidthRespecting) drawable;
@ -172,28 +162,21 @@ public class VerticalLayout implements Layout {
flowing.setMaxWidth(targetWidth); flowing.setMaxWidth(targetWidth);
} }
} }
Drawable drawablePart = removeLeadingEmptyVerticalSpace(drawable, renderContext);
Drawable drawablePart = removeLeadingEmptyVerticalSpace(drawable,
renderContext);
while (renderContext.getRemainingHeight() < drawablePart.getHeight()) { while (renderContext.getRemainingHeight() < drawablePart.getHeight()) {
Dividable dividable = null; Dividable dividable;
if (drawablePart instanceof Dividable) { if (drawablePart instanceof Dividable) {
dividable = (Dividable) drawablePart; dividable = (Dividable) drawablePart;
} else { } else {
dividable = new Cutter(drawablePart); dividable = new Cutter(drawablePart);
} }
Dividable.Divided divided = dividable.divide( Dividable.Divided divided = dividable.divide(renderContext.getRemainingHeight(), renderContext.getHeight());
renderContext.getRemainingHeight(),
renderContext.getHeight());
drawReletivePartAndMovePosition(renderContext, divided.getFirst(), drawReletivePartAndMovePosition(renderContext, divided.getFirst(),
layoutHint, true); layoutHint, true);
// new page // new page
turnPage(renderContext); turnPage(renderContext);
drawablePart = divided.getTail(); drawablePart = divided.getTail();
drawablePart = removeLeadingEmptyVerticalSpace(drawablePart, drawablePart = removeLeadingEmptyVerticalSpace(drawablePart, renderContext);
renderContext);
} }
drawReletivePartAndMovePosition(renderContext, drawablePart, drawReletivePartAndMovePosition(renderContext, drawablePart,
@ -230,12 +213,10 @@ public class VerticalLayout implements Layout {
if (layoutHint instanceof VerticalLayoutHint) { if (layoutHint instanceof VerticalLayoutHint) {
VerticalLayoutHint verticalLayoutHint = (VerticalLayoutHint) layoutHint; VerticalLayoutHint verticalLayoutHint = (VerticalLayoutHint) layoutHint;
Alignment alignment = verticalLayoutHint.getAlignment(); Alignment alignment = verticalLayoutHint.getAlignment();
float horizontalExtraSpace = getTargetWidth(renderContext) float horizontalExtraSpace = getTargetWidth(renderContext) - drawable.getWidth();
- drawable.getWidth();
switch (alignment) { switch (alignment) {
case RIGHT: case RIGHT:
offsetX = horizontalExtraSpace offsetX = horizontalExtraSpace - verticalLayoutHint.getMarginRight();
- verticalLayoutHint.getMarginRight();
break; break;
case CENTER: case CENTER:
offsetX = horizontalExtraSpace / 2f; offsetX = horizontalExtraSpace / 2f;
@ -264,8 +245,7 @@ public class VerticalLayout implements Layout {
* @return <code>true</code> if the current position is top of page. * @return <code>true</code> if the current position is top of page.
*/ */
protected boolean isPositionTopOfPage(final RenderContext renderContext) { protected boolean isPositionTopOfPage(final RenderContext renderContext) {
return renderContext.getCurrentPosition().getY() == renderContext return renderContext.getCurrentPosition().getY() == renderContext.getUpperLeft().getY();
.getUpperLeft().getY();
} }
/** /**
@ -279,8 +259,7 @@ public class VerticalLayout implements Layout {
*/ */
protected Drawable removeLeadingEmptyVerticalSpace(final Drawable drawable, protected Drawable removeLeadingEmptyVerticalSpace(final Drawable drawable,
final RenderContext renderContext) throws IOException { final RenderContext renderContext) throws IOException {
if (isRemoveLeadingEmptyVerticalSpace() if (isRemoveLeadingEmptyVerticalSpace() && isPositionTopOfPage(renderContext)) {
&& isPositionTopOfPage(renderContext)) {
return drawable.removeLeadingEmptyVerticalSpace(); return drawable.removeLeadingEmptyVerticalSpace();
} }
return drawable; return drawable;

View file

@ -2,6 +2,8 @@ package org.xbib.graphics.pdfbox.layout.script;
import org.xbib.graphics.pdfbox.layout.elements.Document; import org.xbib.graphics.pdfbox.layout.elements.Document;
import org.xbib.graphics.pdfbox.layout.elements.Paragraph; import org.xbib.graphics.pdfbox.layout.elements.Paragraph;
import org.xbib.graphics.pdfbox.layout.elements.TableElement;
import org.xbib.graphics.pdfbox.layout.table.Row;
import java.util.Collection; import java.util.Collection;
import java.util.Stack; import java.util.Stack;
@ -12,6 +14,10 @@ public class State {
public Stack<Paragraph> paragraphs = new Stack<>(); public Stack<Paragraph> paragraphs = new Stack<>();
public Stack<TableElement> tables = new Stack<>();
public Stack<Row.Builder> rows = new Stack<>();
public Collection<Document> getDocuments() { public Collection<Document> getDocuments() {
return documents; return documents;
} }

View file

@ -10,8 +10,10 @@ import org.xbib.graphics.pdfbox.layout.text.Position;
import org.xbib.settings.Settings; import org.xbib.settings.Settings;
import java.io.IOException; import java.io.IOException;
import java.util.Locale;
public class BarcodeCommand implements Command { public class BarcodeCommand implements Command {
@Override @Override
public void execute(Engine engine, State state, Settings settings) throws IOException { public void execute(Engine engine, State state, Settings settings) throws IOException {
BarcodeElement element; BarcodeElement element;
@ -19,7 +21,7 @@ public class BarcodeCommand implements Command {
Symbol symbol = Symbols.valueOf(settings.get("symbol")).getSymbol(); Symbol symbol = Symbols.valueOf(settings.get("symbol")).getSymbol();
symbol.setContent(settings.get("value")); symbol.setContent(settings.get("value"));
symbol.setBarHeight(settings.getAsInt("barheight", 150)); symbol.setBarHeight(settings.getAsInt("barheight", 150));
symbol.setHumanReadableLocation(HumanReadableLocation.valueOf(settings.get("readablelocation", "BOTTOM"))); symbol.setHumanReadableLocation(HumanReadableLocation.valueOf(settings.get("readablelocation", "bottom").toUpperCase(Locale.ROOT)));
element = new BarcodeElement(symbol); element = new BarcodeElement(symbol);
} catch (Exception e) { } catch (Exception e) {
throw new IOException(e); throw new IOException(e);

View file

@ -0,0 +1,44 @@
package org.xbib.graphics.pdfbox.layout.script.command;
import org.xbib.graphics.pdfbox.layout.color.ColorFactory;
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.TextCell;
import org.xbib.settings.Settings;
import java.awt.Color;
import java.io.IOException;
import java.util.Locale;
public class CellCommand implements Command {
@Override
public void execute(Engine engine, State state, Settings settings) throws IOException {
TextCell.Builder cell = TextCell.builder();
cell.text(settings.get("value"));
cell.fontSize(settings.getAsFloat("size", 11.0f));
Font font = Fonts.valueOf(settings.get("font", "helvetica").toUpperCase(Locale.ROOT)).getFont(state.documents.peek());
cell.font(font);
cell.padding(settings.getAsFloat("padding", 0f));
Color color = ColorFactory.web(settings.get("color", "black"));
cell.textColor(color);
if (settings.containsSetting("backgroundcolor")) {
Color backgroundColor = ColorFactory.web(settings.get("backgroundcolor", "black"));
cell.backgroundColor(backgroundColor);
}
if (settings.containsSetting("bordercolor")) {
Color borderColor = ColorFactory.web(settings.get("bordercolor", "black"));
cell.borderColor(borderColor);
}
cell.borderWidth(settings.getAsFloat("borderwidth", 0f));
BorderStyleInterface styleInterface = BorderStyle.valueOf(settings.get("borderstyle", "solid").toUpperCase(Locale.ROOT));
cell.borderStyle(styleInterface);
cell.colSpan(settings.getAsInt("colspan", 1));
cell.rowSpan(settings.getAsInt("rowspan", 1));
state.rows.peek().add(cell.build());
}
}

View file

@ -0,0 +1,17 @@
package org.xbib.graphics.pdfbox.layout.script.command;
import org.xbib.graphics.pdfbox.layout.elements.render.ColumnLayout;
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;
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));
state.documents.peek().add(columnLayout);
}
}

View file

@ -7,11 +7,15 @@ import org.xbib.graphics.pdfbox.layout.script.State;
import org.xbib.settings.Settings; import org.xbib.settings.Settings;
import java.io.IOException; import java.io.IOException;
import java.time.Instant;
import java.util.Locale;
public class DocumentCommand implements Command { public class DocumentCommand implements Command {
@Override @Override
public void execute(Engine engine, State state, Settings settings) throws IOException { public void execute(Engine engine, State state, Settings settings) throws IOException {
state.paragraphs.clear();
state.tables.clear();
String margin = settings.get("margin", "0 0 0 0"); String margin = settings.get("margin", "0 0 0 0");
String[] margins = margin.split(" "); String[] margins = margin.split(" ");
PageFormat pageFormat = PageFormat.builder() PageFormat pageFormat = PageFormat.builder()
@ -20,9 +24,25 @@ public class DocumentCommand implements Command {
.marginTop(Float.parseFloat(margins[2])) .marginTop(Float.parseFloat(margins[2]))
.marginBottom(Float.parseFloat(margins[3])) .marginBottom(Float.parseFloat(margins[3]))
.pageFormat(settings.get("format", "A4")) .pageFormat(settings.get("format", "A4"))
.orientation(settings.get("orientiation", "PORTRAIT")) .orientation(settings.get("orientiation", "portrait").toUpperCase(Locale.ROOT))
.build(); .build();
state.documents.push(new Document(pageFormat)); Document document = new Document(pageFormat);
Instant instant = Instant.now();
document.setCreationDate(instant);
document.setModificationDate(instant);
if (settings.containsSetting("author")) {
document.setAuthor(settings.get("author"));
}
if (settings.containsSetting("creator")) {
document.setCreator(settings.get("creator"));
}
if (settings.containsSetting("subject")) {
document.setSubject(settings.get("subject"));
}
if (settings.containsSetting("title")) {
document.setTitle(settings.get("title"));
}
state.documents.push(document);
engine.executeElements(settings); engine.executeElements(settings);
} }
} }

View file

@ -9,13 +9,14 @@ import org.xbib.settings.Settings;
import java.awt.Color; import java.awt.Color;
import java.io.IOException; import java.io.IOException;
import java.util.Locale;
public class HorizontalrulerCommand implements Command { public class HorizontalrulerCommand implements Command {
@Override @Override
public void execute(Engine engine, State state, Settings settings) throws IOException { public void execute(Engine engine, State state, Settings settings) throws IOException {
Stroke.StrokeBuilder strokeBuilder = Stroke.builder() Stroke.StrokeBuilder strokeBuilder = Stroke.builder()
.capStyle(Stroke.CapStyle.valueOf(settings.get("capstyie", "Cap"))) .capStyle(Stroke.CapStyle.valueOf(settings.get("capstyie", "cap").toUpperCase(Locale.ROOT)))
.joinStyle(Stroke.JoinStyle.valueOf(settings.get("joinstyle", "Miter"))) .joinStyle(Stroke.JoinStyle.valueOf(settings.get("joinstyle", "miter").toUpperCase(Locale.ROOT)))
.lineWidth(settings.getAsFloat("linewidth", 1f)); .lineWidth(settings.getAsFloat("linewidth", 1f));
if (settings.containsSetting("dash")) { if (settings.containsSetting("dash")) {
strokeBuilder.dashPattern(new Stroke.DashPattern(settings.getAsFloat("dash", 1f))); strokeBuilder.dashPattern(new Stroke.DashPattern(settings.getAsFloat("dash", 1f)));

View file

@ -9,23 +9,32 @@ import org.xbib.graphics.pdfbox.layout.text.Position;
import org.xbib.settings.Settings; import org.xbib.settings.Settings;
import java.io.IOException; import java.io.IOException;
import java.util.Locale;
public class ImageCommand implements Command { public class ImageCommand implements Command {
@Override @Override
public void execute(Engine engine, State state, Settings settings) throws IOException { public void execute(Engine engine, State state, Settings settings) throws IOException {
ImageElement element = new ImageElement(settings.get("value")); ImageElement imageElement = new ImageElement(settings.get("value"));
if (settings.containsSetting("x") && settings.containsSetting("y")) { if (settings.containsSetting("x") && settings.containsSetting("y")) {
element.setAbsolutePosition(new Position(settings.getAsFloat("x", 0f), settings.getAsFloat("y", 0f))); imageElement.setAbsolutePosition(new Position(settings.getAsFloat("x", 0f), settings.getAsFloat("y", 0f)));
} }
if (settings.containsSetting("width")) { if (settings.containsSetting("width")) {
element.setWidth(settings.getAsFloat("width", element.getWidth())); imageElement.setWidth(settings.getAsFloat("width", imageElement.getWidth()));
} }
if (settings.containsSetting("height")) { if (settings.containsSetting("height")) {
element.setWidth(settings.getAsFloat("height", element.getHeight())); imageElement.setWidth(settings.getAsFloat("height", imageElement.getHeight()));
} }
if (settings.containsSetting("scale")) { if (settings.containsSetting("scale")) {
element.setScale(settings.getAsFloat("scale", element.getScale())); imageElement.setScale(settings.getAsFloat("scale", imageElement.getScale()));
} }
state.documents.peek().add(element, new VerticalLayoutHint(Alignment.LEFT, 10, 10, 10, 10, true)); 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.documents.peek().add(imageElement, verticalLayoutHint);
} }
} }

View file

@ -0,0 +1,17 @@
package org.xbib.graphics.pdfbox.layout.script.command;
import org.xbib.graphics.pdfbox.layout.elements.PositionControl;
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;
public class MarkpositionCommand implements Command {
@Override
public void execute(Engine engine, State state, Settings settings) throws IOException {
PositionControl.MarkPosition markPosition = PositionControl.createMarkPosition();
state.documents.peek().add(markPosition);
}
}

View file

@ -0,0 +1,17 @@
package org.xbib.graphics.pdfbox.layout.script.command;
import org.xbib.graphics.pdfbox.layout.elements.PositionControl;
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;
public class MovepositionCommand implements Command {
@Override
public void execute(Engine engine, State state, Settings settings) throws IOException {
PositionControl.MovePosition movePosition = PositionControl.createMovePosition(settings.getAsFloat("x", null), settings.getAsFloat("y", null));
state.documents.peek().add(movePosition);
}
}

View file

@ -0,0 +1,16 @@
package org.xbib.graphics.pdfbox.layout.script.command;
import org.xbib.graphics.pdfbox.layout.elements.ControlElement;
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;
public class NewcolumnCommand implements Command {
@Override
public void execute(Engine engine, State state, Settings settings) throws IOException {
ControlElement controlElement = ControlElement.NEWCOLUMN;
state.documents.peek().add(controlElement);
}
}

View file

@ -0,0 +1,16 @@
package org.xbib.graphics.pdfbox.layout.script.command;
import org.xbib.graphics.pdfbox.layout.elements.ControlElement;
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;
public class NewpageCommand implements Command {
@Override
public void execute(Engine engine, State state, Settings settings) throws IOException {
ControlElement controlElement = ControlElement.NEWPAGE;
state.documents.peek().add(controlElement);
}
}

View file

@ -3,10 +3,12 @@ package org.xbib.graphics.pdfbox.layout.script.command;
import org.xbib.graphics.pdfbox.layout.elements.Paragraph; import org.xbib.graphics.pdfbox.layout.elements.Paragraph;
import org.xbib.graphics.pdfbox.layout.script.Engine; import org.xbib.graphics.pdfbox.layout.script.Engine;
import org.xbib.graphics.pdfbox.layout.script.State; 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.graphics.pdfbox.layout.text.Position;
import org.xbib.settings.Settings; import org.xbib.settings.Settings;
import java.io.IOException; import java.io.IOException;
import java.util.Locale;
public class ParagraphCommand implements Command { public class ParagraphCommand implements Command {
@ -20,6 +22,9 @@ public class ParagraphCommand implements Command {
if (settings.containsSetting("width")) { if (settings.containsSetting("width")) {
paragraph.setMaxWidth(settings.getAsFloat("width", state.documents.peek().getPageWidth())); paragraph.setMaxWidth(settings.getAsFloat("width", state.documents.peek().getPageWidth()));
} }
if (settings.containsSetting("alignment")) {
paragraph.setAlignment(Alignment.valueOf(settings.get("alignment", "left").toUpperCase(Locale.ROOT)));
}
state.documents.peek().add(paragraph); state.documents.peek().add(paragraph);
engine.executeElements(settings); engine.executeElements(settings);
} }

View file

@ -12,6 +12,7 @@ import org.xbib.settings.Settings;
import java.awt.Color; import java.awt.Color;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Locale;
public class PathCommand implements Command { public class PathCommand implements Command {
@ -39,8 +40,8 @@ public class PathCommand implements Command {
} }
Path path = new Path(list); Path path = new Path(list);
Stroke.StrokeBuilder strokeBuilder = Stroke.builder() Stroke.StrokeBuilder strokeBuilder = Stroke.builder()
.capStyle(Stroke.CapStyle.valueOf(settings.get("capstyie", "Cap"))) .capStyle(Stroke.CapStyle.valueOf(settings.get("capstyie", "cap").toUpperCase(Locale.ROOT)))
.joinStyle(Stroke.JoinStyle.valueOf(settings.get("joinstyle", "Miter"))) .joinStyle(Stroke.JoinStyle.valueOf(settings.get("joinstyle", "miter").toUpperCase(Locale.ROOT)))
.lineWidth(settings.getAsFloat("linewidth", 1f)); .lineWidth(settings.getAsFloat("linewidth", 1f));
if (settings.containsSetting("dash")) { if (settings.containsSetting("dash")) {
strokeBuilder.dashPattern(new Stroke.DashPattern(settings.getAsFloat("dash", 1f))); strokeBuilder.dashPattern(new Stroke.DashPattern(settings.getAsFloat("dash", 1f)));

View file

@ -0,0 +1,17 @@
package org.xbib.graphics.pdfbox.layout.script.command;
import org.xbib.graphics.pdfbox.layout.elements.PositionControl;
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;
public class ResetpositionCommand implements Command {
@Override
public void execute(Engine engine, State state, Settings settings) throws IOException {
PositionControl.ResetPosition resetPosition = PositionControl.createResetPosition();
state.documents.peek().add(resetPosition);
}
}

View file

@ -0,0 +1,21 @@
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.graphics.pdfbox.layout.table.Row;
import org.xbib.settings.Settings;
import java.io.IOException;
public class RowCommand implements Command {
@Override
public void execute(Engine engine, State state, Settings settings) throws IOException {
Row.Builder row = Row.builder();
row.padding(settings.getAsFloat("padding", 0f));
state.rows.push(row);
engine.executeElements(settings);
state.tables.peek().add(row.build());
}
}

View file

@ -0,0 +1,17 @@
package org.xbib.graphics.pdfbox.layout.script.command;
import org.xbib.graphics.pdfbox.layout.elements.PositionControl;
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;
public class SetpositionCommand implements Command {
@Override
public void execute(Engine engine, State state, Settings settings) throws IOException {
PositionControl.SetPosition setPosition = PositionControl.createSetPosition(settings.getAsFloat("x", null), settings.getAsFloat("y", null));
state.documents.peek().add(setPosition);
}
}

View file

@ -0,0 +1,26 @@
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.settings.Settings;
import java.io.IOException;
public class TableCommand implements Command {
@Override
public void execute(Engine engine, State state, Settings settings) throws IOException {
state.rows.clear();
TableElement tableElement = new TableElement();
if (settings.containsSetting("columnwidths")) {
String columnWidths = settings.get("columnwidths");
for (String columnWidth : columnWidths.split(" ")) {
tableElement.addColumnOfWidth(Float.parseFloat(columnWidth));
}
}
state.documents.peek().add(tableElement);
state.tables.push(tableElement);
engine.executeElements(settings);
}
}

View file

@ -6,13 +6,15 @@ import org.xbib.graphics.pdfbox.layout.script.Engine;
import org.xbib.graphics.pdfbox.layout.script.State; import org.xbib.graphics.pdfbox.layout.script.State;
import org.xbib.settings.Settings; import org.xbib.settings.Settings;
import java.util.Locale;
public class TextCommand implements Command { public class TextCommand implements Command {
@Override @Override
public void execute(Engine engine, State state, Settings settings) { public void execute(Engine engine, State state, Settings settings) {
String value = settings.get("value"); String value = settings.get("value");
float size = settings.getAsFloat("size", 11.0f); float size = settings.getAsFloat("size", 11.0f);
Font font = Fonts.valueOf(settings.get("font", "HELVETICA")).getFont(state.documents.peek()); Font font = Fonts.valueOf(settings.get("font", "helvetica").toUpperCase(Locale.ROOT)).getFont(state.documents.peek());
state.paragraphs.peek().addMarkup(value, size, font); state.paragraphs.peek().addMarkup(value, size, font);
} }
} }

View file

@ -0,0 +1,16 @@
package org.xbib.graphics.pdfbox.layout.script.command;
import org.xbib.graphics.pdfbox.layout.elements.VerticalSpacer;
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;
public class VerticalspacerCommand implements Command {
@Override
public void execute(Engine engine, State state, Settings settings) throws IOException {
VerticalSpacer verticalSpacer = new VerticalSpacer(settings.getAsFloat("height", 0f));
state.documents.peek().add(verticalSpacer);
}
}

View file

@ -13,7 +13,8 @@ public class Stroke {
*/ */
public enum CapStyle { public enum CapStyle {
Cap(0), RoundCap(1), Square(2); CAP(0),
ROUND_CAP(1), Square(2);
private final int value; private final int value;
@ -31,7 +32,9 @@ public class Stroke {
*/ */
public enum JoinStyle { public enum JoinStyle {
Miter(0), Round(1), Bevel(2); MITER(0),
ROUND(1),
BEVEL(2);
private final int value; private final int value;
@ -103,7 +106,6 @@ public class Stroke {
public float getPhase() { public float getPhase() {
return phase; return phase;
} }
} }
private final CapStyle capStyle; private final CapStyle capStyle;
@ -116,7 +118,7 @@ public class Stroke {
/** /**
* Creates a Stroke with line width 1, cap style * Creates a Stroke with line width 1, cap style
* {@link CapStyle#Cap}, join style {@link JoinStyle#Miter}, and no dash * {@link CapStyle#CAP}, join style {@link JoinStyle#MITER}, and no dash
* pattern. * pattern.
*/ */
public Stroke() { public Stroke() {
@ -125,13 +127,13 @@ public class Stroke {
/** /**
* Creates a Stroke with the given line width, cap style * Creates a Stroke with the given line width, cap style
* {@link CapStyle#Cap}, join style {@link JoinStyle#Miter}, and no dash * {@link CapStyle#CAP}, join style {@link JoinStyle#MITER}, and no dash
* pattern. * pattern.
* *
* @param lineWidth the line width. * @param lineWidth the line width.
*/ */
public Stroke(float lineWidth) { public Stroke(float lineWidth) {
this(CapStyle.Cap, JoinStyle.Miter, null, lineWidth); this(CapStyle.CAP, JoinStyle.MITER, null, lineWidth);
} }
/** /**
@ -199,9 +201,9 @@ public class Stroke {
*/ */
public static class StrokeBuilder { public static class StrokeBuilder {
private CapStyle capStyle = CapStyle.Cap; private CapStyle capStyle = CapStyle.CAP;
private JoinStyle joinStyle = JoinStyle.Miter; private JoinStyle joinStyle = JoinStyle.MITER;
private DashPattern dashPattern; private DashPattern dashPattern;

View file

@ -15,7 +15,7 @@ public abstract class AbstractTextCell extends AbstractCell {
return parameters.getFont(); return parameters.getFont();
} }
public Integer getFontSize() { public Float getFontSize() {
return parameters.getFontSize(); return parameters.getFontSize();
} }

View file

@ -1,27 +1,15 @@
package org.xbib.graphics.pdfbox.layout.table; package org.xbib.graphics.pdfbox.layout.table;
import org.xbib.graphics.pdfbox.layout.elements.Paragraph; import org.xbib.graphics.pdfbox.layout.elements.Paragraph;
import org.xbib.graphics.pdfbox.layout.font.BaseFont; import org.xbib.graphics.pdfbox.layout.font.Font;
import java.io.IOException; import java.io.IOException;
import java.util.EnumMap;
import java.util.Map;
public class Markup implements ParagraphProcessor { public class Markup implements ParagraphProcessor {
public enum MarkupSupportedFont {
TIMES, COURIER, HELVETICA
}
public static final Map<MarkupSupportedFont, BaseFont> FONT_MAP = new EnumMap<>(Markup.MarkupSupportedFont.class);
static {
FONT_MAP.put(Markup.MarkupSupportedFont.HELVETICA, BaseFont.HELVETICA);
FONT_MAP.put(Markup.MarkupSupportedFont.COURIER, BaseFont.COURIER);
FONT_MAP.put(Markup.MarkupSupportedFont.TIMES, BaseFont.TIMES);
}
private String markup; private String markup;
private MarkupSupportedFont font; private Font font;
private Float fontSize; private Float fontSize;
@ -33,11 +21,11 @@ public class Markup implements ParagraphProcessor {
return markup; return markup;
} }
public void setFont(MarkupSupportedFont font) { public void setFont(Font font) {
this.font = font; this.font = font;
} }
public MarkupSupportedFont getFont() { public Font getFont() {
return font; return font;
} }
@ -50,9 +38,9 @@ public class Markup implements ParagraphProcessor {
} }
@Override @Override
public void process(Paragraph paragraph, Parameters parameters) throws IOException { public void process(Paragraph paragraph, Parameters parameters) {
float fontSize = getFontSize() != null ? getFontSize() : parameters.getFontSize(); float fontSize = getFontSize() != null ? getFontSize() : parameters.getFontSize();
paragraph.addMarkup(getMarkup(), fontSize, FONT_MAP.get(getFont())); paragraph.addMarkup(getMarkup(), fontSize, font);
} }
} }

View file

@ -7,7 +7,7 @@ public class Parameters {
private Font font; private Font font;
private Integer fontSize; private Float fontSize;
private Color textColor; private Color textColor;
@ -133,7 +133,7 @@ public class Parameters {
return horizontalAlignment; return horizontalAlignment;
} }
public Integer getFontSize() { public Float getFontSize() {
return fontSize; return fontSize;
} }
@ -189,7 +189,7 @@ public class Parameters {
this.font = font; this.font = font;
} }
public void setFontSize(Integer fontSize) { public void setFontSize(Float fontSize) {
this.fontSize = fontSize; this.fontSize = fontSize;
} }

View file

@ -22,16 +22,15 @@ public class Row {
private Row next; private Row next;
private Row(final List<AbstractCell> cells) { private Row(List<AbstractCell> cells) {
super();
this.cells = cells; this.cells = cells;
} }
public void setSettings(Parameters parameters) { public void setParameters(Parameters parameters) {
this.parameters = parameters; this.parameters = parameters;
} }
public Parameters getSettings() { public Parameters getParameters() {
return parameters; return parameters;
} }
@ -71,7 +70,6 @@ public class Row {
if (table == null) { if (table == null) {
throw new TableNotYetBuiltException(); throw new TableNotYetBuiltException();
} }
if (height == null) { if (height == null) {
this.height = getCells().stream() this.height = getCells().stream()
.filter(cell -> cell.getRowSpan() == 1) .filter(cell -> cell.getRowSpan() == 1)
@ -79,12 +77,11 @@ public class Row {
.max(naturalOrder()) .max(naturalOrder())
.orElse(DEFAULT_HEIGHT); .orElse(DEFAULT_HEIGHT);
} }
return height; return height;
} }
void doRowSpanSizeAdaption(float heightOfHighestCell, float rowsHeight) { void doRowSpanSizeAdaption(float heightOfHighestCell, float rowsHeight) {
final float rowSpanSizeDifference = heightOfHighestCell - rowsHeight; float rowSpanSizeDifference = heightOfHighestCell - rowsHeight;
this.height += (this.height / (heightOfHighestCell - rowSpanSizeDifference)) * rowSpanSizeDifference; this.height += (this.height / (heightOfHighestCell - rowSpanSizeDifference)) * rowSpanSizeDifference;
} }
@ -111,7 +108,7 @@ public class Row {
return this; return this;
} }
public Builder fontSize(final Integer fontSize) { public Builder fontSize(float fontSize) {
parameters.setFontSize(fontSize); parameters.setFontSize(fontSize);
return this; return this;
} }
@ -172,8 +169,7 @@ public class Row {
public Row build() { public Row build() {
final Row row = new Row(cells); final Row row = new Row(cells);
row.setSettings(parameters); row.setParameters(parameters);
//row.setHeight(height);
return row; return row;
} }
} }

View file

@ -16,7 +16,7 @@ public class Table {
private static final Font DEFAULT_FONT = BaseFont.HELVETICA; private static final Font DEFAULT_FONT = BaseFont.HELVETICA;
private static final int DEFAULT_FONT_SIZE = 12; private static final Float DEFAULT_FONT_SIZE = 11f;
private static final Color DEFAULT_TEXT_COLOR = Color.BLACK; private static final Color DEFAULT_TEXT_COLOR = Color.BLACK;
@ -84,7 +84,7 @@ public class Table {
return DEFAULT_HORIZONTAL_ALIGNMENT; return DEFAULT_HORIZONTAL_ALIGNMENT;
} }
public static int getDefaultFontSize() { public static float getDefaultFontSize() {
return DEFAULT_FONT_SIZE; return DEFAULT_FONT_SIZE;
} }
@ -216,7 +216,7 @@ public class Table {
return this; return this;
} }
public Builder addColumnOfWidth(final float width) { public Builder addColumnOfWidth(float width) {
Column column = new Column(width); Column column = new Column(width);
numberOfColumns++; numberOfColumns++;
columns.add(column); columns.add(column);
@ -229,17 +229,17 @@ public class Table {
return this; return this;
} }
public Builder fontSize(final Integer fontSize) { public Builder fontSize(Float fontSize) {
parameters.setFontSize(fontSize); parameters.setFontSize(fontSize);
return this; return this;
} }
public Builder textColor(final Color textColor) { public Builder textColor(Color textColor) {
parameters.setTextColor(textColor); parameters.setTextColor(textColor);
return this; return this;
} }
public Builder backgroundColor(final Color backgroundColor) { public Builder backgroundColor(Color backgroundColor) {
parameters.setBackgroundColor(backgroundColor); parameters.setBackgroundColor(backgroundColor);
return this; return this;
} }
@ -307,11 +307,11 @@ public class Table {
Row row = rows.get(rowIndex); Row row = rows.get(rowIndex);
row.setTable(table); row.setTable(table);
if (table.getSettings() != null) { if (table.getSettings() != null) {
row.getSettings().fillingMergeBy(table.getSettings()); row.getParameters().fillingMergeBy(table.getSettings());
} }
int columnIndex = 0; int columnIndex = 0;
for (AbstractCell cell : row.getCells()) { for (AbstractCell cell : row.getCells()) {
cell.getParameters().fillingMergeBy(row.getSettings()); cell.getParameters().fillingMergeBy(row.getParameters());
cell.setRow(row); cell.setRow(row);
while (table.isRowSpanAt(rowIndex, columnIndex)) { while (table.isRowSpanAt(rowIndex, columnIndex)) {
columnIndex++; columnIndex++;

View file

@ -21,6 +21,8 @@ public class TableRenderer {
protected final Table table; protected final Table table;
protected PDDocument pdDocument;
protected PDPageContentStream contentStream; protected PDPageContentStream contentStream;
protected PDPage page; protected PDPage page;
@ -63,6 +65,10 @@ public class TableRenderer {
this.endY = endY; this.endY = endY;
} }
public void setDocument(PDDocument pdDocument) {
this.pdDocument = pdDocument;
}
public void setContentStream(PDPageContentStream contentStream) { public void setContentStream(PDPageContentStream contentStream) {
this.contentStream = contentStream; this.contentStream = contentStream;
} }
@ -161,7 +167,7 @@ public class TableRenderer {
x += table.getColumns().get(columnCounter).getWidth(); x += table.getColumns().get(columnCounter).getWidth();
columnCounter++; columnCounter++;
} }
consumer.accept(cell.getDrawer(), new RenderContext(contentStream, page, new Point2D.Float(x, start.y))); consumer.accept(cell.getDrawer(), new RenderContext(pdDocument, contentStream, page, new Point2D.Float(x, start.y)));
x += cell.getWidth(); x += cell.getWidth();
columnCounter += cell.getColSpan(); columnCounter += cell.getColSpan();
} }
@ -186,6 +192,8 @@ public class TableRenderer {
private Table table; private Table table;
private PDDocument pdDocument;
private PDPageContentStream contentStream; private PDPageContentStream contentStream;
private float startX; private float startX;
@ -202,6 +210,11 @@ public class TableRenderer {
return this; return this;
} }
public Builder document(PDDocument document) {
this.pdDocument = document;
return this;
}
public Builder contentStream(PDPageContentStream contentStream) { public Builder contentStream(PDPageContentStream contentStream) {
this.contentStream = contentStream; this.contentStream = contentStream;
return this; return this;
@ -224,6 +237,7 @@ public class TableRenderer {
public TableRenderer build() { public TableRenderer build() {
TableRenderer tableRenderer = new TableRenderer(table); TableRenderer tableRenderer = new TableRenderer(table);
tableRenderer.setDocument(pdDocument);
tableRenderer.setContentStream(contentStream); tableRenderer.setContentStream(contentStream);
tableRenderer.setStartX(startX); tableRenderer.setStartX(startX);
tableRenderer.setStartY(startY); tableRenderer.setStartY(startY);

View file

@ -50,7 +50,7 @@ public class TextCell extends AbstractTextCell {
return this; return this;
} }
public Builder fontSize(Integer fontSize) { public Builder fontSize(Float fontSize) {
parameters.setFontSize(fontSize); parameters.setFontSize(fontSize);
return this; return this;
} }

View file

@ -47,7 +47,7 @@ public abstract class AbstractCellRenderer<T extends AbstractCell> implements Re
? start.y + rowHeight - cell.getHeight() ? start.y + rowHeight - cell.getHeight()
: start.y; : start.y;
final Color cellBorderColor = cell.getBorderColor(); final Color cellBorderColor = cell.getBorderColor();
final Color rowBorderColor = cell.getRow().getSettings().getBorderColor(); final Color rowBorderColor = cell.getRow().getParameters().getBorderColor();
if (cell.hasBorderTop() || cell.hasBorderBottom()) { if (cell.hasBorderTop() || cell.hasBorderBottom()) {
final float correctionLeft = cell.getBorderWidthLeft() / 2; final float correctionLeft = cell.getBorderWidthLeft() / 2;
final float correctionRight = cell.getBorderWidthRight() / 2; final float correctionRight = cell.getBorderWidthRight() / 2;

View file

@ -63,7 +63,7 @@ public class ParagraphCellRenderer extends AbstractCellRenderer<ParagraphCell> {
return new AnnotationDrawListener(new DrawContext() { return new AnnotationDrawListener(new DrawContext() {
@Override @Override
public PDDocument getPdDocument() { public PDDocument getPdDocument() {
return null; return renderContext.getPdDocument();
} }
@Override @Override

View file

@ -14,11 +14,11 @@ public class PositionedStyledText {
private final Font font; private final Font font;
private final int fontSize; private final float fontSize;
private final Color color; private final Color color;
public PositionedStyledText(float x, float y, String text, Font font, int fontSize, Color color) { public PositionedStyledText(float x, float y, String text, Font font, float fontSize, Color color) {
this.x = x; this.x = x;
this.y = y; this.y = y;
this.text = text; this.text = text;
@ -43,7 +43,7 @@ public class PositionedStyledText {
return font; return font;
} }
public int getFontSize() { public float getFontSize() {
return fontSize; return fontSize;
} }

View file

@ -1,5 +1,6 @@
package org.xbib.graphics.pdfbox.layout.table.render; 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.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream; import org.apache.pdfbox.pdmodel.PDPageContentStream;
@ -7,18 +8,25 @@ import java.awt.geom.Point2D;
public class RenderContext { public class RenderContext {
private final PDDocument pdDocument;
private final PDPageContentStream contentStream; private final PDPageContentStream contentStream;
private final PDPage page; private final PDPage page;
private final Point2D.Float startingPoint; private final Point2D.Float startingPoint;
public RenderContext(PDPageContentStream contentStream, PDPage page, Point2D.Float startingPoint) { public RenderContext(PDDocument pdDocument, PDPageContentStream contentStream, PDPage page, Point2D.Float startingPoint) {
this.pdDocument = pdDocument;
this.contentStream = contentStream; this.contentStream = contentStream;
this.page = page; this.page = page;
this.startingPoint = startingPoint; this.startingPoint = startingPoint;
} }
public PDDocument getPdDocument() {
return pdDocument;
}
public PDPageContentStream getContentStream() { public PDPageContentStream getContentStream() {
return contentStream; return contentStream;
} }

View file

@ -23,7 +23,7 @@ public class TextCellRenderer<T extends AbstractTextCell> extends AbstractCellRe
public void renderContent(RenderContext renderContext) { public void renderContent(RenderContext renderContext) {
float startX = renderContext.getStartingPoint().x; float startX = renderContext.getStartingPoint().x;
Font currentFont = cell.getFont(); Font currentFont = cell.getFont();
int currentFontSize = cell.getFontSize(); float currentFontSize = cell.getFontSize();
Color currentTextColor = cell.getTextColor(); Color currentTextColor = cell.getTextColor();
float yOffset = renderContext.getStartingPoint().y + getAdaptionForVerticalAlignment(); float yOffset = renderContext.getStartingPoint().y + getAdaptionForVerticalAlignment();
float xOffset = startX + cell.getPaddingLeft(); float xOffset = startX + cell.getPaddingLeft();
@ -55,7 +55,7 @@ public class TextCellRenderer<T extends AbstractTextCell> extends AbstractCellRe
} }
private float calculateYOffset(Font currentFont, int currentFontSize, int lineIndex) { private float calculateYOffset(Font currentFont, float currentFontSize, int lineIndex) {
return PdfUtil.getFontHeight(currentFont, currentFontSize) + return PdfUtil.getFontHeight(currentFont, currentFontSize) +
(lineIndex > 0 ? PdfUtil.getFontHeight(currentFont, currentFontSize) * cell.getLineSpacing() : 0f); (lineIndex > 0 ? PdfUtil.getFontHeight(currentFont, currentFontSize) * cell.getLineSpacing() : 0f);
} }
@ -76,7 +76,7 @@ public class TextCellRenderer<T extends AbstractTextCell> extends AbstractCellRe
return charSpacing; return charSpacing;
} }
protected List<String> calculateAndGetLines(Font currentFont, int currentFontSize, float maxWidth) { protected List<String> calculateAndGetLines(Font currentFont, float currentFontSize, float maxWidth) {
return cell.isWordBreak() return cell.isWordBreak()
? PdfUtil.getOptimalTextBreakLines(cell.getText(), currentFont, currentFontSize, maxWidth) ? PdfUtil.getOptimalTextBreakLines(cell.getText(), currentFont, currentFontSize, maxWidth)
: Collections.singletonList(cell.getText()); : Collections.singletonList(cell.getText());

View file

@ -25,11 +25,11 @@ public class VerticalTextCellRenderer extends AbstractCellRenderer<VerticalTextC
@Override @Override
public void renderContent(RenderContext renderContext) { public void renderContent(RenderContext renderContext) {
final float startX = renderContext.getStartingPoint().x; float startX = renderContext.getStartingPoint().x;
final float startY = renderContext.getStartingPoint().y; float startY = renderContext.getStartingPoint().y;
final Font currentFont = cell.getFont(); Font currentFont = cell.getFont();
final int currentFontSize = cell.getFontSize(); float currentFontSize = cell.getFontSize();
final Color currentTextColor = cell.getTextColor(); Color currentTextColor = cell.getTextColor();
float yOffset = startY + cell.getPaddingBottom(); float yOffset = startY + cell.getPaddingBottom();
float height = cell.getRow().getHeight(); float height = cell.getRow().getHeight();
if (cell.getRowSpan() > 1) { if (cell.getRowSpan() > 1) {
@ -54,7 +54,7 @@ public class VerticalTextCellRenderer extends AbstractCellRenderer<VerticalTextC
return 0; return 0;
} }
protected void drawText(String text, Font font, int fontSize, Color color, float x, float y, PDPageContentStream contentStream) { protected void drawText(String text, Font font, float fontSize, Color color, float x, float y, PDPageContentStream contentStream) {
try { try {
// Rotate by 90 degrees counter clockwise // Rotate by 90 degrees counter clockwise
AffineTransform transform = AffineTransform.getTranslateInstance(x, y); AffineTransform transform = AffineTransform.getTranslateInstance(x, y);

View file

@ -82,12 +82,12 @@ public class Indent extends ControlFragment {
Alignment alignment, Alignment alignment,
Color color) { Color color) {
super("INDENT", label, fontDescriptor, color); super("INDENT", label, fontDescriptor, color);
if (label == null) {
return;
}
try { try {
float indent = calculateIndent(indentWidth, indentUnit, fontDescriptor); float indent = calculateIndent(indentWidth, indentUnit, fontDescriptor);
float textWidth = 0; float textWidth = fontDescriptor.getSize() * fontDescriptor.getSelectedFont().getStringWidth(label) / 1000f;
if (label != null && !label.isEmpty()) {
textWidth = fontDescriptor.getSize() * fontDescriptor.getSelectedFont().getStringWidth(label) / 1000f;
}
float marginLeft = 0; float marginLeft = 0;
float marginRight = 0; float marginRight = 0;
if (textWidth < indent) { if (textWidth < indent) {
@ -117,8 +117,7 @@ public class Indent extends ControlFragment {
*/ */
public Indent(final float indentPt) { public Indent(final float indentPt) {
super("", DEFAULT_FONT_DESCRIPTOR); super("", DEFAULT_FONT_DESCRIPTOR);
styledText = new StyledText("", getFontDescriptor(), getColor(), 0, styledText = new StyledText("", getFontDescriptor(), getColor(), 0, indentPt, 0);
indentPt, 0);
} }
private float calculateIndent(float indentWidth, SpaceUnit indentUnit, final FontDescriptor fontDescriptor) private float calculateIndent(float indentWidth, SpaceUnit indentUnit, final FontDescriptor fontDescriptor)

View file

@ -1,7 +1,11 @@
package org.xbib.graphics.pdfbox.layout.boxable; package org.xbib.graphics.pdfbox.layout.util;
import org.apache.pdfbox.pdmodel.PDPageContentStream; import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDFont; import org.apache.pdfbox.pdmodel.font.PDFont;
import org.xbib.graphics.pdfbox.layout.boxable.FontUtils;
import org.xbib.graphics.pdfbox.layout.boxable.LineStyle;
import org.xbib.graphics.pdfbox.layout.boxable.PageContentStreamOptimized;
import java.awt.Color; import java.awt.Color;
import java.io.IOException; import java.io.IOException;

View file

@ -27,7 +27,7 @@ public final class PdfUtil {
* @param fontSize FontSize of String * @param fontSize FontSize of String
* @return Width (in points) * @return Width (in points)
*/ */
public static float getStringWidth(String text, Font font, int fontSize) { public static float getStringWidth(String text, Font font, float fontSize) {
return Arrays.stream(text.split(NEW_LINE_REGEX)) return Arrays.stream(text.split(NEW_LINE_REGEX))
.max(Comparator.comparing(String::length)) .max(Comparator.comparing(String::length))
.map(x -> { .map(x -> {
@ -40,7 +40,7 @@ public final class PdfUtil {
.orElseThrow(CouldNotDetermineStringWidthException::new); .orElseThrow(CouldNotDetermineStringWidthException::new);
} }
private static float getWidthOfStringWithoutNewlines(String text, Font font, int fontSize) throws IOException { private static float getWidthOfStringWithoutNewlines(String text, Font font, float fontSize) throws IOException {
List<String> codePointsAsString = text.codePoints() List<String> codePointsAsString = text.codePoints()
.mapToObj(codePoint -> new String(new int[]{codePoint}, 0, 1)) .mapToObj(codePoint -> new String(new int[]{codePoint}, 0, 1))
.collect(Collectors.toList()); .collect(Collectors.toList());
@ -62,7 +62,7 @@ public final class PdfUtil {
* @param fontSize FontSize * @param fontSize FontSize
* @return Height of font * @return Height of font
*/ */
public static float getFontHeight(Font font, int fontSize) { public static float getFontHeight(Font font, float fontSize) {
return font.getRegularFont().getFontDescriptor().getCapHeight() * fontSize / 1000F; return font.getRegularFont().getFontDescriptor().getCapHeight() * fontSize / 1000F;
} }
@ -75,7 +75,7 @@ public final class PdfUtil {
* @param maxWidth Maximal width of resulting text-lines * @param maxWidth Maximal width of resulting text-lines
* @return A list of lines, where all are smaller than maxWidth * @return A list of lines, where all are smaller than maxWidth
*/ */
public static List<String> getOptimalTextBreakLines(String text, Font font, int fontSize, float maxWidth) { public static List<String> getOptimalTextBreakLines(String text, Font font, float fontSize, float maxWidth) {
List<String> result = new ArrayList<>(); List<String> result = new ArrayList<>();
for (String line : text.split(NEW_LINE_REGEX)) { for (String line : text.split(NEW_LINE_REGEX)) {
if (PdfUtil.doesTextLineFit(line, font, fontSize, maxWidth)) { if (PdfUtil.doesTextLineFit(line, font, fontSize, maxWidth)) {
@ -87,7 +87,7 @@ public final class PdfUtil {
return result; return result;
} }
private static List<String> wrapLine(String line, Font font, int fontSize, float maxWidth) { private static List<String> wrapLine(String line, Font font, float fontSize, float maxWidth) {
if (doesTextLineFit(line, font, fontSize, maxWidth)) { if (doesTextLineFit(line, font, fontSize, maxWidth)) {
return Collections.singletonList(line); return Collections.singletonList(line);
} }
@ -101,7 +101,7 @@ public final class PdfUtil {
return goodLines; return goodLines;
} }
private static List<String> splitBySize(String line, Font font, int fontSize, float maxWidth) { private static List<String> splitBySize(String line, Font font, float fontSize, float maxWidth) {
List<String> returnList = new ArrayList<>(); List<String> returnList = new ArrayList<>();
for (int i = line.length() - 1; i > 0; i--) { for (int i = line.length() - 1; i > 0; i--) {
String fittedNewLine = line.substring(0, i) + "-"; String fittedNewLine = line.substring(0, i) + "-";
@ -115,10 +115,7 @@ public final class PdfUtil {
return returnList; return returnList;
} }
private static String buildALine(Stack<String> words, private static String buildALine(Stack<String> words, Font font, float fontSize, float maxWidth) {
Font font,
int fontSize,
float maxWidth) {
StringBuilder line = new StringBuilder(); StringBuilder line = new StringBuilder();
float width = 0; float width = 0;
while (!words.empty()) { while (!words.empty()) {
@ -142,7 +139,7 @@ public final class PdfUtil {
return line.toString().trim(); return line.toString().trim();
} }
private static boolean doesTextLineFit(String textLine, Font font, int fontSize, float maxWidth) { private static boolean doesTextLineFit(String textLine, Font font, float fontSize, float maxWidth) {
return doesTextLineFit(PdfUtil.getStringWidth(textLine, font, fontSize), maxWidth); return doesTextLineFit(PdfUtil.getStringWidth(textLine, font, fontSize), maxWidth);
} }

View file

@ -83,7 +83,7 @@ public class CustomRendererTest {
sectionNumber = ((Section) element).getNumber(); sectionNumber = ((Section) element).getNumber();
renderContext.render(renderContext, element, layoutHint); renderContext.render(renderContext, element, layoutHint);
Element ruler = new HorizontalRuler(Stroke.builder().lineWidth(2) Element ruler = new HorizontalRuler(Stroke.builder().lineWidth(2)
.capStyle(CapStyle.RoundCap).build(), Color.black); .capStyle(CapStyle.ROUND_CAP).build(), Color.black);
renderContext.render(renderContext, ruler, VerticalLayoutHint.builder().marginBottom(10).build()); renderContext.render(renderContext, ruler, VerticalLayoutHint.builder().marginBottom(10).build());
return true; return true;
} }

View file

@ -1,25 +0,0 @@
package org.xbib.graphics.pdfbox.layout.test.script;
import org.junit.jupiter.api.Test;
import org.xbib.settings.Settings;
import java.util.logging.Logger;
public class ElementsTest {
@Test
public void elements() throws Exception {
Settings settings = Settings.settingsBuilder()
.loadFromResource("json", getClass().getResourceAsStream("elements.json"))
.build();
Logger.getAnonymousLogger().info(settings.getAsMap().toString());
Logger.getAnonymousLogger().info(String.valueOf(settings.containsSetting("elements")));
Logger.getAnonymousLogger().info(String.valueOf(settings.containsSetting("elements.0")));
Logger.getAnonymousLogger().info(String.valueOf(settings.containsSetting("elements.1")));
Logger.getAnonymousLogger().info(String.valueOf(settings.containsSetting("elements.2")));
Logger.getAnonymousLogger().info(settings.getAsSettings("elements").getAsMap().toString());
Logger.getAnonymousLogger().info(settings.getAsSettings("elements.0").getAsMap().toString());
Logger.getAnonymousLogger().info(settings.getAsSettings("elements.1").getAsMap().toString());
Logger.getAnonymousLogger().info(settings.getAsSettings("elements.2").getAsMap().toString());
}
}

View file

@ -16,8 +16,9 @@ public class ScriptTest {
.build(); .build();
Engine engine = new Engine(); Engine engine = new Engine();
engine.execute(settings); engine.execute(settings);
int i = 0;
for (Document document : engine.getState().getDocuments()) { for (Document document : engine.getState().getDocuments()) {
document.render().save(new FileOutputStream("build/elements.pdf")).close(); document.render().save(new FileOutputStream("build/elements" + (i++) + ".pdf")).close();
} }
engine.close(); engine.close();
} }

View file

@ -54,6 +54,7 @@ public class TableTest {
.build(); .build();
TableRenderer tableRenderer = TableRenderer.builder() TableRenderer tableRenderer = TableRenderer.builder()
.table(myTable) .table(myTable)
.document(document)
.contentStream(contentStream) .contentStream(contentStream)
.startX(20f) .startX(20f)
.startY(page.getMediaBox().getUpperRightY() - 20f) .startY(page.getMediaBox().getUpperRightY() - 20f)
@ -74,7 +75,6 @@ public class TableTest {
assertThat(table.getNumberOfColumns(), equalTo(3)); assertThat(table.getNumberOfColumns(), equalTo(3));
} }
@Test @Test
public void getWidthTableBuilderWithTwoColumns() { public void getWidthTableBuilderWithTwoColumns() {
final Table.Builder tableBuilder = Table.builder() final Table.Builder tableBuilder = Table.builder()
@ -104,7 +104,7 @@ public class TableTest {
final Table table = Table.builder() final Table table = Table.builder()
.addColumnOfWidth(12) .addColumnOfWidth(12)
.addColumnOfWidth(34) .addColumnOfWidth(34)
.fontSize(12) .fontSize(12f)
.addRow(Row.builder() .addRow(Row.builder()
.add(TextCell.builder().text("11").paddingTop(35).paddingBottom(15).build()) .add(TextCell.builder().text("11").paddingTop(35).paddingBottom(15).build())
.add(TextCell.builder().text("12").paddingTop(15).paddingBottom(25).build()) .add(TextCell.builder().text("12").paddingTop(15).paddingBottom(25).build())
@ -148,7 +148,8 @@ public class TableTest {
Table.Builder tableBuilder = Table.builder() Table.Builder tableBuilder = Table.builder()
.addColumnsOfWidth(10, 10, 10) .addColumnsOfWidth(10, 10, 10)
.horizontalAlignment(HorizontalAlignment.CENTER) .horizontalAlignment(HorizontalAlignment.CENTER)
.fontSize(10).font(BaseFont.HELVETICA) .fontSize(10f)
.font(BaseFont.HELVETICA)
.wordBreak(false); .wordBreak(false);
Row row = Row.builder() Row row = Row.builder()
.add(TextCell.builder().text("iVgebALheQlBkxtDyNDrhKv").colSpan(2).borderWidth(1).build()) .add(TextCell.builder().text("iVgebALheQlBkxtDyNDrhKv").colSpan(2).borderWidth(1).build())

View file

@ -1,6 +1,7 @@
{ {
"type": "document", "type": "document",
"margin": "10 10 10 10", "margin": "10 10 10 10",
"author": "Jörg Prante",
"elements": [ "elements": [
{ {
"type": "image", "type": "image",
@ -26,7 +27,7 @@
"type": "text", "type": "text",
"value": "Hello World", "value": "Hello World",
"size": 24, "size": 24,
"font": "HELVETICA" "font": "helvetica"
} }
] ]
}, },
@ -37,7 +38,7 @@
"type": "text", "type": "text",
"value": "Hello World", "value": "Hello World",
"size": 24, "size": 24,
"font": "HELVETICA" "font": "helvetica"
} }
] ]
}, },
@ -48,7 +49,7 @@
"type": "text", "type": "text",
"value": "Hello World", "value": "Hello World",
"size": 24, "size": 24,
"font": "HELVETICA" "font": "helvetica"
} }
] ]
}, },
@ -62,7 +63,7 @@
"type": "text", "type": "text",
"value": "Hello World", "value": "Hello World",
"size": 16, "size": 16,
"font": "NOTOSANS" "font": "notosans"
} }
] ]
}, },
@ -73,7 +74,104 @@
"type": "text", "type": "text",
"value": "Hello World", "value": "Hello World",
"size": 20, "size": 20,
"font": "NOTOSANS" "font": "notosans"
}
]
},
{
"type": "table",
"columnwidths": "50 50 50",
"elements": [
{
"type": "row",
"elements": [
{
"type": "cell",
"value": "Cell A"
},
{
"type": "cell",
"value": "Cell B"
},
{
"type": "cell",
"value": "Cell C"
}
]
},
{
"type": "row",
"elements": [
{
"type": "cell",
"value": "Cell D"
},
{
"type": "cell",
"value": "Cell E"
},
{
"type": "cell",
"value": "Cell F"
}
]
}
]
},
{
"type": "table",
"columnwidths": "80 80 80",
"elements": [
{
"type": "row",
"elements": [
{
"type": "cell",
"value": "Cell 1"
},
{
"type": "cell",
"value": "Cell 2"
},
{
"type": "cell",
"value": "Cell 3"
}
]
},
{
"type": "row",
"elements": [
{
"type": "cell",
"value": "Cell 4",
"padding": 5,
"borderwidth": 0.5
},
{
"type": "cell",
"value": "Cell 5",
"padding": 5,
"borderwidth": 0.5
},
{
"type": "cell",
"value": "Cell 6",
"padding": 5,
"borderwidth": 0.5
}
]
}
]
},
{
"type": "paragraph",
"elements": [
{
"type": "text",
"value": "Hello World",
"size": 20,
"font": "notosans"
} }
] ]
} }

View file

@ -1,57 +0,0 @@
{
"document1": {
"margin": "10 10 10 10",
"image1": {
"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=="
},
"barcode1": {
"symbol": "Code3Of9",
"value": "12345678"
},
"path1": {
"absolute": false,
"value": "10 10 100 10 100 20 10 20 10 10",
"color": "red",
"dash": 1
},
"paragraph1": {
"text1": {
"value": "Hello World",
"size": 24,
"font": "HELVETICA"
}
},
"paragraph2": {
"text1": {
"value": "Hello World",
"size": 24,
"font": "HELVETICA"
}
},
"paragraph3": {
"text1": {
"value": "Hello World",
"size": 24,
"font": "HELVETICA"
}
},
"paragraph4": {
"type": "horizontalruler"
},
"paragraph5": {
"text1": {
"value": "*Hello World*",
"size": 16,
"font": "NOTOSANS"
}
},
"paragraph6": {
"text1": {
"value": "*Hello World*",
"size": 20,
"font": "NOTOSANS"
}
}
}
}