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.PDType1Font;
import org.xbib.graphics.pdfbox.layout.util.PDStreamUtils;
import java.awt.Color;
import java.io.IOException;
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.interactive.documentnavigation.destination.PDPageXYZDestination;
import org.apache.pdfbox.pdmodel.interactive.documentnavigation.outline.PDOutlineItem;
import org.xbib.graphics.pdfbox.layout.util.PDStreamUtils;
import java.awt.Color;
import java.io.IOException;
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.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.xbib.graphics.pdfbox.layout.util.PDStreamUtils;
import java.io.IOException;
import java.util.List;
import java.util.Map;

View file

@ -6,6 +6,7 @@ package org.xbib.graphics.pdfbox.layout.elements;
public class Dimension {
private final float width;
private final 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.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.LayoutHint;
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.IOException;
import java.io.OutputStream;
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@ -23,11 +29,6 @@ import java.util.Map.Entry;
*/
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<Renderer> customRenderer = new ArrayList<>();
@ -38,11 +39,30 @@ public class Document implements Closeable, RenderListener {
private final PDDocument pdDocument;
private final PDDocumentInformation pdDocumentInformation;
/**
* Creates a Document using the {@link #DEFAULT_PAGE_FORMAT}.
* Creates a 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);
}
/**
* 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() {
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}.
*
@ -176,6 +224,7 @@ public class Document implements Closeable, RenderListener {
* @throws IOException by pdfbox
*/
public Document render() throws IOException {
pdDocument.setDocumentInformation(pdDocumentInformation);
RenderContext renderContext = new RenderContext(this, pdDocument);
for (Entry<Element, LayoutHint> entry : elements) {
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 java.util.Locale;
import java.util.Objects;
/**
* Defines the size and orientation of a page. The default is A4 portrait without margins.
*/
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,
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 A1 = new PDRectangle(Math.round(594f * MM_TO_UNITS), Math.round(841f * MM_TO_UNITS));
public static final PDRectangle Letter = new PDRectangle(215.9f * MM_TO_UNITS,
279.4f * MM_TO_UNITS);
public static final PDRectangle A2 = new PDRectangle(Math.round(420f * MM_TO_UNITS), Math.round(594f * 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;
@ -58,7 +55,7 @@ public class PageFormat implements Element {
*
* @param mediaBox the size.
*/
public PageFormat(final PDRectangle mediaBox) {
public PageFormat(PDRectangle mediaBox) {
this(mediaBox, Orientation.PORTRAIT);
}
@ -68,7 +65,7 @@ public class PageFormat implements Element {
* @param mediaBox the size.
* @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);
}
@ -84,8 +81,7 @@ public class PageFormat implements Element {
* @param marginBottom the bottom margin
*/
public PageFormat(PDRectangle mediaBox, Orientation orientation,
float marginLeft, float marginRight, float marginTop,
float marginBottom) {
float marginLeft, float marginRight, float marginTop, float marginBottom) {
this(mediaBox, orientation, 0, marginLeft, marginRight, marginTop, marginBottom);
}
@ -101,9 +97,8 @@ public class PageFormat implements Element {
* @param marginTop the top margin
* @param marginBottom the bottom margin
*/
public PageFormat(PDRectangle mediaBox, Orientation orientation,
int rotation, float marginLeft, float marginRight,
float marginTop, float marginBottom) {
public PageFormat(PDRectangle mediaBox, Orientation orientation, int rotation,
float marginLeft, float marginRight, float marginTop, float marginBottom) {
this.mediaBox = mediaBox;
this.orientation = orientation;
this.rotation = rotation;
@ -113,8 +108,6 @@ public class PageFormat implements Element {
this.marginBottom = marginBottom;
}
/**
* @return the orientation to use.
*/
@ -179,12 +172,19 @@ public class PageFormat implements Element {
}
public static class PageFormatBuilder {
private float marginLeft;
private float marginRight;
private float marginTop;
private float marginBottom;
private PDRectangle mediaBox = A4;
private Orientation orientation;
private int rotation;
protected PageFormatBuilder() {
@ -243,8 +243,7 @@ public class PageFormat implements Element {
* @param marginBottom the bottom margin to use.
* @return the builder.
*/
public PageFormatBuilder margins(float marginLeft, float marginRight,
float marginTop, float marginBottom) {
public PageFormatBuilder margins(float marginLeft, float marginRight, float marginTop, float marginBottom) {
this.marginLeft = marginLeft;
this.marginRight = marginRight;
this.marginTop = marginTop;
@ -391,7 +390,8 @@ public class PageFormat implements Element {
}
public PageFormatBuilder pageFormat(String format) {
switch (format.toLowerCase(Locale.ROOT)) {
Objects.requireNonNull(format);
switch (format.toUpperCase(Locale.ROOT)) {
case "A0" :
A0();
break;
@ -426,8 +426,7 @@ public class PageFormat implements Element {
* @return the resulting PageFormat.
*/
public PageFormat build() {
return new PageFormat(mediaBox, orientation, rotation, marginLeft,
marginRight, marginTop, marginBottom);
return new PageFormat(mediaBox, orientation, rotation, marginLeft, marginRight, marginTop, marginBottom);
}
}
}

View file

@ -2,11 +2,15 @@ package org.xbib.graphics.pdfbox.layout.elements;
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 A5_PORTRAIT = new PageFormat(PageFormat.A5, Orientation.PORTRAIT);
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 {
/**
* 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.
*
@ -21,18 +15,25 @@ public class PositionControl extends ControlElement {
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.
* 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
* be (re-)set to the marked position.
* to change only X or Y).
*
* @param newX the new X position.
* @param newY new new Y position.
* @return the created element
*/
public static SetPosition createSetPosition(final Float newX,
final Float newY) {
public static SetPosition createSetPosition(Float newX, Float 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.
* @return the created element
*/
public static MovePosition createMovePosition(final float relativeX,
final float relativeY) {
public static MovePosition createMovePosition(float relativeX, float relativeY) {
return new MovePosition(relativeX, relativeY);
}
public static class MarkPosition extends PositionControl {
private MarkPosition() {
super("MARK_POSITION");
}
}
public static class ResetPosition extends PositionControl {
private ResetPosition() {
super("RESET_POSITION");
}
}
public static class SetPosition extends PositionControl {
private final Float newX;
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));
this.newX = newX;
this.newY = newY;
@ -73,15 +83,16 @@ public class PositionControl extends ControlElement {
public Float getY() {
return newY;
}
}
public static class MovePosition extends PositionControl {
private final float relativeX;
private final float relativeY;
private MovePosition(final float relativeX, final float relativeY) {
super(String.format("SET_POSITION x:%f, y%f", relativeX, relativeY));
private MovePosition(float relativeX, float relativeY) {
super(String.format("MOVE_POSITION x:%f, y%f", relativeX, relativeY));
this.relativeX = relativeX;
this.relativeY = relativeY;
}
@ -93,11 +104,9 @@ public class PositionControl extends ControlElement {
public float getY() {
return relativeY;
}
}
private PositionControl(String name) {
super(name);
}
}

View file

@ -6,6 +6,7 @@ package org.xbib.graphics.pdfbox.layout.elements;
public class Rectangle extends Dimension {
private final float x;
private final float y;
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.MarkPosition;
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.text.DrawContext;
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() {
return markedPosition;
@ -301,23 +302,18 @@ public class RenderContext implements Renderer, Closeable, DrawContext, DrawList
setMarkedPosition(getCurrentPosition());
return true;
}
if (positionControl instanceof ResetPosition) {
currentPosition = new Position(getMarkedPosition().getX(), getMarkedPosition().getY());
}
if (positionControl instanceof SetPosition) {
SetPosition setPosition = (SetPosition) positionControl;
Float x = setPosition.getX();
if (x == null) {
x = getCurrentPosition().getX();
} else {
if (x.equals(PositionControl.MARKED_POSITION)) {
x = getMarkedPosition().getX();
}
}
Float y = setPosition.getY();
if (y == null) {
y = getCurrentPosition().getY();
} else {
if (y.equals(PositionControl.MARKED_POSITION)) {
y = getMarkedPosition().getY();
}
}
currentPosition = new Position(x, y);
return true;
@ -390,8 +386,7 @@ public class RenderContext implements Renderer, Closeable, DrawContext, DrawList
}
@Override
public void drawn(Object drawnObject, Position upperLeft, float width,
float height) {
public void drawn(Object drawnObject, Position upperLeft, float width, float height) {
updateMaxPositionOnPage(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.
*
* @param upperLeft
* @param width
* @param height
* @param upperLeft the upper left position
* @param width the width
* @param height the height
*/
protected void updateMaxPositionOnPage(Position upperLeft, float width,
float height) {
protected void updateMaxPositionOnPage(Position upperLeft, float width, float height) {
maxPositionOnPage = new Position(Math.max(maxPositionOnPage.getX(),
upperLeft.getX() + width), Math.min(maxPositionOnPage.getY(),
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.
* @throws IOException by pdfbox
*/
boolean render(RenderContext renderContext, Element element,
LayoutHint layoutHint) throws IOException;
boolean render(RenderContext renderContext, Element element, LayoutHint layoutHint) throws IOException;
}

View file

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

View file

@ -10,8 +10,10 @@ import org.xbib.graphics.pdfbox.layout.text.Position;
import org.xbib.settings.Settings;
import java.io.IOException;
import java.util.Locale;
public class BarcodeCommand implements Command {
@Override
public void execute(Engine engine, State state, Settings settings) throws IOException {
BarcodeElement element;
@ -19,7 +21,7 @@ public class BarcodeCommand implements Command {
Symbol symbol = Symbols.valueOf(settings.get("symbol")).getSymbol();
symbol.setContent(settings.get("value"));
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);
} catch (Exception 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 java.io.IOException;
import java.time.Instant;
import java.util.Locale;
public class DocumentCommand implements Command {
@Override
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[] margins = margin.split(" ");
PageFormat pageFormat = PageFormat.builder()
@ -20,9 +24,25 @@ public class DocumentCommand implements Command {
.marginTop(Float.parseFloat(margins[2]))
.marginBottom(Float.parseFloat(margins[3]))
.pageFormat(settings.get("format", "A4"))
.orientation(settings.get("orientiation", "PORTRAIT"))
.orientation(settings.get("orientiation", "portrait").toUpperCase(Locale.ROOT))
.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);
}
}

View file

@ -9,13 +9,14 @@ import org.xbib.settings.Settings;
import java.awt.Color;
import java.io.IOException;
import java.util.Locale;
public class HorizontalrulerCommand implements Command {
@Override
public void execute(Engine engine, State state, Settings settings) throws IOException {
Stroke.StrokeBuilder strokeBuilder = Stroke.builder()
.capStyle(Stroke.CapStyle.valueOf(settings.get("capstyie", "Cap")))
.joinStyle(Stroke.JoinStyle.valueOf(settings.get("joinstyle", "Miter")))
.capStyle(Stroke.CapStyle.valueOf(settings.get("capstyie", "cap").toUpperCase(Locale.ROOT)))
.joinStyle(Stroke.JoinStyle.valueOf(settings.get("joinstyle", "miter").toUpperCase(Locale.ROOT)))
.lineWidth(settings.getAsFloat("linewidth", 1f));
if (settings.containsSetting("dash")) {
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 java.io.IOException;
import java.util.Locale;
public class ImageCommand implements Command {
@Override
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")) {
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")) {
element.setWidth(settings.getAsFloat("width", element.getWidth()));
imageElement.setWidth(settings.getAsFloat("width", imageElement.getWidth()));
}
if (settings.containsSetting("height")) {
element.setWidth(settings.getAsFloat("height", element.getHeight()));
imageElement.setWidth(settings.getAsFloat("height", imageElement.getHeight()));
}
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.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;
public class ParagraphCommand implements Command {
@ -20,6 +22,9 @@ public class ParagraphCommand implements Command {
if (settings.containsSetting("width")) {
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);
engine.executeElements(settings);
}

View file

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

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 {
Cap(0), RoundCap(1), Square(2);
CAP(0),
ROUND_CAP(1), Square(2);
private final int value;
@ -31,7 +32,9 @@ public class Stroke {
*/
public enum JoinStyle {
Miter(0), Round(1), Bevel(2);
MITER(0),
ROUND(1),
BEVEL(2);
private final int value;
@ -103,7 +106,6 @@ public class Stroke {
public float getPhase() {
return phase;
}
}
private final CapStyle capStyle;
@ -116,7 +118,7 @@ public class Stroke {
/**
* 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.
*/
public Stroke() {
@ -125,13 +127,13 @@ public class Stroke {
/**
* 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.
*
* @param lineWidth the line width.
*/
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 {
private CapStyle capStyle = CapStyle.Cap;
private CapStyle capStyle = CapStyle.CAP;
private JoinStyle joinStyle = JoinStyle.Miter;
private JoinStyle joinStyle = JoinStyle.MITER;
private DashPattern dashPattern;

View file

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

View file

@ -1,27 +1,15 @@
package org.xbib.graphics.pdfbox.layout.table;
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.util.EnumMap;
import java.util.Map;
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 MarkupSupportedFont font;
private Font font;
private Float fontSize;
@ -33,11 +21,11 @@ public class Markup implements ParagraphProcessor {
return markup;
}
public void setFont(MarkupSupportedFont font) {
public void setFont(Font font) {
this.font = font;
}
public MarkupSupportedFont getFont() {
public Font getFont() {
return font;
}
@ -50,9 +38,9 @@ public class Markup implements ParagraphProcessor {
}
@Override
public void process(Paragraph paragraph, Parameters parameters) throws IOException {
public void process(Paragraph paragraph, Parameters parameters) {
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 Integer fontSize;
private Float fontSize;
private Color textColor;
@ -133,7 +133,7 @@ public class Parameters {
return horizontalAlignment;
}
public Integer getFontSize() {
public Float getFontSize() {
return fontSize;
}
@ -189,7 +189,7 @@ public class Parameters {
this.font = font;
}
public void setFontSize(Integer fontSize) {
public void setFontSize(Float fontSize) {
this.fontSize = fontSize;
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -14,11 +14,11 @@ public class PositionedStyledText {
private final Font font;
private final int fontSize;
private final float fontSize;
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.y = y;
this.text = text;
@ -43,7 +43,7 @@ public class PositionedStyledText {
return font;
}
public int getFontSize() {
public float getFontSize() {
return fontSize;
}

View file

@ -1,5 +1,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;
@ -7,18 +8,25 @@ import java.awt.geom.Point2D;
public class RenderContext {
private final PDDocument pdDocument;
private final PDPageContentStream contentStream;
private final PDPage page;
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.page = page;
this.startingPoint = startingPoint;
}
public PDDocument getPdDocument() {
return pdDocument;
}
public PDPageContentStream getContentStream() {
return contentStream;
}

View file

@ -23,7 +23,7 @@ public class TextCellRenderer<T extends AbstractTextCell> extends AbstractCellRe
public void renderContent(RenderContext renderContext) {
float startX = renderContext.getStartingPoint().x;
Font currentFont = cell.getFont();
int currentFontSize = cell.getFontSize();
float currentFontSize = cell.getFontSize();
Color currentTextColor = cell.getTextColor();
float yOffset = renderContext.getStartingPoint().y + getAdaptionForVerticalAlignment();
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) +
(lineIndex > 0 ? PdfUtil.getFontHeight(currentFont, currentFontSize) * cell.getLineSpacing() : 0f);
}
@ -76,7 +76,7 @@ public class TextCellRenderer<T extends AbstractTextCell> extends AbstractCellRe
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()
? PdfUtil.getOptimalTextBreakLines(cell.getText(), currentFont, currentFontSize, maxWidth)
: Collections.singletonList(cell.getText());

View file

@ -25,11 +25,11 @@ public class VerticalTextCellRenderer extends AbstractCellRenderer<VerticalTextC
@Override
public void renderContent(RenderContext renderContext) {
final float startX = renderContext.getStartingPoint().x;
final float startY = renderContext.getStartingPoint().y;
final Font currentFont = cell.getFont();
final int currentFontSize = cell.getFontSize();
final Color currentTextColor = cell.getTextColor();
float startX = renderContext.getStartingPoint().x;
float startY = renderContext.getStartingPoint().y;
Font currentFont = cell.getFont();
float currentFontSize = cell.getFontSize();
Color currentTextColor = cell.getTextColor();
float yOffset = startY + cell.getPaddingBottom();
float height = cell.getRow().getHeight();
if (cell.getRowSpan() > 1) {
@ -54,7 +54,7 @@ public class VerticalTextCellRenderer extends AbstractCellRenderer<VerticalTextC
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 {
// Rotate by 90 degrees counter clockwise
AffineTransform transform = AffineTransform.getTranslateInstance(x, y);

View file

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

View file

@ -27,7 +27,7 @@ public final class PdfUtil {
* @param fontSize FontSize of String
* @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))
.max(Comparator.comparing(String::length))
.map(x -> {
@ -40,7 +40,7 @@ public final class PdfUtil {
.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()
.mapToObj(codePoint -> new String(new int[]{codePoint}, 0, 1))
.collect(Collectors.toList());
@ -62,7 +62,7 @@ public final class PdfUtil {
* @param fontSize FontSize
* @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;
}
@ -75,7 +75,7 @@ public final class PdfUtil {
* @param maxWidth Maximal width of resulting text-lines
* @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<>();
for (String line : text.split(NEW_LINE_REGEX)) {
if (PdfUtil.doesTextLineFit(line, font, fontSize, maxWidth)) {
@ -87,7 +87,7 @@ public final class PdfUtil {
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)) {
return Collections.singletonList(line);
}
@ -101,7 +101,7 @@ public final class PdfUtil {
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<>();
for (int i = line.length() - 1; i > 0; i--) {
String fittedNewLine = line.substring(0, i) + "-";
@ -115,10 +115,7 @@ public final class PdfUtil {
return returnList;
}
private static String buildALine(Stack<String> words,
Font font,
int fontSize,
float maxWidth) {
private static String buildALine(Stack<String> words, Font font, float fontSize, float maxWidth) {
StringBuilder line = new StringBuilder();
float width = 0;
while (!words.empty()) {
@ -142,7 +139,7 @@ public final class PdfUtil {
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);
}

View file

@ -83,7 +83,7 @@ public class CustomRendererTest {
sectionNumber = ((Section) element).getNumber();
renderContext.render(renderContext, element, layoutHint);
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());
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();
Engine engine = new Engine();
engine.execute(settings);
int i = 0;
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();
}

View file

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

View file

@ -1,6 +1,7 @@
{
"type": "document",
"margin": "10 10 10 10",
"author": "Jörg Prante",
"elements": [
{
"type": "image",
@ -26,7 +27,7 @@
"type": "text",
"value": "Hello World",
"size": 24,
"font": "HELVETICA"
"font": "helvetica"
}
]
},
@ -37,7 +38,7 @@
"type": "text",
"value": "Hello World",
"size": 24,
"font": "HELVETICA"
"font": "helvetica"
}
]
},
@ -48,7 +49,7 @@
"type": "text",
"value": "Hello World",
"size": 24,
"font": "HELVETICA"
"font": "helvetica"
}
]
},
@ -62,7 +63,7 @@
"type": "text",
"value": "Hello World",
"size": 16,
"font": "NOTOSANS"
"font": "notosans"
}
]
},
@ -73,7 +74,104 @@
"type": "text",
"value": "Hello World",
"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"
}
}
}
}